first commit

This commit is contained in:
guinux 2014-10-22 18:44:02 +02:00
commit 60a34f6681
69 changed files with 9721 additions and 0 deletions

2
AUTHORS Normal file
View File

@ -0,0 +1,2 @@
Main developers:
Guillaume Benoit <guillaume@manjaro.org>

674
COPYING Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 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) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. 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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

1
README Normal file
View File

@ -0,0 +1 @@
A DBus daemon and Gtk3 frontend for libalpm written in vala

1
TODO Normal file
View File

@ -0,0 +1 @@

3
create_pot_file.sh Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
xgettext --from-code=UTF-8 --files-from=./files_to_translate --keyword=translatable --keyword=_ --output=pamac.pot

View File

@ -0,0 +1,131 @@
[Desktop Entry]
Name=Software Install
Name[af]=Sagteware installeer
Name[ar]=تثبيت البرامج
Name[as]=
Name[ast]=Instalador de software
Name[be]=Усталяванне апраграмавання
Name[bg]=Инсталиране на софтуер
Name[bn_IN]=
Name[ca]=Instal·lació de programari
Name[ca@valencia]=Instal·lació de programari
Name[cs]=Instalace softwaru
Name[da]=Softwareinstallation
Name[de]=Software-Installation
Name[el]=Εγκατάσταση λογισμικού
Name[en_GB]=Software Install
Name[es]=Instalador de software
Name[et]=Tarkvara paigaldamine
Name[eu]=Paketeen instalatzailea
Name[fa]=نصب نرمافزار
Name[fi]=Ohjelmistojen asennus
Name[fr]=Installation de logiciels
Name[gl]=Instalador de software
Name[gu]=
Name[he]=התקנת תכנה
Name[hi]= ि
Name[hu]=Szoftvertelepítő
Name[id]=Pasang Perangkat Lunak
Name[it]=Installatore software
Name[ja]=
Name[kn]=
Name[ko]=
Name[lt]=Programinės įrangos įdiegimas
Name[lv]=Programmatūras instalēšana
Name[mk]=Инсталација на софтвер
Name[ml]=
Name[mr]= ि
Name[nb]=Programvareinstallasjon
Name[nl]=Software-installatie
Name[pa]=
Name[pl]=Instalacja oprogramowania
Name[pt]=Instalar Software
Name[pt_BR]=Instalação de programas
Name[ru]=Установка программ
Name[sk]=Inštalácia softvéru
Name[sl]=Nameščanje programske opreme
Name[sr]=Инсталација софтвера
Name[sr@latin]=Instalacija softvera
Name[sv]=Programinstallation
Name[ta]= ி
Name[te]=
Name[th]=
Name[tr]=Yazılım Kur
Name[ug]=يۇمشاق دېتال ئورنات
Name[uk]=Установлення програм
Name[vi]=Cài phn mm
Name[zh_CN]=
Name[zh_HK]=
Name[zh_TW]=
Comment=Install selected software on the system
Comment[af]=Installeer gekose sagteware op die stelsel
Comment[ar]=ثبت البرمجيات المختارة على النظام
Comment[as]=ি িি
Comment[ast]=Instalar el software escoyíu nel sistema
Comment[be]=Усталяваць вылучанае апраграмаванне ў сістэму
Comment[bg]=Инсталиране на избрания софтуер на системата
Comment[bn]=ি িি
Comment[bn_IN]=ি িি
Comment[ca]=Instal·la el programari seleccionat en el sistema
Comment[ca@valencia]=Instal·la el programari seleccionat en el sistema
Comment[cs]=Instalovat vybraný software do tohoto systému
Comment[da]=Installér valgt software på systemet
Comment[de]=Ausgewählte Software auf dem System installieren
Comment[el]=Εγκατάσταση του επιλεγμένου λογισμικού στο σύστημα
Comment[en@shaw]=𐑦𐑯𐑕𐑑𐑷𐑤 𐑕𐑩𐑤𐑧𐑒𐑑𐑩𐑛 𐑕𐑪𐑓𐑑𐑢𐑺 𐑪𐑯 𐑞 𐑕𐑦𐑕𐑑𐑩𐑥
Comment[en_GB]=Install selected software on the system
Comment[eo]=Instali elektitan programaron sur the sistemo
Comment[es]=Instalar el software seleccionado en el sistema
Comment[et]=Valitud tarkvara paigaldamine arvutisse
Comment[eu]=Instalatu hautatutako softwarea sisteman
Comment[fa]=نصب نرمافزار انتخاب شده بر روی سیستم
Comment[fi]=Asenna valitut ohjelmistot järjestelmään
Comment[fr]=Installer le logiciel sélectionné sur le système
Comment[gl]=Instalar o programa seleccionado no sistema
Comment[gu]=િ િ
Comment[he]=התקנת התוכנות הנבחרות על המערכת
Comment[hi]=ि ि ि
Comment[hu]=A kijelölt szoftverek telepítése a rendszerre
Comment[id]=Pasang perangkat lunak yang dipilih pada sistem
Comment[it]=Installa il software selezionato sul sistema
Comment[ja]=
Comment[kn]=ಿ ಿ ಿ
Comment[ko]=
Comment[lt]=Įdiegti pasirinktą programinę įrangą sistemoje
Comment[lv]=Instalēt izvēlēto programmatūru sistēmā
Comment[mk]=Инсталирај го избраниот софтвер на системот
Comment[ml]= ിി
Comment[mr]= ि
Comment[nb]=Installer valgt programvare på systemet
Comment[nl]=Geselecteerde software op het systeem installeren
Comment[nn]=Installer vald programvare på systemet
Comment[or]= ି
Comment[pa]= ਿ
Comment[pl]=Instalacja wybranego oprogramowania w systemie
Comment[pt]=Instalar software seleccionado no sistema
Comment[pt_BR]=Instale o programa selecionado no sistema
Comment[ro]=Instalează pachetele selectate pe sistem
Comment[ru]=Установить в систему выбранные программы
Comment[sk]=Nainštalovať na systéme zvolený softvér
Comment[sl]=Namestitev izbrane programske opreme v sistem
Comment[sr]=Инсталирајте изабране програме на систем
Comment[sr@latin]=Instalirajte izabrane programe na sistem
Comment[sv]=Installera markerad programvara på systemet
Comment[ta]= ிிி ி
Comment[te]= ి
Comment[th]=
Comment[tr]=Seçili yazılımı sisteme kur
Comment[ug]=تاللانغان يۇمشاق دېتالنى سىستېمىغا ئورنات
Comment[uk]=Встановити у систему вибрані програми
Comment[vi]=Cài đt phn mm đã chn vào h thng
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
Categories=System;
Exec=pamac-install %F
Terminal=false
Type=Application
Icon=system-software-install
StartupNotify=true
NoDisplay=true
MimeType=application/x-xz-compressed-tar;

View File

@ -0,0 +1,139 @@
[Desktop Entry]
Name=Add/Remove Software
Name[af]=Voeg by/verwyder sagteware
Name[ar]=إضافة وإزالة البرمجيات
Name[as]= / ি
Name[ast]=Amestar/Quitar software
Name[be]=Дадаць/выдаліць апраграмаванне
Name[bg]=Инсталиране/деинсталиране на софтуер
Name[bn]= /
Name[bn_IN]= /
Name[ca]=Afegeix/Suprimeix programari
Name[ca@valencia]=Afig/Suprimeix programari
Name[cs]=Přidat/odebrat software
Name[da]=Tilføj/fjern software
Name[de]=Software hinzufügen/entfernen
Name[el]=Προσθαφαίρεση λογισμικού
Name[en@shaw]=𐑨𐑛/𐑮𐑦𐑥𐑵𐑝 𐑕𐑪𐑓𐑑𐑢𐑺
Name[en_GB]=Add/Remove Software
Name[eo]=Aldoni/forigi instalitan pogramaron
Name[es]=Añadir/Quitar software
Name[et]=Tarkvara lisamine ja eemaldamine
Name[eu]=Gehitu/Kendu softwarea
Name[fa]=افزودن/حذف نرمافزار
Name[fi]=Lisää tai poista ohjelmistoja
Name[fr]=Ajouter/supprimer des logiciels
Name[ga]=Cuir Leis/Bain Bogearraí
Name[gl]=Engadir ou eliminar programas
Name[gu]= /
Name[he]=הוספת/הסרת תכנה
Name[hi]= /
Name[hu]=Szoftver telepítése/eltávolítása
Name[id]=Tambah/Hapus Piranti Lunak
Name[it]=Aggiungi/Rimuovi software
Name[ja]=
Name[kn]= ಿ
Name[ko]= /
Name[lt]=Įdiegti ar šalinti programinę įrangą
Name[lv]=Pievienot/Izņemt programmatūru
Name[mk]=Инсталирај/избриши софтвер
Name[ml]= /
Name[mr]= /
Name[ms]=Menambah/Memadam perisian
Name[nb]=Legg til/fjern programvare
Name[nl]=Software installeren/verwijderen
Name[nn]=Legg til/fjern programvare
Name[or]= /
Name[pa]= /
Name[pl]=Dodanie/usuwanie oprogramowania
Name[pt]=Adicionar/Remover Software
Name[pt_BR]=Adicionar/remover programas
Name[ro]=Adăugare sau ștergere programe
Name[ru]=Установка и удаление программ
Name[sk]=Pridať/odstrániť softvér
Name[sl]=Upravljanje programske opreme
Name[sr]=Додај-уклони програме
Name[sr@latin]=Dodaj-ukloni programe
Name[sv]=Lägg till/Ta bort programvara
Name[ta]= /
Name[te]= ి/ిి
Name[th]=/
Name[tr]=Yazılım Ekle/Kaldır
Name[ug]=يۇمشاق دېتالنى قوش/ئۆچۈر
Name[uk]=Встановлення та вилучення програм
Name[vi]=Thêm/G phn mm
Name[zh_CN]=/
Name[zh_HK]=
Name[zh_TW]=
Comment=Add or remove software installed on the system
Comment[af]=Voeg by of verwyder sagteware geïnstalleer op die stelsel
Comment[ar]=أضف أو أزل البرمجيات المثبتة على النظام
Comment[as]= ি
Comment[ast]=Amestar o quitar software instaláu nel sistema
Comment[be]=Дадаць ці выдаліць апраграмаванне, усталяванае ў сістэме
Comment[bg]=Инсталиране и деинсталиране на софтуер към системата
Comment[bn]=ি
Comment[bn_IN]=ি ি
Comment[ca]=Afegeix o suprimeix programari instal·lat en el sistema
Comment[ca@valencia]=Afig o suprimeix programari instal·lat en el sistema
Comment[cs]=Přidat nebo odebrat software instalovaný v systému
Comment[da]=Tilføj eller fjern software installeret på systemet
Comment[de]=Auf dem System installierte Software aktualisieren oder neue Software hinzufügen
Comment[el]=Προσθαφαίρεση λογισμικού στο σύστημα
Comment[en@shaw]=𐑨𐑛 𐑹 𐑮𐑦𐑥𐑵𐑝 𐑕𐑪𐑓𐑑𐑢𐑺 𐑦𐑯𐑕𐑑𐑷𐑤𐑛 𐑪𐑯 𐑞 𐑕𐑦𐑕𐑑𐑩𐑥
Comment[en_GB]=Add or remove software installed on the system
Comment[eo]=Aldoni aŭ forigi instalitan pogramaron sur via sistemo
Comment[es]=Añadir o quitar software instalado en el sistema
Comment[et]=Arvutisse paigaldatud tarkvara lisamine ja eemaldamine
Comment[eu]=Gehitu edo kendu sisteman instalatutako softwarea
Comment[fa]=حذف یا افزودن نرمافزارهای نصب شده بر روی این سیستم
Comment[fi]=Lisää tai poista järjestelmään asennettuja ohjelmistoja
Comment[fr]=Ajouter ou supprimer des logiciels installés sur le système
Comment[gl]=Engadir e eliminar o software instalado no sistema
Comment[gu]=િ િ
Comment[he]=הוספה או הסרה של יישומי המערכת
Comment[hi]=ि ि
Comment[hu]=Szoftverek rendszerre telepítése vagy eltávolítása
Comment[id]=Tambah atau hapus perangkat lunak yang terpasang pada sistem
Comment[it]=Aggiunge o rimuove software installato sul sistema
Comment[ja]=
Comment[kn]= ಿ ಿಿ
Comment[ko]=
Comment[lt]=Įdiegti ar šalinti sistemoje įdiegtą programinę įrangą
Comment[lv]=Pievienot vai izņemt programmatūru sistēmā
Comment[mk]=Инсталирајте или избришете софтвер на системот
Comment[ml]=ിി ിി ി
Comment[mr]= ि ि
Comment[ms]=Menambah atau memadam perisian yang dipasang pada sistem
Comment[nb]=Legg til eller fjern programvare på systemet
Comment[nl]=Software installeren op, of verwijderen van het systeem
Comment[nn]=Legg til eller fjern programvare som er installert på systemet
Comment[or]= ି ି ି ି
Comment[pa]=ਿ
Comment[pl]=Instalowanie lub usuwanie oprogramowania zainstalowanego w systemie
Comment[pt]=Adicionar ou remover software instalado no sistema
Comment[pt_BR]=Adicione ou remova programas instalados no sistema
Comment[ro]=Adăugați sau ștergeți programe instalate pe sistem
Comment[ru]=Установка и удаление программ, установленных в системе
Comment[sk]=Pridať alebo odstrániť softvér nainštalovaný na systéme
Comment[sl]=Nameščanje in odstranjevanje programske opreme sistema
Comment[sr]=Додајте или уклоните програме инсталиране на овом систему
Comment[sr@latin]=Dodajte ili uklonite programe instalirane na ovom sistemu
Comment[sv]=Lägg till eller ta bort programvara installerad på systemet
Comment[ta]=ிிி ி
Comment[te]= ిి ి ిి
Comment[th]=
Comment[tr]=Sisteminizde yüklü yazılımları ekleyin veya kaldırın
Comment[ug]=سىستېمىڭىزغا ئورنىتىلغان يۇمشاق دېتاللارنى قوشىدۇ ياكى ئۆچۈرىدۇ
Comment[uk]=Встановлення та вилучення програм у системі
Comment[vi]=Thêm hoc g phn mm cài đt trên h thng
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
Icon=system-software-install
Exec=pamac-manager
Terminal=false
Type=Application
Categories=GNOME;GTK;System;
#NotShowIn=KDE;
StartupNotify=true

View File

@ -0,0 +1,7 @@
[Desktop Entry]
Name=Update Notifier
Icon=update-notifier
Exec=pamac-tray
Terminal=false
Type=Application
StartupNotify=true

View File

@ -0,0 +1,135 @@
[Desktop Entry]
Name=Software Update
Name[af]=Sagtewarebywerking
Name[ar]=تحديث البرمجيات
Name[as]=
Name[ast]=Anovamientu de software
Name[be]=Абнаўленне апраграмавання
Name[bg]=Обновление на софтуера
Name[bn]=
Name[bn_IN]=
Name[ca]=Actualització de programari
Name[ca@valencia]=Actualització de programari
Name[cs]=Aktualizace softwaru
Name[da]=Softwareopdatering
Name[de]=Software-Aktualisierungen
Name[el]=Ενημέρωση λογισμικού
Name[en@shaw]=𐑕𐑪𐑓𐑑𐑢𐑺 𐑳𐑐𐑛𐑱𐑑
Name[en_GB]=Software Update
Name[eo]=Programar-ĝistatigo
Name[es]=Actualización de software
Name[et]=Tarkvarauuendus
Name[eu]=Softwarearen eguneraketa
Name[fa]=بروزرسانی نرمافزار
Name[fi]=Ohjelmistopäivitykset
Name[fr]=Mise à jour des logiciels
Name[gl]=Actualización de software
Name[gu]=
Name[he]=עדכון תכנה
Name[hi]=
Name[hu]=Szoftverfrissítés
Name[id]=Pembaruan Perangkat Lunak
Name[it]=Aggiornamento software
Name[ja]=
Name[kn]=
Name[ko]=
Name[lt]=Programinės įrangos atnaujinimas
Name[lv]=Programmatūras atjaunināšana
Name[mk]=Ажурирање на софтвер
Name[ml]= ി
Name[mr]=
Name[nb]=Programvareoppdatering
Name[nl]=Software bijwerken
Name[nn]=Programvareoppdatering
Name[or]=
Name[pa]=
Name[pl]=Aktualizacja oprogramowania
Name[pt]=Actualização de Software
Name[pt_BR]=Atualizações de programas
Name[ro]=Actualizări de programe
Name[ru]=Обновление программ
Name[sk]=Aktualizácia softvéru
Name[sl]=Posodobitev programske opreme
Name[sr]=Ажурирање програма
Name[sr@latin]=Ažuriranje programa
Name[sv]=Programuppdatering
Name[ta]=
Name[te]=
Name[th]=
Name[tr]=Yazılım Güncelleme
Name[ug]=يۇمشاق دېتال يېڭىلاش
Name[uk]=Оновлення програм
Name[vi]=Bn cp nht phn mm
Name[zh_CN]=
Name[zh_HK]=
Name[zh_TW]=
Comment=Update software installed on the system
Comment[af]=Werk geïnstalleer sagteware op die stelsel by
Comment[ar]=حدّث الحزم المُثبّتة على النظام
Comment[as]= ি
Comment[ast]=Anovar el software instaláu nel sistema
Comment[be]=Абнаўленне апраграмавання, усталяванага ў сістэме
Comment[bg]=Обновяване на софтуера инсталиран върху системата
Comment[bn]=ি
Comment[bn_IN]=ি
Comment[ca]=Actualitza el programari instal·lat en el sistema
Comment[ca@valencia]=Actualitza el programari instal·lat en el sistema
Comment[cs]=Aktualizovat software instalovaný v tomto systému
Comment[da]=Opdatér software installeret på systemet
Comment[de]=Auf dem System installierte Software aktualisieren
Comment[el]=Ενημέρωση εγκατεστημένου λογισμικού
Comment[en@shaw]=𐑳𐑐𐑛𐑱𐑑 𐑕𐑪𐑓𐑑𐑢𐑺 𐑦𐑯𐑕𐑑𐑷𐑤𐑛 𐑪𐑯 𐑞 𐑕𐑦𐑕𐑑𐑩𐑥
Comment[en_GB]=Update software installed on the system
Comment[es]=Actualizar el software instalado en el sistema
Comment[et]=Süsteemi paigaldatud tarkvara uuendamine
Comment[eu]=Eguneratu sisteman instalatutako softwarea
Comment[fa]=بروزرسانی نرمافزار نصب شده بر روی سیستم
Comment[fi]=Päivitä järjestelmään asennettuja ohjelmistoja
Comment[fr]=Met à jour les logiciels installés sur le système
Comment[gl]=Actualizar o software instalado no sistema
Comment[gu]=િ િ
Comment[he]=עדכון תוכנות המותקנות על המערכת
Comment[hi]=ि ि
Comment[hu]=A rendszerre telepített szoftverek frissítése
Comment[id]=Mutakhirkan perangkat lunak yang terpasang pada sistem
Comment[it]=Aggiorna il software installato sul sistema
Comment[ja]=
Comment[kn]=ಿ ಿಿ
Comment[ko]=
Comment[lt]=Atnaujinti sistemoje įdiegtą programinę įrangą
Comment[lv]=Atjaunināt sistēmā instalēto programmatūru
Comment[mk]=Ажурирај го софтверот инсталирај на системот
Comment[ml]=ിി ിി ിി
Comment[mr]= ि
Comment[nb]=Oppdater programvare som er installert på systemet
Comment[nl]=Werk de op uw systeem geïnstalleerde software bij
Comment[nn]=Oppdater programvare installert på systemet
Comment[or]= ି
Comment[pa]=ਿ
Comment[pl]=Aktualizacja oprogramowania zainstalowanego w systemie
Comment[pt]=Actualizar software instalado no sistema
Comment[pt_BR]=Atualize os programas instalados no sistema
Comment[ro]=Actualizați programele instalate pe sistem
Comment[ru]=Обновление программ, установленных в системе
Comment[sk]=Aktualizovať softvér nainštalovaný na tomto systéme
Comment[sl]=Posodobitev programske opreme nameščene na sistemu
Comment[sr]=Ажурирајте програме инсталиране на овом систему
Comment[sr@latin]=Ažurirajte programe instalirane na ovom sistemu
Comment[sv]=Uppdatera programvara installerade på systemet
Comment[ta]=ிிி ி ி
Comment[te]= ిి ి
Comment[th]=
Comment[tr]=Sisteminizde yüklü yazılımı güncelleyin
Comment[ug]=يېڭىلاش يۇمشاق دېتال بۇ سىستېمىغا ئورنىتىلدى
Comment[uk]=Оновлення програм, встановлених у системі
Comment[vi]=Cp nht phn mm đã cài đt trên h thng
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
Icon=system-software-update
Exec=pamac-updater
Terminal=false
Type=Application
Categories=GNOME;GTK;System;
#NotShowIn=KDE
StartupNotify=true

11
data/config/pamac.conf Normal file
View File

@ -0,0 +1,11 @@
### Pamac configuration file
## How often to check for updates, value in hours:
RefreshPeriod = 4
## Allow Pamac to search and install packages from AUR:
EnableAUR
## When removing a package, also remove those dependencies
## that are not required by other packages (recurse option):
#RemoveUnrequiredDeps

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root can own the service -->
<policy user="root">
<allow own="org.manjaro.pamac"/>
</policy>
<!-- Allow anyone to invoke methods on the interfaces -->
<policy context="default">
<allow send_destination="org.manjaro.pamac"
send_interface="org.manjaro.pamac"/>
</policy>
</busconfig>

View File

@ -0,0 +1,5 @@
[D-BUS Service]
Name=org.manjaro.pamac
Exec=/usr/bin/pamac-daemon
User=root
SystemdService=pamac.service

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,10 @@
#!/bin/sh
INTERFACE=$1 # The interface which is brought up or down
STATUS=$2 # The new state of the interface
case "$STATUS" in
'up') # $INTERFACE is up
/usr/bin/pamac-refresh
;;
esac

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<vendor>Manjaro</vendor>
<vendor_url>http://manjaro.org/</vendor_url>
<icon_name>package-x-generic</icon_name>
<action id="org.manjaro.pamac.commit">
<message>Authentication is required</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.manjaro.pamac.write_config">
<message>Authentication is required</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

View File

@ -0,0 +1,7 @@
[Unit]
Description=Pamac
[Service]
Type=dbus
BusName=org.manjaro.pamac
ExecStart=/usr/bin/pamac-daemon

278
examples/pactree.vala Normal file
View File

@ -0,0 +1,278 @@
/*
* pactree.vala - a simple dependency tree viewer translated in Vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
* Copyright (c) 2010-2011 Pacman Development Team <pacman-dev@archlinux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Compile with: valac --pkg=libalpm --vapidir=../vapi --Xcc=-I../util ../util/alpm-util.c pactree.vala -o pactree
using Alpm;
/* output */
string provides;
string unresolvable;
string branch_tip1;
string branch_tip2;
int indent_size;
/* color */
string branch1_color;
string branch2_color;
string leaf1_color;
string leaf2_color;
string color_off;
/* globals */
Handle handle;
unowned DB localdb;
Alpm.List<string?> walked = null;
Alpm.List<string?> provisions = null;
/* options */
bool color;
bool graphviz;
bool linear;
int max_depth;
bool reverse;
bool unique;
string dbpath;
const OptionEntry[] options = {
{ "dbpath", 'b', 0, OptionArg.STRING, ref dbpath, "set an alternate database location", "path" },
{ "color", 'c', 0, OptionArg.NONE, ref color, "colorize output", null },
{ "depth", 'd', 0, OptionArg.INT, ref max_depth, "limit the depth of recursion", "number" },
{ "graph", 'g', 0, OptionArg.NONE, ref graphviz, "generate output for graphviz", null },
{ "linear", 'l', 0, OptionArg.NONE, ref linear, "enable linear output", null },
{ "reverse", 'r', 0, OptionArg.NONE, ref reverse, "show reverse dependencies", null },
{ "unique", 'u', 0, OptionArg.NONE, ref unique, "show dependencies with no duplicates (implies -l)", null },
{ null }
};
static void init_options() {
/* initialize options */
color = false;
graphviz = false;
linear = false;
max_depth = -1;
reverse = false;
unique = false;
dbpath = "/var/lib/pacman";
/* output */
provides = " provides";
unresolvable = " [unresolvable]";
branch_tip1 = "|--";
branch_tip2 = "+--";
indent_size = 3;
/* color */
branch1_color = "\033[0;33m"; /* yellow */
branch2_color = "\033[0;37m"; /* white */
leaf1_color = "\033[1;32m"; /* bold green */
leaf2_color = "\033[0;32m"; /* green */
color_off = "\033[0m";
}
static int parse_options(ref unowned string[] args) {
var opts = new OptionContext("");
opts.set_help_enabled(true);
opts.add_main_entries(options, null);
try {
bool b = opts.parse(ref args);
if (!b) {
stderr.puts(opts.get_help(false, null));
return 1;
}
}
catch (OptionError e)
{
stderr.puts("Unable to parse options : " + e.message + "\n");
return 1;
}
/* there must be (at least) one argument left */
if (args.length == 1) return 1;
/* unique implies linear */
if (unique) linear = true;
/* no color */
if (!color) {
branch1_color = branch2_color = "";
leaf1_color = leaf2_color = "";
color_off = "";
}
/* linear */
if (linear) {
provides = "";
branch_tip1 = branch_tip2 = "";
indent_size = 0;
}
return 0;
}
static void local_init() {
Alpm.Errno error;
handle = new Handle ("/", dbpath, out error);
assert (error == 0);
localdb = handle.localdb;
assert (localdb != null);
}
static int main (string[] args) {
init_options();
int ret = parse_options(ref args);
if (ret != 0) return ret;
local_init();
string? target_name = args[1];
unowned Package? pkg = find_satisfier(localdb.pkgcache, target_name);
if (pkg == null) {
stderr.printf("Error: package '%s' not found\n", target_name);
return 1;
}
/* begin writing */
print_start(pkg.name, target_name);
if(reverse)
walk_reverse_deps(pkg, 1);
else
walk_deps(pkg, 1);
print_end();
return 0;
}
static void print_text(string? pkg, string? provision, int depth)
{
int indent_sz = (depth + 1) * indent_size;
if ((pkg == null) && (provision == null)) return;
if (pkg == null) {
/* we failed to resolve provision */
stdout.printf("%s%*s%s%s%s%s%s\n", branch1_color, indent_sz, branch_tip1,
leaf1_color, provision, branch1_color, unresolvable, color_off);
} else if ((provision != null) && (provision != pkg)) {
/* pkg provides provision */
stdout.printf("%s%*s%s%s%s%s %s%s%s\n", branch2_color, indent_sz, branch_tip2,
leaf1_color, pkg, leaf2_color, provides, leaf1_color, provision,
color_off);
} else {
/* pkg is a normal package */
stdout.printf("%s%*s%s%s%s\n", branch1_color, indent_sz, branch_tip1, leaf1_color,
pkg, color_off);
}
}
/**
* walk dependencies in reverse, showing packages which require the target
*/
static void walk_reverse_deps(Package pkg, int depth) {
if((max_depth >= 0) && (depth > max_depth)) return;
walked.add(pkg.name);
unowned Alpm.List<string?> required_by = pkg.compute_requiredby ();
foreach(string? i in required_by) {
string pkgname = i;
if (walked.find_str(pkgname) != null) {
/* if we've already seen this package, don't print in "unique" output
* and don't recurse */
if (!unique) print(pkg.name, pkgname, null, depth);
} else {
print(pkg.name, pkgname, null, depth);
walk_reverse_deps(localdb.get_pkg(pkgname), depth + 1);
}
}
}
/**
* walk dependencies, showing dependencies of the target
*/
static void walk_deps(Package pkg, int depth)
{
if((max_depth >= 0) && (depth > max_depth)) return;
walked.add(pkg.name);
foreach (unowned Depend depend in pkg.depends) {
string depname = depend.name;
unowned Package? provider = find_satisfier (localdb.pkgcache, depname);
if (provider != null) {
string provname = provider.name;
if (walked.find_str (provname) != null) {
/* if we've already seen this package, don't print in "unique" output
* and don't recurse */
if (!unique) {
print (pkg.name, provname, depname, depth);
}
} else {
print (pkg.name, provname, depname, depth);
walk_deps(provider, depth + 1);
}
} else {
/* unresolvable package */
print(pkg.name, null, depname, depth);
}
}
}
static void print_graph(string parentname, string? pkgname, string? depname)
{
if(depname != null) {
stdout.printf("\"%s\" -> \"%s\" [color=chocolate4];\n", parentname, depname);
if((pkgname != null) && (depname != pkgname) && (provisions.find_str(depname) != null)) {
stdout.printf("\"%s\" -> \"%s\" [arrowhead=none, color=grey];\n", depname, pkgname);
provisions.add(depname);
}
} else if(pkgname != null) {
stdout.printf("\"%s\" -> \"%s\" [color=chocolate4];\n", parentname, pkgname);
}
}
/* parent depends on dep which is satisfied by pkg */
static void print(string? parentname, string? pkgname, string? depname, int depth)
{
if(graphviz) {
print_graph(parentname, pkgname, depname);
} else {
print_text(pkgname, depname, depth);
}
}
static void print_start(string pkgname, string provname)
{
if(graphviz) {
stdout.printf("digraph G { START [color=red, style=filled];\n" +
"node [style=filled, color=green];\n" +
" \"START\" -> \"%s\";\n", pkgname);
} else {
print_text(pkgname, provname, 0);
}
}
static void print_end()
{
if(graphviz) {
/* close graph output */
stdout.printf("}\n");
}
}

24
files_to_translate Normal file
View File

@ -0,0 +1,24 @@
./resources/choose_provider_dialog.ui
./resources/packages_chooser_dialog.ui
./resources/progress_window.ui
./resources/history_dialog.ui
./resources/transaction_info_dialog.ui
./resources/transaction_sum_dialog.ui
./resources/manager_window.ui
./resources/updater_window.ui
./resources/preferences_dialog.ui
./src/packages_chooser_dialog.vala
./src/transaction_info_dialog.vala
./src/history_dialog.vala
./src/transaction_sum_dialog.vala
./src/installer.vala
./src/tray.vala
./src/manager.vala
./src/preferences_dialog.vala
./src/updater.vala
./src/choose_provider_dialog.vala
./src/manager_window.vala
./src/progress_window.vala
./src/updater_window.vala
./src/common.vala

279
pamac.pot Normal file
View File

@ -0,0 +1,279 @@
# Translation of Pamac.
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
# This file is distributed under the same license as the Pamac package.
# Guillaume Benoit <guillaume@manjaro.org>, 2013-2014.
#
msgid ""
msgstr ""
"Project-Id-Version: pamac 2.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-13-10 15:09+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: data/polkit/org.manjaro.pamac.policy:10
msgid "Authentication is required"
msgstr ""
#: resources/choose_provider_dialog.ui:7
msgid "Choose a Provider"
msgstr ""
#: resources/packages_chooser_dialog.ui:7 resources/manager_window.ui:789
msgid "Install local packages"
msgstr ""
#: resources/progress_window.ui:16
msgid "Progress"
msgstr ""
#: resources/progress_window.ui:63 resources/transaction_info_dialog.ui:84
msgid "details"
msgstr ""
#: resources/history_dialog.ui:7
msgid "Pamac History"
msgstr ""
#: resources/manager_window.ui:14 src/tray.vala:76
msgid "Package Manager"
msgstr ""
#: resources/manager_window.ui:23
msgid "Refresh"
msgstr ""
#: resources/manager_window.ui:47
msgid "Apply changes"
msgstr ""
#: resources/manager_window.ui:71
msgid "Cancel"
msgstr ""
#: resources/manager_window.ui:170
msgid "Search in AUR"
msgstr ""
#: resources/manager_window.ui:234
msgid "Search"
msgstr ""
#: resources/manager_window.ui:279 src/manager_window.vala:336
msgid "Groups"
msgstr ""
#: resources/manager_window.ui:325 resources/manager_window.ui:418
msgid "State"
msgstr ""
#: resources/manager_window.ui:371
msgid "Repos"
msgstr ""
#: resources/manager_window.ui:433
msgid "Name"
msgstr ""
#: resources/manager_window.ui:448
msgid "Version"
msgstr ""
#: resources/manager_window.ui:463
msgid "Repo"
msgstr ""
#: resources/manager_window.ui:478
msgid "Size"
msgstr ""
#: resources/manager_window.ui:582
msgid "Infos"
msgstr ""
#: resources/manager_window.ui:642
msgid "Deps"
msgstr ""
#: resources/manager_window.ui:707
msgid "Details"
msgstr ""
#: resources/manager_window.ui:740
msgid "Files"
msgstr ""
#: resources/manager_window.ui:779
msgid "View History"
msgstr ""
#: resources/updater_window.ui:14 src/tray.vala:73 src/tray.vala:166
#: src/tray.vala:238
msgid "Update Manager"
msgstr ""
#: resources/preferences_dialog.ui:6
msgid "Pamac Preferences"
msgstr ""
#: resources/preferences_dialog.ui:74
msgid "Enable AUR support"
msgstr ""
#: resources/preferences_dialog.ui:87
msgid "Allow Pamac to search and install packages from AUR"
msgstr ""
#: resources/preferences_dialog.ui:105
msgid "Remove unrequired dependencies"
msgstr ""
#: resources/preferences_dialog.ui:118
msgid ""
"When removing a package, also remove those dependencies that are not "
"required by other packages"
msgstr ""
#: resources/preferences_dialog.ui:152 src/preferences_dialog.vala:37
msgid "How often to check for updates, value in hours"
msgstr ""
#: resources/preferences_dialog.ui:177
msgid "Options"
msgstr ""
#: src/packages_chooser_dialog.vala:32
msgid "Packages"
msgstr ""
#: src/tray.vala:24 src/updater_window.vala:167
msgid "{number} available updates"
msgstr ""
#: src/tray.vala:25 src/updater_window.vala:164
msgid "1 available update"
msgstr ""
#: src/tray.vala:27 src/updater_window.vala:56 src/updater_window.vala:161
msgid "Your system is up-to-date"
msgstr ""
#: src/tray.vala:79
msgid "Quit"
msgstr ""
#: src/tray.vala:167
msgid "Show available updates"
msgstr ""
#: src/manager_window.vala:179 src/manager_window.vala:777
msgid "local"
msgstr ""
#: src/manager_window.vala:183 src/manager_window.vala:250
#: src/manager_window.vala:262 src/manager_window.vala:737
msgid "Installed"
msgstr ""
#: src/manager_window.vala:185 src/manager_window.vala:751
msgid "Orphans"
msgstr ""
#: src/manager_window.vala:186 src/manager_window.vala:720
msgid "To install"
msgstr ""
#: src/manager_window.vala:187 src/manager_window.vala:731
msgid "To remove"
msgstr ""
#: src/manager_window.vala:210
msgid "Licenses"
msgstr ""
#: src/manager_window.vala:232
msgid "Depends On"
msgstr ""
#: src/manager_window.vala:252
msgid "Optional Deps"
msgstr ""
#: src/manager_window.vala:272
msgid "Required By"
msgstr ""
#: src/manager_window.vala:286
msgid "Provides"
msgstr ""
#: src/manager_window.vala:299
msgid "Replaces"
msgstr ""
#: src/manager_window.vala:312
msgid "Conflicts With"
msgstr ""
#: src/manager_window.vala:328
msgid "Repository"
msgstr ""
#: src/manager_window.vala:346
msgid "Packager"
msgstr ""
#: src/manager_window.vala:352
msgid "Install Date"
msgstr ""
#: src/manager_window.vala:356
msgid "Explicitly installed"
msgstr ""
#: src/manager_window.vala:358
msgid "Installed as a dependency for another package"
msgstr ""
#: src/manager_window.vala:360
msgid "Unknown"
msgstr ""
#: src/manager_window.vala:362
msgid "Install Reason"
msgstr ""
#: src/manager_window.vala:367
msgid "Signatures"
msgstr ""
#: src/manager_window.vala:375
msgid "Backup files"
msgstr ""
#: src/manager_window.vala:497
msgid "No package found"
msgstr ""
#: src/manager_window.vala:739
msgid "Uninstalled"
msgstr ""
#: src/updater_window.vala:173
msgid "Total download size:"
msgstr ""
#: src/common.vala:62
#, c-format
msgid "%.0f KiB"
msgstr ""
#: src/common.vala:65
#, c-format
msgid "%.2f MiB"
msgstr ""

21
pot_head Normal file
View File

@ -0,0 +1,21 @@
# Translation of Pamac.
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
# This file is distributed under the same license as the Pamac package.
# Guillaume Benoit <guillaume@manjaro.org>, 2013-2014.
#
msgid ""
msgstr ""
"Project-Id-Version: pamac 2.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-30 15:09+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: data/polkit/org.manjaro.pamac.policy:10
msgid "Authentication is required"
msgstr ""

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacChooseProviderDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Choose a Provider</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox2">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area2">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="track_visited_links">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="comboboxtext">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">button</action-widget>
</action-widgets>
</template>
</interface>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacHistoryDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Pamac History</property>
<property name="default_width">600</property>
<property name="default_height">500</property>
<property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="close_button">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">300</property>
<property name="min_content_height">400</property>
<child>
<object class="GtkTextView" id="textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="pixels_above_lines">2</property>
<property name="pixels_below_lines">2</property>
<property name="editable">False</property>
<property name="cursor_visible">False</property>
<signal name="size-allocate" handler="on_textview_size_allocate" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-7">close_button</action-widget>
</action-widgets>
</template>
</interface>

818
resources/manager_window.ui Normal file
View File

@ -0,0 +1,818 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacManagerWindow" parent="GtkApplicationWindow">
<property name="visible">True</property>
<property name="window_position">center</property>
<property name="default_width">900</property>
<property name="default_height">600</property>
<property name="icon_name">system-software-install</property>
<property name="show_menubar">True</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
<property name="title" translatable="yes">Package Manager</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="refresh_button">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Refresh</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/>
<style>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage" id="refresh-icon">
<property name="visible">True</property>
<property name="icon-name">view-refresh-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">start</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="valid_button">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Apply changes</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_valid_button_clicked" swapped="no"/>
<style>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage" id="valid-icon">
<property name="visible">True</property>
<property name="icon-name">emblem-ok-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">start</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Cancel</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/>
<style>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage" id="cancel-icon">
<property name="visible">True</property>
<property name="icon-name">edit-delete-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">start</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="pack_type">start</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<child>
<object class="GtkMenuButton" id="menu_button">
<property name="visible">True</property>
<property name="popup">main_menu</property>
<property name="use_popover">True</property>
<style>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage" id="menu-icon">
<property name="visible">True</property>
<property name="icon-name">emblem-system-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkPaned" id="paned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkNotebook" id="filters_notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="switch-page" handler="on_filters_notebook_switch_page" after="yes" swapped="no"/>
<child>
<object class="GtkBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
<property name="caps_lock_warning">False</property>
<property name="primary_icon_name">edit-find-symbolic</property>
<signal name="activate" handler="on_search_entry_activate" swapped="no"/>
<signal name="icon-press" handler="on_search_entry_icon_press" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="search_aur_label">
<property name="label" translatable="yes">Search in AUR</property>
<property name="visible">True</property>
<property name="halign">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="search_aur_button">
<property name="visible">True</property>
<property name="halign">2</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="search_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="search_treeview_selection">
<signal name="changed" handler="on_search_treeview_selection_changed" after="yes" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="Terms">
<child>
<object class="GtkCellRendererText" id="cellrenderertext8"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="tab1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Search</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="groups_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="groups_treeview_selection">
<signal name="changed" handler="on_groups_treeview_selection_changed" after="yes" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="Groups">
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="tab2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Groups</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="states_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="states_treeview_selection">
<signal name="changed" handler="on_states_treeview_selection_changed" after="yes" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="State">
<child>
<object class="GtkCellRendererText" id="cellrenderertext9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="tab3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">State</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow8">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="repos_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="repos_treeview_selection">
<signal name="changed" handler="on_repos_treeview_selection_changed" after="yes" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="Repos">
<child>
<object class="GtkCellRendererText" id="cellrenderertext10"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="tab4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Repos</property>
</object>
<packing>
<property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkPaned" id="paned2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="packages_treeview">
<property name="width_request">500</property>
<property name="height_request">300</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="reorderable">True</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<signal name="button-press-event" handler="on_list_treeview_button_press_event" swapped="no"/>
<signal name="row-activated" handler="on_packages_treeview_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="packages_treeview_selection">
<signal name="changed" handler="on_packages_treeview_selection_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="state_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">State</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_state_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererPixbuf" id="state_rendererpixbuf"/>
<attributes>
<attribute name="pixbuf">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="name_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Name</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_name_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="name_renderertext"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="version_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Version</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_version_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="version_renderertext"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="repo_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Repo</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_repo_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="repo_renderertext"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="size_column">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Size</property>
<property name="clickable">True</property>
<signal name="clicked" handler="on_size_column_clicked" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="size_renderertext"/>
<attributes>
<attribute name="text">4</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="infos_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="name_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">1</property>
<property name="margin">6</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="desc_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">1</property>
<property name="margin">6</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="link_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="halign">1</property>
<property name="margin">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="licenses_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">1</property>
<property name="margin">6</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Infos</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="deps_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="deps_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="deps_treeview_selection">
<property name="mode">none</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="dep_type">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext12">
<property name="yalign">0</property>
<property name="weight">600</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="deps">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext13"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Deps</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="details_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="details_treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection6">
<property name="mode">none</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="infotype">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1">
<property name="yalign">0</property>
<property name="weight">600</property>
<property name="wrap_mode">word</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="type">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext4">
<property name="wrap_mode">word</property>
</object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Details</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="files_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="files_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="pixels_above_lines">3</property>
<property name="editable">False</property>
<property name="left_margin">6</property>
<property name="right_margin">6</property>
<property name="cursor_visible">False</property>
<property name="input_purpose">name</property>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="files_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Files</property>
</object>
<packing>
<property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
</child>
</template>
<object class="GtkImage" id="file_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-file</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="local_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">emblem-package</property>
</object>
<object class="GtkMenu" id="main_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="history_item">
<property name="label" translatable="yes">View History</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">file_icon</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_history_item_activate" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="local_item">
<property name="label" translatable="yes">Install local packages</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">local_icon</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_local_item_activate" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="preferences_item">
<property name="label">gtk-preferences</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_preferences_item_activate" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="about_item">
<property name="label">gtk-about</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_about_item_activate" swapped="no"/>
</object>
</child>
</object>
</interface>

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacPackagesChooserDialog" parent="GtkFileChooserDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Install local packages</property>
<property name="role">GtkFileChooserDialog</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">900</property>
<property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property>
<property name="create_folders">False</property>
<property name="local_only">False</property>
<property name="select_multiple">True</property>
<signal name="file-activated" handler="on_file_activated" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="filechooserdialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="filechooserdialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="package_cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="package_open_button">
<property name="label">gtk-open</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">package_cancel_button</action-widget>
<action-widget response="-3">package_open_button</action-widget>
</action-widgets>
</template>
</interface>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/manjaro/pamac/transaction">
<file preprocess="xml-stripblanks">progress_window.ui</file>
<file preprocess="xml-stripblanks">choose_provider_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_sum_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_info_dialog.ui</file>
</gresource>
</gresources>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/manjaro/pamac/manager">
<file preprocess="xml-stripblanks">manager_window.ui</file>
<file preprocess="xml-stripblanks">history_dialog.ui</file>
<file preprocess="xml-stripblanks">packages_chooser_dialog.ui</file>
<file preprocess="to-pixdata">package-available.png</file>
<file preprocess="to-pixdata">package-install.png</file>
<file preprocess="to-pixdata">package-installed-locked.png</file>
<file preprocess="to-pixdata">package-installed-updated.png</file>
<file preprocess="to-pixdata">package-reinstall.png</file>
<file preprocess="to-pixdata">package-remove.png</file>
</gresource>
<gresource prefix="/org/manjaro/pamac/preferences">
<file preprocess="xml-stripblanks">preferences_dialog.ui</file>
</gresource>
<gresource prefix="/org/manjaro/pamac/transaction">
<file preprocess="xml-stripblanks">progress_window.ui</file>
<file preprocess="xml-stripblanks">choose_provider_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_sum_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_info_dialog.ui</file>
</gresource>
</gresources>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/manjaro/pamac/updater">
<file preprocess="xml-stripblanks">updater_window.ui</file>
</gresource>
<gresource prefix="/org/manjaro/pamac/preferences">
<file preprocess="xml-stripblanks">preferences_dialog.ui</file>
</gresource>
<gresource prefix="/org/manjaro/pamac/transaction">
<file preprocess="xml-stripblanks">progress_window.ui</file>
<file preprocess="xml-stripblanks">choose_provider_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_sum_dialog.ui</file>
<file preprocess="xml-stripblanks">transaction_info_dialog.ui</file>
</gresource>
</gresources>

View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacPreferencesDialog" parent="GtkDialog">
<property name="border_width">12</property>
<property name="title" translatable="yes">Pamac Preferences</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">300</property>
<property name="default_height">250</property>
<property name="icon_name">system-software-install</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="preferences_valid_button">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="preferences_close_button">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="enable_aur_label">
<property name="label" translatable="yes">Enable AUR support</property>
<property name="visible">True</property>
<property name="halign">1</property>
<property name="margin">6</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="enable_aur_button">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Allow Pamac to search and install packages from AUR</property>
<property name="halign">2</property>
<property name="margin">3</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="remove_unrequired_deps_label">
<property name="label" translatable="yes">Remove unrequired dependencies</property>
<property name="visible">True</property>
<property name="halign">1</property>
<property name="margin">6</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="remove_unrequired_deps_button">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">When removing a package, also remove those dependencies that are not required by other packages</property>
<property name="halign">2</property>
<property name="margin">3</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="refresh_period_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">1</property>
<property name="margin">6</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="refresh_period_spin_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">2</property>
<property name="margin">3</property>
<property name="tooltip_text" translatable="yes">How often to check for updates, value in hours</property>
<property name="caps_lock_warning">False</property>
<property name="input_purpose">number</property>
<property name="adjustment">adjustment</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="tab_label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Options</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">preferences_valid_button</action-widget>
<action-widget response="-7">preferences_close_button</action-widget>
</action-widgets>
</template>
<object class="GtkAdjustment" id="adjustment">
<property name="lower">1</property>
<property name="upper">10000</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
</interface>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacProgressWindow" parent="GtkWindow">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">500</property>
<property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property>
<property name="deletable">False</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="manager_headerbar">
<property name="visible">True</property>
<property name="title" translatable="yes">Progress</property>
<property name="show_close_button">True</property>
</object>
</child>
<child>
<object class="GtkBox" id="box8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">0</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="action_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progressbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_text">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="resize_toplevel">True</property>
<child>
<placeholder/>
</child>
<child type="label">
<object class="GtkLabel" id="expander_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">details</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButtonBox" id="buttonbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="close_button">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacTransactionInfoDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="default_width">300</property>
<property name="icon_name">system-software-install</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox4">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area4">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="resize_toplevel">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="width_request">450</property>
<property name="height_request">200</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="pixels_above_lines">3</property>
<property name="editable">False</property>
<property name="left_margin">6</property>
<property name="right_margin">6</property>
<property name="cursor_visible">False</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="expander_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">details</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">button</action-widget>
</action-widgets>
</template>
</interface>

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacTransactionSumDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox6">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area6">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="valid_button">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="top_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">330</property>
<property name="min_content_height">250</property>
<child>
<object class="GtkTreeView" id="treeview">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection">
<property name="mode">none</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="_action">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext5">
<property name="yalign">0</property>
<property name="weight">600</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="_packages">
<property name="sizing">autosize</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext6"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">cancel_button</action-widget>
<action-widget response="-5">valid_button</action-widget>
</action-widgets>
</template>
</interface>

191
resources/updater_window.ui Normal file
View File

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="PamacUpdaterWindow" parent="GtkApplicationWindow">
<property name="visible">True</property>
<property name="border_width">6</property>
<property name="window_position">center</property>
<property name="default_width">500</property>
<property name="icon_name">system-software-update</property>
<property name="show_menubar">True</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<property name="title" translatable="yes">Update Manager</property>
<property name="show_close_button">True</property>
</object>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="top_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="width_request">400</property>
<property name="height_request">400</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkTreeView" id="updates_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="search_column">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<property name="mode">none</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<child>
<object class="GtkCellRendererText" id="_name"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<child>
<object class="GtkCellRendererText" id="_size"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">12</property>
<child>
<object class="GtkButtonBox" id="buttonbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="preferences_button">
<property name="label">gtk-preferences</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_preferences_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButtonBox" id="buttonbox1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="spacing">6</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="refresh_button">
<property name="label">gtk-refresh</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="apply_button">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_apply_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="close_button">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

146
src/Makefile Normal file
View File

@ -0,0 +1,146 @@
COMMON_VALA_FLAGS = --pkg=libalpm \
--pkg=gio-2.0 \
--pkg=posix \
--pkg=json-glib-1.0 \
--pkg=libsoup-2.4 \
--vapidir=../vapi \
--Xcc=-I../util \
-X -D_FILE_OFFSET_BITS=64 \
--target-glib=2.38
COMMON_SOURCES = ../util/alpm-util.c \
alpm_config.vala \
pamac_config.vala \
aur.vala \
common.vala
MANAGER_GRESOURCE_FILE = ../resources/pamac.manager.gresource.xml
MANAGER_RESOURCES_FILES = ../resources/manager_window.ui \
../resources/packages_chooser_dialog.ui \
../resources/history_dialog.ui \
../resources/preferences_dialog.ui \
../resources/progress_window.ui \
../resources/choose_provider_dialog.ui \
../resources/transaction_sum_dialog.ui \
../resources/transaction_info_dialog.ui \
../resources/package-available.png \
../resources/package-install.png \
../resources/package-installed-locked.png \
../resources/package-installed-updated.png \
../resources/package-reinstall.png \
../resources/package-remove.png
UPDATER_GRESOURCE_FILE = ../resources/pamac.updater.gresource.xml
UPDATER_RESOURCES_FILES = ../resources/updater_window.ui \
../resources/preferences_dialog.ui \
../resources/progress_window.ui \
../resources/choose_provider_dialog.ui \
../resources/transaction_sum_dialog.ui \
../resources/transaction_info_dialog.ui
INSTALLER_GRESOURCE_FILE = ../resources/pamac.installer.gresource.xml
INSTALLER_RESOURCES_FILES = ../resources/progress_window.ui \
../resources/choose_provider_dialog.ui \
../resources/transaction_sum_dialog.ui \
../resources/transaction_info_dialog.ui
DIALOGS_FILES = choose_provider_dialog.vala \
transaction_sum_dialog.vala \
transaction_info_dialog.vala \
progress_window.vala
pamac-daemon: $(COMMON_SOURCES) daemon.vala
valac -o pamac-daemon \
$(COMMON_VALA_FLAGS) \
--pkg=polkit-gobject-1 \
-X -DGETTEXT_PACKAGE="pacman" \
--thread \
$(COMMON_SOURCES) \
daemon.vala
pamac-tray: $(COMMON_SOURCES) tray.vala
valac -o pamac-tray \
$(COMMON_VALA_FLAGS) \
--pkg=gtk+-3.0 \
--pkg=libnotify \
-X -DGETTEXT_PACKAGE="pamac" \
$(COMMON_SOURCES) \
tray.vala
manager_resources.c: $(MANAGER_GRESOURCE_FILE) $(MANAGER_RESOURCES_FILES)
glib-compile-resources $(MANAGER_GRESOURCE_FILE) --sourcedir=../resources --target=manager_resources.c --generate-source
updater_resources.c: $(UPDATER_GRESOURCE_FILE) $(UPDATER_RESOURCES_FILES)
glib-compile-resources $(UPDATER_GRESOURCE_FILE) --sourcedir=../resources --target=updater_resources.c --generate-source
installer_resources.c: $(INSTALLER_GRESOURCE_FILE) $(INSTALLER_RESOURCES_FILES)
glib-compile-resources $(INSTALLER_GRESOURCE_FILE) --sourcedir=../resources --target=installer_resources.c --generate-source
pamac-manager: $(COMMON_SOURCES) $(DIALOGS_FILES) preferences_dialog.vala history_dialog.vala packages_chooser_dialog.vala manager_resources.c package.vala transaction.vala packages_model.vala manager_window.vala manager.vala
valac -o pamac-manager \
$(COMMON_VALA_FLAGS) \
--pkg=gtk+-3.0 \
--pkg=gmodule-2.0 \
--pkg=gdk-3.0 \
--pkg=vte-2.91 \
--gresources=$(MANAGER_GRESOURCE_FILE) \
-X -DGETTEXT_PACKAGE="pamac" \
$(COMMON_SOURCES) \
$(DIALOGS_FILES) \
preferences_dialog.vala \
history_dialog.vala \
packages_chooser_dialog.vala \
manager_resources.c \
package.vala \
transaction.vala \
packages_model.vala \
manager_window.vala \
manager.vala
pamac-updater: $(COMMON_SOURCES) $(DIALOGS_FILES) preferences_dialog.vala updater_resources.c transaction.vala updater_window.vala updater.vala
valac -o pamac-updater \
$(COMMON_VALA_FLAGS) \
--pkg=gtk+-3.0 \
--pkg=gmodule-2.0 \
--pkg=vte-2.91 \
--gresources=$(UPDATER_GRESOURCE_FILE) \
-X -DGETTEXT_PACKAGE="pamac" \
$(COMMON_SOURCES) \
$(DIALOGS_FILES) \
preferences_dialog.vala \
updater_resources.c \
transaction.vala \
updater_window.vala \
updater.vala
pamac-install: $(COMMON_SOURCES) $(DIALOGS_FILES) installer_resources.c transaction.vala installer.vala
valac -o pamac-install \
$(COMMON_VALA_FLAGS) \
--pkg=gtk+-3.0 \
--pkg=gmodule-2.0 \
--pkg=vte-2.91 \
--gresources=$(INSTALLER_GRESOURCE_FILE) \
-X -DGETTEXT_PACKAGE="pamac" \
$(COMMON_SOURCES) \
$(DIALOGS_FILES) \
installer_resources.c \
transaction.vala \
installer.vala
all: pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install
clean:
rm -f *.c pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install
install:
install -Dm744 pamac-daemon /usr/bin/pamac-daemon
install -Dm755 pamac-tray /usr/bin/pamac-tray
install -Dm755 pamac-manager /usr/bin/pamac-manager
install -Dm755 pamac-updater /usr/bin/pamac-updater
install -Dm755 pamac-install /usr/bin/pamac-install
uninstall:
rm -f /usr/bin/pamac-daemon /usr/bin/pamac-updater /usr/bin/pamac-tray /usr/bin/pamac-manager /usr/bin/pamac-install

258
src/alpm_config.vala Normal file
View File

@ -0,0 +1,258 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Alpm {
class Repo {
public string name;
public SigLevel siglevel;
public string[] urls;
public Repo (string name) {
this.name = name;
urls = {};
}
}
public class Config {
public Handle handle;
private string[] priv_holdpkg;
private string[] priv_syncfirst;
public string[] holdpkg;
public string[] syncfirst;
SigLevel siglevel;
SigLevel localfilesiglevel;
SigLevel remotefilesiglevel;
Repo[] repo_order;
public Config (string path) {
// rootdir and dbpath are hardcoded so we parse config file only once
const string rootdir = "/";
const string dbpath = "/var/lib/pacman";
Alpm.Errno error;
handle = new Handle (rootdir, dbpath, out error);
const string gpgdir = "/etc/pacman.d/gnupg/";
const string logfile = "/var/log/pacman.log";
const string cachedir = "/var/cache/pacman/pkg/";
priv_holdpkg = {};
priv_syncfirst = {};
siglevel = SigLevel.PACKAGE | SigLevel.PACKAGE_OPTIONAL | SigLevel.DATABASE | SigLevel.DATABASE_OPTIONAL;
localfilesiglevel = SigLevel.USE_DEFAULT;
remotefilesiglevel = SigLevel.USE_DEFAULT;
repo_order = {};
// parse conf file
parse_file (path);
// check essential settings
if (handle.gpgdir == null) handle.gpgdir = gpgdir;
if (handle.logfile == null) handle.logfile = logfile;
if (handle.arch == null) handle.arch = Posix.utsname().machine;
if (handle.cachedirs == null) handle.add_cachedir(cachedir);
// register dbs
foreach (Repo repo in repo_order) {
unowned DB db = handle.register_syncdb (repo.name, repo.siglevel);
foreach (string url in repo.urls) {
db.add_server (url.replace ("$repo", repo.name).replace ("$arch", handle.arch));
}
}
}
public void parse_file (string path, string? section = null) {
string current_section = section;
var file = GLib.File.new_for_path (path);
if (file.query_exists () == false)
GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ());
else {
try {
// Open file for reading and wrap returned FileInputStream into a
// DataInputStream, so we can read line by line
var dis = new DataInputStream (file.read ());
string line;
// Read lines until end of file (null) is reached
while ((line = dis.read_line (null)) != null) {
line = line.strip ();
if (line.length == 0) continue;
if (line[0] == '#') continue;
if (line[0] == '[' && line[line.length-1] == ']') {
current_section = line[1:-1];
if (current_section != "options") {
Repo repo = new Repo (current_section);
repo.siglevel = siglevel;
repo_order += repo;
}
continue;
}
string[] splitted = line.split ("=");
string _key = splitted[0].strip ();
string _value = null;
if (splitted[1] != null)
_value = splitted[1].strip ();
if (_key == "Include")
parse_file (_value, current_section);
if (current_section == "options") {
if (_key == "GPGDir")
handle.gpgdir = _value;
else if (_key == "LogFile")
handle.logfile = _value;
else if (_key == "Architecture") {
if (_value == "auto")
handle.arch = Posix.utsname ().machine;
else
handle.arch = _value;
} else if (_key == "UseDelta")
handle.deltaratio = double.parse (_value);
else if (_key == "UseSysLog")
handle.usesyslog = 1;
else if (_key == "CheckSpace")
handle.checkspace = 1;
else if (_key == "SigLevel")
siglevel = define_siglevel (siglevel, _value);
else if (_key == "LocalSigLevel")
handle.localfilesiglevel = merge_siglevel (siglevel, define_siglevel (localfilesiglevel, _value));
else if (_key == "RemoteSigLevel")
handle.remotefilesiglevel = merge_siglevel (siglevel, define_siglevel (remotefilesiglevel, _value));
else if (_key == "HoldPkg") {
foreach (string name in _value.split (" ")) {
priv_holdpkg += name;
}
} else if (_key == "SyncFirst") {
foreach (string name in _value.split (" ")) {
priv_syncfirst += name;
}
} else if (_key == "CacheDir") {
foreach (string dir in _value.split (" ")) {
handle.add_cachedir (dir);
}
} else if (_key == "IgnoreGroup") {
foreach (string name in _value.split (" ")) {
handle.add_ignoregroup (name);
}
} else if (_key == "IgnorePkg") {
foreach (string name in _value.split (" ")) {
handle.add_ignorepkg (name);
}
} else if (_key == "Noextract") {
foreach (string name in _value.split (" ")) {
handle.add_noextract (name);
}
} else if (_key == "NoUpgrade") {
foreach (string name in _value.split (" ")) {
handle.add_noupgrade (name);
}
}
} else {
foreach (Repo _repo in repo_order) {
if (_repo.name == current_section) {
if (_key == "Server")
_repo.urls += _value;
else if (_key == "SigLevel")
_repo.siglevel = define_siglevel(siglevel, _value);
}
}
}
}
} catch (GLib.Error e) {
GLib.stderr.printf("%s\n", e.message);
}
holdpkg = priv_holdpkg;
syncfirst = priv_syncfirst;
}
}
public SigLevel define_siglevel (SigLevel default_level, string conf_string) {
foreach (string directive in conf_string.split(" ")) {
bool affect_package = false;
bool affect_database = false;
if ("Package" in directive) affect_package = true;
else if ("Database" in directive) affect_database = true;
else {
affect_package = true;
affect_database = true;
}
if ("Never" in directive) {
if (affect_package) {
default_level &= ~SigLevel.PACKAGE;
default_level |= SigLevel.PACKAGE_SET;
}
if (affect_database) default_level &= ~SigLevel.DATABASE;
}
else if ("Optional" in directive) {
if (affect_package) {
default_level |= SigLevel.PACKAGE;
default_level |= SigLevel.PACKAGE_OPTIONAL;
default_level |= SigLevel.PACKAGE_SET;
}
if (affect_database) {
default_level |= SigLevel.DATABASE;
default_level |= SigLevel.DATABASE_OPTIONAL;
}
}
else if ("Required" in directive) {
if (affect_package) {
default_level |= SigLevel.PACKAGE;
default_level &= ~SigLevel.PACKAGE_OPTIONAL;
default_level |= SigLevel.PACKAGE_SET;
}
if (affect_database) {
default_level |= SigLevel.DATABASE;
default_level &= ~SigLevel.DATABASE_OPTIONAL;
}
}
else if ("TrustedOnly" in directive) {
if (affect_package) {
default_level &= ~SigLevel.PACKAGE_MARGINAL_OK;
default_level &= ~SigLevel.PACKAGE_UNKNOWN_OK;
default_level |= SigLevel.PACKAGE_TRUST_SET;
}
if (affect_database) {
default_level &= ~SigLevel.DATABASE_MARGINAL_OK;
default_level &= ~SigLevel.DATABASE_UNKNOWN_OK;
}
}
else if ("TrustAll" in directive) {
if (affect_package) {
default_level |= SigLevel.PACKAGE_MARGINAL_OK;
default_level |= SigLevel.PACKAGE_UNKNOWN_OK;
default_level |= SigLevel.PACKAGE_TRUST_SET;
}
if (affect_database) {
default_level |= SigLevel.DATABASE_MARGINAL_OK;
default_level |= SigLevel.DATABASE_UNKNOWN_OK;
}
}
else GLib.stderr.printf("unrecognized siglevel: %s\n", conf_string);
}
default_level &= ~SigLevel.USE_DEFAULT;
return default_level;
}
public SigLevel merge_siglevel (SigLevel base_level, SigLevel over_level) {
if ((over_level & SigLevel.USE_DEFAULT) != 0) over_level = base_level;
else {
if ((over_level & SigLevel.PACKAGE_SET) == 0) {
over_level |= base_level & SigLevel.PACKAGE;
over_level |= base_level & SigLevel.PACKAGE_OPTIONAL;
}
if ((over_level & SigLevel.PACKAGE_TRUST_SET) == 0) {
over_level |= base_level & SigLevel.PACKAGE_MARGINAL_OK;
over_level |= base_level & SigLevel.PACKAGE_UNKNOWN_OK;
}
}
return over_level;
}
}
}

102
src/aur.vala Normal file
View File

@ -0,0 +1,102 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//~ const string srcpkgdir = "/tmp/pamac";
namespace AUR {
// AUR urls
const string aur_url = "http://aur.archlinux.org";
const string rpc_url = aur_url + "/rpc.php";
const string rpc_search = "?type=search&arg=";
const string rpc_info = "?type=info&arg=";
const string rpc_multiinfo = "?type=multiinfo";
const string rpc_multiinfo_arg = "&arg[]=";
const string aur_url_id = "/packages.php?setlang=en&ID=";
public Json.Array search (string needle) {
string uri = rpc_url + rpc_search + needle;
var session = new Soup.Session ();
var message = new Soup.Message ("GET", uri);
session.send_message (message);
Json.Array results = new Json.Array ();
try {
var parser = new Json.Parser ();
parser.load_from_data ((string) message.response_body.flatten ().data, -1);
unowned Json.Object root_object = parser.get_root ().get_object ();
results = root_object.get_array_member ("results");
//~ foreach (unowned Json.Node node in results.get_elements ()) {
//~ Json.Object pkg_info = node.get_object ();
//~ results.append (new Pamac.Package (null, pkg_info));
//~ }
} catch (Error e) {
print (e.message);
}
return results;
}
public Json.Object? info (string pkgname) {
unowned Json.Object? pkg_info = null;
string uri = rpc_url + rpc_info + pkgname;
stdout.printf("get %s from AUR\n", pkgname);
var session = new Soup.Session ();
var message = new Soup.Message ("GET", uri);
session.send_message (message);
try {
var parser = new Json.Parser ();
parser.load_from_data ((string) message.response_body.flatten ().data, -1);
pkg_info = parser.get_root ().get_object ().get_object_member ("results");
} catch (Error e) {
stderr.printf ("Failed to get infos about %s from AUR\n", pkgname);
print (e.message);
}
return pkg_info;
}
public Json.Array multiinfo (string[] pkgnames) {
Json.Array results = new Json.Array ();
var builder = new StringBuilder ();
builder.append (rpc_url);
builder.append (rpc_multiinfo);
foreach (string pkgname in pkgnames) {
builder.append (rpc_multiinfo_arg);
builder.append (pkgname);
}
var session = new Soup.Session ();
var message = new Soup.Message ("GET", builder.str);
session.send_message (message);
try {
var parser = new Json.Parser ();
parser.load_from_data ((string) message.response_body.flatten ().data, -1);
unowned Json.Object root_object = parser.get_root ().get_object ();
results = root_object.get_array_member ("results");
//~ foreach (var node in results.get_elements ()) {
//~ var pkg_info = node.get_object ();
//~ results.append (new Pamac.Package (null, pkg_info));
//~ }
} catch (Error e) {
print (e.message);
}
return results;
}
}

72
src/aur3.vala Normal file
View File

@ -0,0 +1,72 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//~ const string srcpkgdir = "/tmp/pamac";
namespace AUR {
// AUR urls
const string aur_url = "http://aur3.org/";
public string[] search (string needle) {
string[] results = {};
try {
// Resolve hostname to IP address
var resolver = Resolver.get_default ();
var addresses = resolver.lookup_by_name (host, null);
var address = addresses.nth_data (0);
// Connect
var client = new SocketClient ();
var conn = client.connect (new InetSocketAddress (address, 1819));
// Send HTTP GET request
var message = @"nd $query";
conn.output_stream.write (message.data);
// Receive response
var response = new DataInputStream (conn.input_stream);
string line;
while ((line = response.read_line (null)) != null) {
results += line;
}
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
return results;
}
public void info (string pkgname) {
string uri = rpc_url + rpc_info + pkgname;
var session = new Soup.Session ();
var message = new Soup.Message ("GET", uri);
session.send_message (message);
try {
var parser = new Json.Parser ();
parser.load_from_data ((string) message.response_body.flatten ().data, -1);
var root_object = parser.get_root ().get_object ();
var pkg_info = root_object.get_object_member ("results");
AUR.Pkg aur_pkg = new AUR.Pkg (pkg_info);
stdout.printf ("got %s (%s)\n", aur_pkg.name, aur_pkg.license);
} catch (Error e) {
stderr.printf ("Failed to get infos about %s from AUR\n", pkgname);
print (e.message);
}
}
}

View File

@ -0,0 +1,34 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/transaction/choose_provider_dialog.ui")]
public class ChooseProviderDialog : Gtk.Dialog {
[GtkChild]
public Gtk.Label label;
[GtkChild]
public Gtk.ComboBoxText comboboxtext;
public ChooseProviderDialog (Gtk.ApplicationWindow? window) {
Object (transient_for: window, use_header_bar: 0);
}
}
}

265
src/common.vala Normal file
View File

@ -0,0 +1,265 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public struct UpdatesInfos {
public string name;
public string version;
public string db_name;
public string tarpath;
public uint64 download_size;
}
public struct Updates {
public bool syncfirst;
public UpdatesInfos[] infos;
}
public enum Mode {
MANAGER,
UPDATER,
NO_CONFIRM
}
public struct TransactionData {
public Alpm.TransFlag flags;
// those hashtables will be used as set
public HashTable<string, string> to_add;
public HashTable<string, string> to_remove;
public HashTable<string, string> to_load;
public HashTable<string, string> to_build;
}
public struct ErrorInfos {
public string str;
public string[] details;
public ErrorInfos () {
str = "";
details = {};
}
}
}
public string format_size (uint64 size) {
float KiB_size = size / 1024;
if (KiB_size < 1000) {
string size_string = dgettext ("pamac", "%.0f KiB").printf (KiB_size);
return size_string;
} else {
string size_string = dgettext ("pamac", "%.2f MiB").printf (KiB_size / 1024);
return size_string;
}
}
public int pkgcmp (Alpm.Package pkg1, Alpm.Package pkg2) {
return strcmp (pkg1.name, pkg2.name);
}
public unowned Alpm.List<Alpm.Package?> search_all_dbs (Alpm.Handle handle, Alpm.List<string?> needles) {
unowned Alpm.List<Alpm.Package?> syncpkgs = null;
unowned Alpm.List<Alpm.Package?> tmp = null;
unowned Alpm.List<Alpm.Package?> diff = null;
unowned Alpm.List<Alpm.Package?> result = null;
result = handle.localdb.search (needles);
foreach (unowned Alpm.DB db in handle.syncdbs) {
if (syncpkgs.length == 0)
syncpkgs = db.search (needles);
else {
tmp = db.search (needles);
diff = tmp.diff (syncpkgs, (Alpm.List.CompareFunc) pkgcmp);
syncpkgs.join (diff);
}
}
diff = syncpkgs.diff (result, (Alpm.List.CompareFunc) pkgcmp);
result.join (diff);
//result.sort ((Alpm.List.CompareFunc) pkgcmp);
return result;
}
public unowned Alpm.List<Alpm.Package?> group_pkgs_all_dbs (Alpm.Handle handle, string grp_name) {
unowned Alpm.List<Alpm.Package?> result = null;
unowned Alpm.Group? grp = handle.localdb.get_group (grp_name);
if (grp != null) {
foreach (unowned Alpm.Package pkg in grp.packages)
result.add (pkg);
}
// FIX IT: provided methods don't work for syncdbs so it's done manually
foreach (unowned Alpm.DB db in handle.syncdbs) {
foreach (unowned Alpm.Package pkg in db.pkgcache) {
foreach (string name in pkg.groups) {
if (name == grp_name) {
if (Alpm.pkg_find (result, pkg.name) == null)
result.add (pkg);
}
}
}
}
//result.sort ((Alpm.List.CompareFunc) pkgcmp);
return result;
}
public unowned Alpm.List<Alpm.Package?> get_all_pkgs (Alpm.Handle handle) {
unowned Alpm.List<Alpm.Package?> syncpkgs = null;
unowned Alpm.List<Alpm.Package?> tmp = null;
unowned Alpm.List<Alpm.Package?> diff = null;
unowned Alpm.List<Alpm.Package?> result = null;
result = handle.localdb.pkgcache;
foreach (unowned Alpm.DB db in handle.syncdbs) {
if (syncpkgs.length == 0)
syncpkgs = db.pkgcache;
else {
tmp = db.pkgcache;
diff = tmp.diff (syncpkgs, (Alpm.List.CompareFunc) pkgcmp);
syncpkgs.join (diff);
}
}
diff = syncpkgs.diff (result, (Alpm.List.CompareFunc) pkgcmp);
result.join (diff);
//result.sort ((Alpm.List.CompareFunc) pkgcmp);
return result;
}
public unowned Alpm.Package? get_syncpkg (Alpm.Handle handle, string name) {
unowned Alpm.Package? pkg = null;
foreach (unowned Alpm.DB db in handle.syncdbs) {
pkg = db.get_pkg (name);
if (pkg != null)
break;
}
return pkg;
}
public Pamac.UpdatesInfos[] get_syncfirst_updates (Alpm.Config alpm_config) {
Pamac.UpdatesInfos infos = Pamac.UpdatesInfos ();
Pamac.UpdatesInfos[] syncfirst_infos = {};
unowned Alpm.Package? pkg = null;
unowned Alpm.Package? candidate = null;
foreach (string name in alpm_config.syncfirst) {
pkg = Alpm.find_satisfier (alpm_config.handle.localdb.pkgcache, name);
if (pkg != null) {
candidate = Alpm.sync_newversion (pkg, alpm_config.handle.syncdbs);
if (candidate != null) {
infos.name = candidate.name;
infos.version = candidate.version;
infos.db_name = candidate.db.name;
infos.tarpath = "";
infos.download_size = candidate.download_size;
syncfirst_infos += infos;
}
}
}
return syncfirst_infos;
}
public string[] get_ignore_pkgs (Alpm.Config alpm_config) {
string[] ignore_pkgs = {};
unowned Alpm.Group? group = null;
foreach (string name in alpm_config.handle.ignorepkgs)
ignore_pkgs += name;
foreach (string grp_name in alpm_config.handle.ignoregroups) {
group = alpm_config.handle.localdb.get_group (grp_name);
if (group != null) {
foreach (unowned Alpm.Package found_pkg in group.packages)
ignore_pkgs += found_pkg.name;
}
}
return ignore_pkgs;
}
public Pamac.UpdatesInfos[] get_repos_updates (Alpm.Config alpm_config, string[] ignore_pkgs) {
unowned Alpm.Package? candidate = null;
Pamac.UpdatesInfos infos = Pamac.UpdatesInfos ();
Pamac.UpdatesInfos[] updates = {};
foreach (unowned Alpm.Package local_pkg in alpm_config.handle.localdb.pkgcache) {
// continue only if the local pkg is not in IgnorePkg or IgnoreGroup
if ((local_pkg.name in ignore_pkgs) == false) {
candidate = Alpm.sync_newversion (local_pkg, alpm_config.handle.syncdbs);
if (candidate != null) {
infos.name = candidate.name;
infos.version = candidate.version;
infos.db_name = candidate.db.name;
infos.tarpath = "";
infos.download_size = candidate.download_size;
updates += infos;
}
}
}
return updates;
}
public Pamac.UpdatesInfos[] get_aur_updates (Alpm.Config alpm_config, string[] ignore_pkgs) {
unowned Alpm.Package? sync_pkg = null;
unowned Alpm.Package? candidate = null;
string[] local_pkgs = {};
Pamac.UpdatesInfos infos = Pamac.UpdatesInfos ();
Pamac.UpdatesInfos[] aur_updates = {};
// get local pkgs
foreach (unowned Alpm.Package local_pkg in alpm_config.handle.localdb.pkgcache) {
// continue only if the local pkg is not in IgnorePkg or IgnoreGroup
if ((local_pkg.name in ignore_pkgs) == false) {
// check updates from AUR only for local packages
foreach (unowned Alpm.DB db in alpm_config.handle.syncdbs) {
sync_pkg = Alpm.find_satisfier (db.pkgcache, local_pkg.name);
if (sync_pkg != null)
break;
}
if (sync_pkg == null) {
// check update from AUR only if no package from dbs will replace it
candidate = Alpm.sync_newversion (local_pkg, alpm_config.handle.syncdbs);
if (candidate == null) {
local_pkgs += local_pkg.name;
}
}
}
}
// get aur updates
Json.Array aur_pkgs = AUR.multiinfo (local_pkgs);
int cmp;
string version;
string name;
foreach (Json.Node node in aur_pkgs.get_elements ()) {
unowned Json.Object pkg_info = node.get_object ();
version = pkg_info.get_string_member ("Version");
name = pkg_info.get_string_member ("Name");
cmp = Alpm.pkg_vercmp (version, alpm_config.handle.localdb.get_pkg (name).version);
if (cmp == 1) {
infos.name = name;
infos.version = version;
infos.db_name = "AUR";
infos.tarpath = pkg_info.get_string_member ("URLPath");
infos.download_size = 0;
aur_updates += infos;
}
}
return aur_updates;
}

697
src/daemon.vala Normal file
View File

@ -0,0 +1,697 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Alpm;
using Pamac;
using Polkit;
// i18n
const string GETTEXT_PACKAGE = "pacman";
PamacServer server;
MainLoop loop;
[DBus (name = "org.manjaro.pamac")]
public class PamacServer : Object {
Alpm.Config alpm_config;
Pamac.Config pamac_config;
unowned Alpm.DB localdb;
unowned Alpm.List<DB?> syncdbs;
public uint64 previous_percent;
unowned Alpm.List<string?> local_packages;
int force_refresh;
bool emit_refreshed_signal;
public Cond provider_cond;
public Mutex provider_mutex;
public int? choosen_provider;
public signal void emit_event (uint event, string msg);
public signal void emit_providers (string depend, string[] providers);
public signal void emit_progress (uint progress, string action, string pkgname, int percent, uint n_targets, uint current_target);
public signal void emit_download (string filename, uint64 xfered, uint64 total);
public signal void emit_totaldownload (uint64 total);
public signal void emit_log (uint level, string msg);
public signal void emit_updates (Updates updates);
public signal void emit_refreshed (ErrorInfos error);
public signal void emit_trans_prepared (ErrorInfos error);
public signal void emit_trans_committed (ErrorInfos error);
public PamacServer () {
previous_percent = 0;
local_packages = null;
get_handle ();
force_refresh = 0;
emit_refreshed_signal = true;
}
private void get_handle () {
alpm_config = new Alpm.Config ("/etc/pacman.conf");
pamac_config = new Pamac.Config ("/etc/pamac.conf");
alpm_config.handle.eventcb = (EventCallBack) cb_event;
alpm_config.handle.progresscb = (ProgressCallBack) cb_progress;
alpm_config.handle.questioncb = (QuestionCallBack) cb_question;
alpm_config.handle.dlcb = (DownloadCallBack) cb_download;
alpm_config.handle.totaldlcb = (TotalDownloadCallBack) cb_totaldownload;
alpm_config.handle.logcb = (LogCallBack) cb_log;
localdb = alpm_config.handle.localdb;
syncdbs = alpm_config.handle.syncdbs;
}
public void write_config (HashTable<string,string> new_conf, GLib.BusName sender) {
try {
Polkit.Authority authority = Polkit.Authority.get_sync (null);
Polkit.Subject subject = Polkit.SystemBusName.new (sender);
Polkit.AuthorizationResult result = authority.check_authorization_sync
(subject,
"org.manjaro.pamac.commit",
null,
Polkit.CheckAuthorizationFlags.ALLOW_USER_INTERACTION,
null);
if (result.get_is_authorized ()) {
pamac_config.write (new_conf);
}
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
}
private void refresh_real () {
ErrorInfos err = ErrorInfos ();
string[] details = {};
uint success = 0;
int ret = alpm_config.handle.trans_init (0);
if (ret == 0) {
foreach (unowned DB db in syncdbs) {
ret = db.update (force_refresh);
if (ret >= 0) {
success++;
}
}
// We should always succeed if at least one DB was upgraded - we may possibly
// fail later with unresolved deps, but that should be rare, and would be expected
if (success == 0) {
err.str = _("failed to synchronize any databases\n");
details += Alpm.strerror (alpm_config.handle.errno ()) + "\n";
err.details = details;
}
trans_release ();
get_handle ();
if (emit_refreshed_signal)
emit_refreshed (err);
else
emit_refreshed_signal = true;
}
}
public async void refresh (int force, bool emit_signal) {
force_refresh = force;
emit_refreshed_signal = emit_signal;
try {
new Thread<void*>.try ("refresh thread", (ThreadFunc) refresh_real);
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
}
public UpdatesInfos[] get_updates () {
UpdatesInfos[] updates = {};
updates = get_syncfirst_updates (alpm_config);
if (updates.length != 0) {
return updates;
} else {
string[] ignore_pkgs = get_ignore_pkgs (alpm_config);
updates = get_repos_updates (alpm_config, ignore_pkgs);
if (pamac_config.enable_aur) {
UpdatesInfos[] aur_updates = get_aur_updates (alpm_config, ignore_pkgs);
foreach (UpdatesInfos infos in aur_updates)
updates += infos;
}
return updates;
}
}
public ErrorInfos trans_init (TransFlag transflags) {
ErrorInfos err = ErrorInfos ();
int ret = alpm_config.handle.trans_init (transflags);
if (ret == -1) {
//err = _("failed to init transaction (%s)\n").printf (Alpm.strerror (errno));
err.str = Alpm.strerror (alpm_config.handle.errno ()) + "\n";
}
return err;
}
public ErrorInfos trans_sysupgrade (int enable_downgrade) {
ErrorInfos err = ErrorInfos ();
int ret = alpm_config.handle.trans_sysupgrade (enable_downgrade);
if (ret == -1) {;
err.str = Alpm.strerror (alpm_config.handle.errno ()) + "\n";
}
return err;
}
public ErrorInfos trans_add_pkg (string pkgname) {
ErrorInfos err = ErrorInfos ();
unowned Package? pkg = null;
//pkg = alpm_config.handle.find_dbs_satisfier (syncdbs, pkgname);
foreach (var db in syncdbs) {
pkg = find_satisfier (db.pkgcache, pkgname);
if (pkg != null)
break;
}
if (pkg == null) {
err.str = _("target not found: %s\n").printf (pkgname);
return err;
}
int ret = alpm_config.handle.trans_add_pkg (pkg);
if (ret == -1) {
Alpm.Errno errno = alpm_config.handle.errno ();
if (errno == Errno.TRANS_DUP_TARGET || errno == Errno.PKG_IGNORED)
// just skip duplicate or ignored targets
return err;
else {
err.str = "'%s': %s\n".printf (pkg.name, Alpm.strerror (errno));
return err;
}
}
return err;
}
public ErrorInfos trans_load_pkg (string pkgpath) {
ErrorInfos err = ErrorInfos ();
unowned Package? pkg = alpm_config.handle.load_file (pkgpath, 1, alpm_config.handle.localfilesiglevel);
if (pkg == null) {
err.str = "'%s': %s\n".printf (pkgpath, Alpm.strerror (alpm_config.handle.errno ()));
return err;
} else {
int ret = alpm_config.handle.trans_add_pkg (pkg);
if (ret == -1) {
Alpm.Errno errno = alpm_config.handle.errno ();
if (errno == Errno.TRANS_DUP_TARGET || errno == Errno.PKG_IGNORED) {
// just skip duplicate or ignored targets
return err;
} else {
err.str = "'%s': %s\n".printf (pkg.name, Alpm.strerror (errno));
return err;
}
}
}
return err;
}
public ErrorInfos trans_remove_pkg (string pkgname) {
ErrorInfos err = ErrorInfos ();
unowned Package? pkg = localdb.get_pkg (pkgname);
if (pkg == null) {
err.str = _("target not found: %s\n").printf (pkgname);
return err;
}
int ret = alpm_config.handle.trans_remove_pkg (pkg);
if (ret == -1) {
err.str = "'%s': %s\n".printf (pkg.name, Alpm.strerror (alpm_config.handle.errno ()));
}
return err;
}
public void trans_prepare_real () {
ErrorInfos err = ErrorInfos ();
string[] details = {};
Alpm.List<void*> err_data = null;
int ret = alpm_config.handle.trans_prepare (out err_data);
if (ret == -1) {
Alpm.Errno errno = alpm_config.handle.errno ();
//err = _("failed to prepare transaction (%s)\n").printf ();
err.str = Alpm.strerror (errno) + "\n";
switch (errno) {
case Errno.PKG_INVALID_ARCH:
foreach (void *i in err_data) {
char *pkgname = i;
details += _("package %s does not have a valid architecture\n").printf (pkgname);
}
break;
case Errno.UNSATISFIED_DEPS:
foreach (void *i in err_data) {
DepMissing *miss = i;
string depstring = miss->depend.compute_string ();
details += _("%s: requires %s\n").printf (miss->target, depstring);
}
break;
case Errno.CONFLICTING_DEPS:
foreach (void *i in err_data) {
Conflict *conflict = i;
// only print reason if it contains new information
if (conflict->reason.mod == DepMod.ANY)
details += _("%s and %s are in conflict\n").printf (conflict->package1, conflict->package2);
else {
string reason = conflict->reason.compute_string ();
details += _("%s and %s are in conflict (%s)\n").printf (conflict->package1, conflict->package2, reason);
}
}
break;
default:
break;
}
err.details = details;
trans_release ();
}
emit_trans_prepared (err);
}
public async void trans_prepare () {
try {
new Thread<void*>.try ("prepare thread", (ThreadFunc) trans_prepare_real);
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
}
public void choose_provider (int provider) {
provider_mutex.lock ();
choosen_provider = provider;
provider_cond.signal ();
provider_mutex.unlock ();
}
public UpdatesInfos[] trans_to_add () {
UpdatesInfos info = UpdatesInfos ();
UpdatesInfos[] infos = {};
foreach (unowned Package pkg in alpm_config.handle.trans_to_add ()) {
info.name = pkg.name;
info.version = pkg.version;
// if pkg was load from a file, pkg.db is null
if (pkg.db != null)
info.db_name = pkg.db.name;
else
info.db_name = "";
info.tarpath = "";
info.download_size = pkg.download_size;
infos += info;
}
return infos;
}
public UpdatesInfos[] trans_to_remove () {
UpdatesInfos info = UpdatesInfos ();
UpdatesInfos[] infos = {};
foreach (unowned Package pkg in alpm_config.handle.trans_to_remove ()) {
info.name = pkg.name;
info.version = pkg.version;
info.db_name = pkg.db.name;
info.tarpath = "";
info.download_size = pkg.download_size;
infos += info;
}
return infos;
}
private void trans_commit_real () {
ErrorInfos err = ErrorInfos ();
string[] details = {};
Alpm.List<void*> err_data = null;
int ret = alpm_config.handle.trans_commit (out err_data);
if (ret == -1) {
Alpm.Errno errno = alpm_config.handle.errno ();
//err = _("failed to commit transaction (%s)\n").printf (Alpm.strerror (errno));
err.str = Alpm.strerror (errno) + "\n";
switch (errno) {
case Alpm.Errno.FILE_CONFLICTS:
TransFlag flags = alpm_config.handle.trans_get_flags ();
if ((flags & TransFlag.FORCE) != 0) {
details += _("unable to %s directory-file conflicts\n").printf ("--force");
}
foreach (void *i in err_data) {
FileConflict *conflict = i;
switch (conflict->type) {
case FileConflictType.TARGET:
details += _("%s exists in both '%s' and '%s'\n").printf (conflict->file, conflict->target, conflict->ctarget);
break;
case FileConflictType.FILESYSTEM:
details += _("%s: %s exists in filesystem\n").printf (conflict->target, conflict->file);
break;
}
}
break;
case Alpm.Errno.PKG_INVALID:
case Alpm.Errno.PKG_INVALID_CHECKSUM:
case Alpm.Errno.PKG_INVALID_SIG:
case Alpm.Errno.DLT_INVALID:
foreach (void *i in err_data) {
char *filename = i;
details += _("%s is invalid or corrupted\n").printf (filename);
}
break;
default:
break;
}
err.details = details;
}
trans_release ();
get_handle ();
emit_trans_committed (err);
}
public async void trans_commit (GLib.BusName sender) {
try {
Polkit.Authority authority = Polkit.Authority.get_sync (null);
Polkit.Subject subject = Polkit.SystemBusName.new (sender);
Polkit.AuthorizationResult result = authority.check_authorization_sync
(subject,
"org.manjaro.pamac.commit",
null,
Polkit.CheckAuthorizationFlags.ALLOW_USER_INTERACTION,
null);
if (result.get_is_authorized ()) {
new Thread<void*>.try ("commit thread", (ThreadFunc) trans_commit_real);
} else {
ErrorInfos err = ErrorInfos ();
err.str = "Not Authorized\n";
emit_trans_committed (err);
trans_release ();
}
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
}
public int trans_release () {
return alpm_config.handle.trans_release ();
}
public void trans_cancel () {
alpm_config.handle.trans_interrupt ();
alpm_config.handle.trans_release ();
get_handle ();
}
public void quit () {
GLib.File lockfile = GLib.File.new_for_path ("/var/lib/pacman/db.lck");
if (lockfile.query_exists () == false)
loop.quit ();
}
// End of Server Object
}
private void write_log_file (string event) {
var now = new DateTime.now_local ();
string log = "%s %s".printf (now.format ("[%Y-%m-%d %H:%M]"), event);
var file = GLib.File.new_for_path ("/var/log/pamac.log");
try {
// creating a DataOutputStream to the file
var dos = new DataOutputStream (file.append_to (FileCreateFlags.NONE));
// writing a short string to the stream
dos.put_string (log);
} catch (GLib.Error e) {
GLib.stderr.printf("%s\n", e.message);
}
}
private void cb_event (Event event, void *data1, void *data2) {
string event_str = null;
switch (event) {
case Event.CHECKDEPS_START:
event_str = _("checking dependencies...\n");
break;
case Event.FILECONFLICTS_START:
event_str = _("checking for file conflicts...\n");
break;
case Event.RESOLVEDEPS_START:
event_str = _("resolving dependencies...\n");
break;
case Event.INTERCONFLICTS_START:
event_str = _("looking for inter-conflicts...\n");
break;
case Event.ADD_START:
unowned Package pkg = (Package) data1;
event_str = _("installing %s...\n").printf ("%s (%s)".printf (pkg.name, pkg.version));
break;
case Event.ADD_DONE:
unowned Package pkg = (Package) data1;
string log = "installed %s (%s)\n".printf (pkg.name, pkg.version);
write_log_file (log);
break;
case Event.REMOVE_START:
unowned Package pkg = (Package) data1;
event_str = _("removing %s...\n").printf ("%s (%s)".printf (pkg.name, pkg.version));
break;
case Event.REMOVE_DONE:
unowned Package pkg = (Package) data1;
string log = "removed %s (%s)\n".printf (pkg.name, pkg.version);
write_log_file (log);
break;
case Event.UPGRADE_START:
unowned Package new_pkg = (Package) data1;
unowned Package old_pkg = (Package) data2;
event_str = _("upgrading %s...\n").printf ("%s (%s -> %s)".printf (old_pkg.name, old_pkg.version, new_pkg.version));
break;
case Event.UPGRADE_DONE:
unowned Package new_pkg = (Package) data1;
unowned Package old_pkg = (Package) data2;
string log = _("upgraded %s (%s -> %s)\n").printf (old_pkg.name, old_pkg.version, new_pkg.version);
write_log_file (log);
break;
case Event.DOWNGRADE_START:
unowned Package new_pkg = (Package) data1;
unowned Package old_pkg = (Package) data2;
event_str = _("downgrading %s...\n").printf ("%s (%s -> %s)".printf (old_pkg.name, old_pkg.version, new_pkg.version));
break;
case Event.DOWNGRADE_DONE:
unowned Package new_pkg = (Package) data1;
unowned Package old_pkg = (Package) data2;
string log = _("downgraded %s (%s -> %s)\n").printf (old_pkg.name, old_pkg.version, new_pkg.version);
write_log_file (log);
break;
case Event.REINSTALL_START:
unowned Package pkg = (Package) data1;
event_str = _("reinstalling %s...\n").printf ("%s (%s)".printf (pkg.name, pkg.version));
break;
case Event.REINSTALL_DONE:
unowned Package pkg = (Package) data1;
string log = "reinstalled %s (%s)\n".printf (pkg.name, pkg.version);
write_log_file (log);
break;
case Event.INTEGRITY_START:
event_str = _("checking package integrity...\n");
break;
case Event.KEYRING_START:
event_str = _("checking keyring...\n");
break;
case Event.KEY_DOWNLOAD_START:
event_str = _("downloading required keys...\n");
break;
case Event.LOAD_START:
event_str = _("loading package files...\n");
break;
case Event.DELTA_INTEGRITY_START:
event_str = _("checking delta integrity...\n");
break;
case Event.DELTA_PATCHES_START:
event_str = _("applying deltas...\n");
break;
case Event.DELTA_PATCH_START:
unowned string string1 = (string) data1;
unowned string string2 = (string) data2;
event_str = _("generating %s with %s... ").printf (string1, string2);
break;
case Event.DELTA_PATCH_DONE:
event_str = _("success!\n");
break;
case Event.DELTA_PATCH_FAILED:
event_str = _("failed.\n");
break;
case Event.SCRIPTLET_INFO:
unowned string info = (string) data1;
event_str = info;
write_log_file (event_str);
break;
case Event.RETRIEVE_START:
event_str = _("Retrieving packages ...\n");
break;
case Event.DISKSPACE_START:
event_str = _("checking available disk space...\n");
break;
case Event.OPTDEP_REQUIRED:
unowned Package pkg = (Package) data1;
Depend *depend = data2;
event_str = _("%s optionally requires %s\n").printf (pkg.name, depend->compute_string ());
break;
case Event.DATABASE_MISSING:
event_str = _("database file for '%s' does not exist\n").printf ((char *) data1);
break;
/* all the simple done events, with fallthrough for each */
case Event.FILECONFLICTS_DONE:
case Event.CHECKDEPS_DONE:
case Event.RESOLVEDEPS_DONE:
case Event.INTERCONFLICTS_DONE:
case Event.INTEGRITY_DONE:
case Event.KEYRING_DONE:
case Event.KEY_DOWNLOAD_DONE:
case Event.LOAD_DONE:
case Event.DELTA_INTEGRITY_DONE:
case Event.DELTA_PATCHES_DONE:
case Event.DISKSPACE_DONE:
/* nothing */
break;
default:
event_str = "unknown event";
break;
}
if (event_str != null)
server.emit_event ((uint) event, event_str);
}
private void cb_question (Question question, void *data1, void *data2, void *data3, out int response) {
switch (question) {
case Question.INSTALL_IGNOREPKG:
// Do not install package in IgnorePkg/IgnoreGroup
response = 0;
break;
case Question.REPLACE_PKG:
// Auto-remove conflicts in case of replaces
response = 1;
break;
case Question.CONFLICT_PKG:
// Auto-remove conflicts
response = 1;
break;
case Question.REMOVE_PKGS:
// Do not upgrade packages which have unresolvable dependencies
response = 1;
break;
case Question.SELECT_PROVIDER:
unowned Alpm.List<Package?> providers = (Alpm.List<Package?>) data1;
Depend *depend = data2;
string depend_str = depend->compute_string ();
string[] providers_str = {};
foreach (unowned Package pkg in providers) {
providers_str += pkg.name;
}
server.provider_cond = Cond ();
server.provider_mutex = Mutex ();
server.choosen_provider = null;
server.emit_providers (depend_str, providers_str);
server.provider_mutex.lock ();
while (server.choosen_provider == null) {
server.provider_cond.wait (server.provider_mutex);
}
response = server.choosen_provider;
server.provider_mutex.unlock ();
break;
case Question.CORRUPTED_PKG:
// Auto-remove corrupted pkgs in cache
response = 1;
break;
case Question.IMPORT_KEY:
PGPKey *key = data1;
// Do not get revoked key
if (key->revoked == 1) response = 0;
// Auto get not revoked key
else response = 1;
break;
default:
response = 0;
break;
}
}
private void cb_progress (Progress progress, string pkgname, int percent, uint n_targets, uint current_target) {
string action = "";
switch (progress) {
case Progress.ADD_START:
action = _("installing");
break;
case Progress.UPGRADE_START:
action = _("upgrading");
break;
case Progress.DOWNGRADE_START:
action = _("downgrading");
break;
case Progress.REINSTALL_START:
action = _("reinstalling");
break;
case Progress.REMOVE_START:
action = _("removing");
break;
case Progress.CONFLICTS_START:
action = _("checking for file conflicts");
break;
case Progress.DISKSPACE_START:
action = _("checking available disk space");
break;
case Progress.INTEGRITY_START:
action = _("checking package integrity");
break;
case Progress.KEYRING_START:
action = _("checking keys in keyring");
break;
case Progress.LOAD_START:
action = _("loading package files");
break;
default:
break;
}
if ((uint64) percent != server.previous_percent) {
server.previous_percent = (uint64) percent;
server.emit_progress ((uint) progress, action, pkgname, percent, n_targets, current_target);
}
}
private void cb_download (string filename, uint64 xfered, uint64 total) {
if (xfered != server.previous_percent) {
server.previous_percent = xfered;
server.emit_download (filename, xfered, total);
}
}
private void cb_totaldownload (uint64 total) {
server.emit_totaldownload (total);
}
private void cb_log (LogLevel level, string fmt, va_list args) {
LogLevel logmask = LogLevel.ERROR | LogLevel.WARNING;
if ((level & logmask) == 0)
return;
string? log = null;
log = fmt.vprintf (args);
if (log != null)
server.emit_log ((uint) level, log);
}
void on_bus_acquired (DBusConnection conn) {
server = new PamacServer ();
try {
conn.register_object ("/org/manjaro/pamac", server);
}
catch (IOError e) {
stderr.printf ("Could not register service\n");
}
}
void main () {
// i18n
Intl.setlocale(LocaleCategory.ALL, "");
Intl.textdomain(GETTEXT_PACKAGE);
Bus.own_name(BusType.SYSTEM, "org.manjaro.pamac", BusNameOwnerFlags.NONE,
on_bus_acquired,
() => {},
() => stderr.printf("Could not acquire name\n"));
loop = new MainLoop ();
loop.run ();
}

40
src/history_dialog.vala Normal file
View File

@ -0,0 +1,40 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/manager/history_dialog.ui")]
public class HistoryDialog : Gtk.Dialog {
[GtkChild]
public Gtk.TextView textview;
public HistoryDialog (ManagerWindow window) {
Object (transient_for: window, use_header_bar: 0);
}
[GtkCallback]
public void on_textview_size_allocate () {
// auto-scrolling method
var scrollable = textview as Gtk.Scrollable;
var adj = scrollable.get_vadjustment ();
adj.set_value (adj.get_upper () - adj.get_page_size ());
}
}
}

69
src/installer.vala Normal file
View File

@ -0,0 +1,69 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Installer: Gtk.Application {
Transaction transaction;
Pamac.Config pamac_config;
public Installer () {
application_id = "org.manjaro.pamac.install";
flags |= ApplicationFlags.HANDLES_OPEN;
}
public override void startup () {
// i18n
Intl.textdomain ("pamac");
Intl.setlocale (LocaleCategory.ALL, "");
base.startup ();
pamac_config = new Pamac.Config ("/etc/pamac.conf");
transaction = new Pamac.Transaction (null, pamac_config);
transaction.finished.connect (on_emit_trans_finished);
this.hold ();
}
public override void activate () {
print ("\nError: Path(s) of tarball(s) to install is needed\n");
transaction.stop_daemon ();
this.release ();
}
public override void open (File[] files, string hint) {
foreach (File file in files) {
string? path = file.get_path ();
transaction.data.to_load.insert (path, path);
}
transaction.run ();
}
public void on_emit_trans_finished (bool error) {
transaction.stop_daemon ();
this.release ();
}
public static int main (string[] args) {
var installer = new Installer();
return installer.run (args);
}
}
}

55
src/manager.vala Normal file
View File

@ -0,0 +1,55 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Manager : Gtk.Application {
ManagerWindow manager_window;
public Manager () {
application_id = "org.manjaro.pamac.manager";
flags = ApplicationFlags.FLAGS_NONE;
}
public override void startup () {
// i18n
Intl.textdomain ("pamac");
Intl.setlocale (LocaleCategory.ALL, "");
base.startup ();
manager_window = new ManagerWindow (this);
}
public override void activate () {
manager_window.present ();
}
public override void shutdown () {
base.shutdown ();
manager_window.transaction.stop_daemon ();
}
}
public static int main (string[] args) {
var manager = new Manager ();
return manager.run (args);
}
}

927
src/manager_window.vala Normal file
View File

@ -0,0 +1,927 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Gtk;
using Alpm;
const string VERSION = "2.0";
namespace Pamac {
public struct SortInfo {
public int column_number;
public Gtk.SortType sort_type;
}
[GtkTemplate (ui = "/org/manjaro/pamac/manager/manager_window.ui")]
public class ManagerWindow : Gtk.ApplicationWindow {
// icons
public Gdk.Pixbuf? installed_icon;
public Gdk.Pixbuf? uninstalled_icon;
public Gdk.Pixbuf? to_install_icon;
public Gdk.Pixbuf? to_reinstall_icon;
public Gdk.Pixbuf? to_remove_icon;
public Gdk.Pixbuf? locked_icon;
// manager objects
[GtkChild]
public TreeView packages_treeview;
[GtkChild]
public TreeViewColumn state_column;
[GtkChild]
public TreeViewColumn name_column;
[GtkChild]
public TreeViewColumn version_column;
[GtkChild]
public TreeViewColumn repo_column;
[GtkChild]
public TreeViewColumn size_column;
[GtkChild]
public Notebook filters_notebook;
[GtkChild]
public SearchEntry search_entry;
[GtkChild]
public TreeView search_treeview;
[GtkChild]
public TreeView groups_treeview;
[GtkChild]
public TreeView states_treeview;
[GtkChild]
public TreeView repos_treeview;
[GtkChild]
public TreeView deps_treeview;
[GtkChild]
public TreeView details_treeview;
[GtkChild]
public ScrolledWindow deps_scrolledwindow;
[GtkChild]
public ScrolledWindow details_scrolledwindow;
[GtkChild]
public ScrolledWindow files_scrolledwindow;
[GtkChild]
public Label name_label;
[GtkChild]
public Label desc_label;
[GtkChild]
public Label link_label;
[GtkChild]
public Label licenses_label;
[GtkChild]
public TextView files_textview;
[GtkChild]
public Switch search_aur_button;
[GtkChild]
public Button valid_button;
[GtkChild]
public Button cancel_button;
public ListStore search_list;
public ListStore groups_list;
public ListStore states_list;
public ListStore repos_list;
public ListStore deps_list;
public ListStore details_list;
PackagesModel packages_list;
HashTable<string, Json.Array> aur_results;
public Pamac.Config pamac_config;
public Transaction transaction;
public SortInfo sortinfo;
//dialogs
HistoryDialog history_dialog;
PackagesChooserDialog packages_chooser_dialog;
PreferencesDialog preferences_dialog;
public ManagerWindow (Gtk.Application application) {
Object (application: application);
aur_results = new HashTable<string, Json.Array> (str_hash, str_equal);
search_list = new Gtk.ListStore (1, typeof (string));
search_treeview.set_model (search_list);
groups_list = new Gtk.ListStore (1, typeof (string));
groups_treeview.set_model (groups_list);
states_list = new Gtk.ListStore (1, typeof (string));
states_treeview.set_model (states_list);
repos_list = new Gtk.ListStore (1, typeof (string));
repos_treeview.set_model (repos_list);
deps_list = new Gtk.ListStore (2, typeof (string), typeof (string));
deps_treeview.set_model (deps_list);
details_list = new Gtk.ListStore (2, typeof (string), typeof (string));
details_treeview.set_model (details_list);;
try {
installed_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-updated.png");
uninstalled_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available.png");
to_install_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-install.png");
to_reinstall_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-reinstall.png");
to_remove_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-remove.png");
locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png");
} catch (GLib.Error e) {
stderr.printf (e.message);
}
pamac_config = new Pamac.Config ("/etc/pamac.conf");
transaction = new Pamac.Transaction (this as ApplicationWindow, pamac_config);
transaction.finished.connect (on_emit_trans_finished);
history_dialog = new HistoryDialog (this);
packages_chooser_dialog = new PackagesChooserDialog (this, transaction);
preferences_dialog = new PreferencesDialog (this as ApplicationWindow);
set_buttons_sensitive (false);
search_aur_button.set_active (pamac_config.enable_aur);
// sort by name by default
sortinfo = {0, SortType.ASCENDING};
update_lists ();
}
public void enable_aur (bool enable) {
search_aur_button.set_active (enable);
}
public void set_buttons_sensitive (bool sensitive) {
valid_button.set_sensitive (sensitive);
cancel_button.set_sensitive (sensitive);
}
public void update_lists () {
Alpm.List <string?> grps = null;
TreeIter iter;
foreach (unowned DB db in transaction.alpm_config.handle.syncdbs) {
repos_list.insert_with_values (out iter, -1, 0, db.name);
foreach (unowned Group grp in db.groupcache) {
if (grps.find_str (grp.name) == null)
grps.add(grp.name);
}
}
repos_list.insert_with_values (out iter, -1, 0, dgettext (null, "local"));
foreach (string name in grps)
groups_list.insert_with_values (out iter, -1, 0, name);
groups_list.set_sort_column_id (0, SortType.ASCENDING);
states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Installed"));
//states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Uninstalled"));
states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Orphans"));
states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To install"));
states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To remove"));
}
public void set_infos_list (Pamac.Package pkg) {
name_label.set_markup ("<big><b>%s %s</b></big>".printf (pkg.name, pkg.version));
// fix &,-,>,< in desc
string desc;
if (pkg.alpm_pkg != null)
desc = pkg.alpm_pkg.desc;
else
desc = pkg.aur_json.get_string_member ("Description");
desc = desc.replace ("&", "&amp;");
desc = desc.replace ("<->", "/");
desc_label.set_markup (desc);
// fix & in url
string url;
if (pkg.alpm_pkg != null)
url = pkg.alpm_pkg.url;
else
url = pkg.aur_json.get_string_member ("URL");
url = url.replace ("&", "&amp;");
link_label.set_markup ("<a href=\"%s\">%s</a>".printf (url, url));
StringBuilder licenses = new StringBuilder ();
licenses.append (dgettext (null, "Licenses"));
licenses.append (":");
if (pkg.alpm_pkg != null) {
foreach (unowned string license in pkg.alpm_pkg.licenses) {
licenses.append (" ");
licenses.append (license);
}
} else {
licenses.append (" ");
licenses.append (pkg.aur_json.get_string_member ("License"));
}
licenses_label.set_markup (licenses.str);
}
public void set_deps_list (Alpm.Package pkg) {
deps_list.clear ();
TreeIter iter;
unowned Alpm.List<Depend?> list = pkg.depends;
size_t len = list.length;
size_t i;
if (len != 0) {
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Depends On") + ":",
1, list.nth (0).get_data ().compute_string ());
i = 1;
while (i < len) {
deps_list.insert_with_values (out iter, -1,
1, list.nth (i).get_data ().compute_string ());
i++;
}
}
list = pkg.optdepends;
len = list.length;
if (len != 0) {
unowned Depend optdep = list.nth (0).get_data ();
unowned Alpm.Package? satisfier = find_satisfier (
transaction.alpm_config.handle.localdb.pkgcache,
optdep.name);
string optdep_str = optdep.compute_string ();
if (satisfier != null)
optdep_str = optdep_str + " [" + dgettext (null, "Installed") + "]";
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Optional Deps") + ":",
1, optdep_str);
i = 1;
while (i < len) {
optdep = list.nth (i).get_data ();
satisfier = find_satisfier (
transaction.alpm_config.handle.localdb.pkgcache,
optdep.name);
optdep_str = optdep.compute_string ();
if (satisfier != null)
optdep_str = optdep_str + " [" + dgettext (null, "Installed") + "]";
deps_list.insert_with_values (out iter, -1, 1, optdep_str);
i++;
}
}
if (pkg.origin == PkgFrom.LOCALDB) {
unowned Alpm.List<string?> str_list = pkg.compute_requiredby ();
len = str_list.length;
if (len != 0) {
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Required By") + ":",
1, str_list.nth (0).get_data ());
i = 1;
while (i < len) {
deps_list.insert_with_values (out iter, -1,
1, str_list.nth (i).get_data ());
i++;
}
}
}
list = pkg.provides;
len = list.length;
if (len != 0) {
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Provides") + ":",
1, list.nth (0).get_data ().compute_string ());
i = 1;
while (i < len) {
deps_list.insert_with_values (out iter, -1,
1, list.nth (i).get_data ().compute_string ());
i++;
}
}
list = pkg.replaces;
len = list.length;
if (len != 0) {
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Replaces") + ":",
1, list.nth (0).get_data ().compute_string ());
i = 1;
while (i < len) {
deps_list.insert_with_values (out iter, -1,
1, list.nth (i).get_data ().compute_string ());
i++;
}
}
list = pkg.conflicts;
len = list.length;
if (len != 0) {
deps_list.insert_with_values (out iter, -1,
0, dgettext (null, "Conflicts With") + ":",
1, list.nth (0).get_data ().compute_string ());
i = 1;
while (i < len) {
deps_list.insert_with_values (out iter, -1,
1, list.nth (i).get_data ().compute_string ());
i++;
}
}
}
public void set_details_list (Alpm.Package pkg) {
details_list.clear ();
TreeIter iter;
if (pkg.origin == PkgFrom.SYNCDB) {
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Repository") + ":",
1, pkg.db.name);
}
unowned Alpm.List<string?> list = pkg.groups;
size_t len = list.length;
size_t i;
if (len != 0) {
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Groups") + ":",
1, list.nth (0).get_data ());
i = 1;
while (i < len) {
details_list.insert_with_values (out iter, -1,
1, list.nth (i).get_data ());
i++;
}
}
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Packager") + ":",
1, pkg.packager);
if (pkg.origin == PkgFrom.LOCALDB) {
GLib.Time time = GLib.Time.local ((time_t) pkg.installdate);
string strtime = time.format ("%a %d %b %Y %X %Z");
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Install Date") + ":",
1, strtime);
string reason;
if (pkg.reason == PkgReason.EXPLICIT)
reason = dgettext (null, "Explicitly installed");
else if (pkg.reason == PkgReason.EXPLICIT)
reason = dgettext (null, "Installed as a dependency for another package");
else
reason = dgettext (null, "Unknown");
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Install Reason") + ":",
1, reason);
}
if (pkg.origin == PkgFrom.SYNCDB) {
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Signatures") + ":",
1, pkg.base64_sig != null ? "Yes" : "No");
}
if (pkg.origin == PkgFrom.LOCALDB) {
unowned Alpm.List<Backup?> backup_list = pkg.backup;
len = backup_list.length;
if (len != 0) {
details_list.insert_with_values (out iter, -1,
0, dgettext (null, "Backup files") + ":",
1, "/" + backup_list.nth (0).get_data ().name);
i = 1;
while (i < len) {
details_list.insert_with_values (out iter, -1,
1, "/" + backup_list.nth (i).get_data ().name);
i++;
}
}
}
}
public void set_files_list (Alpm.Package pkg) {
StringBuilder text = new StringBuilder ();
foreach (unowned Alpm.File file in pkg.files) {
if (text.len != 0)
text.append ("\n");
text.append ("/");
text.append (file.name);
}
files_textview.buffer.set_text (text.str, (int) text.len);
}
public async unowned Alpm.List<Alpm.Package?> search_pkgs (string search_string, out Json.Array aur_pkgs) {
unowned Alpm.List<Alpm.Package?> pkgs = null;
unowned Alpm.List<string?> needles = null;
string[] splitted = search_string.split (" ");
foreach (unowned string part in splitted)
needles.add (part);
pkgs = search_all_dbs (transaction.alpm_config.handle, needles);
if (search_aur_button.get_active()) {
if (aur_results.contains (search_string)) {
aur_pkgs = aur_results.get (search_string);
} else {
aur_pkgs = AUR.search (search_string);
aur_results.insert (search_string, aur_pkgs);
}
} else {
aur_pkgs = new Json.Array ();
}
return pkgs;
}
public void populate_packages_list (Alpm.List<Alpm.Package?>? pkgs, Json.Array? aur_pkgs = null) {
packages_treeview.freeze_child_notify ();
packages_treeview.set_model (null);
// populate liststore
packages_list = new PackagesModel (pkgs, aur_pkgs, this);
// sort liststore
int column = sortinfo.column_number;
if (column == 0)
packages_list.sort_by_name (sortinfo.sort_type);
else if (column == 1)
packages_list.sort_by_state (sortinfo.sort_type);
else if (column == 2)
packages_list.sort_by_version (sortinfo.sort_type);
else if (column == 3)
packages_list.sort_by_repo (sortinfo.sort_type);
else if (column == 4)
packages_list.sort_by_size (sortinfo.sort_type);
packages_treeview.set_model (packages_list);
packages_treeview.thaw_child_notify ();
this.get_window ().set_cursor (null);
}
public void refresh_packages_list () {
int current_page = filters_notebook.get_current_page ();
if (current_page == 0) {
TreeModel model;
TreeIter? iter;
TreeSelection selection = search_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
on_search_treeview_selection_changed ();
}
} else if (current_page == 1) {
on_groups_treeview_selection_changed ();
} else if (current_page == 2) {
on_states_treeview_selection_changed ();
} else if (current_page == 3) {
on_repos_treeview_selection_changed ();
}
}
[GtkCallback]
public void on_packages_treeview_selection_changed () {
TreeModel model;
TreeIter? iter;
TreeSelection selection = packages_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
Pamac.Package pkg = (Pamac.Package) iter.user_data;
if (pkg.alpm_pkg != null) {
set_infos_list (pkg);
set_deps_list (pkg.alpm_pkg);
set_details_list (pkg.alpm_pkg);
deps_scrolledwindow.visible = true;
details_scrolledwindow.visible = true;
if (pkg.alpm_pkg.origin == PkgFrom.LOCALDB) {
set_files_list (pkg.alpm_pkg);
files_scrolledwindow.visible = true;
} else {
files_scrolledwindow.visible = false;
}
} else if (pkg.aur_json != null) {
set_infos_list (pkg);
deps_scrolledwindow.visible = false;
details_scrolledwindow.visible = false;
files_scrolledwindow.visible = false;
}
}
}
[GtkCallback]
public void on_packages_treeview_row_activated (TreeView treeview, TreePath path, TreeViewColumn column) {
TreeIter iter;
if (packages_list.get_iter (out iter, path)) {
GLib.Value val;
packages_list.get_value (iter, 0, out val);
string name = val.get_string ();
if (name != dgettext (null, "No package found")) {
if (transaction.data.to_add.contains (name)) {
transaction.data.to_add.steal (name);
} else if (transaction.data.to_remove.contains (name)) {
transaction.data.to_remove.steal (name);
} else if (transaction.data.to_build.contains (name)) {
transaction.data.to_build.steal (name);
} else {
packages_list.get_value (iter, 3, out val);
string db_name = val.get_string ();
if (db_name == "local") {
if (!(name in transaction.alpm_config.holdpkg)) {
transaction.data.to_remove.insert (name, name);
}
} else if (db_name == "AUR") {
transaction.data.to_build.insert (name, name);
} else {
transaction.data.to_add.insert (name, name);
}
}
}
}
if (transaction.data.to_add.size () + transaction.data.to_remove.size () + transaction.data.to_build.size () == 0) {
set_buttons_sensitive (false);
} else {
set_buttons_sensitive (true);
}
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public bool on_list_treeview_button_press_event (Gdk.EventButton event) {
// to do
return false;
}
[GtkCallback]
public void on_name_column_clicked () {
SortType new_order;
if (name_column.sort_indicator == false)
new_order = SortType.ASCENDING;
else {
if (sortinfo.sort_type == SortType.ASCENDING)
new_order = SortType.DESCENDING;
else
new_order = SortType.ASCENDING;
}
packages_list.sort_by_name (new_order);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_state_column_clicked () {
SortType new_order;
if (state_column.sort_indicator == false)
new_order = SortType.ASCENDING;
else {
if (sortinfo.sort_type == SortType.ASCENDING)
new_order = SortType.DESCENDING;
else
new_order = SortType.ASCENDING;
}
packages_list.sort_by_state (new_order);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_version_column_clicked () {
SortType new_order;
if (version_column.sort_indicator == false)
new_order = SortType.ASCENDING;
else {
if (sortinfo.sort_type == SortType.ASCENDING)
new_order = SortType.DESCENDING;
else
new_order = SortType.ASCENDING;
}
packages_list.sort_by_version (new_order);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_repo_column_clicked () {
SortType new_order;
if (repo_column.sort_indicator == false)
new_order = SortType.ASCENDING;
else {
if (sortinfo.sort_type == SortType.ASCENDING)
new_order = SortType.DESCENDING;
else
new_order = SortType.ASCENDING;
}
packages_list.sort_by_repo (new_order);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_size_column_clicked () {
SortType new_order;
if (size_column.sort_indicator == false)
new_order = SortType.ASCENDING;
else {
if (sortinfo.sort_type == SortType.ASCENDING)
new_order = SortType.DESCENDING;
else
new_order = SortType.ASCENDING;
}
packages_list.sort_by_size (new_order);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_search_entry_activate () {
string search_string = search_entry.get_text ();
if (search_string != "") {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
search_pkgs.begin (search_string, (obj, res) => {
Json.Array aur_pkgs;
unowned Alpm.List<Alpm.Package?> pkgs = search_pkgs.end (res, out aur_pkgs);
if (pkgs.length != 0) {
// add search string in search_list if needed
bool found = false;
TreeIter? iter;
TreeModel model;
TreeSelection selection = search_treeview.get_selection ();
// check if search string is already selected in search list
if (selection.get_selected (out model, out iter)) {
GLib.Value val;
model.get_value (iter, 0, out val);
string selected_string = val.get_string ();
if (selected_string == search_string) {
found = true;
// we need to populate packages_list
populate_packages_list (pkgs, aur_pkgs);
} else {
search_list.foreach ((_model, _path, _iter) => {
GLib.Value line;
model.get_value (_iter, 0, out line);
if ((string) line == search_string) {
found = true;
// populate will be done because we select the iter in search_list
selection.select_iter (_iter);
}
return found;
});
}
}
if (!found) {
search_list.insert_with_values (out iter, -1, 0, search_string);
// populate will be done because we select the iter in search_list
selection.select_iter (iter);
}
} else
// populate with empty lists
populate_packages_list (pkgs, aur_pkgs);
});
}
}
[GtkCallback]
public void on_search_entry_icon_press (EntryIconPosition p0, Gdk.Event? p1) {
on_search_entry_activate ();
}
[GtkCallback]
public void on_search_treeview_selection_changed () {
TreeModel model;
TreeIter? iter;
TreeSelection selection = search_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
GLib.Value val;
model.get_value (iter, 0, out val);
string search_string = val.get_string ();
search_pkgs.begin (search_string, (obj, res) => {
Json.Array aur_pkgs;
unowned Alpm.List<Alpm.Package?> pkgs = search_pkgs.end (res, out aur_pkgs);
populate_packages_list (pkgs, aur_pkgs);
});
}
}
[GtkCallback]
public void on_groups_treeview_selection_changed () {
TreeModel model;
TreeIter? iter;
TreeSelection selection = groups_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
GLib.Value val;
model.get_value (iter, 0, out val);
string grp_name = val.get_string ();
unowned Alpm.List<Alpm.Package?> pkgs = group_pkgs_all_dbs (transaction.alpm_config.handle, grp_name);
populate_packages_list (pkgs);
}
}
[GtkCallback]
public void on_states_treeview_selection_changed () {
TreeModel model;
TreeIter? iter;
TreeSelection selection = states_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
GLib.Value val;
model.get_value (iter, 0, out val);
string state = val.get_string ();
unowned Alpm.List<Alpm.Package?> pkgs = null;
unowned Alpm.Package? find_pkg = null;
if (state == dgettext (null, "To install")) {
foreach (string name in transaction.data.to_add.get_keys ()) {
find_pkg = transaction.alpm_config.handle.localdb.get_pkg (name);
if (find_pkg != null)
pkgs.add (find_pkg);
else {
find_pkg = get_syncpkg (transaction.alpm_config.handle, name);
if (find_pkg != null)
pkgs.add (find_pkg);
}
}
} else if (state == dgettext (null, "To remove")) {
foreach (string name in transaction.data.to_remove.get_keys ()) {
find_pkg = transaction.alpm_config.handle.localdb.get_pkg (name);
if (find_pkg != null)
pkgs.add (find_pkg);
}
} else if (state == dgettext (null, "Installed")) {
pkgs = transaction.alpm_config.handle.localdb.pkgcache;
} else if (state == dgettext (null, "Uninstalled")) {
unowned Alpm.List<Alpm.Package?> tmp = null;
unowned Alpm.List<Alpm.Package?> diff = null;
foreach (unowned DB db in transaction.alpm_config.handle.syncdbs) {
if (pkgs.length == 0)
pkgs = db.pkgcache;
else {
tmp = db.pkgcache;
diff = tmp.diff (pkgs, (Alpm.List.CompareFunc) pkgcmp);
pkgs.join (diff);
}
}
} else if (state == dgettext (null, "Orphans")) {
foreach (unowned Alpm.Package pkg in transaction.alpm_config.handle.localdb.pkgcache) {
if (pkg.reason == PkgReason.DEPEND) {
if (pkg.compute_requiredby().length == 0)
pkgs.add (pkg);
}
}
}
populate_packages_list (pkgs);
}
}
[GtkCallback]
public void on_repos_treeview_selection_changed () {
TreeModel model;
TreeIter? iter;
TreeSelection selection = repos_treeview.get_selection ();
if (selection.get_selected (out model, out iter)) {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
GLib.Value val;
model.get_value (iter, 0, out val);
string repo = val.get_string ();
unowned Alpm.List<Alpm.Package?> pkgs = null;
unowned Alpm.Package? find_pkg = null;
if (repo == dgettext (null, "local")) {
foreach (unowned Alpm.Package pkg in transaction.alpm_config.handle.localdb.pkgcache) {
find_pkg = get_syncpkg (transaction.alpm_config.handle, pkg.name);
if (find_pkg == null)
pkgs.add (pkg);
}
} else {
foreach (unowned DB db in transaction.alpm_config.handle.syncdbs) {
if (db.name == repo) {
foreach (unowned Alpm.Package pkg in db.pkgcache) {
find_pkg = transaction.alpm_config.handle.localdb.get_pkg (pkg.name);
if (find_pkg != null)
pkgs.add (find_pkg);
else
pkgs.add (pkg);
}
}
}
}
populate_packages_list (pkgs);
}
}
[GtkCallback]
public void on_filters_notebook_switch_page (Widget page, uint page_num) {
refresh_packages_list ();
}
[GtkCallback]
public void on_history_item_activate () {
var file = GLib.File.new_for_path ("/var/log/pamac.log");
if (!file.query_exists ())
GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ());
else {
StringBuilder text = new StringBuilder ();
try {
// Open file for reading and wrap returned FileInputStream into a
// DataInputStream, so we can read line by line
var dis = new DataInputStream (file.read ());
string line;
// Read lines until end of file (null) is reached
while ((line = dis.read_line (null)) != null) {
text.append (line);
text.append ("\n");
}
} catch (GLib.Error e) {
GLib.stderr.printf("%s\n", e.message);
}
history_dialog.textview.buffer.set_text (text.str, (int) text.len);
history_dialog.run ();
history_dialog.hide ();
}
}
[GtkCallback]
public void on_local_item_activate () {
int response = packages_chooser_dialog.run ();
if (response== ResponseType.ACCEPT) {
SList<string> packages_paths = packages_chooser_dialog.get_filenames ();
if (packages_paths.length () != 0) {
foreach (string path in packages_paths) {
transaction.data.to_load.insert (path, path);
}
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
packages_chooser_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
transaction.run ();
}
} else
packages_chooser_dialog.hide ();
}
[GtkCallback]
public void on_preferences_item_activate () {
bool enable_aur = pamac_config.enable_aur;
bool recurse = pamac_config.recurse;
uint64 refresh_period = pamac_config.refresh_period;
preferences_dialog.enable_aur_button.set_active (enable_aur);
preferences_dialog.remove_unrequired_deps_button.set_active (recurse);
preferences_dialog.refresh_period_spin_button.set_value (refresh_period);
int response = preferences_dialog.run ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
if (response == ResponseType.OK) {
HashTable<string,string> new_conf = new HashTable<string,string> (str_hash, str_equal);
enable_aur = preferences_dialog.enable_aur_button.get_active ();
recurse = preferences_dialog.remove_unrequired_deps_button.get_active ();
refresh_period = (uint64) preferences_dialog.refresh_period_spin_button.get_value ();
if (enable_aur != pamac_config.enable_aur) {
search_aur_button.set_active (enable_aur);
new_conf.insert ("EnableAUR", enable_aur.to_string ());
}
if (recurse != pamac_config.recurse)
new_conf.insert ("RemoveUnrequiredDeps", recurse.to_string ());
if (refresh_period != pamac_config.refresh_period)
new_conf.insert ("RefreshPeriod", refresh_period.to_string ());
if (new_conf.size () != 0) {
transaction.write_config (new_conf);
pamac_config.reload ();
}
}
preferences_dialog.hide ();
}
[GtkCallback]
public void on_about_item_activate () {
Gtk.show_about_dialog (
this,
"program_name", "Pamac",
"logo_icon_name", "system-software-install",
"comments", "A GTK3 frontend of libalpm",
"copyright", "Copyright © 2014 Guillaume Benoit",
"version", VERSION,
"license_type", License.GPL_3_0,
"website", "http://manjaro.org");
}
[GtkCallback]
public void on_valid_button_clicked () {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
if (pamac_config.recurse)
transaction.data.flags |= Alpm.TransFlag.RECURSE;
transaction.run ();
}
[GtkCallback]
public void on_cancel_button_clicked () {
transaction.clear_lists ();
set_buttons_sensitive (false);
// force a display refresh
packages_treeview.queue_draw ();
}
[GtkCallback]
public void on_refresh_button_clicked () {
transaction.refresh (0);
}
public void on_emit_trans_finished (bool error) {
if (error == false) {
set_buttons_sensitive (false);
refresh_packages_list ();
}
transaction.data.to_load.steal_all ();
this.get_window ().set_cursor (null);
}
}
}

61
src/package.vala Normal file
View File

@ -0,0 +1,61 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Package: Object {
public unowned Alpm.Package? alpm_pkg;
public unowned Json.Object? aur_json;
public string name;
public string version;
public string repo;
public uint64 size;
public string size_string;
public Package (Alpm.Package? alpm_pkg, Json.Object? aur_json) {
if (alpm_pkg != null) {
this.alpm_pkg = alpm_pkg;
this.aur_json = null;
name = alpm_pkg.name;
version = alpm_pkg.version;
if (alpm_pkg.db != null)
repo = alpm_pkg.db.name;
else
repo = "";
size = alpm_pkg.isize;
size_string = format_size (alpm_pkg.isize);
} else if (aur_json != null ) {
this.alpm_pkg = null;
this.aur_json = aur_json;
name = aur_json.get_string_member ("Name");
version = aur_json.get_string_member ("Version");
repo = "AUR";
size = 0;
size_string = "";
} else {
this.alpm_pkg = null;
this.aur_json = null;
name = dgettext (null, "No package found");
version = "";
repo = "";
size = 0;
size_string = "";
}
}
}
}

View File

@ -0,0 +1,56 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/manager/packages_chooser_dialog.ui")]
public class PackagesChooserDialog : Gtk.FileChooserDialog {
ManagerWindow window;
Transaction transaction;
public PackagesChooserDialog (ManagerWindow window, Transaction transaction) {
Object (transient_for: window, use_header_bar: 0);
Gtk.FileFilter package_filter = new Gtk.FileFilter ();
package_filter.set_filter_name (dgettext (null, "Packages"));
package_filter.add_pattern ("*.pkg.tar.gz");
package_filter.add_pattern ("*.pkg.tar.xz");
this.add_filter (package_filter);
this.window = window;
this.transaction = transaction;
}
[GtkCallback]
public void on_file_activated () {
SList<string> packages_paths = this.get_filenames ();
if (packages_paths.length () != 0) {
foreach (string path in packages_paths) {
transaction.data.to_load.insert (path, path);
}
window.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
this.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
transaction.run ();
}
}
}
}

309
src/packages_model.vala Normal file
View File

@ -0,0 +1,309 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class PackagesModel : Object, Gtk.TreeModel {
private GLib.List<Pamac.Package> all_pkgs;
public ManagerWindow manager_window;
public PackagesModel (Alpm.List<Alpm.Package?>? alpm_pkgs, Json.Array? aur_pkgs, ManagerWindow manager_window) {
this.manager_window = manager_window;
all_pkgs = new GLib.List<Pamac.Package> ();
foreach (unowned Alpm.Package alpm_pkg in alpm_pkgs) {
all_pkgs.append (new Pamac.Package (alpm_pkg, null));
}
if (aur_pkgs != null) {
unowned Json.Object pkg_info;
string name;
bool found;
foreach (Json.Node node in aur_pkgs.get_elements ()) {
pkg_info = node.get_object ();
name = pkg_info.get_string_member ("Name");
// add only the packages which are not already in the list
found = false;
foreach (Pamac.Package pkg in all_pkgs) {
if (pkg.name == name) {
found = true;
break;
}
}
if (found == false)
all_pkgs.append (new Pamac.Package (null, pkg_info));
}
}
if (all_pkgs.length () == 0) {
// create a fake "No package found" package
all_pkgs.append (new Pamac.Package (null, null));
}
}
// TreeModel interface
public Type get_column_type (int index) {
switch (index) {
case 0: // name
case 2: // version
case 3: // repo
case 4: // installed size
return typeof (string);
case 1: // icon
return typeof (Gdk.Pixbuf);
default:
return Type.INVALID;
}
}
public Gtk.TreeModelFlags get_flags () {
return Gtk.TreeModelFlags.LIST_ONLY | Gtk.TreeModelFlags.ITERS_PERSIST;
}
public void get_value (Gtk.TreeIter iter, int column, out Value val) {
Pamac.Package pkg = (Pamac.Package) iter.user_data;
return_if_fail (pkg != null);
switch (column) {
case 0:
val = Value (typeof (string));
val.set_string (pkg.name);
break;
case 1:
val = Value (typeof (Object));
if (pkg.alpm_pkg != null) {
if (pkg.name in manager_window.transaction.alpm_config.holdpkg)
val.set_object (manager_window.locked_icon);
else if (pkg.repo == "local") {
if (manager_window.transaction.data.to_add.contains (pkg.name))
val.set_object (manager_window.to_reinstall_icon);
else if (manager_window.transaction.data.to_remove.contains (pkg.name))
val.set_object (manager_window.to_remove_icon);
else
val.set_object (manager_window.installed_icon);
} else if (manager_window.transaction.data.to_add.contains (pkg.name))
val.set_object (manager_window.to_install_icon);
else
val.set_object (manager_window.uninstalled_icon);
} else if (pkg.aur_json != null) {
if (manager_window.transaction.data.to_build.contains (pkg.name))
val.set_object (manager_window.to_install_icon);
else
val.set_object (manager_window.uninstalled_icon);
} else {
Object? object = null;
val.set_object (object);
}
break;
case 2:
val = Value (typeof (string));
val.set_string (pkg.version);
break;
case 3:
val = Value (typeof (string));
val.set_string (pkg.repo);
break;
case 4:
val = Value (typeof (string));
val.set_string (pkg.size_string);
break;
default:
val = Value (Type.INVALID);
break;
}
}
public bool get_iter (out Gtk.TreeIter iter, Gtk.TreePath path) {;
if (path.get_depth () != 1 || all_pkgs.length () == 0) {
return invalid_iter (out iter);
}
iter = Gtk.TreeIter ();
int pos = path.get_indices ()[0];
iter.stamp = pos;
Pamac.Package pkg = all_pkgs.nth_data((uint) pos);
iter.user_data = pkg;
return true;
}
public int get_n_columns () {
// name, icon, version, repo, isize
return 5;
}
public Gtk.TreePath? get_path (Gtk.TreeIter iter) {
return new Gtk.TreePath.from_indices (iter.stamp);
}
public int iter_n_children (Gtk.TreeIter? iter) {
return 0;
}
public bool iter_next (ref Gtk.TreeIter iter) {
int pos = (iter.stamp) + 1;
if (pos >= all_pkgs.length ()) {
return false;
}
iter.stamp = pos;
Pamac.Package pkg = all_pkgs.nth_data((uint) pos);
iter.user_data = pkg;
return true;
}
public bool iter_previous (ref Gtk.TreeIter iter) {
int pos = iter.stamp;
if (pos >= 0) {
return false;
}
iter.stamp = (--pos);
Pamac.Package pkg = all_pkgs.nth_data((uint) pos);
iter.user_data = pkg;
return true;
}
public bool iter_nth_child (out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) {
return invalid_iter (out iter);
}
public bool iter_children (out Gtk.TreeIter iter, Gtk.TreeIter? parent) {
return invalid_iter (out iter);
}
public bool iter_has_child (Gtk.TreeIter iter) {
return false;
}
public bool iter_parent (out Gtk.TreeIter iter, Gtk.TreeIter child) {
return invalid_iter (out iter);
}
private bool invalid_iter (out Gtk.TreeIter iter) {
iter = Gtk.TreeIter ();
iter.stamp = -1;
return false;
}
// custom sort functions
public void sort_by_name (Gtk.SortType order) {
CompareFunc<Pamac.Package> namecmp = (pkg_a, pkg_b) => {
return strcmp (pkg_a.name, pkg_b.name);
};
all_pkgs.sort (namecmp);
if (order == Gtk.SortType.DESCENDING)
all_pkgs.reverse ();
manager_window.name_column.sort_order = order;
manager_window.state_column.sort_indicator = false;
manager_window.name_column.sort_indicator = true;
manager_window.version_column.sort_indicator = false;
manager_window.repo_column.sort_indicator = false;
manager_window.size_column.sort_indicator = false;
manager_window.sortinfo.column_number = 0;
manager_window.sortinfo.sort_type = order;
}
public void sort_by_state (Gtk.SortType order) {
CompareFunc<Pamac.Package> statecmp = (pkg_a, pkg_b) => {
int state_a;
int state_b;
if (pkg_a.alpm_pkg != null) {
if (pkg_a.repo == "local")
state_a = 0;
else
state_a = 1;
} else
state_a = 1;
if (pkg_b.alpm_pkg != null) {
if (pkg_b.repo == "local")
state_b = 0;
else
state_b = 1;
} else
state_b = 1;
return (int) (state_a > state_b) - (int) (state_a < state_b);
};
all_pkgs.sort (statecmp);
if (order == Gtk.SortType.DESCENDING)
all_pkgs.reverse ();
manager_window.state_column.sort_order = order;
manager_window.state_column.sort_indicator = true;
manager_window.name_column.sort_indicator = false;
manager_window.version_column.sort_indicator = false;
manager_window.repo_column.sort_indicator = false;
manager_window.size_column.sort_indicator = false;
manager_window.sortinfo.column_number = 1;
manager_window.sortinfo.sort_type = order;
}
public void sort_by_version (Gtk.SortType order) {
CompareFunc<Pamac.Package> versioncmp = (pkg_a, pkg_b) => {
return Alpm.pkg_vercmp (pkg_a.version, pkg_b.version);
};
all_pkgs.sort (versioncmp);
if (order == Gtk.SortType.DESCENDING)
all_pkgs.reverse ();
manager_window.version_column.sort_order = order;
manager_window.state_column.sort_indicator = false;
manager_window.name_column.sort_indicator = false;
manager_window.version_column.sort_indicator = true;
manager_window.repo_column.sort_indicator = false;
manager_window.size_column.sort_indicator = false;
manager_window.sortinfo.column_number = 2;
manager_window.sortinfo.sort_type = order;
}
public void sort_by_repo (Gtk.SortType order) {
CompareFunc<Pamac.Package> repocmp = (pkg_a, pkg_b) => {
return strcmp (pkg_a.repo, pkg_b.repo);
};
all_pkgs.sort (repocmp);
if (order == Gtk.SortType.DESCENDING)
all_pkgs.reverse ();
manager_window.repo_column.sort_order = order;
manager_window.state_column.sort_indicator = false;
manager_window.name_column.sort_indicator = false;
manager_window.version_column.sort_indicator = false;
manager_window.repo_column.sort_indicator = true;
manager_window.size_column.sort_indicator = false;
manager_window.sortinfo.column_number = 3;
manager_window.sortinfo.sort_type = order;
}
public void sort_by_size (Gtk.SortType order) {
CompareFunc<Pamac.Package> sizecmp = (pkg_a, pkg_b) => {
uint64 size_a;
uint64 size_b;
if (pkg_a.alpm_pkg != null)
size_a = pkg_a.size;
else
size_a = 0;
if (pkg_b.alpm_pkg != null)
size_b = pkg_b.size;
else
size_b = 0;
return (int) (size_a > size_b) - (int) (size_a < size_b);
};
all_pkgs.sort (sizecmp);
if (order == Gtk.SortType.DESCENDING)
all_pkgs.reverse ();
manager_window.size_column.sort_order = order;
manager_window.state_column.sort_indicator = false;
manager_window.name_column.sort_indicator = false;
manager_window.version_column.sort_indicator = false;
manager_window.repo_column.sort_indicator = false;
manager_window.size_column.sort_indicator = true;
manager_window.sortinfo.column_number = 4;
manager_window.sortinfo.sort_type = order;
}
}
}

133
src/pamac_config.vala Normal file
View File

@ -0,0 +1,133 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Config: Object {
public uint64 refresh_period;
public bool enable_aur;
public bool recurse;
public string conf_path;
public Config (string path) {
this.conf_path = path;
// set default options
this.refresh_period = 4;
this.enable_aur = false;
this.recurse = false;
// parse conf file
this.parse_include_file (conf_path);
}
public void parse_include_file (string path) {
var file = GLib.File.new_for_path (path);
if (file.query_exists () == false)
GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ());
else {
try {
// Open file for reading and wrap returned FileInputStream into a
// DataInputStream, so we can read line by line
var dis = new DataInputStream (file.read ());
string line;
// Read lines until end of file (null) is reached
while ((line = dis.read_line (null)) != null) {
line = line.strip ();
if (line.length == 0) continue;
if (line[0] == '#') continue;
string[] splitted = line.split ("=");
string _key = splitted[0].strip ();
string _value = null;
if (splitted[1] != null)
_value = splitted[1].strip ();
if (_key == "RefreshPeriod")
this.refresh_period = uint64.parse (_value);
else if (_key == "EnableAUR")
this.enable_aur = true;
else if (_key == "RemoveUnrequiredDeps")
this.recurse = true;
}
} catch (GLib.Error e) {
GLib.stderr.printf("%s\n", e.message);
}
}
}
public void write (HashTable<string,string> new_conf) {
var file = GLib.File.new_for_path (this.conf_path);
if (file.query_exists () == false)
GLib.stderr.printf ("File '%s' doesn't exist.\n", file.get_path ());
else {
try {
// Open file for reading and wrap returned FileInputStream into a
// DataInputStream, so we can read line by line
var dis = new DataInputStream (file.read ());
string line;
string[] data = {};
// Read lines until end of file (null) is reached
while ((line = dis.read_line (null)) != null) {
if (line.contains ("RefreshPeriod")) {
if (new_conf.contains ("RefreshPeriod")) {
string _value = new_conf.get ("RefreshPeriod");
data += "RefreshPeriod = %s\n".printf (_value);
this.refresh_period = uint64.parse (_value);
} else
data += line + "\n";
} else if (line.contains ("EnableAUR")) {
if (new_conf.contains ("EnableAUR")) {
bool _value = bool.parse (new_conf.get ("EnableAUR"));
if (_value == true)
data += "EnableAUR\n";
else
data += "#EnableAUR\n";
this.enable_aur = _value;
} else
data += line + "\n";
} else if (line.contains ("RemoveUnrequiredDeps")) {
if (new_conf.contains ("RemoveUnrequiredDeps")) {
bool _value = bool.parse (new_conf.get ("RemoveUnrequiredDeps"));
if (_value == true)
data += "RemoveUnrequiredDeps\n";
else
data += "#RemoveUnrequiredDeps\n";
this.enable_aur = _value;
} else
data += line + "\n";
} else
data += line + "\n";
}
// delete the file before rewrite it
file.delete ();
// creating a DataOutputStream to the file
var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION));
foreach (string new_line in data) {
// writing a short string to the stream
dos.put_string (new_line);
}
} catch (GLib.Error e) {
GLib.stderr.printf("%s\n", e.message);
}
}
}
public void reload () {
this.enable_aur = false;
this.recurse = false;
this.parse_include_file (this.conf_path);
}
}
}

View File

@ -0,0 +1,40 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/preferences/preferences_dialog.ui")]
public class PreferencesDialog : Gtk.Dialog {
[GtkChild]
public Gtk.Switch enable_aur_button;
[GtkChild]
public Gtk.Switch remove_unrequired_deps_button;
[GtkChild]
public Gtk.SpinButton refresh_period_spin_button;
[GtkChild]
public Gtk.Label refresh_period_label;
public PreferencesDialog (Gtk.ApplicationWindow window) {
Object (transient_for: window, use_header_bar: 0);
refresh_period_label.set_markup (dgettext (null, "How often to check for updates, value in hours") +":");
}
}
}

61
src/progress_window.vala Normal file
View File

@ -0,0 +1,61 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/transaction/progress_window.ui")]
public class ProgressWindow : Gtk.Window {
[GtkChild]
public Gtk.ProgressBar progressbar;
[GtkChild]
public Gtk.Label action_label;
[GtkChild]
public Gtk.Button cancel_button;
[GtkChild]
public Gtk.Button close_button;
[GtkChild]
public Gtk.Expander expander;
Transaction transaction;
public ProgressWindow (Transaction transaction, Gtk.ApplicationWindow? window) {
Object (transient_for: window);
this.transaction = transaction;
}
[GtkCallback]
public void on_close_button_clicked () {
this.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
[GtkCallback]
public void on_cancel_button_clicked () {
transaction.cancel ();
transaction.clear_lists ();
transaction.finished (false);
this.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
}
}

899
src/transaction.vala Normal file
View File

@ -0,0 +1,899 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Gtk;
using Vte;
using Alpm;
namespace Pamac {
[DBus (name = "org.manjaro.pamac")]
public interface Daemon : Object {
public abstract void write_config (HashTable<string,string> new_conf) throws IOError;
public abstract async void refresh (int force, bool emit_signal) throws IOError;
public abstract ErrorInfos trans_init (TransFlag transflags) throws IOError;
public abstract ErrorInfos trans_sysupgrade (int enable_downgrade) throws IOError;
public abstract ErrorInfos trans_add_pkg (string pkgname) throws IOError;
public abstract ErrorInfos trans_remove_pkg (string pkgname) throws IOError;
public abstract ErrorInfos trans_load_pkg (string pkgpath) throws IOError;
public abstract async void trans_prepare () throws IOError;
public abstract void choose_provider (int provider) throws IOError;
public abstract UpdatesInfos[] trans_to_add () throws IOError;
public abstract UpdatesInfos[] trans_to_remove () throws IOError;
public abstract async void trans_commit () throws IOError;
public abstract void trans_release () throws IOError;
public abstract void trans_cancel () throws IOError;
[DBus (no_reply = true)]
public abstract void quit () throws IOError;
public signal void emit_event (uint event, string msg);
public signal void emit_providers (string depend, string[] providers);
public signal void emit_progress (uint progress, string action, string pkgname, int percent, uint n_targets, uint current_target);
public signal void emit_download (string filename, uint64 xfered, uint64 total);
public signal void emit_totaldownload (uint64 total);
public signal void emit_log (uint level, string msg);
public signal void emit_refreshed (ErrorInfos error);
public signal void emit_trans_prepared (ErrorInfos error);
public signal void emit_trans_committed (ErrorInfos error);
}
public class Transaction: Object {
public Daemon daemon;
public Alpm.Config alpm_config;
public Pamac.Config pamac_config;
public TransactionData data;
public Mode mode;
uint64 total_download;
uint64 already_downloaded;
string previous_label;
string previous_textbar;
double previous_percent;
string previous_filename;
uint build_timeout_id;
bool sysupgrade_after_trans;
bool sysupgrade_after_build;
Terminal term;
//dialogs
ChooseProviderDialog choose_provider_dialog;
TransactionSumDialog transaction_sum_dialog;
TransactionInfoDialog transaction_info_dialog;
ProgressWindow progress_window;
//parent window
ApplicationWindow? window;
public signal void finished (bool error);
public Transaction (ApplicationWindow? window, Pamac.Config pamac_config) {
alpm_config = new Alpm.Config ("/etc/pacman.conf");
this.pamac_config = pamac_config;
mode = Mode.MANAGER;
data = TransactionData ();
data.flags = Alpm.TransFlag.CASCADE;
data.to_add = new HashTable<string, string> (str_hash, str_equal);
data.to_remove = new HashTable<string, string> (str_hash, str_equal);
data.to_load = new HashTable<string, string> (str_hash, str_equal);
data.to_build = new HashTable<string, string> (str_hash, str_equal);
connecting_dbus_signals ();
//creating dialogs
this.window = window;
choose_provider_dialog = new ChooseProviderDialog (window);
transaction_sum_dialog = new TransactionSumDialog (window);
transaction_info_dialog = new TransactionInfoDialog (window);
progress_window = new ProgressWindow (this, window);
//creating terminal
term = new Terminal ();
term.scroll_on_output = false;
term.expand = true;
term.height_request = 200;
term.set_visible (true);
// add term in a grid with a scrollbar
var grid = new Grid ();
grid.expand = true;
grid.set_visible (true);
var sb = new Scrollbar (Orientation.VERTICAL, term.vadjustment);
sb.set_visible (true);
grid.attach (term, 0, 0, 1, 1);
grid.attach (sb, 1, 0, 1, 1);
progress_window.expander.add (grid);
// progress data
total_download = 0;
already_downloaded = 0;
previous_label = "";
previous_textbar = "";
previous_percent = 0.0;
previous_filename = "";
sysupgrade_after_trans = false;
sysupgrade_after_build = false;
}
public void write_config (HashTable<string,string> new_conf) {
try {
daemon.write_config (new_conf);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void refresh_alpm_config () {
alpm_config = new Alpm.Config ("/etc/pacman.conf");
}
public void refresh (int force) {
string action = dgettext ("pacman", "Synchronizing package databases...\n").replace ("\n", "");
try {
term.reset (true, true);
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", action}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
progress_window.action_label.set_text (action);
progress_window.progressbar.set_fraction (0);
progress_window.progressbar.set_text ("");
progress_window.cancel_button.visible = true;
progress_window.close_button.visible = false;
progress_window.show ();
daemon.refresh.begin (force, true, (obj, res) => {
try {
daemon.refresh.end (res);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
});
}
public void sysupgrade_simple (int enable_downgrade) {
print("simple sysupgrade\n");
progress_window.progressbar.set_fraction (0);
progress_window.cancel_button.visible = true;
ErrorInfos err = ErrorInfos ();
try {
err = daemon.trans_init (0);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "") {
finished (true);
handle_error (err);
} else {
try {
err = daemon.trans_sysupgrade (enable_downgrade);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str == "") {
progress_window.show ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
daemon.trans_prepare.begin ((obj, res) => {
try {
daemon.trans_prepare.end (res);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
});
} else {
release ();
finished (true);
handle_error (err);
}
}
}
public void sysupgrade (int enable_downgrade) {
string action = dgettext ("pacman", "Starting full system upgrade...\n").replace ("\n", "");
try {
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", action}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
progress_window.action_label.set_text (action);
progress_window.progressbar.set_fraction (0);
progress_window.progressbar.set_text ("");
progress_window.cancel_button.visible = true;
progress_window.close_button.visible = false;
while (Gtk.events_pending ())
Gtk.main_iteration ();
// sysupgrade
print("get syncfirst\n");
// get syncfirst updates
UpdatesInfos[] syncfirst_updates = get_syncfirst_updates (alpm_config);
if (syncfirst_updates.length != 0) {
clear_lists ();
if (mode == Mode.MANAGER)
sysupgrade_after_trans = true;
foreach (UpdatesInfos infos in syncfirst_updates)
data.to_add.insert (infos.name, infos.name);
// run as a standard transaction
run ();
} else {
if (pamac_config.enable_aur) {
print("get aur updates\n");
string[] ignore_pkgs = get_ignore_pkgs (alpm_config);
UpdatesInfos[] aur_updates = get_aur_updates (alpm_config, ignore_pkgs);
if (aur_updates.length != 0) {
clear_lists ();
sysupgrade_after_build = true;
foreach (UpdatesInfos infos in aur_updates)
data.to_build.insert (infos.name, infos.name);
}
}
sysupgrade_simple (enable_downgrade);
}
}
public void clear_lists () {
data.to_add.steal_all ();
data.to_remove.steal_all ();
data.to_build.steal_all ();
}
public void run () {
string action = dgettext (null,"Preparing") + "...";
try {
term.reset (true, true);
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", action}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
progress_window.action_label.set_text (action);
progress_window.progressbar.set_fraction (0);
progress_window.progressbar.set_text ("");
progress_window.cancel_button.visible = true;
progress_window.close_button.visible = false;
progress_window.show ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
// run
ErrorInfos err = ErrorInfos ();
if (data.to_add.size () == 0
&& data.to_remove.size () == 0
&& data.to_load.size () == 0
&& data.to_build.size () != 0) {
// there only AUR packages to build so no need to prepare transaction
on_emit_trans_prepared (err);
} else {
try {
err = daemon.trans_init (data.flags);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "") {
finished (true);
handle_error (err);
} else {
foreach (string name in data.to_add.get_keys ()) {
try {
err = daemon.trans_add_pkg (name);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
foreach (string name in data.to_remove.get_keys ()) {
try {
err = daemon.trans_remove_pkg (name);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
foreach (string path in data.to_load.get_keys ()) {
try {
err = daemon.trans_load_pkg (path);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
if (err.str == "") {
daemon.trans_prepare.begin ((obj, res) => {
try {
daemon.trans_prepare.end (res);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
});
} else {
release ();
finished (true);
handle_error (err);
}
}
}
}
public void choose_provider (string depend, string[] providers) {
int len = providers.length;
choose_provider_dialog.label.set_markup ("<b>%s</b>".printf (dgettext (null, "Choose a provider for %s:").printf (depend, len)));
choose_provider_dialog.comboboxtext.remove_all ();
foreach (string provider in providers)
choose_provider_dialog.comboboxtext.append_text (provider);
choose_provider_dialog.comboboxtext.active = 0;
choose_provider_dialog.run ();
choose_provider_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
try {
daemon.choose_provider (choose_provider_dialog.comboboxtext.active);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public int set_transaction_sum () {
// return 1 if transaction_sum is empty, 0 otherwise
int ret = 1;
uint64 dsize = 0;
UpdatesInfos[] prepared_to_add = {};
UpdatesInfos[] prepared_to_remove = {};
string[] to_downgrade = {};
string[] to_install = {};
string[] to_reinstall = {};
string[] to_update = {};
string[] to_build = {};
TreeIter iter;
transaction_sum_dialog.top_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Transaction Summary")));
transaction_sum_dialog.sum_list.clear ();
try {
prepared_to_add = daemon.trans_to_add ();
prepared_to_remove = daemon.trans_to_remove ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
foreach (UpdatesInfos pkg_info in prepared_to_add) {
dsize += pkg_info.download_size;
unowned Alpm.Package? local_pkg = alpm_config.handle.localdb.get_pkg (pkg_info.name);
if (local_pkg == null) {
to_install += "%s %s".printf (pkg_info.name, pkg_info.version);
} else {
int cmp = pkg_vercmp (pkg_info.version, local_pkg.version);
if (cmp == 1)
to_update += "%s %s".printf (pkg_info.name, pkg_info.version);
else if (cmp == 0)
to_reinstall += "%s %s".printf (pkg_info.name, pkg_info.version);
else
to_downgrade += "%s %s".printf (pkg_info.name, pkg_info.version);
}
}
foreach (string name in data.to_build.get_keys ())
to_build += name;
int len = prepared_to_remove.length;
int i;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To remove") + ":",
1, "%s %s".printf (prepared_to_remove[0].name, prepared_to_remove[0].version));
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, "%s %s".printf (prepared_to_remove[i].name, prepared_to_remove[i].version));
i++;
}
}
len = to_downgrade.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To downgrade") + ":",
1, to_downgrade[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_downgrade[i]);
i++;
}
}
len = to_build.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To build") + ":",
1, to_build[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_build[i]);
i++;
}
}
len = to_install.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To install") + ":",
1, to_install[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_install[i]);
i++;
}
}
len = to_reinstall.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To reinstall") + ":",
1, to_reinstall[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_reinstall[i]);
i++;
}
}
if (mode == Mode.MANAGER) {
len = to_update.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To update") + ":",
1, to_update[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_update[i]);
i++;
}
}
}
if (dsize == 0)
transaction_sum_dialog.bottom_label.set_visible (false);
else {
transaction_sum_dialog.bottom_label.set_markup ("<b>%s %s</b>".printf (dgettext (null, "Total download size:"), format_size (dsize)));
transaction_sum_dialog.bottom_label.set_visible (true);
}
return ret;
}
public void commit () {
progress_window.cancel_button.visible = false;
daemon.trans_commit.begin ((obj, res) => {
try {
daemon.trans_commit.end (res);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
});
}
public void build_aur_packages () {
string[] cmds = {"/usr/bin/yaourt", "-S"};
foreach (string name in data.to_build.get_keys ())
cmds += name;
string action = dgettext (null,"Building packages") + "...";
try {
term.reset (true, true);
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", action}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
progress_window.action_label.set_text (action);
progress_window.progressbar.set_fraction (0);
progress_window.progressbar.set_text ("");
progress_window.cancel_button.visible = false;
progress_window.close_button.visible = false;
progress_window.expander.set_expanded (true);
progress_window.width_request = 700;
term.child_exited.connect (on_term_child_exited);
term.grab_focus ();
build_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_window.progressbar.pulse);
try {
Pid child_pid;
term.spawn_sync (PtyFlags.DEFAULT, "~/", cmds, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, out child_pid);
//term.watch_child (child_pid);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
public void cancel () {
try {
daemon.trans_cancel ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void release () {
try {
daemon.trans_release ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void stop_daemon () {
try {
daemon.quit ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
void on_emit_event (uint event, string msg) {
switch (event) {
case Event.CHECKDEPS_START:
break;
case Event.FILECONFLICTS_START:
break;
case Event.RESOLVEDEPS_START:
break;
case Event.INTERCONFLICTS_START:
break;
case Event.ADD_START:
progress_window.cancel_button.visible = false;
break;
case Event.ADD_DONE:
break;
case Event.REMOVE_START:
progress_window.cancel_button.visible = false;
break;
case Event.REMOVE_DONE:
break;
case Event.UPGRADE_START:
break;
case Event.UPGRADE_DONE:
break;
case Event.DOWNGRADE_START:
break;
case Event.DOWNGRADE_DONE:
break;
case Event.REINSTALL_START:
break;
case Event.REINSTALL_DONE:
break;
case Event.INTEGRITY_START:
break;
case Event.KEYRING_START:
break;
//~ case Event.KEY_DOWNLOAD_START:
//~ break;
case Event.LOAD_START:
break;
//~ case Event.DELTA_INTEGRITY_START:
//~ break;
//~ case Event.DELTA_PATCHES_START:
//~ break;
//~ case Event.DELTA_PATCH_START:
//~ break;
//~ case Event.DELTA_PATCH_DONE:
//~ break;
//~ case Event.DELTA_PATCH_FAILED:
//~ break;
case Event.SCRIPTLET_INFO:
progress_window.expander.set_expanded (true);
break;
case Event.RETRIEVE_START:
progress_window.action_label.set_text (msg.replace ("\n", ""));
break;
case Event.DISKSPACE_START:
break;
//~ case Event.OPTDEP_REQUIRED:
//~ break;
//~ case Event.DATABASE_MISSING:
//~ break;
case Event.FILECONFLICTS_DONE:
case Event.CHECKDEPS_DONE:
case Event.RESOLVEDEPS_DONE:
case Event.INTERCONFLICTS_DONE:
case Event.INTEGRITY_DONE:
case Event.KEYRING_DONE:
case Event.KEY_DOWNLOAD_DONE:
case Event.LOAD_DONE:
case Event.DELTA_INTEGRITY_DONE:
case Event.DELTA_PATCHES_DONE:
case Event.DISKSPACE_DONE:
break;
default:
break;
}
try {
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", "-n", msg}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
void on_emit_providers (string depend, string[] providers) {
choose_provider (depend, providers);
}
void on_emit_progress (uint progress, string action, string pkgname, int percent, uint n_targets, uint current_target) {
double fraction;
switch (progress) {
case Progress.ADD_START:
case Progress.UPGRADE_START:
case Progress.DOWNGRADE_START:
case Progress.REINSTALL_START:
case Progress.REMOVE_START:
fraction = ((float) (current_target-1)/n_targets)+((float) percent/(100*n_targets));
break;
case Progress.CONFLICTS_START:
case Progress.DISKSPACE_START:
case Progress.INTEGRITY_START:
case Progress.KEYRING_START:
case Progress.LOAD_START:
default:
fraction = (float) percent/100;
break;
}
string label;
if (pkgname != "")
label = "%s %s...".printf (action, pkgname);
else
label = "%s...".printf (action);
if (label != previous_label) {
previous_label = label;
progress_window.action_label.set_text (label);
}
string textbar = "%lu/%lu".printf (current_target, n_targets);
if (textbar != previous_textbar) {
previous_textbar = textbar;
progress_window.progressbar.set_text (textbar);
}
if (fraction != previous_percent) {
previous_percent = fraction;
progress_window.progressbar.set_fraction (fraction);
}
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
void on_emit_download (string filename, uint64 xfered, uint64 total) {
string label;
string textbar;
double fraction;
if (filename != previous_filename) {
previous_filename = filename;
if (filename.has_suffix (".db")) {
label = dgettext (null, "Refreshing {repo}").replace ("{repo}", filename.replace (".db", "")) + "...";
} else {
label = dgettext (null, "Downloading {pkgname}").replace ("{pkgname}", filename.replace (".pkg.tar.xz", "")) + "...";
}
if (label != previous_label) {
previous_label = label;
progress_window.action_label.set_text (label);
try {
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", label}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
}
if (total_download > 0) {
fraction = (float) (xfered + already_downloaded) / total_download;
textbar = "%s/%s".printf (format_size (xfered + already_downloaded), format_size (total_download));
} else {
fraction = (float) xfered / total;
textbar = "%s/%s".printf (format_size (xfered), format_size (total));
}
if (fraction != previous_percent) {
previous_percent = fraction;
progress_window.progressbar.set_fraction (fraction);
}
if (textbar != previous_textbar) {
previous_textbar = textbar;
progress_window.progressbar.set_text (textbar);
}
if (xfered == total)
already_downloaded += total;
}
void on_emit_totaldownload (uint64 total) {
total_download = total;
}
void on_emit_log (uint level, string msg) {
// msg ends with \n
string? line = null;
TextIter end_iter;
if ((Alpm.LogLevel) level == Alpm.LogLevel.WARNING) {
line = dgettext (null, "Warning") + ": " + msg;
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length);
} else if ((Alpm.LogLevel) level == Alpm.LogLevel.ERROR) {
line = dgettext (null, "Error") + ": " + msg;
}
if (line != null) {
progress_window.expander.set_expanded (true);
try {
term.spawn_sync (PtyFlags.DEFAULT, "~/", {"/usr/bin/echo", "-n", line}, {}, SpawnFlags.DO_NOT_REAP_CHILD, null, null);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
}
public void handle_warning () {
if (transaction_info_dialog.textbuffer.text != "") {
transaction_info_dialog.set_title (dgettext (null, "Warning"));
transaction_info_dialog.label.set_visible (false);
transaction_info_dialog.expander.set_visible (true);
transaction_info_dialog.expander.set_expanded (true);
transaction_info_dialog.run ();
transaction_info_dialog.hide ();
TextIter start_iter;
TextIter end_iter;
transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
}
}
public void handle_error (ErrorInfos error) {
TextIter start_iter;
TextIter end_iter;
transaction_info_dialog.set_title (dgettext (null, "Error"));
transaction_info_dialog.label.set_visible (true);
transaction_info_dialog.label.set_markup (error.str.replace ("\n", ""));
transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
if (error.details.length != 0) {
foreach (string detail in error.details) {
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.insert (ref end_iter, detail, detail.length);
}
transaction_info_dialog.expander.set_visible (true);
} else
transaction_info_dialog.expander.set_visible (false);
transaction_info_dialog.run ();
transaction_info_dialog.hide ();
progress_window.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
public void on_emit_refreshed (ErrorInfos error) {
print("transaction refreshed\n");
refresh_alpm_config ();
if (error.str == "") {
if (mode == Mode.UPDATER) {
progress_window.hide ();
finished (false);
} else {
sysupgrade (0);
}
} else {
handle_error (error);
finished (true);
}
}
public void on_emit_trans_prepared (ErrorInfos error) {
print ("transaction prepared\n");
if (error.str == "") {
handle_warning ();
int ret = set_transaction_sum ();
if (ret == 0) {
if (data.to_add.size () == 0
&& data.to_remove.size () == 0
&& data.to_load.size () == 0
&& data.to_build.size () != 0) {
// there only AUR packages to build or we update AUR packages first
release ();
if (transaction_sum_dialog.run () == ResponseType.OK) {
transaction_sum_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
ErrorInfos err = ErrorInfos ();
on_emit_trans_committed (err);
} else {
progress_window.hide ();
transaction_sum_dialog.hide ();
finished (true);
}
} else if (sysupgrade_after_build) {
print("sysupgrade_after_build\n");
sysupgrade_after_build = false;
commit ();
} else if (transaction_sum_dialog.run () == ResponseType.OK) {
transaction_sum_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
commit ();
} else {
progress_window.hide ();
transaction_sum_dialog.hide ();
release ();
finished (true);
}
} else if (mode == Mode.UPDATER) {
commit ();
} else {
//ErrorInfos err = ErrorInfos ();
//err.str = dgettext (null, "Nothing to do") + "\n";
progress_window.hide ();
release ();
clear_lists ();
finished (false);
//handle_error (err);
}
} else {
finished (true);
handle_error (error);
}
}
public void on_emit_trans_committed (ErrorInfos error) {
print("transaction committed\n");
term.child_exited.disconnect (on_term_child_exited);
if (error.str == "") {
if (data.to_build.size () != 0) {
build_aur_packages ();
} else {
//progress_window.action_label.set_text (dgettext (null, "Transaction successfully finished"));
//progress_window.close_button.set_visible (true);
clear_lists ();
handle_warning ();
refresh_alpm_config ();
if (sysupgrade_after_trans) {
sysupgrade_after_trans = false;
sysupgrade (0);
} else if (sysupgrade_after_build) {
sysupgrade_simple (0);
} else {
progress_window.hide ();
finished (false);
}
}
} else {
finished (true);
handle_error (error);
}
total_download = 0;
already_downloaded = 0;
}
void on_term_child_exited (int status) {
Source.remove (build_timeout_id);
data.to_build.steal_all ();
ErrorInfos err = ErrorInfos ();
on_emit_trans_committed (err);
}
void connecting_dbus_signals () {
try {
daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac",
"/org/manjaro/pamac");
// Connecting to signals
daemon.emit_event.connect (on_emit_event);
daemon.emit_providers.connect (on_emit_providers);
daemon.emit_progress.connect (on_emit_progress);
daemon.emit_download.connect (on_emit_download);
daemon.emit_totaldownload.connect (on_emit_totaldownload);
daemon.emit_log.connect (on_emit_log);
daemon.emit_refreshed.connect (on_emit_refreshed);
daemon.emit_trans_prepared.connect (on_emit_trans_prepared);
daemon.emit_trans_committed.connect (on_emit_trans_committed);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/transaction/transaction_info_dialog.ui")]
public class TransactionInfoDialog : Gtk.Dialog {
[GtkChild]
public Gtk.Label label;
[GtkChild]
public Gtk.Expander expander;
[GtkChild]
public Gtk.TextView textview;
public Gtk.TextBuffer textbuffer;
public TransactionInfoDialog (Gtk.ApplicationWindow? window) {
Object (transient_for: window, use_header_bar: 0);
textbuffer = textview.get_buffer ();
}
}
}

View File

@ -0,0 +1,41 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/transaction/transaction_sum_dialog.ui")]
public class TransactionSumDialog : Gtk.Dialog {
[GtkChild]
public Gtk.Label top_label;
[GtkChild]
public Gtk.Label bottom_label;
[GtkChild]
public Gtk.TreeView treeview;
public Gtk.ListStore sum_list;
public TransactionSumDialog (Gtk.ApplicationWindow? window) {
Object (transient_for: window, use_header_bar: 0);
sum_list = new Gtk.ListStore (2, typeof (string), typeof (string));
treeview.set_model (sum_list);
}
}
}

256
src/tray.vala Normal file
View File

@ -0,0 +1,256 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// i18n
const string GETTEXT_PACKAGE = "pamac";
const string update_icon_name = "pamac-tray-update";
const string update_info = _("{number} available updates");
const string one_update_info = _("1 available update");
const string noupdate_icon_name = "pamac-tray-no-update";
const string noupdate_info = _("Your system is up-to-date");
namespace Pamac {
[DBus (name = "org.manjaro.pamac")]
public interface Daemon : Object {
public abstract async void refresh (int force, bool emit_signal) throws IOError;
public abstract UpdatesInfos[] get_updates () throws IOError;
[DBus (no_reply = true)]
public abstract void quit () throws IOError;
}
public class TrayIcon: Gtk.Application {
Notify.Notification notification;
Daemon daemon;
Pamac.Config pamac_config;
bool locked;
uint refresh_timeout_id;
Gtk.StatusIcon status_icon;
Gtk.Menu menu;
public TrayIcon () {
application_id = "org.manjaro.pamac.tray";
flags = ApplicationFlags.FLAGS_NONE;
}
void start_daemon () {
try {
daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac",
"/org/manjaro/pamac");
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
void stop_daemon () {
try {
daemon.quit ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
// Create menu for right button
void create_menu () {
menu = new Gtk.Menu ();
Gtk.MenuItem item;
item = new Gtk.MenuItem.with_label (_("Update Manager"));
item.activate.connect (execute_updater);
menu.append (item);
item = new Gtk.MenuItem.with_label (_("Package Manager"));
item.activate.connect (execute_manager);
menu.append (item);
item = new Gtk.MenuItem.with_label (_("Quit"));
item.activate.connect (this.release);
menu.append (item);
menu.show_all ();
}
// Show popup menu on right button
void menu_popup (uint button, uint time) {
menu.popup (null, null, null, button, time);
}
void left_clicked () {
if (status_icon.icon_name == "pamac-tray-update")
execute_updater ();
}
void execute_updater () {
try {
Process.spawn_async(null, new string[]{"/usr/bin/pamac-updater"}, null, SpawnFlags.SEARCH_PATH, null, null);
} catch (Error e) {
print(e.message);
}
}
void execute_manager () {
try {
Process.spawn_async(null, new string[]{"/usr/bin/pamac-manager"}, null, SpawnFlags.SEARCH_PATH, null, null);
} catch (Error e) {
print(e.message);
}
}
public void update_icon (string icon, string info) {
status_icon.set_from_icon_name (icon);
status_icon.set_tooltip_markup (info);
}
bool refresh () {
start_daemon ();
daemon.refresh.begin (1, false, (obj, res) => {
try {
daemon.refresh.end (res);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
});
return true;
}
void check_updates () {
UpdatesInfos[] updates = {};
bool pamac_run = check_pamac_running ();
try {
updates = daemon.get_updates ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
uint updates_nb = updates.length;
if (updates_nb == 0) {
this.update_icon (noupdate_icon_name, noupdate_info);
} else if (updates_nb == 1) {
this.update_icon (update_icon_name, one_update_info);
if (pamac_run == false)
show_notification (one_update_info);
} else {
// workaround to use python format string
string info = update_info.replace ("{number}", updates_nb.to_string ());
this.update_icon (update_icon_name, info);
if (pamac_run == false)
show_notification (info);
}
if (pamac_run == false)
stop_daemon ();
}
void show_notification (string info) {
//~ notification = new Notification (_("Update Manager"));
//~ Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default ();
//~ Gdk.Pixbuf icon = icon_theme.load_icon ("system-software-update", 32, 0);
//~ notification.set_icon (icon);
//~ notification.set_body (info);
//~ var action = new SimpleAction ("update", null);
//~ action.activate.connect (execute_updater);
//~ this.add_action (action);
//~ notification.add_button (_("Show available updates"), "app.update");
//~ this.send_notification (_("Update Manager"), notification);
try {
notification = new Notify.Notification (_("Update Manager"), info, "system-software-update");
notification.add_action ("update", _("Show available updates"), execute_updater);
notification.show ();
} catch (Error e) {
stderr.printf ("Notify Error: %s", e.message);
}
}
bool check_pamac_running () {
Application app;
bool run = false;
app = new Application ("org.manjaro.pamac.manager", 0);
try {
app.register ();
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
run = app.get_is_remote ();
if (run)
return run;
else {
app = new Application ("org.manjaro.pamac.updater", 0);
try {
app.register ();
} catch (GLib.Error e) {
stderr.printf ("%s\n", e.message);
}
run = app.get_is_remote ();
return run;
}
}
bool check_pacman_running () {
GLib.File lockfile = GLib.File.new_for_path ("/var/lib/pacman/db.lck");
if (locked) {
if (lockfile.query_exists () == false) {
locked = false;
check_updates ();
}
} else {
if (lockfile.query_exists () == true) {
locked = true;
}
}
return true;
}
void launch_refresh_timeout (string? msg = null) {
if (refresh_timeout_id != 0) {
pamac_config.reload ();
Source.remove (refresh_timeout_id);
}
refresh_timeout_id = Timeout.add_seconds ((uint) pamac_config.refresh_period*3600, refresh);
}
public override void startup () {
// i18n
Intl.textdomain ("pamac");
Intl.setlocale (LocaleCategory.ALL, "");
base.startup ();
pamac_config = new Pamac.Config ("/etc/pamac.conf");
locked = false;
refresh_timeout_id = 0;
status_icon = new Gtk.StatusIcon ();
status_icon.set_visible (true);
status_icon.activate.connect (left_clicked);
create_menu ();
status_icon.popup_menu.connect (menu_popup);
Notify.init(_("Update Manager"));
refresh ();
launch_refresh_timeout ();
Timeout.add (500, check_pacman_running);
this.hold ();
}
public override void activate () {
// nothing to do
}
public static int main (string[] args) {
var tray_icon = new TrayIcon();
return tray_icon.run (args);
}
}
}

55
src/updater.vala Normal file
View File

@ -0,0 +1,55 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Updater : Gtk.Application {
UpdaterWindow updater_window;
public Updater () {
application_id = "org.manjaro.pamac.updater";
flags = ApplicationFlags.FLAGS_NONE;
}
public override void startup () {
// i18n
Intl.textdomain ("pamac");
Intl.setlocale (LocaleCategory.ALL, "");
base.startup ();
updater_window = new UpdaterWindow (this);
}
public override void activate () {
updater_window.present ();
}
public override void shutdown () {
base.shutdown ();
updater_window.transaction.stop_daemon ();
}
}
public static int main (string[] args) {
var updater = new Updater ();
return updater.run (args);
}
}

178
src/updater_window.vala Normal file
View File

@ -0,0 +1,178 @@
/*
* pamac-vala
*
* Copyright (C) 2014 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Gtk;
namespace Pamac {
[GtkTemplate (ui = "/org/manjaro/pamac/updater/updater_window.ui")]
public class UpdaterWindow : Gtk.ApplicationWindow {
[GtkChild]
public Label top_label;
[GtkChild]
public TreeView updates_treeview;
[GtkChild]
public Label bottom_label;
[GtkChild]
public Button apply_button;
public ListStore updates_list;
public Pamac.Config pamac_config;
public Pamac.Transaction transaction;
PreferencesDialog preferences_dialog;
public UpdaterWindow (Gtk.Application application) {
Object (application: application);
pamac_config = new Pamac.Config ("/etc/pamac.conf");
updates_list = new Gtk.ListStore (2, typeof (string), typeof (string));
updates_treeview.set_model (updates_list);
transaction = new Transaction (this as ApplicationWindow, pamac_config);
transaction.mode = Mode.UPDATER;
transaction.finished.connect (on_emit_trans_finished);
preferences_dialog = new PreferencesDialog (this as ApplicationWindow);
top_label.set_markup("<b>%s</b>".printf (dgettext (null, "Your system is up-to-date")));
bottom_label.set_visible (false);
apply_button.set_sensitive (false);
transaction.refresh (0);
}
[GtkCallback]
public void on_preferences_button_clicked () {
bool enable_aur = pamac_config.enable_aur;
bool recurse = pamac_config.recurse;
uint64 refresh_period = pamac_config.refresh_period;
preferences_dialog.enable_aur_button.set_active (enable_aur);
preferences_dialog.remove_unrequired_deps_button.set_active (recurse);
preferences_dialog.refresh_period_spin_button.set_value (refresh_period);
int response = preferences_dialog.run ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
if (response == ResponseType.OK) {
HashTable<string,string> new_conf = new HashTable<string,string> (str_hash, str_equal);
enable_aur = preferences_dialog.enable_aur_button.get_active ();
recurse = preferences_dialog.remove_unrequired_deps_button.get_active ();
refresh_period = (uint64) preferences_dialog.refresh_period_spin_button.get_value ();
if (enable_aur != pamac_config.enable_aur) {
new_conf.insert ("EnableAUR", enable_aur.to_string ());
}
if (recurse != pamac_config.recurse)
new_conf.insert ("RemoveUnrequiredDeps", recurse.to_string ());
if (refresh_period != pamac_config.refresh_period)
new_conf.insert ("RefreshPeriod", refresh_period.to_string ());
if (new_conf.size () != 0) {
transaction.write_config (new_conf);
pamac_config.reload ();
}
}
preferences_dialog.hide ();
}
[GtkCallback]
public void on_apply_button_clicked () {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
transaction.sysupgrade (0);
}
[GtkCallback]
public void on_refresh_button_clicked () {
this.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.WATCH));
while (Gtk.events_pending ())
Gtk.main_iteration ();
transaction.refresh (0);
}
[GtkCallback]
public void on_close_button_clicked () {
this.application.quit ();
}
public void on_emit_trans_finished (bool error) {
if (error == false) {
set_updates_list ();
}
this.get_window ().set_cursor (null);
}
public void set_updates_list () {
TreeIter iter;
string name;
string size;
uint64 dsize = 0;
uint updates_nb = 0;
updates_list.clear ();
// get syncfirst updates
UpdatesInfos[] syncfirst_updates = get_syncfirst_updates (transaction.alpm_config);
if (syncfirst_updates.length != 0) {
updates_nb = syncfirst_updates.length;
foreach (UpdatesInfos infos in syncfirst_updates) {
name = infos.name + " " + infos.version;
size = format_size (infos.download_size);
dsize += infos.download_size;
updates_list.insert_with_values (out iter, -1, 0, name, 1, size);
}
} else {
string[] ignore_pkgs = get_ignore_pkgs (transaction.alpm_config);
UpdatesInfos[] updates = get_repos_updates (transaction.alpm_config, ignore_pkgs);
foreach (UpdatesInfos infos in updates) {
name = infos.name + " " + infos.version;
size = format_size (infos.download_size);
dsize += infos.download_size;
updates_list.insert_with_values (out iter, -1, 0, name, 1, size);
}
updates_nb += updates.length;
if (pamac_config.enable_aur) {
UpdatesInfos[] aur_updates = get_aur_updates (transaction.alpm_config, ignore_pkgs);
updates_nb += aur_updates.length;
foreach (UpdatesInfos infos in aur_updates) {
name = infos.name + " " + infos.version;
size = format_size (infos.download_size);
dsize += infos.download_size;
updates_list.insert_with_values (out iter, -1, 0, name, 1, size);
}
}
}
if (updates_nb == 0) {
top_label.set_markup("<b>%s</b>".printf (dgettext (null, "Your system is up-to-date")));
apply_button.set_sensitive (false);
} else if (updates_nb == 1) {
top_label.set_markup("<b>%s</b>".printf (dgettext (null, "1 available update")));
apply_button.set_sensitive (true);
} else {
top_label.set_markup("<b>%s</b>".printf (dgettext (null, "{number} available updates").replace ("{number}", updates_nb.to_string ())));
apply_button.set_sensitive (true);
}
if (dsize == 0)
bottom_label.set_visible (false);
else {
bottom_label.set_markup("<b>%s %s</b>".printf (dgettext (null, "Total download size:"), format_size(dsize)));
bottom_label.set_visible (true);
}
}
}
}

5
update_po_files.sh Executable file
View File

@ -0,0 +1,5 @@
#! /bin/sh
for i in `ls po | sed s'|.po||'` ; do
msgmerge --update --no-fuzzy-matching po/$i.po pamac.pot
done

55
util/alpm-util.c Normal file
View File

@ -0,0 +1,55 @@
#include "alpm-util.h"
alpm_pkg_t* alpm_pkg_load_file (alpm_handle_t *handle, const char *filename, int full, alpm_siglevel_t level) {
alpm_pkg_t *p;
int err = alpm_pkg_load(handle, filename, full, level, &p);
if (err == -1) return NULL;
else return p;
}
alpm_list_t* alpm_pkg_get_files_list (alpm_pkg_t* pkg) {
alpm_list_t *list = NULL;
alpm_filelist_t *pkgfiles;
size_t i;
pkgfiles = alpm_pkg_get_files(pkg);
for(i = 0; i < pkgfiles->count; i++) {
const alpm_file_t *file = pkgfiles->files + i;
list = alpm_list_add(list, file);
}
return list;
}
void* alpm_list_get_data (alpm_list_t *list) {
return list->data;
}
alpm_list_t* alpm_list_remove_data (alpm_list_t *list, const void *needle, alpm_list_fn_cmp fn) {
void *data = NULL;
list = alpm_list_remove (list, needle, fn, data);
free(data);
return list;
}
alpm_list_t* alpm_list_sort_data (alpm_list_t *list, alpm_list_fn_cmp fn) {
list = alpm_list_msort (list, alpm_list_count (list), fn);
return list;
}
void alpm_list_free_all(alpm_list_t *list) {
do { alpm_list_free_inner(list, free); alpm_list_free(list); list = NULL; } while(0);
}
void alpm_list_iterator(alpm_list_t *list, alpm_list_iterator_t* iter) {
iter->pos = list;
}
void* alpm_list_iterator_next_value (alpm_list_iterator_t *iter) {
if (iter->pos) {
void* result = alpm_list_get_data(iter->pos);
iter->pos = alpm_list_next(iter->pos);
return result;
}
else return NULL;
}

20
util/alpm-util.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef ALPM_VALA_H
#define ALPM_VALA_H
#include <alpm.h>
typedef struct __alpm_list_iterator_t {
alpm_list_t* pos;
} alpm_list_iterator_t;
void* alpm_list_get_data(alpm_list_t *list);
alpm_list_t *alpm_list_remove_data(alpm_list_t *list, const void *needle, alpm_list_fn_cmp fn);
alpm_list_t *alpm_list_sort_data(alpm_list_t *list, alpm_list_fn_cmp fn);
void alpm_list_free_all(alpm_list_t *list);
void alpm_list_iterator(alpm_list_t *list, alpm_list_iterator_t* i);
void* alpm_list_iterator_next_value(alpm_list_iterator_t *iter);
alpm_pkg_t* alpm_pkg_load_file(alpm_handle_t *handle, const char *filename, int full, alpm_siglevel_t level);
alpm_list_t* alpm_pkg_get_files_list (alpm_pkg_t* pkg);
#endif //!ALPM_VALA_H

1006
vapi/libalpm.vapi Normal file

File diff suppressed because it is too large Load Diff

220
vapi/polkit-gobject-1.vapi Normal file
View File

@ -0,0 +1,220 @@
/* polkit-gobject-1.vapi generated by vapigen, do not modify. */
[CCode (cprefix = "Polkit", gir_namespace = "Polkit", gir_version = "1.0", lower_case_cprefix = "polkit_")]
namespace Polkit {
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_action_description_get_type ()")]
public class ActionDescription : GLib.Object {
[CCode (has_construct_function = false)]
protected ActionDescription ();
public unowned string get_action_id ();
public unowned string get_annotation (string key);
[CCode (array_length = false, array_null_terminated = true)]
public unowned string[] get_annotation_keys ();
public unowned string get_description ();
public unowned string get_icon_name ();
public Polkit.ImplicitAuthorization get_implicit_active ();
public Polkit.ImplicitAuthorization get_implicit_any ();
public Polkit.ImplicitAuthorization get_implicit_inactive ();
public unowned string get_message ();
public unowned string get_vendor_name ();
public unowned string get_vendor_url ();
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_authority_get_type ()")]
public class Authority : GLib.Object, GLib.AsyncInitable, GLib.Initable {
[CCode (has_construct_function = false)]
protected Authority ();
public async bool authentication_agent_response (string cookie, Polkit.Identity identity, GLib.Cancellable? cancellable) throws GLib.Error;
public bool authentication_agent_response_sync (string cookie, Polkit.Identity identity, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async Polkit.AuthorizationResult check_authorization (Polkit.Subject subject, string action_id, Polkit.Details? details, Polkit.CheckAuthorizationFlags flags, GLib.Cancellable? cancellable) throws GLib.Error;
public Polkit.AuthorizationResult check_authorization_sync (Polkit.Subject subject, string action_id, Polkit.Details? details, Polkit.CheckAuthorizationFlags flags, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async GLib.List<Polkit.ActionDescription> enumerate_actions (GLib.Cancellable? cancellable) throws GLib.Error;
public GLib.List<Polkit.ActionDescription> enumerate_actions_sync (GLib.Cancellable? cancellable = null) throws GLib.Error;
public async GLib.List<Polkit.TemporaryAuthorization> enumerate_temporary_authorizations (Polkit.Subject subject, GLib.Cancellable? cancellable) throws GLib.Error;
public GLib.List<Polkit.TemporaryAuthorization> enumerate_temporary_authorizations_sync (Polkit.Subject subject, GLib.Cancellable? cancellable = null) throws GLib.Error;
public static Polkit.Authority @get ();
public static async Polkit.Authority get_async (GLib.Cancellable? cancellable) throws GLib.Error;
public Polkit.AuthorityFeatures get_backend_features ();
public unowned string get_backend_name ();
public unowned string get_backend_version ();
public string get_owner ();
public static Polkit.Authority get_sync (GLib.Cancellable? cancellable = null) throws GLib.Error;
public async bool register_authentication_agent (Polkit.Subject subject, string locale, string object_path, GLib.Cancellable? cancellable) throws GLib.Error;
public bool register_authentication_agent_sync (Polkit.Subject subject, string locale, string object_path, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async bool register_authentication_agent_with_options (Polkit.Subject subject, string locale, string object_path, GLib.Variant? options, GLib.Cancellable? cancellable) throws GLib.Error;
public bool register_authentication_agent_with_options_sync (Polkit.Subject subject, string locale, string object_path, GLib.Variant? options, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async bool revoke_temporary_authorization_by_id (string id, GLib.Cancellable? cancellable) throws GLib.Error;
public bool revoke_temporary_authorization_by_id_sync (string id, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async bool revoke_temporary_authorizations (Polkit.Subject subject, GLib.Cancellable? cancellable) throws GLib.Error;
public bool revoke_temporary_authorizations_sync (Polkit.Subject subject, GLib.Cancellable? cancellable = null) throws GLib.Error;
public async bool unregister_authentication_agent (Polkit.Subject subject, string object_path, GLib.Cancellable? cancellable) throws GLib.Error;
public bool unregister_authentication_agent_sync (Polkit.Subject subject, string object_path, GLib.Cancellable? cancellable = null) throws GLib.Error;
public Polkit.AuthorityFeatures backend_features { get; }
public string backend_name { get; }
public string backend_version { get; }
public string owner { owned get; }
public signal void changed ();
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_authorization_result_get_type ()")]
public class AuthorizationResult : GLib.Object {
[CCode (has_construct_function = false)]
public AuthorizationResult (bool is_authorized, bool is_challenge, Polkit.Details? details);
public unowned Polkit.Details get_details ();
public bool get_dismissed ();
public bool get_is_authorized ();
public bool get_is_challenge ();
public bool get_retains_authorization ();
public unowned string get_temporary_authorization_id ();
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_details_get_type ()")]
public class Details : GLib.Object {
[CCode (has_construct_function = false)]
public Details ();
[CCode (array_length = false, array_null_terminated = true)]
public string[] get_keys ();
public void insert (string key, string? value);
public unowned string lookup (string key);
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_permission_get_type ()")]
public class Permission : GLib.Permission, GLib.AsyncInitable, GLib.Initable {
[CCode (cname = "polkit_permission_new", has_construct_function = false)]
public async Permission (string action_id, Polkit.Subject? subject, GLib.Cancellable? cancellable) throws GLib.Error;
public unowned string get_action_id ();
public unowned Polkit.Subject get_subject ();
[CCode (has_construct_function = false, type = "GPermission*")]
public Permission.sync (string action_id, Polkit.Subject? subject, GLib.Cancellable? cancellable = null) throws GLib.Error;
public string action_id { get; construct; }
public Polkit.Subject subject { get; construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_system_bus_name_get_type ()")]
public class SystemBusName : GLib.Object, Polkit.Subject {
[CCode (has_construct_function = false)]
protected SystemBusName ();
public unowned string get_name ();
public Polkit.Subject get_process_sync (GLib.Cancellable? cancellable = null) throws GLib.Error;
public static Polkit.Subject @new (string name);
public void set_name (string name);
public string name { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_temporary_authorization_get_type ()")]
public class TemporaryAuthorization : GLib.Object {
[CCode (has_construct_function = false)]
protected TemporaryAuthorization ();
public unowned string get_action_id ();
public unowned string get_id ();
public Polkit.Subject get_subject ();
public uint64 get_time_expires ();
public uint64 get_time_obtained ();
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_unix_group_get_type ()")]
public class UnixGroup : GLib.Object, Polkit.Identity {
[CCode (has_construct_function = false)]
protected UnixGroup ();
public int get_gid ();
public static Polkit.Identity @new (int gid);
public static Polkit.Identity new_for_name (string name) throws GLib.Error;
public void set_gid (int gid);
public int gid { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_unix_netgroup_get_type ()")]
public class UnixNetgroup : GLib.Object, Polkit.Identity {
[CCode (has_construct_function = false)]
protected UnixNetgroup ();
public unowned string get_name ();
public static Polkit.Identity @new (string name);
public void set_name (string name);
public string name { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_unix_process_get_type ()")]
public class UnixProcess : GLib.Object, Polkit.Subject {
[CCode (has_construct_function = false)]
protected UnixProcess ();
public int get_owner () throws GLib.Error;
public int get_pid ();
public uint64 get_start_time ();
public int get_uid ();
public static Polkit.Subject @new (int pid);
public static Polkit.Subject new_for_owner (int pid, uint64 start_time, int uid);
public static Polkit.Subject new_full (int pid, uint64 start_time);
public void set_pid (int pid);
public void set_start_time (uint64 start_time);
public void set_uid (int uid);
public int pid { get; set construct; }
public uint64 start_time { get; set construct; }
public int uid { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_unix_session_get_type ()")]
public class UnixSession : GLib.Object, GLib.AsyncInitable, GLib.Initable, Polkit.Subject {
[CCode (has_construct_function = false)]
protected UnixSession ();
public unowned string get_session_id ();
public static Polkit.Subject @new (string session_id);
public static async Polkit.Subject new_for_process (int pid, GLib.Cancellable? cancellable) throws GLib.Error;
public static Polkit.Subject new_for_process_sync (int pid, GLib.Cancellable? cancellable = null) throws GLib.Error;
public void set_session_id (string session_id);
public int pid { construct; }
public string session_id { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_unix_user_get_type ()")]
public class UnixUser : GLib.Object, Polkit.Identity {
[CCode (has_construct_function = false)]
protected UnixUser ();
public unowned string get_name ();
public int get_uid ();
public static Polkit.Identity @new (int uid);
public static Polkit.Identity new_for_name (string name) throws GLib.Error;
public void set_uid (int uid);
public int uid { get; set construct; }
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_identity_get_type ()")]
public interface Identity : GLib.Object {
public abstract bool equal (Polkit.Identity b);
public static Polkit.Identity from_string (string str) throws GLib.Error;
public abstract uint hash ();
public abstract string to_string ();
}
[CCode (cheader_filename = "polkit/polkit.h", type_id = "polkit_subject_get_type ()")]
public interface Subject : GLib.Object {
public abstract bool equal (Polkit.Subject b);
public abstract async bool exists (GLib.Cancellable? cancellable) throws GLib.Error;
public abstract bool exists_sync (GLib.Cancellable? cancellable = null) throws GLib.Error;
public static Polkit.Subject from_string (string str) throws GLib.Error;
public abstract uint hash ();
public abstract string to_string ();
}
[CCode (cheader_filename = "polkit/polkit.h", cprefix = "POLKIT_AUTHORITY_FEATURES_", type_id = "polkit_authority_features_get_type ()")]
[Flags]
public enum AuthorityFeatures {
NONE,
TEMPORARY_AUTHORIZATION
}
[CCode (cheader_filename = "polkit/polkit.h", cprefix = "POLKIT_CHECK_AUTHORIZATION_FLAGS_", type_id = "polkit_check_authorization_flags_get_type ()")]
[Flags]
public enum CheckAuthorizationFlags {
NONE,
ALLOW_USER_INTERACTION
}
[CCode (cheader_filename = "polkit/polkit.h", cprefix = "POLKIT_IMPLICIT_AUTHORIZATION_", type_id = "polkit_implicit_authorization_get_type ()")]
public enum ImplicitAuthorization {
UNKNOWN,
NOT_AUTHORIZED,
AUTHENTICATION_REQUIRED,
ADMINISTRATOR_AUTHENTICATION_REQUIRED,
AUTHENTICATION_REQUIRED_RETAINED,
ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED,
AUTHORIZED;
public static bool from_string (string string, Polkit.ImplicitAuthorization out_implicit_authorization);
public static unowned string to_string (Polkit.ImplicitAuthorization implicit_authorization);
}
[CCode (cheader_filename = "polkit/polkit.h", cprefix = "POLKIT_ERROR_")]
public errordomain Error {
FAILED,
CANCELLED,
NOT_SUPPORTED,
NOT_AUTHORIZED;
public static GLib.Quark quark ();
}
[CCode (cheader_filename = "polkit/polkit.h")]
public static Polkit.Identity identity_from_string (string str) throws GLib.Error;
[CCode (cheader_filename = "polkit/polkit.h")]
public static Polkit.Subject subject_from_string (string str) throws GLib.Error;
}