Merge branch 'work-3.3' into calamares
This commit is contained in:
commit
72240d0d59
10
.gersemirc
Normal file
10
.gersemirc
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Gersemi configuration
|
||||
color: false
|
||||
definitions: [ CMakeModules/CalamaresAddTest.cmake ]
|
||||
line_length: 120
|
||||
quiet: false
|
||||
unsafe: false
|
||||
|
488
3rdparty/kdsingleapplicationguard/LICENSE.LGPL.txt
vendored
488
3rdparty/kdsingleapplicationguard/LICENSE.LGPL.txt
vendored
@ -1,488 +0,0 @@
|
||||
|
||||
The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
|
||||
You may use, distribute and copy the KD Tools Library under the terms of
|
||||
GNU Library General Public License version 2, which is displayed below.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey 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 library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
@ -1,481 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#include "kdlockedsharedmemorypointer.h"
|
||||
|
||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
|
||||
#ifndef QT_NO_SHAREDMEMORY
|
||||
|
||||
namespace kdtools
|
||||
{
|
||||
}
|
||||
using namespace kdtools;
|
||||
|
||||
KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory * m )
|
||||
: locker( m ),
|
||||
mem( m )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory & m )
|
||||
: locker( &m ),
|
||||
mem( &m )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
KDLockedSharedMemoryPointerBase::~KDLockedSharedMemoryPointerBase() {}
|
||||
|
||||
void * KDLockedSharedMemoryPointerBase::get() {
|
||||
return mem ? mem->data() : 0 ;
|
||||
}
|
||||
|
||||
const void * KDLockedSharedMemoryPointerBase::get() const {
|
||||
return mem ? mem->data() : 0 ;
|
||||
}
|
||||
|
||||
size_t KDLockedSharedMemoryPointerBase::byteSize() const {
|
||||
return mem ? mem->size() : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class KDLockedSharedMemoryPointer
|
||||
\ingroup core raii smartptr
|
||||
\brief Locking pointer for Qt shared memory segments
|
||||
\since_c 2.1
|
||||
|
||||
(The exception safety of this class has not been evaluated yet.)
|
||||
|
||||
KDLockedSharedMemoryPointer is a smart immutable pointer, which gives convenient and safe access to a QSharedMemory data segment.
|
||||
The content of a KDLockedSharedMemoryPointer cannot be changed during it's lifetime.
|
||||
|
||||
You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
|
||||
\note You can only put simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
|
||||
documentation of QSharedMemory for details.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory * mem )
|
||||
|
||||
Constructor. Constructs a KDLockedSharedMemory pointer which points to the data segment of \a mem.
|
||||
The constructor locks \a mem. If the memory segment is already locked by another process, this constructor
|
||||
blocks until the lock is released.
|
||||
|
||||
\post data() == mem->data() and the memory segment has been locked
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory & mem )
|
||||
|
||||
\overload
|
||||
|
||||
\post data() == mem.data() and the memory segment has been locked
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryPointer::~KDLockedSharedMemoryPointer()
|
||||
|
||||
Destructor. Unlocks the shared memory segment.
|
||||
|
||||
\post The shared memory segment has been unlocked
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T * KDLockedSharedMemoryPointer::get()
|
||||
|
||||
\returns a pointer to the contained object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T * KDLockedSharedMemoryPointer::get() const
|
||||
|
||||
\returns a const pointer to the contained object
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T * KDLockedSharedMemoryPointer::data()
|
||||
|
||||
Equivalent to get(), provided for consistency with Qt naming conventions.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T * KDLockedSharedMemoryPointer::data() const
|
||||
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T & KDLockedSharedMemoryPointer::operator*()
|
||||
|
||||
Dereference operator. Returns \link get() *get()\endlink.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T & KDLockedSharedMemoryPointer::operator*() const
|
||||
|
||||
Dereference operator. Returns \link get() *get()\endlink.
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T * KDLockedSharedMemoryPointer::operator->()
|
||||
|
||||
Member-by-pointer operator. Returns get().
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T * KDLockedSharedMemoryPointer::operator->() const
|
||||
|
||||
Member-by-pointer operator. Returns get().
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class KDLockedSharedMemoryArray
|
||||
\ingroup core raii smartptr
|
||||
\brief Locking array pointer to Qt shared memory segments
|
||||
\since_c 2.1
|
||||
|
||||
(The exception safety of this class has not been evaluated yet.)
|
||||
|
||||
KDLockedSharedMemoryArray is a smart immutable pointer, which gives convenient and safe access to array data stored in a QSharedMemory
|
||||
data segment.
|
||||
The content of a KDLockedSharedMemoryArray cannot be changed during it's lifetime.
|
||||
|
||||
You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
|
||||
\note You can only put arrays of simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
|
||||
documentation of QSharedMemory for details.
|
||||
|
||||
\sa KDLockedSharedMemoryPointer
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory* mem )
|
||||
Constructor. Constructs a KDLockedSharedMemoryArray which points to the data segment of \a mem. The constructor locks \a mem. If the memory
|
||||
segment is already locked by another process, this constructor blocks until the lock is release.
|
||||
|
||||
\post get() == mem->data() and the memory segment has been locked
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory& mem )
|
||||
\overload
|
||||
|
||||
\post get() == mem->data() and the memory segment has been locked
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::size_type
|
||||
Typedef for std::size_t. Provided for STL compatibility.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::difference_type
|
||||
Typedef for std::ptrdiff_t. Provided for STL compatibility.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::iterator
|
||||
Typedef for T*. Provided for STL compatibility.
|
||||
\since_t 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::const_iterator
|
||||
Typedef for const T*. Provided for STL compatibility.
|
||||
\since_t 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::reverse_iterator
|
||||
Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::iterator iterator\endlink >. Provided for STL compatibility.
|
||||
\since_t 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef KDLockedSharedMemoryArray::const_reverse_iterator
|
||||
Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::const_iterator const_iterator\endlink >. Provided for STL compatibility.
|
||||
\since_t 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::begin()
|
||||
Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the first item of the array.
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::begin() const
|
||||
\overload
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::end()
|
||||
Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the item after the last item of the array.
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::end() const
|
||||
\overload
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rbegin()
|
||||
Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the item after the last item of the array.
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rbegin() const
|
||||
\overload
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rend()
|
||||
Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the first item of the array.
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rend() const
|
||||
\overload
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn KDLockedSharedMemoryArray::size_type KDLockedSharedMemoryArray::size() const
|
||||
Returns the size of this array. The size is calculated from the storage size of T and
|
||||
the size of the shared memory segment.
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T& KDLockedSharedMemoryArray::operator[]( difference_type n )
|
||||
Array access operator. Returns a reference to the item at index position \a n.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T& KDLockedSharedMemoryArray::operator[]( difference_type n ) const
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T& KDLockedSharedMemoryArray::front()
|
||||
Returns a reference to the first item in the array. This is the same as operator[](0).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T& KDLockedSharedMemoryArray::front() const
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T& KDLockedSharedMemoryArray::back()
|
||||
Returns a reference to the last item in the array. This is the same as operator[](size()-1).
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T& KDLockedSharedMemoryArray::back() const
|
||||
\overload
|
||||
\since_f 2.2
|
||||
*/
|
||||
|
||||
|
||||
#ifdef eKDTOOLSCORE_UNITTESTS
|
||||
|
||||
#include <KDUnitTest/Test>
|
||||
|
||||
#include <QThread>
|
||||
#include <QUuid>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct TestStruct
|
||||
{
|
||||
TestStruct( uint nn = 0 )
|
||||
: n( nn ),
|
||||
f( 0.0 ),
|
||||
c( '\0' ),
|
||||
b( false )
|
||||
{
|
||||
}
|
||||
uint n;
|
||||
double f;
|
||||
char c;
|
||||
bool b;
|
||||
};
|
||||
|
||||
bool operator==( const TestStruct& lhs, const TestStruct& rhs )
|
||||
{
|
||||
return lhs.n == rhs.n && lhs.f == rhs.f && lhs.c == rhs.c && lhs.b == rhs.b;
|
||||
}
|
||||
|
||||
class TestThread : public QThread
|
||||
{
|
||||
public:
|
||||
TestThread( const QString& key )
|
||||
: mem( key )
|
||||
{
|
||||
mem.attach();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
msleep( 100 );
|
||||
kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
|
||||
if( !p->b )
|
||||
continue;
|
||||
|
||||
p->n = 5;
|
||||
p->f = 3.14;
|
||||
p->c = 'A';
|
||||
p->b = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QSharedMemory mem;
|
||||
};
|
||||
|
||||
bool isConst( TestStruct* )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isConst( const TestStruct* )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KDAB_UNITTEST_SIMPLE( KDLockedSharedMemoryPointer, "kdcoretools" ) {
|
||||
|
||||
const QString key = QUuid::createUuid();
|
||||
QSharedMemory mem( key );
|
||||
const bool created = mem.create( sizeof( TestStruct ) );
|
||||
assertTrue( created );
|
||||
if ( !created )
|
||||
return; // don't execute tests if shm coulnd't be created
|
||||
|
||||
// On Windows, shared mem is only available in increments of page
|
||||
// size (4k), so don't fail if the segment is larger:
|
||||
const unsigned long mem_size = mem.size();
|
||||
assertGreaterOrEqual( mem_size, sizeof( TestStruct ) );
|
||||
|
||||
{
|
||||
kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
|
||||
assertTrue( p );
|
||||
*p = TestStruct();
|
||||
assertEqual( p->n, 0u );
|
||||
assertEqual( p->f, 0.0 );
|
||||
assertEqual( p->c, '\0' );
|
||||
assertFalse( p->b );
|
||||
}
|
||||
|
||||
{
|
||||
TestThread thread( key );
|
||||
assertEqual( thread.mem.key().toStdString(), key.toStdString() );
|
||||
assertEqual( static_cast< unsigned long >( thread.mem.size() ), mem_size );
|
||||
thread.start();
|
||||
|
||||
assertTrue( thread.isRunning() );
|
||||
thread.wait( 2000 );
|
||||
assertTrue( thread.isRunning() );
|
||||
|
||||
{
|
||||
kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
|
||||
p->b = true;
|
||||
}
|
||||
|
||||
thread.wait( 2000 );
|
||||
assertFalse( thread.isRunning() );
|
||||
}
|
||||
|
||||
{
|
||||
kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
|
||||
assertEqual( p->n, 5u );
|
||||
assertEqual( p->f, 3.14 );
|
||||
assertEqual( p->c, 'A' );
|
||||
assertFalse( p->b );
|
||||
}
|
||||
|
||||
{
|
||||
kdtools::KDLockedSharedMemoryPointer< TestStruct > p( mem );
|
||||
assertEqual( mem.data(), p.get() );
|
||||
assertEqual( p.get(), p.operator->() );
|
||||
assertEqual( p.get(), &(*p) );
|
||||
assertEqual( p.get(), p.data() );
|
||||
assertFalse( isConst( p.get() ) );
|
||||
}
|
||||
|
||||
{
|
||||
const kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
|
||||
assertEqual( mem.data(), p.get() );
|
||||
assertEqual( p.get(), p.operator->() );
|
||||
assertEqual( p.get(), &(*p) );
|
||||
assertEqual( p.get(), p.data() );
|
||||
assertTrue( isConst( p.get() ) );
|
||||
}
|
||||
|
||||
{
|
||||
QSharedMemory mem2( key + key );
|
||||
const bool created2 = mem2.create( 16 * sizeof( TestStruct ) );
|
||||
assertTrue( created2 );
|
||||
if ( !created2 )
|
||||
return; // don't execute tests if shm coulnd't be created
|
||||
|
||||
kdtools::KDLockedSharedMemoryArray<TestStruct> a( mem2 );
|
||||
assertTrue( a );
|
||||
assertEqual( a.get(), mem2.data() );
|
||||
assertEqual( &a[0], a.get() );
|
||||
|
||||
a[1] = a[0];
|
||||
assertTrue( a[0] == a[1] );
|
||||
|
||||
TestStruct ts;
|
||||
ts.n = 5;
|
||||
ts.f = 3.14;
|
||||
a[0] = ts;
|
||||
assertFalse( a[0] == a[1] );
|
||||
assertEqual( a.front().n, ts.n );
|
||||
assertEqual( a[0].f, ts.f );
|
||||
a[0].n = 10;
|
||||
assertEqual( a.front().n, 10u );
|
||||
ts = a[0];
|
||||
assertEqual( ts.n, 10u );
|
||||
|
||||
std::vector< TestStruct > v;
|
||||
for( uint i = 0; i < a.size(); ++i )
|
||||
v.push_back( TestStruct( i ) );
|
||||
|
||||
std::copy( v.begin(), v.end(), a.begin() );
|
||||
for( uint i = 0; i < a.size(); ++i )
|
||||
assertEqual( a[ i ].n, i );
|
||||
assertEqual( a.front().n, 0u );
|
||||
assertEqual( a.back().n, a.size() - 1 );
|
||||
|
||||
std::copy( v.begin(), v.end(), a.rbegin() );
|
||||
for( uint i = 0; i < a.size(); ++i )
|
||||
assertEqual( a[ i ].n, a.size() - 1 - i );
|
||||
assertEqual( a.front().n, a.size() - 1 );
|
||||
assertEqual( a.back().n, 0u );
|
||||
}
|
||||
|
||||
}
|
||||
#endif // KDTOOLSCORE_UNITTESTS
|
||||
#endif // QT_NO_SHAREDMEMORY
|
||||
#endif // QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#ifndef __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__
|
||||
#define __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
|
||||
#ifndef QT_NO_SHAREDMEMORY
|
||||
|
||||
#include "kdsharedmemorylocker.h"
|
||||
#include <QtCore/QSharedMemory>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
namespace kdtools {
|
||||
#endif
|
||||
|
||||
class KDLockedSharedMemoryPointerBase {
|
||||
protected:
|
||||
explicit KDLockedSharedMemoryPointerBase( QSharedMemory * mem );
|
||||
explicit KDLockedSharedMemoryPointerBase( QSharedMemory & mem );
|
||||
~KDLockedSharedMemoryPointerBase();
|
||||
|
||||
// PENDING(marc) do we really want const propagation here? I
|
||||
// usually declare all my RAII objects const...
|
||||
void * get();
|
||||
const void * get() const;
|
||||
|
||||
KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( get() )
|
||||
|
||||
size_t byteSize() const;
|
||||
|
||||
private:
|
||||
KDSharedMemoryLocker locker;
|
||||
QSharedMemory * const mem;
|
||||
};
|
||||
|
||||
template< typename T>
|
||||
class MAKEINCLUDES_EXPORT KDLockedSharedMemoryPointer : KDLockedSharedMemoryPointerBase {
|
||||
KDAB_DISABLE_COPY( KDLockedSharedMemoryPointer );
|
||||
public:
|
||||
explicit KDLockedSharedMemoryPointer( QSharedMemory * m )
|
||||
: KDLockedSharedMemoryPointerBase( m ) {}
|
||||
explicit KDLockedSharedMemoryPointer( QSharedMemory & m )
|
||||
: KDLockedSharedMemoryPointerBase( m ) {}
|
||||
|
||||
T * get() { return static_cast<T*>( KDLockedSharedMemoryPointerBase::get() ); }
|
||||
const T * get() const { return static_cast<const T*>( KDLockedSharedMemoryPointerBase::get() ); }
|
||||
|
||||
T * data() { return static_cast<T*>( get() ); }
|
||||
const T * data() const { return static_cast<const T*>( get() ); }
|
||||
|
||||
T & operator*() { assert( get() ); return *get(); }
|
||||
const T & operator*() const { assert( get() ); return *get(); }
|
||||
|
||||
T * operator->() { return get(); }
|
||||
const T * operator->() const { return get(); }
|
||||
|
||||
KDAB_USING_SAFE_BOOL_OPERATOR( KDLockedSharedMemoryPointerBase )
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MAKEINCLUDES_EXPORT KDLockedSharedMemoryArray : KDLockedSharedMemoryPointerBase {
|
||||
KDAB_DISABLE_COPY( KDLockedSharedMemoryArray );
|
||||
public:
|
||||
explicit KDLockedSharedMemoryArray( QSharedMemory * m )
|
||||
: KDLockedSharedMemoryPointerBase( m ) {}
|
||||
explicit KDLockedSharedMemoryArray( QSharedMemory & m )
|
||||
: KDLockedSharedMemoryPointerBase( m ) {}
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
typedef std::reverse_iterator< iterator > reverse_iterator;
|
||||
|
||||
iterator begin() { return get(); }
|
||||
const_iterator begin() const { return get(); }
|
||||
|
||||
iterator end() { return begin() + size(); }
|
||||
const_iterator end() const { return begin() + size(); }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator( end() ); }
|
||||
const_reverse_iterator rbegin() const { return reverse_iterator( end() ); }
|
||||
|
||||
reverse_iterator rend() { return reverse_iterator( begin() ); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); }
|
||||
|
||||
size_type size() const { return byteSize() / sizeof( T ); }
|
||||
|
||||
T * get() { return static_cast<T*>( KDLockedSharedMemoryPointerBase::get() ); }
|
||||
const T * get() const { return static_cast<const T*>( KDLockedSharedMemoryPointerBase::get() ); }
|
||||
|
||||
T & operator[]( difference_type n ) { assert( get() ); return *(get()+n); }
|
||||
const T & operator[]( difference_type n ) const { assert( get() ); return *(get()+n); }
|
||||
|
||||
T & front() { assert( get() ); return *get(); }
|
||||
const T & front() const { assert( get() ); return *get(); }
|
||||
|
||||
T & back() { assert( get() ); return *( get() + size() - 1 ); }
|
||||
const T & back() const { assert( get() ); return *( get() + size() - 1 ); }
|
||||
|
||||
KDAB_USING_SAFE_BOOL_OPERATOR( KDLockedSharedMemoryPointerBase )
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* QT_NO_SHAREDMEMORY */
|
||||
|
||||
#endif /* QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN ) */
|
||||
|
||||
#endif /* __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__ */
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#include "kdsharedmemorylocker.h"
|
||||
|
||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
|
||||
|
||||
#include <QSharedMemory>
|
||||
|
||||
using namespace kdtools;
|
||||
|
||||
/*!
|
||||
\class KDSharedMemoryLocker
|
||||
\ingroup raii core
|
||||
\brief Exception-safe and convenient wrapper around QSharedMemory::lock()
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor. Locks the shared memory segment \a mem.
|
||||
* If another process has locking the segment, this constructor blocks
|
||||
* until the lock is released. The memory segments needs to be properly created or attached.
|
||||
*/
|
||||
KDSharedMemoryLocker::KDSharedMemoryLocker( QSharedMemory* mem )
|
||||
: mem( mem )
|
||||
{
|
||||
mem->lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor. Unlocks the shared memory segment associated with this
|
||||
* KDSharedMemoryLocker.
|
||||
*/
|
||||
KDSharedMemoryLocker::~KDSharedMemoryLocker()
|
||||
{
|
||||
mem->unlock();
|
||||
}
|
||||
|
||||
#ifdef KDAB_EVAL
|
||||
#include KDAB_EVAL
|
||||
static const EvalDialogChecker evalChecker( "KD Tools", false );
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#ifndef __KDTOOLS__CORE__KDSHAREDMEMORYLOCKER_H
|
||||
#define __KDTOOLS__CORE__KDSHAREDMEMORYLOCKER_H
|
||||
|
||||
#include "kdtoolsglobal.h"
|
||||
|
||||
#if QT_VERSION < 0x040400 && !defined( DOXYGEN_RUN )
|
||||
#ifdef Q_CC_GNU
|
||||
#warning "Can't use KDTools KDSharedMemoryLocker with Qt versions prior to 4.4"
|
||||
#endif
|
||||
#else
|
||||
|
||||
class QSharedMemory;
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
namespace kdtools
|
||||
{
|
||||
#endif
|
||||
|
||||
class KDTOOLSCORE_EXPORT KDSharedMemoryLocker
|
||||
{
|
||||
Q_DISABLE_COPY( KDSharedMemoryLocker )
|
||||
public:
|
||||
KDSharedMemoryLocker( QSharedMemory* mem );
|
||||
~KDSharedMemoryLocker();
|
||||
|
||||
private:
|
||||
QSharedMemory* const mem;
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#ifndef KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H
|
||||
#define KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#ifndef QT_NO_SHAREDMEMORY
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QMetaType>
|
||||
|
||||
#include "pimpl_ptr.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
template <typename T> class QVector;
|
||||
class QCoreApplication;
|
||||
|
||||
class DLLEXPORT KDSingleApplicationGuard : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS( Policy )
|
||||
Q_PROPERTY( bool operational READ isOperational )
|
||||
Q_PROPERTY( bool exitRequested READ isExitRequested )
|
||||
Q_PROPERTY( bool primaryInstance READ isPrimaryInstance NOTIFY becamePrimaryInstance )
|
||||
Q_PROPERTY( Policy policy READ policy WRITE setPolicy NOTIFY policyChanged )
|
||||
public:
|
||||
enum Policy
|
||||
{
|
||||
NoPolicy = 0,
|
||||
AutoKillOtherInstances = 1
|
||||
};
|
||||
|
||||
explicit KDSingleApplicationGuard( QObject * parent=nullptr );
|
||||
explicit KDSingleApplicationGuard( Policy policy, QObject * parent=nullptr );
|
||||
explicit KDSingleApplicationGuard( const QStringList & arguments, QObject * parent=nullptr );
|
||||
explicit KDSingleApplicationGuard( const QStringList & arguments, Policy policy, QObject * parent=nullptr );
|
||||
~KDSingleApplicationGuard() override;
|
||||
|
||||
bool isOperational() const;
|
||||
|
||||
bool isExitRequested() const;
|
||||
|
||||
bool isPrimaryInstance() const;
|
||||
|
||||
Policy policy() const;
|
||||
void setPolicy( Policy policy );
|
||||
|
||||
class Instance;
|
||||
|
||||
QVector<Instance> instances() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted( const KDSingleApplicationGuard::Instance & instance );
|
||||
void instanceExited( const KDSingleApplicationGuard::Instance & instance );
|
||||
void exitRequested();
|
||||
void raiseRequested();
|
||||
void becamePrimaryInstance();
|
||||
void becameSecondaryInstance();
|
||||
void policyChanged( KDSingleApplicationGuard::Policy policy );
|
||||
|
||||
public Q_SLOTS:
|
||||
void shutdownOtherInstances();
|
||||
void killOtherInstances();
|
||||
|
||||
protected:
|
||||
/*! \reimp */ bool event( QEvent * event ) override;
|
||||
|
||||
private:
|
||||
#ifndef Q_WS_WIN
|
||||
static void SIGINT_handler( int );
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend struct ProcessInfo;
|
||||
|
||||
class Private;
|
||||
kdtools::pimpl_ptr< Private > d;
|
||||
};
|
||||
|
||||
class DLLEXPORT KDSingleApplicationGuard::Instance {
|
||||
friend class ::KDSingleApplicationGuard;
|
||||
friend class ::KDSingleApplicationGuard::Private;
|
||||
Instance( const QStringList &, bool, qint64 );
|
||||
public:
|
||||
Instance();
|
||||
Instance( const Instance & other );
|
||||
~Instance();
|
||||
|
||||
void swap( Instance & other ) {
|
||||
std::swap( d, other.d );
|
||||
}
|
||||
|
||||
Instance & operator=( Instance other ) {
|
||||
swap( other );
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isNull() const { return !d; }
|
||||
bool isValid() const;
|
||||
|
||||
bool areArgumentsTruncated() const;
|
||||
|
||||
const QStringList & arguments() const;
|
||||
qint64 pid() const;
|
||||
|
||||
void shutdown();
|
||||
void kill();
|
||||
void raise();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private * d;
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
inline void swap( KDSingleApplicationGuard::Instance & lhs,
|
||||
KDSingleApplicationGuard::Instance & rhs )
|
||||
{
|
||||
lhs.swap( rhs );
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
template <>
|
||||
inline void qSwap( KDSingleApplicationGuard::Instance & lhs,
|
||||
KDSingleApplicationGuard::Instance & rhs )
|
||||
{
|
||||
lhs.swap( rhs );
|
||||
}
|
||||
Q_DECLARE_METATYPE( KDSingleApplicationGuard::Instance )
|
||||
Q_DECLARE_TYPEINFO( KDSingleApplicationGuard::Instance, Q_MOVABLE_TYPE );
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
#endif // QT_NO_SHAREDMEMORY
|
||||
|
||||
#endif /* KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H */
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#include "kdtoolsglobal.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
struct Version {
|
||||
unsigned char v[3];
|
||||
};
|
||||
|
||||
static inline bool operator<( const Version & lhs, const Version & rhs ) {
|
||||
return std::lexicographical_compare( lhs.v, lhs.v + 3, rhs.v, rhs.v + 3 );
|
||||
}
|
||||
static inline bool operator==( const Version & lhs, const Version & rhs ) {
|
||||
return std::equal( lhs.v, lhs.v + 3, rhs.v );
|
||||
}
|
||||
KDTOOLS_MAKE_RELATION_OPERATORS( Version, static inline )
|
||||
}
|
||||
|
||||
static Version kdParseQtVersion( const char * const version ) {
|
||||
if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || ( version[5] != 0 && version[5] != '.' && version[5] != '-' ) )
|
||||
return Version(); // parse error
|
||||
const Version result = { { static_cast< unsigned char >( version[0] - '0' ),
|
||||
static_cast< unsigned char >( version[2] - '0' ),
|
||||
static_cast< unsigned char >( version[4] - '0' ) } };
|
||||
return result;
|
||||
}
|
||||
|
||||
bool _kdCheckQtVersion_impl( unsigned int major, unsigned int minor, unsigned int patchlevel ) {
|
||||
static const Version actual = kdParseQtVersion( qVersion() ); // do this only once each run...
|
||||
const Version requested = { { static_cast< unsigned char >( major ),
|
||||
static_cast< unsigned char >( minor ),
|
||||
static_cast< unsigned char >( patchlevel ) } };
|
||||
return actual >= requested;
|
||||
}
|
120
3rdparty/kdsingleapplicationguard/kdtoolsglobal.h
vendored
120
3rdparty/kdsingleapplicationguard/kdtoolsglobal.h
vendored
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#ifndef KDTOOLS_KDTOOLSGLOBAL_H
|
||||
#define KDTOOLS_KDTOOLSGLOBAL_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#define KDAB_DISABLE_COPY( x ) private: x( const x & ); x & operator=( const x & )
|
||||
|
||||
#ifdef KDTOOLS_SHARED
|
||||
# ifdef BUILD_SHARED_KDTOOLSCORE
|
||||
# define KDTOOLSCORE_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define KDTOOLSCORE_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# ifdef BUILD_SHARED_KDTOOLSGUI
|
||||
# define KDTOOLSGUI_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define KDTOOLSGUI_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# ifdef BUILD_SHARED_KDTOOLSXML
|
||||
# define KDTOOLSXML_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define KDTOOLSXML_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# ifdef BUILD_SHARED_KDUPDATER
|
||||
# define KDTOOLS_UPDATER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define KDTOOLS_UPDATER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else // KDTOOLS_SHARED
|
||||
# define KDTOOLSCORE_EXPORT
|
||||
# define KDTOOLSGUI_EXPORT
|
||||
# define KDTOOLSXML_EXPORT
|
||||
# define KDTOOLS_UPDATER_EXPORT
|
||||
#endif // KDTOOLS_SHARED
|
||||
|
||||
#define MAKEINCLUDES_EXPORT
|
||||
|
||||
#define DOXYGEN_PROPERTY( x )
|
||||
#ifdef DOXYGEN_RUN
|
||||
# define KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( func ) operator unspecified_bool_type() const { return func; }
|
||||
# define KDAB_USING_SAFE_BOOL_OPERATOR( Class ) operator unspecified_bool_type() const;
|
||||
#else
|
||||
# define KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( func ) \
|
||||
private: \
|
||||
struct __safe_bool_dummy__ { void nonnull() {} }; \
|
||||
public: \
|
||||
typedef void ( __safe_bool_dummy__::*unspecified_bool_type )(); \
|
||||
operator unspecified_bool_type() const { \
|
||||
return ( func ) ? &__safe_bool_dummy__::nonnull : 0 ; \
|
||||
}
|
||||
#define KDAB_USING_SAFE_BOOL_OPERATOR( Class ) \
|
||||
using Class::operator Class::unspecified_bool_type;
|
||||
#endif
|
||||
|
||||
#define KDTOOLS_MAKE_RELATION_OPERATORS( Class, linkage ) \
|
||||
linkage bool operator>( const Class & lhs, const Class & rhs ) { \
|
||||
return operator<( rhs, lhs ); \
|
||||
} \
|
||||
linkage bool operator!=( const Class & lhs, const Class & rhs ) { \
|
||||
return !operator==( lhs, rhs ); \
|
||||
} \
|
||||
linkage bool operator<=( const Class & lhs, const Class & rhs ) { \
|
||||
return !operator>( lhs, rhs ); \
|
||||
} \
|
||||
linkage bool operator>=( const Class & lhs, const Class & rhs ) { \
|
||||
return !operator<( lhs, rhs ); \
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T & __kdtools__dereference_for_methodcall( T & o ) {
|
||||
return o;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T & __kdtools__dereference_for_methodcall( T * o ) {
|
||||
return *o;
|
||||
}
|
||||
|
||||
#define KDAB_SET_OBJECT_NAME( x ) __kdtools__dereference_for_methodcall( x ).setObjectName( QLatin1String( #x ) )
|
||||
|
||||
KDTOOLSCORE_EXPORT bool _kdCheckQtVersion_impl( unsigned int major, unsigned int minor=0, unsigned int patchlevel=0 );
|
||||
static inline bool kdCheckQtVersion( unsigned int major, unsigned int minor=0, unsigned int patchlevel=0 ) {
|
||||
return (major<<16|minor<<8|patchlevel) <= static_cast<unsigned int>(QT_VERSION)
|
||||
|| _kdCheckQtVersion_impl( major, minor, patchlevel );
|
||||
}
|
||||
|
||||
#define KDTOOLS_DECLARE_PRIVATE_BASE( Class ) \
|
||||
protected: \
|
||||
class Private; \
|
||||
Private * d_func() { return _d; } \
|
||||
const Private * d_func() const { return _d; } \
|
||||
Class( Private * _d_, bool b ) : _d( _d_ ) { init(b); } \
|
||||
private: \
|
||||
void init(bool); \
|
||||
private: \
|
||||
Private * _d
|
||||
|
||||
#define KDTOOLS_DECLARE_PRIVATE_DERIVED( Class, Base ) \
|
||||
protected: \
|
||||
class Private; \
|
||||
Private * d_func() { \
|
||||
return reinterpret_cast<Private*>( Base::d_func() ); \
|
||||
} \
|
||||
const Private * d_func() const { \
|
||||
return reinterpret_cast<const Private*>( Base::d_func() ); \
|
||||
} \
|
||||
Class( Private * _d_, bool b ) \
|
||||
: Base( reinterpret_cast<Base::Private*>(_d_), b ) { init(b); } \
|
||||
private: \
|
||||
void init(bool)
|
||||
|
||||
|
||||
#endif /* KDTOOLS_KDTOOLSGLOBAL_H */
|
||||
|
209
3rdparty/kdsingleapplicationguard/pimpl_ptr.cpp
vendored
209
3rdparty/kdsingleapplicationguard/pimpl_ptr.cpp
vendored
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#include "pimpl_ptr.h"
|
||||
|
||||
/*!
|
||||
\class pimpl_ptr:
|
||||
\ingroup core smartptr
|
||||
\brief Owning pointer for private implementations
|
||||
\since_c 2.1
|
||||
|
||||
(The exception safety of this class has not been evaluated yet.)
|
||||
|
||||
pimpl_ptr is a smart immutable pointer, which owns the contained object. Unlike other smart pointers,
|
||||
it creates a standard constructed object when instanciated via the
|
||||
\link pimpl_ptr() standard constructor\endlink.
|
||||
Additionally, pimpl_ptr respects constness of the pointer object and returns \c const \c T* for
|
||||
a const pimpl_ptr object.
|
||||
|
||||
The content of a pimpl_ptr cannot be changed during it's lifetime.
|
||||
|
||||
\section general-use General Use
|
||||
|
||||
The general use case of pimpl_ptr is the "Pimpl Idiom", i.e. hiding the private implementation of a class
|
||||
from the user's compiler which see \c MyClass as
|
||||
|
||||
\code
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
MyClass();
|
||||
~MyClass();
|
||||
|
||||
// public class API
|
||||
int value() const;
|
||||
|
||||
private:
|
||||
class Private; // defined later
|
||||
kdtools::pimpl_ptr< Private > d;
|
||||
};
|
||||
\endcode
|
||||
|
||||
but not the private parts of it. These can only be seen (and accessed) by the code knowing \c MyClass::Private:
|
||||
|
||||
\code
|
||||
class MyClass::Private
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
};
|
||||
|
||||
MyClass::MyClass()
|
||||
{
|
||||
// d was automatically filled with new Private
|
||||
d->value = 42;
|
||||
}
|
||||
|
||||
MyClass::~MyClass()
|
||||
{
|
||||
// the content of d gets deleted automatically
|
||||
}
|
||||
|
||||
int MyClass::value() const
|
||||
{
|
||||
// access the private part:
|
||||
// since MyClass::value() is const, the returned pointee is const, too
|
||||
return d->value;
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn pimpl_ptr::pimpl_ptr()
|
||||
|
||||
Default constructor. Constructs a pimpl_tr that contains (owns) a standard constructed
|
||||
instance of \c T.
|
||||
|
||||
\post \c *this owns a new object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn pimpl_ptr::pimpl_ptr( T * t )
|
||||
|
||||
Constructor. Constructs a pimpl_ptr that contains (owns) \a t.
|
||||
|
||||
\post get() == obj
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn pimpl_ptr::~pimpl_ptr()
|
||||
|
||||
Destructor.
|
||||
|
||||
\post The object previously owned by \c *this has been deleted.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T * pimpl_ptr::get() const
|
||||
|
||||
\returns a const pointer to the contained (owned) object.
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T * pimpl_ptr::get()
|
||||
|
||||
\returns a pointer to the contained (owned) object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T & pimpl_ptr::operator*() const
|
||||
|
||||
Dereference operator. Returns \link get() *get()\endlink.
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T & pimpl_ptr::operator*()
|
||||
|
||||
Dereference operator. Returns \link get() *get()\endlink.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const T * pimpl_ptr::operator->() const
|
||||
|
||||
Member-by-pointer operator. Returns get().
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn T * pimpl_ptr::operator->()
|
||||
|
||||
Member-by-pointer operator. Returns get().
|
||||
*/
|
||||
|
||||
#ifdef KDTOOLSCORE_UNITTESTS
|
||||
|
||||
#include <kdunittest/test.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ConstTester
|
||||
{
|
||||
bool isConst()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isConst() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
KDAB_UNITTEST_SIMPLE( pimpl_ptr, "kdcoretools" ) {
|
||||
|
||||
{
|
||||
kdtools::pimpl_ptr< QObject > p;
|
||||
assertNotNull( p.get() );
|
||||
assertNull( p->parent() );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
QPointer< QObject > o;
|
||||
{
|
||||
kdtools::pimpl_ptr< QObject > qobject( new QObject );
|
||||
o = qobject.get();
|
||||
assertEqual( o, qobject.operator->() );
|
||||
assertEqual( o, &(qobject.operator*()) );
|
||||
}
|
||||
assertNull( o );
|
||||
}
|
||||
|
||||
{
|
||||
const kdtools::pimpl_ptr< QObject > qobject( new QObject );
|
||||
const QObject* o = qobject.get();
|
||||
assertEqual( o, qobject.operator->() );
|
||||
assertEqual( o, &(qobject.operator*()) );
|
||||
}
|
||||
|
||||
{
|
||||
kdtools::pimpl_ptr< QObject > o1;
|
||||
assertTrue( o1 );
|
||||
kdtools::pimpl_ptr< QObject > o2( 0 );
|
||||
assertFalse( o2 );
|
||||
}
|
||||
|
||||
{
|
||||
const kdtools::pimpl_ptr< ConstTester > o1;
|
||||
kdtools::pimpl_ptr< ConstTester > o2;
|
||||
assertTrue( o1->isConst() );
|
||||
assertFalse( o2->isConst() );
|
||||
assertTrue( (*o1).isConst() );
|
||||
assertFalse( (*o2).isConst() );
|
||||
assertTrue( o1.get()->isConst() );
|
||||
assertFalse( o2.get()->isConst() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KDTOOLSCORE_UNITTESTS
|
50
3rdparty/kdsingleapplicationguard/pimpl_ptr.h
vendored
50
3rdparty/kdsingleapplicationguard/pimpl_ptr.h
vendored
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
* SPDX-License-Identifier: LGPL-2.0-only
|
||||
*
|
||||
* The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
*/
|
||||
#ifndef KDTOOLSCORE_PIMPL_PTR_H
|
||||
#define KDTOOLSCORE_PIMPL_PTR_H
|
||||
|
||||
#include "kdtoolsglobal.h"
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
namespace kdtools {
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
class pimpl_ptr {
|
||||
KDAB_DISABLE_COPY( pimpl_ptr );
|
||||
T * d;
|
||||
public:
|
||||
pimpl_ptr() : d( new T ) {}
|
||||
explicit pimpl_ptr( T * t ) : d( t ) {}
|
||||
~pimpl_ptr() { delete d; d = nullptr; }
|
||||
|
||||
T * get() { return d; }
|
||||
const T * get() const { return d; }
|
||||
|
||||
T * operator->() { return get(); }
|
||||
const T * operator->() const { return get(); }
|
||||
|
||||
T & operator*() { return *get(); }
|
||||
const T & operator*() const { return *get(); }
|
||||
|
||||
KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( get() )
|
||||
};
|
||||
|
||||
// these are not implemented, so's we can catch their use at
|
||||
// link-time. Leaving them undeclared would open up a comparison
|
||||
// via operator unspecified-bool-type().
|
||||
template <typename T, typename S>
|
||||
void operator==( const pimpl_ptr<T> &, const pimpl_ptr<S> & );
|
||||
template <typename T, typename S>
|
||||
void operator!=( const pimpl_ptr<T> &, const pimpl_ptr<S> & );
|
||||
|
||||
#ifndef DOXYGEN_RUN
|
||||
} // namespace kdtools
|
||||
#endif
|
||||
|
||||
#endif /* KDTOOLSCORE_PIMPL_PTR_H */
|
||||
|
284
3rdparty/waitingspinnerwidget.cpp
vendored
284
3rdparty/waitingspinnerwidget.cpp
vendored
@ -1,284 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
|
||||
* SPDX-FileCopyrightText: 2014 William Hallatt
|
||||
* SPDX-FileCopyrightText: 2015 Jacob Dawid
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
|
||||
Modified 2014 by William Hallatt
|
||||
Modified 2015 by Jacob Dawid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Own includes
|
||||
#include "waitingspinnerwidget.h"
|
||||
|
||||
// Standard includes
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
// Qt includes
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
WaitingSpinnerWidget::WaitingSpinnerWidget(QWidget *parent,
|
||||
bool centerOnParent,
|
||||
bool disableParentWhenSpinning)
|
||||
: QWidget(parent),
|
||||
_centerOnParent(centerOnParent),
|
||||
_disableParentWhenSpinning(disableParentWhenSpinning) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
WaitingSpinnerWidget::WaitingSpinnerWidget(Qt::WindowModality modality,
|
||||
QWidget *parent,
|
||||
bool centerOnParent,
|
||||
bool disableParentWhenSpinning)
|
||||
: QWidget(parent, Qt::Dialog | Qt::FramelessWindowHint),
|
||||
_centerOnParent(centerOnParent),
|
||||
_disableParentWhenSpinning(disableParentWhenSpinning){
|
||||
initialize();
|
||||
|
||||
// We need to set the window modality AFTER we've hidden the
|
||||
// widget for the first time since changing this property while
|
||||
// the widget is visible has no effect.
|
||||
setWindowModality(modality);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::initialize() {
|
||||
_color = Qt::black;
|
||||
_roundness = 100.0;
|
||||
_minimumTrailOpacity = 3.14159265358979323846;
|
||||
_trailFadePercentage = 80.0;
|
||||
_revolutionsPerSecond = 1.57079632679489661923;
|
||||
_numberOfLines = 20;
|
||||
_lineLength = 10;
|
||||
_lineWidth = 2;
|
||||
_innerRadius = 10;
|
||||
_currentCounter = 0;
|
||||
_isSpinning = false;
|
||||
|
||||
_timer = new QTimer(this);
|
||||
connect(_timer, SIGNAL(timeout()), this, SLOT(rotate()));
|
||||
updateSize();
|
||||
updateTimer();
|
||||
hide();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::paintEvent(QPaintEvent *) {
|
||||
updatePosition();
|
||||
QPainter painter(this);
|
||||
painter.fillRect(this->rect(), Qt::transparent);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
if (_currentCounter >= _numberOfLines) {
|
||||
_currentCounter = 0;
|
||||
}
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
for (int i = 0; i < _numberOfLines; ++i) {
|
||||
painter.save();
|
||||
painter.translate(_innerRadius + _lineLength,
|
||||
_innerRadius + _lineLength);
|
||||
qreal rotateAngle =
|
||||
static_cast<qreal>(360 * i) / static_cast<qreal>(_numberOfLines);
|
||||
painter.rotate(rotateAngle);
|
||||
painter.translate(_innerRadius, 0);
|
||||
int distance =
|
||||
lineCountDistanceFromPrimary(i, _currentCounter, _numberOfLines);
|
||||
QColor color =
|
||||
currentLineColor(distance, _numberOfLines, _trailFadePercentage,
|
||||
_minimumTrailOpacity, _color);
|
||||
painter.setBrush(color);
|
||||
// TODO improve the way rounded rect is painted
|
||||
painter.drawRoundedRect(
|
||||
QRect(0, -_lineWidth / 2, _lineLength, _lineWidth), _roundness,
|
||||
_roundness, Qt::RelativeSize);
|
||||
painter.restore();
|
||||
}
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::start() {
|
||||
updatePosition();
|
||||
_isSpinning = true;
|
||||
show();
|
||||
|
||||
if(parentWidget() && _disableParentWhenSpinning) {
|
||||
parentWidget()->setEnabled(false);
|
||||
}
|
||||
|
||||
if (!_timer->isActive()) {
|
||||
_timer->start();
|
||||
_currentCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::stop() {
|
||||
_isSpinning = false;
|
||||
hide();
|
||||
|
||||
if(parentWidget() && _disableParentWhenSpinning) {
|
||||
parentWidget()->setEnabled(true);
|
||||
}
|
||||
|
||||
if (_timer->isActive()) {
|
||||
_timer->stop();
|
||||
_currentCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setNumberOfLines(int lines) {
|
||||
_numberOfLines = lines;
|
||||
_currentCounter = 0;
|
||||
updateTimer();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setLineLength(int length) {
|
||||
_lineLength = length;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setLineWidth(int width) {
|
||||
_lineWidth = width;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setInnerRadius(int radius) {
|
||||
_innerRadius = radius;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
QColor WaitingSpinnerWidget::color() {
|
||||
return _color;
|
||||
}
|
||||
|
||||
qreal WaitingSpinnerWidget::roundness() {
|
||||
return _roundness;
|
||||
}
|
||||
|
||||
qreal WaitingSpinnerWidget::minimumTrailOpacity() {
|
||||
return _minimumTrailOpacity;
|
||||
}
|
||||
|
||||
qreal WaitingSpinnerWidget::trailFadePercentage() {
|
||||
return _trailFadePercentage;
|
||||
}
|
||||
|
||||
qreal WaitingSpinnerWidget::revolutionsPersSecond() {
|
||||
return _revolutionsPerSecond;
|
||||
}
|
||||
|
||||
int WaitingSpinnerWidget::numberOfLines() {
|
||||
return _numberOfLines;
|
||||
}
|
||||
|
||||
int WaitingSpinnerWidget::lineLength() {
|
||||
return _lineLength;
|
||||
}
|
||||
|
||||
int WaitingSpinnerWidget::lineWidth() {
|
||||
return _lineWidth;
|
||||
}
|
||||
|
||||
int WaitingSpinnerWidget::innerRadius() {
|
||||
return _innerRadius;
|
||||
}
|
||||
|
||||
bool WaitingSpinnerWidget::isSpinning() const {
|
||||
return _isSpinning;
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setRoundness(qreal roundness) {
|
||||
_roundness = std::max(0.0, std::min(100.0, roundness));
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setColor(QColor color) {
|
||||
_color = color;
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setRevolutionsPerSecond(qreal revolutionsPerSecond) {
|
||||
_revolutionsPerSecond = revolutionsPerSecond;
|
||||
updateTimer();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setTrailFadePercentage(qreal trail) {
|
||||
_trailFadePercentage = trail;
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::setMinimumTrailOpacity(qreal minimumTrailOpacity) {
|
||||
_minimumTrailOpacity = minimumTrailOpacity;
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::rotate() {
|
||||
++_currentCounter;
|
||||
if (_currentCounter >= _numberOfLines) {
|
||||
_currentCounter = 0;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::updateSize() {
|
||||
int size = (_innerRadius + _lineLength) * 2;
|
||||
setFixedSize(size, size);
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::updateTimer() {
|
||||
_timer->setInterval(1000 / (_numberOfLines * _revolutionsPerSecond));
|
||||
}
|
||||
|
||||
void WaitingSpinnerWidget::updatePosition() {
|
||||
if (parentWidget() && _centerOnParent) {
|
||||
move(parentWidget()->width() / 2 - width() / 2,
|
||||
parentWidget()->height() / 2 - height() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
int WaitingSpinnerWidget::lineCountDistanceFromPrimary(int current, int primary,
|
||||
int totalNrOfLines) {
|
||||
int distance = primary - current;
|
||||
if (distance < 0) {
|
||||
distance += totalNrOfLines;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
QColor WaitingSpinnerWidget::currentLineColor(int countDistance, int totalNrOfLines,
|
||||
qreal trailFadePerc, qreal minOpacity,
|
||||
QColor color) {
|
||||
if (countDistance == 0) {
|
||||
return color;
|
||||
}
|
||||
const qreal minAlphaF = minOpacity / 100.0;
|
||||
int distanceThreshold =
|
||||
static_cast<int>(ceil((totalNrOfLines - 1) * trailFadePerc / 100.0));
|
||||
if (countDistance > distanceThreshold) {
|
||||
color.setAlphaF(minAlphaF);
|
||||
} else {
|
||||
qreal alphaDiff = color.alphaF() - minAlphaF;
|
||||
qreal gradient = alphaDiff / static_cast<qreal>(distanceThreshold + 1);
|
||||
qreal resultAlpha = color.alphaF() - gradient * countDistance;
|
||||
|
||||
// If alpha is out of bounds, clip it.
|
||||
resultAlpha = std::min(1.0, std::max(0.0, resultAlpha));
|
||||
color.setAlphaF(resultAlpha);
|
||||
}
|
||||
return color;
|
||||
}
|
122
3rdparty/waitingspinnerwidget.h
vendored
122
3rdparty/waitingspinnerwidget.h
vendored
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
|
||||
* SPDX-FileCopyrightText: 2014 William Hallatt
|
||||
* SPDX-FileCopyrightText: 2015 Jacob Dawid
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
|
||||
Modified 2014 by William Hallatt
|
||||
Modified 2015 by Jacob Dawid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Qt includes
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QColor>
|
||||
|
||||
class WaitingSpinnerWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/*! Constructor for "standard" widget behaviour - use this
|
||||
* constructor if you wish to, e.g. embed your widget in another. */
|
||||
WaitingSpinnerWidget(QWidget *parent = nullptr,
|
||||
bool centerOnParent = true,
|
||||
bool disableParentWhenSpinning = true);
|
||||
|
||||
/*! Constructor - use this constructor to automatically create a modal
|
||||
* ("blocking") spinner on top of the calling widget/window. If a valid
|
||||
* parent widget is provided, "centreOnParent" will ensure that
|
||||
* QtWaitingSpinner automatically centres itself on it, if not,
|
||||
* "centreOnParent" is ignored. */
|
||||
WaitingSpinnerWidget(Qt::WindowModality modality,
|
||||
QWidget *parent = nullptr,
|
||||
bool centerOnParent = true,
|
||||
bool disableParentWhenSpinning = true);
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
public:
|
||||
void setColor(QColor color);
|
||||
void setRoundness(qreal roundness);
|
||||
void setMinimumTrailOpacity(qreal minimumTrailOpacity);
|
||||
void setTrailFadePercentage(qreal trail);
|
||||
void setRevolutionsPerSecond(qreal revolutionsPerSecond);
|
||||
void setNumberOfLines(int lines);
|
||||
void setLineLength(int length);
|
||||
void setLineWidth(int width);
|
||||
void setInnerRadius(int radius);
|
||||
void setText(QString text);
|
||||
|
||||
QColor color();
|
||||
qreal roundness();
|
||||
qreal minimumTrailOpacity();
|
||||
qreal trailFadePercentage();
|
||||
qreal revolutionsPersSecond();
|
||||
int numberOfLines();
|
||||
int lineLength();
|
||||
int lineWidth();
|
||||
int innerRadius();
|
||||
|
||||
bool isSpinning() const;
|
||||
|
||||
private slots:
|
||||
void rotate();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *paintEvent) override;
|
||||
|
||||
private:
|
||||
static int lineCountDistanceFromPrimary(int current, int primary,
|
||||
int totalNrOfLines);
|
||||
static QColor currentLineColor(int distance, int totalNrOfLines,
|
||||
qreal trailFadePerc, qreal minOpacity,
|
||||
QColor color);
|
||||
|
||||
void initialize();
|
||||
void updateSize();
|
||||
void updateTimer();
|
||||
void updatePosition();
|
||||
|
||||
private:
|
||||
QColor _color;
|
||||
qreal _roundness; // 0..100
|
||||
qreal _minimumTrailOpacity;
|
||||
qreal _trailFadePercentage;
|
||||
qreal _revolutionsPerSecond;
|
||||
int _numberOfLines;
|
||||
int _lineLength;
|
||||
int _lineWidth;
|
||||
int _innerRadius;
|
||||
|
||||
private:
|
||||
WaitingSpinnerWidget(const WaitingSpinnerWidget&);
|
||||
WaitingSpinnerWidget& operator=(const WaitingSpinnerWidget&);
|
||||
|
||||
QTimer *_timer;
|
||||
bool _centerOnParent;
|
||||
bool _disableParentWhenSpinning;
|
||||
int _currentCounter;
|
||||
bool _isSpinning;
|
||||
};
|
55
CHANGES-3.3
Normal file
55
CHANGES-3.3
Normal file
@ -0,0 +1,55 @@
|
||||
<!-- SPDX-FileCopyrightText: no
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
-->
|
||||
|
||||
This is the changelog for Calamares. For each release, the major changes and
|
||||
contributors are listed. Note that Calamares does not have a historical
|
||||
changelog -- this log starts with version 3.3.0. See CHANGES-3.2 for
|
||||
the history of the 3.2 series (2018-05 - 2021-12).
|
||||
|
||||
# 3.3.0 (unreleased) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Anubhav Choudhary
|
||||
- Evan James
|
||||
- Vitor Lopes
|
||||
|
||||
This is a "minor" version change, but the size of the changes is very
|
||||
large. Configuration files from previous versions of Calamares will
|
||||
**certainly** need to be re-validated. Take heed of the many changes
|
||||
in the *Modules* heading, below.
|
||||
|
||||
## Project ##
|
||||
- The C++ code in the project is now formatted with clang-format 12 or 13,
|
||||
with the coding-style as found in `.clang-format`; there are minor
|
||||
differences from the tool, compared to the clang-format 9 usually applied
|
||||
to Calamares 3.2.
|
||||
- The CMake code in the project is now formatted with gersemi 0.7.5.
|
||||
|
||||
## Core ##
|
||||
- CMake 3.16, Qt 5.15 are now required; the newer CMake is to support
|
||||
new features (also for KDE Frameworks), Qt is the current LTS version.
|
||||
- KDE Framework "DBusAddons" is now required, and is used to "activate"
|
||||
Calamares; the KDAB Single Application Guard is no longer used.
|
||||
KDSAG needed patching to chase Qt 5.15 deprecations, and the DBus
|
||||
activation code is tried and tested in Frameworks (tier 1).
|
||||
Running `calamares -d` no longer enforces a single-application
|
||||
(it is for debugging purposes, after all).
|
||||
- Python 3.6 or later is now required, to allow for F-strings in
|
||||
Python code and allow other tidy-ups in the Python modules.
|
||||
Boost::Python now requires 1.67 or later (for CMake support).
|
||||
- The log file now **always** contains a debug-log, and the `-D` flag
|
||||
primarily controls what is printed to stdout. By default, stdout
|
||||
only gets errors; use `-D6` to match stdout with the file. Use `-D8`
|
||||
to get a verbose log file **and** verbose stdout.
|
||||
|
||||
## Modules ##
|
||||
- *bootloader* now supports more options when building the kernel
|
||||
command-line. (Thanks Evan)
|
||||
- *displaymanager* no longer supports the discontinued *kdm* display manager.
|
||||
- *grubcfg* changed the key *keepDistributor* to *keep_distributor*.
|
||||
Please update configurations.
|
||||
- *partition* requires KPMCore 21.12 (e.g. KPMCore 4.2 API, or later).
|
||||
- *partition* can now skip installing the bootloader in more scenarios.
|
||||
#1632 (Thanks Anubhav)
|
||||
|
528
CMakeLists.txt
528
CMakeLists.txt
@ -25,10 +25,13 @@
|
||||
# CMake once. These affect the ABI offered by Calamares.
|
||||
# - PYTHON (enable Python Job modules)
|
||||
# - QML (enable QML UI View modules)
|
||||
# - PYTHONQT # TODO:3.3: remove
|
||||
# The WITH_* options affect the ABI of Calamares: you must
|
||||
# build (C++) modules for Calamares with the same WITH_*
|
||||
# settings, or they may not load at all.
|
||||
# BUILD_<foo> : choose additional things to build
|
||||
# - TESTING (standard CMake option)
|
||||
# - SCHEMA_TESTING (requires Python, see ci/configvalidator.py)
|
||||
# - KF5Crash (uses KCrash, rather than Calamares internal, for crash reporting)
|
||||
# DEBUG_<foo> : special developer flags for debugging
|
||||
#
|
||||
# Example usage:
|
||||
@ -38,35 +41,39 @@
|
||||
# One special target is "show-version", which can be built
|
||||
# to obtain the version number from here.
|
||||
|
||||
# TODO:3.3: Require CMake 3.12
|
||||
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
|
||||
project( CALAMARES
|
||||
VERSION 3.2.59
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development
|
||||
if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||
message( FATAL_ERROR "Do not build development versions in the source-directory." )
|
||||
set(CALAMARES_VERSION 3.3.0)
|
||||
set(CALAMARES_RELEASE_MODE OFF) # Set to ON during a release
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake)
|
||||
set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
extend_version( ${CALAMARES_VERSION} OFF _vshort _vlong )
|
||||
message("${_vlong}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(CALAMARES VERSION ${CALAMARES_VERSION} LANGUAGES C CXX HOMEPAGE_URL "https://calamares.io/")
|
||||
|
||||
if(NOT CALAMARES_RELEASE_MODE AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
message(FATAL_ERROR "Do not build development versions in the source-directory.")
|
||||
endif()
|
||||
|
||||
### OPTIONS
|
||||
#
|
||||
option( INSTALL_CONFIG "Install configuration files" OFF )
|
||||
option( INSTALL_POLKIT "Install Polkit configuration" ON )
|
||||
option( INSTALL_COMPLETION "Install shell completions" OFF )
|
||||
# Options for the calamares executable
|
||||
option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) # TODO:3.3: WITH->BUILD (this isn't an ABI thing)
|
||||
option( WITH_KF5DBus "Use DBus service for unique-application." OFF ) # TODO:3.3: WITH->BUILD
|
||||
option(INSTALL_CONFIG "Install configuration files" OFF)
|
||||
option(INSTALL_POLKIT "Install Polkit configuration" ON)
|
||||
option(INSTALL_COMPLETION "Install shell completions" OFF)
|
||||
# When adding WITH_* that affects the ABI offered by libcalamares,
|
||||
# also update libcalamares/CalamaresConfig.h.in
|
||||
option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON )
|
||||
option( WITH_PYTHONQT "Enable Python view modules API (deprecated, requires PythonQt)." OFF ) # TODO:3.3: remove
|
||||
option( WITH_QML "Enable QML UI options." ON )
|
||||
option(WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON)
|
||||
option(WITH_QML "Enable QML UI options." ON)
|
||||
#
|
||||
# Additional parts to build
|
||||
option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
|
||||
|
||||
# Additional parts to build that do not affect ABI
|
||||
option(BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON)
|
||||
# Options for the calamares executable
|
||||
option(BUILD_KF5Crash "Enable crash reporting with KCrash." ON)
|
||||
|
||||
# Possible debugging flags are:
|
||||
# - DEBUG_TIMEZONES draws latitude and longitude lines on the timezone
|
||||
@ -77,7 +84,6 @@ option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
|
||||
# - DEBUG_PARTITION_UNSAFE (see partition/CMakeLists.txt)
|
||||
# - DEBUG_PARTITION_BAIL_OUT (see partition/CMakeLists.txt)
|
||||
|
||||
|
||||
### USE_*
|
||||
#
|
||||
# By convention, when there are multiple modules that implement similar
|
||||
@ -101,15 +107,14 @@ option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
|
||||
# - *services* picks one of the two service-configuration modules,
|
||||
# for either systemd or openrc. This defaults to empty so that
|
||||
# **both** modules are available.
|
||||
set( USE_services "" CACHE STRING "Select the services module to use" )
|
||||
set(USE_services "" CACHE STRING "Select the services module to use")
|
||||
|
||||
### Calamares application info
|
||||
#
|
||||
set( CALAMARES_ORGANIZATION_NAME "Calamares" )
|
||||
set( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
|
||||
set( CALAMARES_APPLICATION_NAME "Calamares" )
|
||||
set( CALAMARES_DESCRIPTION_SUMMARY
|
||||
"The distribution-independent installer framework" )
|
||||
set(CALAMARES_ORGANIZATION_NAME "Calamares")
|
||||
set(CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares")
|
||||
set(CALAMARES_APPLICATION_NAME "Calamares")
|
||||
set(CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework")
|
||||
|
||||
### Transifex (languages) info
|
||||
#
|
||||
@ -135,40 +140,42 @@ set( CALAMARES_DESCRIPTION_SUMMARY
|
||||
# `txstats.py -e`. See also
|
||||
#
|
||||
# Total 74 languages
|
||||
set( _tx_complete az az_AZ ca es fi_FI he hi hr ja lt pt_BR pt_PT
|
||||
sq sv uk zh_TW )
|
||||
set( _tx_good as be ca@valencia cs_CZ da de fa fr fur it_IT ko ml
|
||||
nl ru si sk tg tr_TR vi zh_CN )
|
||||
set( _tx_complete az az_AZ ca es fi_FI he hi hr ja ko lt pt_BR
|
||||
pt_PT sq sv tr_TR uk zh_TW )
|
||||
set( _tx_good as be ca@valencia cs_CZ da de fa fr fur it_IT ml nl
|
||||
ru si sk tg vi zh_CN )
|
||||
set( _tx_ok ar ast bg bn el en_GB es_MX et eu gl hu id is mr nb oc
|
||||
pl ro sl sr sr@latin th )
|
||||
set( _tx_incomplete eo es_PR gu ie ja-Hira kk kn lo lv mk ne_NP
|
||||
ta_IN te ur zh zh_HK )
|
||||
# Total 74 languages
|
||||
|
||||
### Required versions
|
||||
#
|
||||
# See DEPENDENCIES section below.
|
||||
set( QT_VERSION 5.9.0 )
|
||||
set( YAMLCPP_VERSION 0.5.1 )
|
||||
set( ECM_VERSION 5.18 )
|
||||
set( PYTHONLIBS_VERSION 3.3 )
|
||||
set( BOOSTPYTHON_VERSION 1.55.0 )
|
||||
|
||||
set(QT_VERSION 5.15.0)
|
||||
set(YAMLCPP_VERSION 0.5.1)
|
||||
set(ECM_VERSION 5.18)
|
||||
set(PYTHONLIBS_VERSION 3.6)
|
||||
set(BOOSTPYTHON_VERSION 1.72.0)
|
||||
|
||||
### CMAKE SETUP
|
||||
#
|
||||
set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" )
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules")
|
||||
|
||||
# Enable IN_LIST
|
||||
if( POLICY CMP0057 )
|
||||
cmake_policy( SET CMP0057 NEW )
|
||||
if(POLICY CMP0057)
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
endif()
|
||||
# Let ``AUTOMOC`` and ``AUTOUIC`` process ``GENERATED`` files.
|
||||
if( POLICY CMP0071 )
|
||||
cmake_policy( SET CMP0071 NEW )
|
||||
if(POLICY CMP0071)
|
||||
cmake_policy(SET CMP0071 NEW)
|
||||
endif()
|
||||
# Recognize more macros to trigger automoc
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
|
||||
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES
|
||||
list(
|
||||
APPEND
|
||||
CMAKE_AUTOMOC_MACRO_NAMES
|
||||
"K_PLUGIN_FACTORY_WITH_JSON"
|
||||
"K_EXPORT_PLASMA_DATAENGINE_WITH_JSON"
|
||||
"K_EXPORT_PLASMA_RUNNER"
|
||||
@ -176,40 +183,50 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
|
||||
endif()
|
||||
|
||||
# CMake Modules
|
||||
include( CMakePackageConfigHelpers )
|
||||
include( CTest )
|
||||
include( FeatureSummary )
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CTest)
|
||||
include(FeatureSummary)
|
||||
|
||||
# Calamares Modules
|
||||
include( CMakeColors )
|
||||
include(CMakeColors)
|
||||
|
||||
### C++ SETUP
|
||||
#
|
||||
set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror=return-type" )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "-Og -g ${CMAKE_CXX_FLAGS_DEBUG}" )
|
||||
set( CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG" )
|
||||
set( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" )
|
||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" )
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror=return-type")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||
|
||||
set( CMAKE_C_STANDARD 99 )
|
||||
set( CMAKE_C_STANDARD_REQUIRED ON )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall" )
|
||||
set( CMAKE_C_FLAGS_DEBUG "-Og -g" )
|
||||
set( CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG" )
|
||||
set( CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG" )
|
||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g" )
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Og -g")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings" )
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings")
|
||||
|
||||
if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
message( STATUS "Found Clang ${CMAKE_CXX_COMPILER_VERSION}, setting up Clang-specific compiler flags." )
|
||||
# If no build type is set, pick a reasonable one
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
if(CALAMARES_RELEASE_MODE)
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
message(STATUS "Found Clang ${CMAKE_CXX_COMPILER_VERSION}, setting up Clang-specific compiler flags.")
|
||||
|
||||
# Clang warnings: doing *everything* is counter-productive, since it warns
|
||||
# about things which we can't fix (e.g. C++98 incompatibilities, but
|
||||
# Calamares is C++17).
|
||||
foreach( CLANG_WARNINGS
|
||||
foreach(
|
||||
CLANG_WARNINGS
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
@ -221,68 +238,69 @@ if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
-Wno-documentation-unknown-command
|
||||
-Wno-unknown-warning-option
|
||||
)
|
||||
string( APPEND CMAKE_CXX_FLAGS " ${CLANG_WARNINGS}" )
|
||||
string(APPEND CMAKE_CXX_FLAGS " ${CLANG_WARNINGS}")
|
||||
endforeach()
|
||||
|
||||
# The dwarf-debugging flags are slightly different, too
|
||||
string( APPEND CMAKE_CXX_FLAGS_DEBUG " -gdwarf" )
|
||||
string( APPEND CMAKE_C_FLAGS_DEBUG " -gdwarf" )
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gdwarf")
|
||||
string(APPEND CMAKE_C_FLAGS_DEBUG " -gdwarf")
|
||||
|
||||
# Third-party code where we don't care so much about compiler warnings
|
||||
# (because it's uncomfortable to patch) get different flags; use
|
||||
# mark_thirdparty_code( <file> [<file>...] )
|
||||
# to switch off warnings for those sources.
|
||||
set( SUPPRESS_3RDPARTY_WARNINGS "-Wno-everything" )
|
||||
set(SUPPRESS_3RDPARTY_WARNINGS "-Wno-everything")
|
||||
|
||||
set( CMAKE_TOOLCHAIN_PREFIX "llvm-" )
|
||||
set(CMAKE_TOOLCHAIN_PREFIX "llvm-")
|
||||
|
||||
# The path prefix is only relevant for CMake 3.16 and later, fixes #1286
|
||||
set( CMAKE_AUTOMOC_PATH_PREFIX OFF )
|
||||
set( CALAMARES_AUTOMOC_OPTIONS "-butils/moc-warnings.h" )
|
||||
set( CALAMARES_AUTOUIC_OPTIONS --include utils/moc-warnings.h )
|
||||
set(CMAKE_AUTOMOC_PATH_PREFIX OFF)
|
||||
set(CALAMARES_AUTOMOC_OPTIONS "-butils/moc-warnings.h")
|
||||
set(CALAMARES_AUTOUIC_OPTIONS --include utils/moc-warnings.h)
|
||||
else()
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual")
|
||||
|
||||
set( SUPPRESS_3RDPARTY_WARNINGS "" )
|
||||
set(SUPPRESS_3RDPARTY_WARNINGS "")
|
||||
endif()
|
||||
|
||||
# Use mark_thirdparty_code() to reduce warnings from the compiler
|
||||
# on code that we're not going to fix. Call this with a list of files.
|
||||
macro(mark_thirdparty_code)
|
||||
set_source_files_properties( ${ARGV}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${SUPPRESS_3RDPARTY_WARNINGS}"
|
||||
COMPILE_DEFINITIONS "THIRDPARTY"
|
||||
set_source_files_properties(
|
||||
${ARGV}
|
||||
PROPERTIES COMPILE_FLAGS "${SUPPRESS_3RDPARTY_WARNINGS}" COMPILE_DEFINITIONS "THIRDPARTY"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
if( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR
|
||||
CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9 )
|
||||
message( STATUS "Found GNU g++ ${CMAKE_CXX_COMPILER_VERSION}, enabling colorized error messages." )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto" )
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9)
|
||||
message(STATUS "Found GNU g++ ${CMAKE_CXX_COMPILER_VERSION}, enabling colorized error messages.")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# API that was deprecated before Qt 5.15 causes a compile error
|
||||
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050f00)
|
||||
|
||||
### DEPENDENCIES
|
||||
#
|
||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui LinguistTools Network Svg Widgets )
|
||||
if( WITH_QML )
|
||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets )
|
||||
find_package(Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui LinguistTools Network Svg Widgets)
|
||||
if(WITH_QML)
|
||||
find_package(Qt5 ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets)
|
||||
endif()
|
||||
# Optional Qt parts
|
||||
find_package( Qt5DBus CONFIG )
|
||||
find_package(Qt5DBus CONFIG)
|
||||
|
||||
find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED )
|
||||
if( INSTALL_POLKIT )
|
||||
find_package( PolkitQt5-1 REQUIRED )
|
||||
find_package(YAMLCPP ${YAMLCPP_VERSION} REQUIRED)
|
||||
if(INSTALL_POLKIT)
|
||||
find_package(PolkitQt5-1 REQUIRED)
|
||||
else()
|
||||
# Find it anyway, for dependencies-reporting
|
||||
find_package( PolkitQt5-1 )
|
||||
find_package(PolkitQt5-1)
|
||||
endif()
|
||||
set_package_properties(
|
||||
PolkitQt5-1 PROPERTIES
|
||||
PolkitQt5-1
|
||||
PROPERTIES
|
||||
DESCRIPTION "Qt5 support for Polkit"
|
||||
URL "https://cgit.kde.org/polkit-qt-1.git"
|
||||
PURPOSE "PolkitQt5-1 helps with installing Polkit configuration"
|
||||
@ -293,115 +311,104 @@ set_package_properties(
|
||||
# find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE),
|
||||
# no need to mess with the module path after.
|
||||
find_package(ECM ${ECM_VERSION} NO_MODULE)
|
||||
if( ECM_FOUND )
|
||||
if(ECM_FOUND)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH})
|
||||
if ( BUILD_TESTING )
|
||||
if(BUILD_TESTING)
|
||||
# ECM implies that we can build the tests, too
|
||||
find_package( Qt5 COMPONENTS Test REQUIRED )
|
||||
include( ECMAddTests )
|
||||
find_package(Qt5 COMPONENTS Test REQUIRED)
|
||||
include(ECMAddTests)
|
||||
endif()
|
||||
include(KDEInstallDirs)
|
||||
endif()
|
||||
|
||||
find_package( KF5 QUIET COMPONENTS CoreAddons Crash DBusAddons )
|
||||
find_package(KF5 QUIET COMPONENTS CoreAddons Crash DBusAddons)
|
||||
set_package_properties(
|
||||
KF5::CoreAddons PROPERTIES
|
||||
KF5::CoreAddons
|
||||
PROPERTIES
|
||||
TYPE REQUIRED
|
||||
DESCRIPTION "Classes built on QtCore for About Data"
|
||||
URL "https://api.kde.org/frameworks/kcoreaddons/"
|
||||
PURPOSE "About Calamares"
|
||||
)
|
||||
if( NOT KF5Crash_FOUND )
|
||||
if( WITH_KF5Crash )
|
||||
message(WARNING "WITH_KF5Crash is set, but KF5::Crash is not available.")
|
||||
set_package_properties(
|
||||
KF5::DBusAddons
|
||||
PROPERTIES
|
||||
TYPE REQUIRED
|
||||
DESCRIPTION "Classes for DBus activation"
|
||||
URL "https://api.kde.org/frameworks/dbusaddons/"
|
||||
PURPOSE "Unique instance of Calamares"
|
||||
)
|
||||
if(NOT KF5Crash_FOUND)
|
||||
if(BUILD_KF5Crash)
|
||||
message(WARNING "BUILD_KF5Crash is set, but KF5::Crash is not available.")
|
||||
endif()
|
||||
set( WITH_KF5Crash OFF )
|
||||
endif()
|
||||
if( NOT KF5DBusAddons_FOUND )
|
||||
if( WITH_KF5DBus )
|
||||
message(WARNING "WITH_KF5DBus is set, but KF5::DBusAddons is not available.")
|
||||
endif()
|
||||
set( WITH_KF5DBus OFF )
|
||||
set(BUILD_KF5Crash OFF)
|
||||
endif()
|
||||
|
||||
# TODO:3.3: Use FindPython3 instead
|
||||
find_package( PythonInterp ${PYTHONLIBS_VERSION} )
|
||||
find_package(Python ${PYTHONLIBS_VERSION} COMPONENTS Interpreter Development)
|
||||
set_package_properties(
|
||||
PythonInterp PROPERTIES
|
||||
DESCRIPTION "Python 3 interpreter."
|
||||
Python
|
||||
PROPERTIES
|
||||
DESCRIPTION "Python3 interpreter."
|
||||
URL "https://python.org"
|
||||
PURPOSE "Python 3 interpreter for certain tests."
|
||||
PURPOSE "Python3 interpreter for certain tests."
|
||||
)
|
||||
|
||||
set( _schema_explanation "" )
|
||||
if ( PYTHONINTERP_FOUND )
|
||||
if ( BUILD_SCHEMA_TESTING )
|
||||
set(_schema_explanation "")
|
||||
if(Python_Interpreter_FOUND)
|
||||
if(BUILD_SCHEMA_TESTING)
|
||||
# The configuration validator script has some dependencies,
|
||||
# and if they are not installed, don't run. If errors out
|
||||
# with exit(1) on missing dependencies.
|
||||
if ( CALAMARES_CONFIGVALIDATOR_CHECKED )
|
||||
set( _validator_deps ${CALAMARES_CONFIGVALIDATOR_RESULT} )
|
||||
if(CALAMARES_CONFIGVALIDATOR_CHECKED)
|
||||
set(_validator_deps ${CALAMARES_CONFIGVALIDATOR_RESULT})
|
||||
else()
|
||||
exec_program( ${PYTHON_EXECUTABLE} ARGS "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" -x RETURN_VALUE _validator_deps )
|
||||
set( CALAMARES_CONFIGVALIDATOR_CHECKED TRUE CACHE INTERNAL "Dependencies for configvalidator checked" )
|
||||
set( CALAMARES_CONFIGVALIDATOR_RESULT ${_validator_deps} CACHE INTERNAL "Result of configvalidator dependency check" )
|
||||
exec_program(
|
||||
${Python_EXECUTABLE}
|
||||
ARGS
|
||||
"${CMAKE_SOURCE_DIR}/ci/configvalidator.py"
|
||||
-x
|
||||
RETURN_VALUE
|
||||
_validator_deps
|
||||
)
|
||||
set(CALAMARES_CONFIGVALIDATOR_CHECKED TRUE CACHE INTERNAL "Dependencies for configvalidator checked")
|
||||
set(CALAMARES_CONFIGVALIDATOR_RESULT ${_validator_deps}
|
||||
CACHE INTERNAL "Result of configvalidator dependency check"
|
||||
)
|
||||
endif()
|
||||
# It should never succeed, but only returns 1 when the imports fail
|
||||
if ( _validator_deps EQUAL 1 )
|
||||
set( _schema_explanation " Missing dependencies for configvalidator.py." )
|
||||
set( BUILD_SCHEMA_TESTING OFF )
|
||||
if(_validator_deps EQUAL 1)
|
||||
set(_schema_explanation " Missing dependencies for configvalidator.py.")
|
||||
set(BUILD_SCHEMA_TESTING OFF)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# Can't run schema tests without Python3.
|
||||
set( _schema_explanation " Missing Python3." )
|
||||
set( BUILD_SCHEMA_TESTING OFF )
|
||||
set(_schema_explanation " Missing Python3.")
|
||||
set(BUILD_SCHEMA_TESTING OFF)
|
||||
endif()
|
||||
add_feature_info( yaml-schema BUILD_SCHEMA_TESTING "Validate YAML (config files) with schema.${_schema_explanation}" )
|
||||
add_feature_info(yaml-schema BUILD_SCHEMA_TESTING "Validate YAML (config files) with schema.${_schema_explanation}")
|
||||
|
||||
find_package( PythonLibs ${PYTHONLIBS_VERSION} )
|
||||
set_package_properties(
|
||||
PythonLibs PROPERTIES
|
||||
DESCRIPTION "C interface libraries for the Python 3 interpreter."
|
||||
URL "https://python.org"
|
||||
PURPOSE "Python 3 is used for Python job modules."
|
||||
)
|
||||
|
||||
if ( PYTHONLIBS_FOUND )
|
||||
# TODO:3.3: Require Boost + CMake; sort out Boost::Python
|
||||
# Since Boost provides CMake config files (starting with Boost 1.70.
|
||||
# or so) the mess that is the Calamares find code picks the wrong
|
||||
# bits. Suppress those CMake config files, as suggested by @jmrcpn
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
include( BoostPython3 )
|
||||
find_boost_python3( ${BOOSTPYTHON_VERSION} ${PYTHONLIBS_VERSION_STRING} CALAMARES_BOOST_PYTHON3_FOUND )
|
||||
set_package_properties(
|
||||
Boost PROPERTIES
|
||||
PURPOSE "Boost.Python is used for Python job modules."
|
||||
)
|
||||
# TODO:3.3: Remove PythonQt support
|
||||
find_package( PythonQt )
|
||||
set_package_properties( PythonQt PROPERTIES
|
||||
DESCRIPTION "A Python embedding solution for Qt applications."
|
||||
URL "http://pythonqt.sourceforge.net"
|
||||
PURPOSE "PythonQt is used for Python view modules."
|
||||
)
|
||||
if(Python_Development_FOUND)
|
||||
find_package(boost_python)
|
||||
if(NOT TARGET Boost::python)
|
||||
find_package(Boost ${BOOSTPYTHON_VERSION} COMPONENTS python)
|
||||
set_package_properties(Boost PROPERTIES PURPOSE "Boost.Python is used for Python job modules.")
|
||||
else()
|
||||
message(STATUS "Found boost_python with target Boost::python")
|
||||
set(Boost_FOUND ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( NOT PYTHONLIBS_FOUND OR NOT CALAMARES_BOOST_PYTHON3_FOUND )
|
||||
if(NOT Python_Development_FOUND OR NOT Boost_FOUND)
|
||||
message(STATUS "Disabling Boost::Python modules")
|
||||
set( WITH_PYTHON OFF )
|
||||
endif()
|
||||
if( NOT PYTHONLIBS_FOUND OR NOT PYTHONQT_FOUND )
|
||||
message(STATUS "Disabling PythonQt modules")
|
||||
set( WITH_PYTHONQT OFF )
|
||||
set(WITH_PYTHON OFF)
|
||||
endif()
|
||||
|
||||
# Now we know the state of the ABI-options, copy them into "Calamares_"
|
||||
# prefixed variables, to match how the variables would-be-named
|
||||
# when building out-of-tree.
|
||||
set(Calamares_WITH_PYTHON ${WITH_PYTHON})
|
||||
set(Calamares_WITH_PYTHONQT ${WITH_PYTHONQT})
|
||||
set(Calamares_WITH_QML ${WITH_QML})
|
||||
|
||||
### Transifex Translation status
|
||||
@ -411,39 +418,39 @@ set(Calamares_WITH_QML ${WITH_QML})
|
||||
# for some obvious error. The actual work of compiling translations
|
||||
# is done in the lang/ directory.
|
||||
#
|
||||
if( Qt5_VERSION VERSION_GREATER 5.12.1 )
|
||||
if(Qt5_VERSION VERSION_GREATER 5.12.1)
|
||||
# At least Qt 5.12.2 seems to support Esperanto in QLocale
|
||||
if( "eo" IN_LIST _tx_incomplete )
|
||||
if("eo" IN_LIST _tx_incomplete)
|
||||
message(STATUS "Esperanto support since Qt 5.12.2, enabling Esperanto locale")
|
||||
list( REMOVE_ITEM _tx_incomplete "eo" )
|
||||
list( APPEND _tx_ok "eo" )
|
||||
list(REMOVE_ITEM _tx_incomplete "eo")
|
||||
list(APPEND _tx_ok "eo")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set( curr_tx ${_tx_complete} ${_tx_good} ${_tx_ok} ${_tx_incomplete} )
|
||||
set( tx_errors OFF )
|
||||
if ( curr_tx )
|
||||
set(curr_tx ${_tx_complete} ${_tx_good} ${_tx_ok} ${_tx_incomplete})
|
||||
set(tx_errors OFF)
|
||||
if(curr_tx)
|
||||
# New in list
|
||||
foreach( l ${curr_tx} )
|
||||
set( p_l "lang/calamares_${l}.ts" )
|
||||
if( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${p_l} )
|
||||
foreach(l ${curr_tx})
|
||||
set(p_l "lang/calamares_${l}.ts")
|
||||
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${p_l})
|
||||
message(WARNING "Language ${l} has no .ts file yet.")
|
||||
set( tx_errors ON )
|
||||
set(tx_errors ON)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
unset( p_l )
|
||||
unset( l )
|
||||
unset(p_l)
|
||||
unset(l)
|
||||
endif()
|
||||
unset( curr_tx )
|
||||
if( tx_errors )
|
||||
message( FATAL_ERROR "Translation warnings, see above." )
|
||||
unset(curr_tx)
|
||||
if(tx_errors)
|
||||
message(FATAL_ERROR "Translation warnings, see above.")
|
||||
endif()
|
||||
|
||||
set( CALAMARES_TRANSLATION_LANGUAGES en ${_tx_complete} ${_tx_good} ${_tx_ok} )
|
||||
list( SORT CALAMARES_TRANSLATION_LANGUAGES )
|
||||
set(CALAMARES_TRANSLATION_LANGUAGES en ${_tx_complete} ${_tx_good} ${_tx_ok})
|
||||
list(SORT CALAMARES_TRANSLATION_LANGUAGES)
|
||||
|
||||
add_subdirectory( lang ) # i18n tools
|
||||
add_subdirectory(lang) # i18n tools
|
||||
|
||||
### Example Distro
|
||||
#
|
||||
@ -462,22 +469,22 @@ add_subdirectory( lang ) # i18n tools
|
||||
#
|
||||
# make example-distro
|
||||
#
|
||||
find_program( mksquashfs_PROGRAM mksquashfs )
|
||||
if( mksquashfs_PROGRAM )
|
||||
set( mksquashfs_FOUND ON )
|
||||
set( src_fs ${CMAKE_SOURCE_DIR}/data/example-root/ )
|
||||
set( dst_fs ${CMAKE_BINARY_DIR}/example.sqfs )
|
||||
if( EXISTS ${src_fs} )
|
||||
find_program(mksquashfs_PROGRAM mksquashfs)
|
||||
if(mksquashfs_PROGRAM)
|
||||
set(mksquashfs_FOUND ON)
|
||||
set(src_fs ${CMAKE_SOURCE_DIR}/data/example-root/)
|
||||
set(dst_fs ${CMAKE_BINARY_DIR}/example.sqfs)
|
||||
if(EXISTS ${src_fs})
|
||||
# based on the build host. If /lib64 exists, assume it is needed.
|
||||
# Collect directories needed for a minimal binary distro,
|
||||
# Note that the last path component is added to the root, so
|
||||
# if you add /usr/sbin here, it will be put into /sbin_1.
|
||||
# Add such paths to /etc/profile under ${src_fs}.
|
||||
set( candidate_fs /sbin /bin /lib /lib64 )
|
||||
set( host_fs "" )
|
||||
foreach( c_fs ${candidate_fs} )
|
||||
if( EXISTS ${c_fs} )
|
||||
list( APPEND host_fs ${c_fs} )
|
||||
set(candidate_fs /sbin /bin /lib /lib64)
|
||||
set(host_fs "")
|
||||
foreach(c_fs ${candidate_fs})
|
||||
if(EXISTS ${c_fs})
|
||||
list(APPEND host_fs ${c_fs})
|
||||
endif()
|
||||
endforeach()
|
||||
add_custom_command(
|
||||
@ -488,105 +495,89 @@ if( mksquashfs_PROGRAM )
|
||||
add_custom_target(example-distro DEPENDS ${dst_fs})
|
||||
endif()
|
||||
else()
|
||||
set( mksquashfs_FOUND OFF )
|
||||
set(mksquashfs_FOUND OFF)
|
||||
endif()
|
||||
# Doesn't list mksquashfs as an optional dep, though, because it
|
||||
# hasn't been sent through the find_package() scheme.
|
||||
#
|
||||
# "http://tldp.org/HOWTO/SquashFS-HOWTO/creatingandusing.html"
|
||||
add_feature_info( ExampleDistro ${mksquashfs_FOUND} "Create example-distro target.")
|
||||
|
||||
add_feature_info(ExampleDistro ${mksquashfs_FOUND} "Create example-distro target.")
|
||||
|
||||
### CALAMARES PROPER
|
||||
#
|
||||
set( CALAMARES_VERSION ${CALAMARES_VERSION_MAJOR}.${CALAMARES_VERSION_MINOR}.${CALAMARES_VERSION_PATCH} )
|
||||
set(CALAMARES_VERSION ${CALAMARES_VERSION_MAJOR}.${CALAMARES_VERSION_MINOR}.${CALAMARES_VERSION_PATCH})
|
||||
# In rare cases we have hotfix-releases with a tweak
|
||||
if( CALAMARES_VERSION_TWEAK )
|
||||
set( CALAMARES_VERSION "${CALAMARES_VERSION}.${CALAMARES_VERSION_TWEAK}" )
|
||||
if(CALAMARES_VERSION_TWEAK)
|
||||
set(CALAMARES_VERSION "${CALAMARES_VERSION}.${CALAMARES_VERSION_TWEAK}")
|
||||
endif()
|
||||
set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" )
|
||||
set(CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}")
|
||||
|
||||
# Additional info for non-release builds. The "extended" version information
|
||||
# with date and git information (commit, dirty status) is used only
|
||||
# by CalamaresVersionX.h, which is included by consumers that need a full
|
||||
# version number with all that information; normal consumers can include
|
||||
# CalamaresVersion.h with more stable numbers.
|
||||
if( NOT BUILD_RELEASE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git/" )
|
||||
include( ExtendedVersion )
|
||||
if(NOT BUILD_RELEASE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git/")
|
||||
include(ExtendedVersion)
|
||||
extend_version( "${CALAMARES_VERSION}" OFF CALAMARES_VERSION_SHORT CALAMARES_VERSION )
|
||||
endif()
|
||||
|
||||
# Special target for not-RC (e.g. might-be-release) builds.
|
||||
# This is used by the release script to get the version.
|
||||
if ( CALAMARES_VERSION_RC EQUAL 0 )
|
||||
add_custom_target(show-version
|
||||
${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT}
|
||||
USES_TERMINAL
|
||||
)
|
||||
# Special define for RC (e.g. not-a-release) builds.
|
||||
# This is consumed via the CalamaresConfig.h header.
|
||||
if(NOT CALAMARES_RELEASE_MODE)
|
||||
set(CALAMARES_VERSION_RC 1)
|
||||
endif()
|
||||
|
||||
# enforce using constBegin, constEnd for const-iterators
|
||||
add_definitions(
|
||||
-DQT_STRICT_ITERATORS
|
||||
-DQT_SHARED
|
||||
-DQT_SHAREDPOINTER_TRACK_POINTERS
|
||||
)
|
||||
add_definitions(-DQT_STRICT_ITERATORS -DQT_SHARED -DQT_SHAREDPOINTER_TRACK_POINTERS)
|
||||
|
||||
# set paths
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
|
||||
# Better default installation paths: GNUInstallDirs defines
|
||||
# CMAKE_INSTALL_FULL_SYSCONFDIR to be CMAKE_INSTALL_PREFIX/etc by default
|
||||
# but we really want /etc
|
||||
if( NOT DEFINED CMAKE_INSTALL_SYSCONFDIR )
|
||||
set( CMAKE_INSTALL_SYSCONFDIR "/etc" )
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "/etc")
|
||||
endif()
|
||||
|
||||
# make predefined install dirs available everywhere
|
||||
include( GNUInstallDirs )
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# This is used by CalamaresAddLibrary; once Calamares is installed,
|
||||
# the CalamaresConfig.cmake module sets this variable to the IMPORTED
|
||||
# libraries for Calamares.
|
||||
set( Calamares_LIBRARIES calamares )
|
||||
set(Calamares_LIBRARIES calamares)
|
||||
|
||||
add_subdirectory( src )
|
||||
add_subdirectory(src)
|
||||
|
||||
add_feature_info(Python ${WITH_PYTHON} "Python job modules")
|
||||
add_feature_info(PythonQt ${WITH_PYTHONQT} "Python view modules")
|
||||
add_feature_info(Qml ${WITH_QML} "QML UI support")
|
||||
add_feature_info(Config ${INSTALL_CONFIG} "Install Calamares configuration")
|
||||
add_feature_info(KCrash ${WITH_KF5Crash} "Crash dumps via KCrash")
|
||||
add_feature_info(KDBusAddons ${WITH_KF5DBus} "Unique-application via DBus")
|
||||
add_feature_info(Polkit ${INSTALL_POLKIT} "Install Polkit files")
|
||||
add_feature_info(KCrash ${BUILD_KF5Crash} "Crash dumps via KCrash")
|
||||
|
||||
### CMake infrastructure installation
|
||||
#
|
||||
#
|
||||
set( CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files" )
|
||||
set( CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}" )
|
||||
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files")
|
||||
set(CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}")
|
||||
|
||||
export( PACKAGE Calamares )
|
||||
export(PACKAGE Calamares)
|
||||
configure_package_config_file(
|
||||
"CalamaresConfig.cmake.in"
|
||||
"${PROJECT_BINARY_DIR}/CalamaresConfig.cmake"
|
||||
INSTALL_DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
|
||||
PATH_VARS
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
CMAKE_INSTALL_DATADIR
|
||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_DATADIR
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
${PROJECT_BINARY_DIR}/CalamaresConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(
|
||||
EXPORT Calamares
|
||||
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
|
||||
FILE "CalamaresTargets.cmake"
|
||||
NAMESPACE Calamares::
|
||||
)
|
||||
install(EXPORT Calamares DESTINATION "${CMAKE_INSTALL_CMAKEDIR}" FILE "CalamaresTargets.cmake" NAMESPACE Calamares::)
|
||||
|
||||
# Install the cmake files
|
||||
install(
|
||||
@ -603,69 +594,48 @@ install(
|
||||
"CMakeModules/CalamaresCheckModuleSelection.cmake"
|
||||
"CMakeModules/CMakeColors.cmake"
|
||||
"CMakeModules/FindYAMLCPP.cmake"
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_CMAKEDIR}"
|
||||
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
|
||||
)
|
||||
|
||||
### Miscellaneous installs
|
||||
#
|
||||
#
|
||||
if( INSTALL_CONFIG )
|
||||
install(
|
||||
FILES settings.conf
|
||||
DESTINATION share/calamares
|
||||
)
|
||||
if(INSTALL_CONFIG)
|
||||
install(FILES settings.conf DESTINATION share/calamares)
|
||||
endif()
|
||||
|
||||
if( INSTALL_POLKIT )
|
||||
install(
|
||||
FILES com.github.calamares.calamares.policy
|
||||
DESTINATION "${POLKITQT-1_POLICY_FILES_INSTALL_DIR}"
|
||||
)
|
||||
if(INSTALL_POLKIT)
|
||||
install(FILES com.github.calamares.calamares.policy DESTINATION "${POLKITQT-1_POLICY_FILES_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
if ( INSTALL_COMPLETION )
|
||||
if( NOT CMAKE_INSTALL_BASHCOMPLETIONDIR )
|
||||
set( CMAKE_INSTALL_BASHCOMPLETIONDIR "${CMAKE_INSTALL_DATADIR}/bash-completion/completions" )
|
||||
if(INSTALL_COMPLETION)
|
||||
if(NOT CMAKE_INSTALL_BASHCOMPLETIONDIR)
|
||||
set(CMAKE_INSTALL_BASHCOMPLETIONDIR "${CMAKE_INSTALL_DATADIR}/bash-completion/completions")
|
||||
endif()
|
||||
|
||||
install( FILES ${CMAKE_SOURCE_DIR}/data/completion/bash/calamares DESTINATION "${CMAKE_INSTALL_BASHCOMPLETIONDIR}" )
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/data/completion/bash/calamares DESTINATION "${CMAKE_INSTALL_BASHCOMPLETIONDIR}")
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES calamares.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
|
||||
)
|
||||
install(FILES calamares.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
|
||||
install(
|
||||
FILES man/calamares.8
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/
|
||||
)
|
||||
install(FILES man/calamares.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/)
|
||||
|
||||
# uninstall target
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY
|
||||
IMMEDIATE
|
||||
@ONLY
|
||||
)
|
||||
|
||||
add_custom_target( uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
|
||||
)
|
||||
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
### CMAKE SUMMARY REPORT
|
||||
#
|
||||
get_directory_property( SKIPPED_MODULES
|
||||
DIRECTORY src/modules
|
||||
DEFINITION LIST_SKIPPED_MODULES
|
||||
)
|
||||
get_directory_property(SKIPPED_MODULES DIRECTORY src/modules DEFINITION LIST_SKIPPED_MODULES)
|
||||
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
|
||||
|
||||
feature_summary(
|
||||
WHAT DISABLED_FEATURES
|
||||
DESCRIPTION "The following features have been disabled:"
|
||||
QUIET_ON_EMPTY
|
||||
)
|
||||
feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "The following features have been disabled:" QUIET_ON_EMPTY)
|
||||
feature_summary(
|
||||
WHAT OPTIONAL_PACKAGES_NOT_FOUND
|
||||
DESCRIPTION "The following OPTIONAL packages were not found:"
|
||||
@ -682,11 +652,11 @@ feature_summary(
|
||||
#
|
||||
# Note: most distro's will do distro-specific packaging rather than
|
||||
# using CPack, and this duplicates information in the AppStream, too.
|
||||
# TODO:3.3 With newer CMake, move HOMEPAGE_URL to the project()call
|
||||
set(CPACK_PACKAGE_VENDOR calamares)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A Linux system installer")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "Calamares is a Linux system installer, intended for Linux distributions to use on their ISOs and other bootable media to install the distribution to the end-user's computer. Calamares can also be used as an OEM configuration tool. It is modular, extensible and highly-configurable for Linux distributions from all five major Linux families.")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://calamares.io")
|
||||
set(CPACK_PACKAGE_DESCRIPTION
|
||||
"Calamares is a Linux system installer, intended for Linux distributions to use on their ISOs and other bootable media to install the distribution to the end-user's computer. Calamares can also be used as an OEM configuration tool. It is modular, extensible and highly-configurable for Linux distributions from all five major Linux families."
|
||||
)
|
||||
set(CPACK_PACKAGE_ICON "data/images/squid.png")
|
||||
|
||||
include(CPack)
|
||||
|
@ -1,97 +0,0 @@
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
|
||||
# SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2019 Kevin Kofler <kevin.kofler@chello.at>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
###
|
||||
#
|
||||
# Handles the mess that Boost::Python is before CMake 3.16 and
|
||||
# Boost 1.70 or so.
|
||||
#
|
||||
###
|
||||
#
|
||||
# On Ubuntu 14.04, the libboost-python1.54-dev package comes with one library
|
||||
# for each Python version:
|
||||
# libboost_python-py27.so
|
||||
# libboost_python-py33.so
|
||||
# libboost_python-py34.so
|
||||
#
|
||||
# Boost upstream however installs Boost.Python3 libboost_python3.so, which is
|
||||
# what FindBoost.cmake is looking for. It looks for a library named
|
||||
# "libboost_${component}.so".
|
||||
#
|
||||
# On Gentoo instead, the >=dev-libs/boost-1.54 package provides boost library
|
||||
# with a name like:
|
||||
# libboost_python-2.7.so
|
||||
# libboost_python-3.3.so
|
||||
# libboost_python-3.4.so
|
||||
# depending on what python's targets you selected during install
|
||||
#
|
||||
# On Fedora >= 30 instead, the boost-python3-devel provides boost library with a
|
||||
# name like:
|
||||
# libboost_python37.so
|
||||
# depending on what python's targets you selected during install
|
||||
#
|
||||
# find_boost_python3() tries to find the package with different component
|
||||
# names. By default it tries "python3", "python-py$suffix" and
|
||||
# "python-$dotsuffix", where suffix is based on the `python_version` argument.
|
||||
# One can supply a custom component name by setting the
|
||||
# `CALAMARES_BOOST_PYTHON3_COMPONENT` variable at CMake time.
|
||||
set( CALAMARES_BOOST_PYTHON3_COMPONENT python3 CACHE STRING
|
||||
"Name of the Boost.Python component. If Boost.Python is installed as
|
||||
libboost_python-foo.so then this variable should be set to 'python-foo'."
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
macro( _find_boost_python3_int boost_version componentname found_var )
|
||||
foreach( _fbp_name ${CALAMARES_BOOST_PYTHON3_COMPONENT} ${componentname} )
|
||||
find_package( Boost ${boost_version} QUIET COMPONENTS ${_fbp_name} )
|
||||
string( TOUPPER ${_fbp_name} _fbp_uc_name )
|
||||
if( Boost_${_fbp_uc_name}_FOUND )
|
||||
if( CMAKE_SYSTEM_NAME MATCHES "FreeBSD" )
|
||||
# No upcasing
|
||||
set( ${found_var} ${_fbp_name} )
|
||||
else()
|
||||
set( ${found_var} ${_fbp_uc_name} )
|
||||
endif()
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro( find_boost_python3 boost_version python_version found_var )
|
||||
set( ${found_var} OFF )
|
||||
set( _fbp_found OFF )
|
||||
|
||||
# turns "3.4.123abc" into "34"
|
||||
string( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\..*" "\\1\\2" _fbp_python_short_version ${python_version} )
|
||||
_find_boost_python3_int( ${boost_version} python-py${_fbp_python_short_version} _fbp_found )
|
||||
|
||||
if (NOT _fbp_found)
|
||||
_find_boost_python3_int( ${boost_version} python${_fbp_python_short_version} _fbp_found )
|
||||
endif()
|
||||
|
||||
if (NOT _fbp_found)
|
||||
# The following loop changes the searched name for Gentoo based distributions
|
||||
# turns "3.4.123abc" into "3.4"
|
||||
string( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\..*" "\\1.\\2" _fbp_python_short_version ${python_version} )
|
||||
_find_boost_python3_int( ${boost_version} python-${_fbp_python_short_version} _fbp_found )
|
||||
endif()
|
||||
|
||||
set( ${found_var} ${_fbp_found} )
|
||||
|
||||
# This is superfluous, but allows proper reporting in the features list
|
||||
if ( _fbp_found )
|
||||
find_package( Boost ${boost_version} COMPONENTS ${_fbp_found} )
|
||||
else()
|
||||
find_package( Boost ${boost_version} COMPONENTS Python )
|
||||
endif()
|
||||
set_package_properties(
|
||||
Boost PROPERTIES
|
||||
DESCRIPTION "A C++ library which enables seamless interoperability between C++ and Python 3."
|
||||
URL "http://www.boost.org"
|
||||
)
|
||||
endmacro()
|
@ -121,7 +121,8 @@ function( _calamares_add_module_subdirectory_impl )
|
||||
# _mod_testing boolean if the module should be added to the loadmodule tests
|
||||
file(STRINGS "${_mod_dir}/module.desc" MODULE_INTERFACE REGEX "^interface")
|
||||
if ( MODULE_INTERFACE MATCHES "pythonqt" )
|
||||
set( _mod_enabled ${Calamares_WITH_PYTHONQT} )
|
||||
message( FATAL_ERROR "PythonQt is no longer supported" )
|
||||
set( _mod_enabled OFF )
|
||||
set( _mod_reason "No PythonQt support" )
|
||||
set( _mod_testing OFF )
|
||||
elseif ( MODULE_INTERFACE MATCHES "python" )
|
||||
|
@ -18,19 +18,17 @@
|
||||
# SOURCES <FILE..>
|
||||
# )
|
||||
|
||||
include( CMakeParseArguments )
|
||||
include( CalamaresAutomoc )
|
||||
include(CMakeParseArguments)
|
||||
include(CalamaresAutomoc)
|
||||
|
||||
function( calamares_add_test )
|
||||
# parse arguments (name needs to be saved before passing ARGN into the macro)
|
||||
set( NAME ${ARGV0} )
|
||||
set( options GUI )
|
||||
set( oneValueArgs NAME RESOURCES )
|
||||
set( multiValueArgs SOURCES LIBRARIES DEFINITIONS )
|
||||
cmake_parse_arguments( TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
set( TEST_NAME ${NAME} )
|
||||
function(calamares_add_test name)
|
||||
set(options GUI)
|
||||
set(oneValueArgs RESOURCES)
|
||||
set(multiValueArgs SOURCES LIBRARIES DEFINITIONS)
|
||||
cmake_parse_arguments(TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
set(TEST_NAME ${name})
|
||||
|
||||
if( ECM_FOUND AND BUILD_TESTING )
|
||||
if(ECM_FOUND AND BUILD_TESTING)
|
||||
ecm_add_test(
|
||||
${TEST_SOURCES} ${TEST_RESOURCES}
|
||||
TEST_NAME
|
||||
@ -40,15 +38,18 @@ function( calamares_add_test )
|
||||
${TEST_LIBRARIES}
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
)
|
||||
)
|
||||
calamares_automoc( ${TEST_NAME} )
|
||||
# We specifically pass in the source directory of the test-being-
|
||||
# compiled, so that it can find test-files in that source dir.
|
||||
target_compile_definitions( ${TEST_NAME} PRIVATE -DBUILD_AS_TEST="${CMAKE_CURRENT_SOURCE_DIR}" ${TEST_DEFINITIONS} )
|
||||
if( TEST_GUI )
|
||||
target_link_libraries( ${TEST_NAME} Calamares::calamaresui Qt5::Gui )
|
||||
target_compile_definitions(
|
||||
${TEST_NAME}
|
||||
PRIVATE -DBUILD_AS_TEST="${CMAKE_CURRENT_SOURCE_DIR}" ${TEST_DEFINITIONS}
|
||||
)
|
||||
if(TEST_GUI)
|
||||
target_link_libraries(${TEST_NAME} Calamares::calamaresui Qt5::Gui)
|
||||
endif()
|
||||
if( TEST_RESOURCES )
|
||||
if(TEST_RESOURCES)
|
||||
calamares_autorcc( ${TEST_NAME} ${TEST_RESOURCES} )
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1,185 +0,0 @@
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
# SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
###
|
||||
#
|
||||
# Find PythonQt
|
||||
#
|
||||
# Sets PYTHONQT_FOUND, PYTHONQT_INCLUDE_DIR, PYTHONQT_LIBRARY, PYTHONQT_LIBRARIES
|
||||
#
|
||||
# Also sets PYTHONQT_INCLUDE_DIRS to add whatever directories
|
||||
# that are needed for extensions.
|
||||
#
|
||||
|
||||
# Python is required
|
||||
find_package(PythonLibs)
|
||||
if(NOT PYTHONLIBS_FOUND)
|
||||
message(FATAL_ERROR "error: Python is required to build PythonQt")
|
||||
endif()
|
||||
|
||||
# Cut X.Y[.Z] down to just X.Y
|
||||
string(REGEX REPLACE
|
||||
"^([0-9][0-9]*)\.([0-9][0-9]*)"
|
||||
"\\1.\\2@"
|
||||
_PYTHONLIBS_MAJMIN
|
||||
${PYTHONLIBS_VERSION_STRING}
|
||||
)
|
||||
string(REGEX REPLACE
|
||||
"@.*"
|
||||
""
|
||||
PYTHONLIBS_MAJMIN
|
||||
${_PYTHONLIBS_MAJMIN}
|
||||
)
|
||||
|
||||
if(NOT EXISTS "${PYTHONQT_INSTALL_DIR}")
|
||||
find_path(PYTHONQT_INSTALL_DIR
|
||||
NAMES
|
||||
include/PythonQt/PythonQt.h
|
||||
include/PythonQt5/PythonQt.h
|
||||
DOC "Directory where PythonQt was installed.")
|
||||
endif()
|
||||
|
||||
# XXX Since PythonQt 3.0 is not yet cmakeified, depending
|
||||
# on how PythonQt is built, headers will not always be
|
||||
# installed in "include/PythonQt". That is why "src"
|
||||
# is added as an option. See [1] for more details.
|
||||
# [1] https://github.com/commontk/CTK/pull/538#issuecomment-86106367
|
||||
find_path(PYTHONQT_INCLUDE_DIR PythonQt.h
|
||||
PATHS
|
||||
"${PYTHONQT_INSTALL_DIR}/include/PythonQt"
|
||||
"${PYTHONQT_INSTALL_DIR}/include/PythonQt5"
|
||||
"${PYTHONQT_INSTALL_DIR}/src"
|
||||
DOC "Path to the PythonQt include directory")
|
||||
find_path(PYTHONQT_ALL_INCLUDE_DIR PythonQt_QtAll.h
|
||||
PATHS
|
||||
"${PYTHONQT_INCLUDE_DIR}"
|
||||
"${PYTHONQT_INSTALL_DIR}"
|
||||
PATH_SUFFIXES
|
||||
"extensions/PythonQt_QtAll"
|
||||
"src"
|
||||
DOC "Path to the PythonQt 'all' header")
|
||||
|
||||
if ( NOT PythonQt_FIND_QUIETLY )
|
||||
message( STATUS "Searching for PythonQt (PythonLibs ${PYTHONLIBS_MAJMIN}) .." )
|
||||
if ( PYTHONQT_INCLUDE_DIR )
|
||||
message( STATUS " .. found include ${PYTHONQT_INCLUDE_DIR}" )
|
||||
message( STATUS " .. found all include ${PYTHONQT_ALL_INCLUDE_DIR}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Minimum v3.1 is needed
|
||||
find_library(PYTHONQT_LIBRARY_RELEASE
|
||||
NAMES
|
||||
PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}
|
||||
PythonQt-Qt5-Python3
|
||||
PythonQt
|
||||
PATHS "${PYTHONQT_INSTALL_DIR}/lib"
|
||||
DOC "The PythonQt library."
|
||||
)
|
||||
find_library(PYTHONQT_LIBRARY_DEBUG
|
||||
NAMES
|
||||
PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}JMIN${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}
|
||||
PythonQt-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt-Qt5-Python3${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt-Qt5-Python3
|
||||
PythonQt${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt
|
||||
PATHS "${PYTHONQT_INSTALL_DIR}/lib"
|
||||
DOC "The PythonQt library (debug build)."
|
||||
)
|
||||
find_library(PYTHONQT_QTALL_LIBRARY_RELEASE
|
||||
NAMES
|
||||
PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}
|
||||
PythonQt_QtAll-Qt5-Python3
|
||||
PythonQt_QtAll
|
||||
PATHS "${PYTHONQT_INSTALL_DIR}/lib"
|
||||
DOC "Full Qt bindings for the PythonQt library."
|
||||
)
|
||||
find_library(PYTHONQT_QTALL_LIBRARY_DEBUG
|
||||
NAMES
|
||||
PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}
|
||||
PythonQt_QtAll-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll-Qt5-Python3${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll-Qt5-Python3
|
||||
PythonQt_QtAll${CTK_CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll${CMAKE_DEBUG_POSTFIX}
|
||||
PythonQt_QtAll
|
||||
PATHS "${PYTHONQT_INSTALL_DIR}/lib"
|
||||
DOC "Full Qt bindings for the PythonQt library (debug build)."
|
||||
)
|
||||
|
||||
set(PYTHONQT_LIBRARY)
|
||||
if(PYTHONQT_LIBRARY_RELEASE)
|
||||
list(APPEND PYTHONQT_LIBRARY optimized ${PYTHONQT_LIBRARY_RELEASE})
|
||||
endif()
|
||||
if(PYTHONQT_LIBRARY_DEBUG)
|
||||
list(APPEND PYTHONQT_LIBRARY debug ${PYTHONQT_LIBRARY_DEBUG})
|
||||
endif()
|
||||
|
||||
set(PYTHONQT_QTALL_LIBRARY)
|
||||
if(PYTHONQT_QTALL_LIBRARY_RELEASE)
|
||||
list(APPEND PYTHONQT_QTALL_LIBRARY optimized ${PYTHONQT_QTALL_LIBRARY_RELEASE})
|
||||
endif()
|
||||
if(PYTHONQT_QTALL_LIBRARY_DEBUG)
|
||||
list(APPEND PYTHONQT_QTALL_LIBRARY debug ${PYTHONQT_QTALL_LIBRARY_DEBUG})
|
||||
endif()
|
||||
|
||||
if ( NOT PythonQt_FIND_QUIETLY )
|
||||
if ( PYTHONQT_LIBRARY )
|
||||
message( STATUS " .. found library ${PYTHONQT_LIBRARY}" )
|
||||
endif()
|
||||
if ( PYTHONQT_QTALL_LIBRARY )
|
||||
message( STATUS " .. found qtall ${PYTHONQT_QTALL_LIBRARY}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
mark_as_advanced(PYTHONQT_INSTALL_DIR)
|
||||
mark_as_advanced(PYTHONQT_INCLUDE_DIR)
|
||||
mark_as_advanced(PYTHONQT_LIBRARY_RELEASE)
|
||||
mark_as_advanced(PYTHONQT_LIBRARY_DEBUG)
|
||||
mark_as_advanced(PYTHONQT_QTALL_LIBRARY_RELEASE)
|
||||
mark_as_advanced(PYTHONQT_QTALL_LIBRARY_DEBUG)
|
||||
|
||||
# On linux, also find libutil
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_library(PYTHONQT_LIBUTIL util)
|
||||
mark_as_advanced(PYTHONQT_LIBUTIL)
|
||||
endif()
|
||||
|
||||
# All upper case _FOUND variable is maintained for backwards compatibility.
|
||||
set(PYTHONQT_FOUND 0)
|
||||
set(PythonQt_FOUND 0)
|
||||
|
||||
if(PYTHONQT_INCLUDE_DIR AND PYTHONQT_LIBRARY AND PYTHONQT_QTALL_LIBRARY)
|
||||
# Currently CMake'ified PythonQt only supports building against a python Release build.
|
||||
# This applies independently of CTK build type (Release, Debug, ...)
|
||||
add_definitions(-DPYTHONQT_USE_RELEASE_PYTHON_FALLBACK)
|
||||
set(PYTHONQT_FOUND 1)
|
||||
set(PythonQt_FOUND ${PYTHONQT_FOUND})
|
||||
set(PYTHONQT_LIBRARIES ${PYTHONQT_LIBRARY} ${PYTHONQT_LIBUTIL} ${PYTHONQT_QTALL_LIBRARY})
|
||||
set(PYTHONQT_INCLUDE_DIRS ${PYTHONQT_INCLUDE_DIR})
|
||||
if(PYTHONQT_ALL_INCLUDE_DIR)
|
||||
list(APPEND PYTHONQT_INCLUDE_DIRS ${PYTHONQT_ALL_INCLUDE_DIR})
|
||||
endif()
|
||||
elseif(NOT PythonQt_FIND_QUIETLY)
|
||||
set(_missing "")
|
||||
if (NOT PYTHONQT_INCLUDE_DIR)
|
||||
list(APPEND _missing "includes")
|
||||
endif()
|
||||
if (NOT PYTHONQT_LIBRARY)
|
||||
list(APPEND _missing "library")
|
||||
endif()
|
||||
if (NOT PYTHONQT_QTALL_LIBRARY)
|
||||
list(APPEND _missing "qtall")
|
||||
endif()
|
||||
message(STATUS "PythonQt not found, missing components ${_missing}")
|
||||
endif()
|
@ -10,7 +10,7 @@
|
||||
if ( NOT KPMcore_searched_for )
|
||||
set( KPMcore_searched_for TRUE )
|
||||
|
||||
find_package( KPMcore 3.3 )
|
||||
find_package( KPMcore 21.12.0 )
|
||||
set_package_properties(
|
||||
KPMcore PROPERTIES
|
||||
URL "https://invent.kde.org/kde/kpmcore"
|
||||
@ -21,18 +21,6 @@ if ( NOT KPMcore_searched_for )
|
||||
|
||||
if( KPMcore_FOUND )
|
||||
set( KPMcore_API_DEFINITIONS "" )
|
||||
if( KPMcore_VERSION VERSION_GREATER "3.3.70" AND KPMcore_VERSION VERSION_LESS "4.0" )
|
||||
message( FATAL_ERROR "KPMCore beta versions ${KPMcore_VERSION} not supported" )
|
||||
endif()
|
||||
if ( KPMcore_VERSION VERSION_GREATER "3.3.0")
|
||||
list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE331API) # kpmcore > 3.3.0 with deprecations
|
||||
endif()
|
||||
if ( KPMcore_VERSION VERSION_GREATER_EQUAL "4.0")
|
||||
list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE4API) # kpmcore 4 with new API
|
||||
endif()
|
||||
if( KPMcore_VERSION VERSION_GREATER_EQUAL "4.2" )
|
||||
list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE42API) # kpmcore 4.2 with new API
|
||||
endif()
|
||||
else()
|
||||
set( KPMcore_API_DEFINITIONS WITHOUT_KPMcore )
|
||||
endif()
|
||||
|
@ -77,16 +77,15 @@ instructions are on the wiki.
|
||||
### Dependencies
|
||||
|
||||
Main:
|
||||
* Compiler with C++17 support: GCC >= 7 or Clang >= 5
|
||||
* CMake >= 3.3
|
||||
* Qt >= 5.9
|
||||
* Compiler with C++17 support
|
||||
* CMake >= 3.16
|
||||
* Qt >= 5.15
|
||||
* yaml-cpp >= 0.5.1
|
||||
* Python >= 3.3 (required for some modules)
|
||||
* Boost.Python >= 1.55.0 (required for some modules)
|
||||
* Python >= 3.6 (required for some modules)
|
||||
* Boost.Python >= 1.67.0 (required for some modules)
|
||||
* KDE extra-cmake-modules >= 5.18 (recommended; required for some modules;
|
||||
required for some tests)
|
||||
* KDE Frameworks KCoreAddons (>= 5.58 recommended)
|
||||
* PythonQt (optional, deprecated)
|
||||
|
||||
Individual modules may have their own requirements;
|
||||
these are listed in CMake output.
|
||||
|
@ -87,5 +87,4 @@ include(CalamaresAddPlugin)
|
||||
# This list should match the one in libcalamares/CalamaresConfig.h,
|
||||
# which is the C++-language side of the same configuration.
|
||||
set(Calamares_WITH_PYTHON @WITH_PYTHON@)
|
||||
set(Calamares_WITH_PYTHONQT @WITH_PYTHONQT@)
|
||||
set(Calamares_WITH_QML @WITH_QML@)
|
||||
|
@ -1,488 +0,0 @@
|
||||
|
||||
The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
|
||||
|
||||
You may use, distribute and copy the KD Tools Library under the terms of
|
||||
GNU Library General Public License version 2, which is displayed below.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey 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 library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
73
ci/abicheck.sh
Executable file
73
ci/abicheck.sh
Executable file
@ -0,0 +1,73 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Compares the ABI of the current working tree with the ABI
|
||||
# from a base-version. Uses libabigail for the actual comparison.
|
||||
#
|
||||
# To use the tool, just run the script. It will build Calamares at
|
||||
# least once, maybe twice (if it needs the base-version ABI information
|
||||
# and hasn't cached it).
|
||||
|
||||
# The base version can be a tag or git-hash; it will be checked-out
|
||||
# in a worktree.
|
||||
#
|
||||
# Note that the hash here now is the very start of 3.3, when ABI
|
||||
# compatibility was not expected yet at **all**.
|
||||
BASE_VERSION=419be4df25bc6fcc1958cb6e44afc1b9e64fce71
|
||||
|
||||
### Build a tree and cache the ABI info into ci/
|
||||
#
|
||||
#
|
||||
do_build() {
|
||||
LABEL=$1
|
||||
SOURCE_DIR=$2
|
||||
|
||||
BUILD_DIR=build-abi-$LABEL
|
||||
rm -rf $BUILD_DIR
|
||||
mkdir $BUILD_DIR
|
||||
|
||||
if ( cd $BUILD_DIR && cmake $SOURCE_DIR -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -gdwarf" -DCMAKE_C_FLAGS="-Og -g -gdwarf" && make -j12 ) > /dev/null 2>&1
|
||||
then
|
||||
ls -1 $BUILD_DIR/libcalamares*.so.*
|
||||
# Copy the un-versioned files; .so is a symlink to the just-built one
|
||||
for lib in $BUILD_DIR/libcalamares*.so
|
||||
do
|
||||
cp $lib ci/`basename $lib`.$LABEL
|
||||
done
|
||||
else
|
||||
echo "! failed to build $LABEL"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
### Build current tree and get ABI info
|
||||
#
|
||||
#
|
||||
do_build current `pwd -P`
|
||||
|
||||
### Build ABI base version
|
||||
#
|
||||
# We cache this to save on some build time, if we are chasing a
|
||||
# single branch from an unchanging base version.
|
||||
#
|
||||
if test -f ci/libcalamares.so.$BASE_VERSION
|
||||
then
|
||||
# The ABI version is cached, so we're good
|
||||
:
|
||||
else
|
||||
git worktree remove --force tree-abi-$BASE_VERSION
|
||||
git worktree add tree-abi-$BASE_VERSION $BASE_VERSION > /dev/null 2>&1 || { echo "! could not create worktree for $BASE_VERSION" ; exit 1 ; }
|
||||
do_build $BASE_VERSION $( cd tree-abi-$BASE_VERSION && pwd -P )
|
||||
fi
|
||||
|
||||
### Compare & Report
|
||||
#
|
||||
# abidiff compares the Application Binary Interfaces (ABI) of two
|
||||
# shared libraries in ELF format. It emits a meaningful report describing
|
||||
# the differences between the two ABIs.
|
||||
#
|
||||
# -l prints only the leaf changes, leaving out explanations of why.
|
||||
#
|
||||
abidiff -l ci/libcalamares.so.$BASE_VERSION ci/libcalamares.so.current
|
@ -97,10 +97,12 @@ class EditingOutputter(object):
|
||||
lines = f.readlines()
|
||||
|
||||
mark = None
|
||||
mark_text = None
|
||||
for l in lines:
|
||||
# Note that we didn't strip the lines, so need the \n here
|
||||
if l.startswith("# Total ") and l.endswith(" languages\n"):
|
||||
mark = lines.index(l)
|
||||
mark_text = l
|
||||
break
|
||||
if mark is None:
|
||||
raise TXError("No CMakeLists.txt lines for TX stats found")
|
||||
@ -108,18 +110,17 @@ class EditingOutputter(object):
|
||||
|
||||
nextmark = mark + 1
|
||||
for l in lines[mark+1:]:
|
||||
if l.startswith("set( _tx_"):
|
||||
nextmark += 1
|
||||
continue
|
||||
if l.startswith(" "):
|
||||
nextmark += 1
|
||||
continue
|
||||
break
|
||||
if nextmark > mark + 12 or nextmark > len(lines) - 4:
|
||||
nextmark += 1
|
||||
if l.startswith(mark_text):
|
||||
break
|
||||
if nextmark > mark + 100 or nextmark > len(lines) - 4:
|
||||
# Try to catch runaway nextmarks: we know there should
|
||||
# be four set-lines, which are unlikely to be 3 lines each;
|
||||
# similarly the CMakeLists.txt is supposed to end with
|
||||
# some boilerplate.
|
||||
#
|
||||
# However, gersemi will reformat to one-language-per-line,
|
||||
# so we can get really long sections, that's why we use 100 as a limit.
|
||||
raise TXError("Could not find end of TX settings in CMakeLists.txt")
|
||||
self.post_lines = lines[nextmark:]
|
||||
|
||||
@ -185,7 +186,8 @@ def get_tx_stats(languages, outputter, verbose):
|
||||
)
|
||||
|
||||
all_langs = []
|
||||
outputter.print("# Total %d languages" % len(languages))
|
||||
mark_text = "# Total %d languages" % len(languages)
|
||||
outputter.print(mark_text)
|
||||
for lang_name in languages:
|
||||
stats = languages[lang_name]["translated"]["percentage"]
|
||||
# Make the by-definition-incomplete languages have a percentage
|
||||
@ -202,6 +204,7 @@ def get_tx_stats(languages, outputter, verbose):
|
||||
output_langs(all_langs, outputter, "good", lambda s : 1.0 > s >= 0.75)
|
||||
output_langs(all_langs, outputter, "ok", lambda s : 0.75 > s >= 0.05)
|
||||
output_langs(all_langs, outputter, "incomplete", lambda s : 0.05 > s)
|
||||
outputter.print(mark_text)
|
||||
|
||||
# Audit the languages that are in TX, mapped to git
|
||||
for lang_name in languages:
|
||||
|
@ -13,15 +13,15 @@
|
||||
# - defines an OBJECT LIBRARY calamares-i18n for linking the compiled
|
||||
# translations into an executable.
|
||||
|
||||
include( CalamaresAddTranslations )
|
||||
include(CalamaresAddTranslations)
|
||||
|
||||
find_package(Qt5 COMPONENTS Xml)
|
||||
if( Qt5Xml_FOUND )
|
||||
if(Qt5Xml_FOUND)
|
||||
add_executable(txload txload.cpp)
|
||||
target_link_libraries(txload Qt5::Xml)
|
||||
endif()
|
||||
|
||||
install_calamares_gettext_translations( python
|
||||
install_calamares_gettext_translations(python
|
||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/lang/python
|
||||
FILENAME python.mo
|
||||
RENAME calamares-python.mo
|
||||
@ -30,25 +30,25 @@ install_calamares_gettext_translations( python
|
||||
### TRANSLATIONS
|
||||
#
|
||||
#
|
||||
set( TS_FILES "" )
|
||||
set( calamares_i18n_qrc_content "" )
|
||||
set(TS_FILES "")
|
||||
set(calamares_i18n_qrc_content "")
|
||||
|
||||
# calamares and qt language files
|
||||
foreach( lang ${CALAMARES_TRANSLATION_LANGUAGES} )
|
||||
foreach( tlsource "calamares_${lang}" "tz_${lang}" "kb_${lang}" )
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts" )
|
||||
string( APPEND calamares_i18n_qrc_content "<file>${tlsource}.qm</file>\n" )
|
||||
list( APPEND TS_FILES "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts" )
|
||||
foreach(lang ${CALAMARES_TRANSLATION_LANGUAGES})
|
||||
foreach(tlsource "calamares_${lang}" "tz_${lang}" "kb_${lang}")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts")
|
||||
string(APPEND calamares_i18n_qrc_content "<file>${tlsource}.qm</file>\n")
|
||||
list(APPEND TS_FILES "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
set( trans_file calamares_i18n )
|
||||
set( trans_infile ${CMAKE_CURRENT_BINARY_DIR}/${trans_file}.qrc )
|
||||
set( trans_outfile ${CMAKE_CURRENT_BINARY_DIR}/calamares-i18n.cxx )
|
||||
set( CALAMARES_TRANSLATIONS_SOURCE ${trans_outfile} )
|
||||
set(trans_file calamares_i18n)
|
||||
set(trans_infile ${CMAKE_CURRENT_BINARY_DIR}/${trans_file}.qrc)
|
||||
set(trans_outfile ${CMAKE_CURRENT_BINARY_DIR}/calamares-i18n.cxx)
|
||||
set(CALAMARES_TRANSLATIONS_SOURCE ${trans_outfile})
|
||||
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/lang/calamares_i18n.qrc.in ${trans_infile} @ONLY )
|
||||
configure_file(${CMAKE_SOURCE_DIR}/lang/calamares_i18n.qrc.in ${trans_infile} @ONLY)
|
||||
|
||||
qt5_add_translation(QM_FILES ${TS_FILES})
|
||||
|
||||
|
@ -3,26 +3,26 @@
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
include( CalamaresAddBrandingSubdirectory )
|
||||
include( CalamaresAddLibrary )
|
||||
include( CalamaresAddModuleSubdirectory )
|
||||
include( CalamaresAddPlugin )
|
||||
include( CalamaresAddTest )
|
||||
include( CalamaresAddTranslations )
|
||||
include(CalamaresAddBrandingSubdirectory)
|
||||
include(CalamaresAddLibrary)
|
||||
include(CalamaresAddModuleSubdirectory)
|
||||
include(CalamaresAddPlugin)
|
||||
include(CalamaresAddTest)
|
||||
include(CalamaresAddTranslations)
|
||||
|
||||
# library
|
||||
add_subdirectory( libcalamares )
|
||||
add_subdirectory(libcalamares)
|
||||
|
||||
add_subdirectory( libcalamaresui )
|
||||
add_subdirectory(libcalamaresui)
|
||||
|
||||
# all things qml
|
||||
add_subdirectory( qml/calamares )
|
||||
add_subdirectory(qml/calamares)
|
||||
|
||||
# application
|
||||
add_subdirectory( calamares )
|
||||
add_subdirectory(calamares)
|
||||
|
||||
# plugins
|
||||
add_subdirectory( modules )
|
||||
add_subdirectory(modules)
|
||||
|
||||
# branding components
|
||||
add_subdirectory( branding )
|
||||
add_subdirectory(branding)
|
||||
|
@ -204,3 +204,22 @@ Adding the subdirectory can be done as follows:
|
||||
to `.qm` files before being installed. The CMake macro's do this
|
||||
automatically. For manual packaging, use `lrelease` to compile
|
||||
the files.
|
||||
|
||||
## Global Storage keys
|
||||
|
||||
The following keys from the `branding.desc` file are copied into
|
||||
Global Storage under a *branding* parent key:
|
||||
"productName",
|
||||
"version",
|
||||
"shortVersion",
|
||||
"versionedName",
|
||||
"shortVersionedName",
|
||||
"shortProductName",
|
||||
"bootloaderEntryName",
|
||||
"productUrl",
|
||||
"supportUrl",
|
||||
"knownIssuesUrl",
|
||||
"releaseNotesUrl",
|
||||
"donateUrl"
|
||||
|
||||
<!-- see Branding::s_stringEntryStrings and Branding::setGlobals() -->
|
||||
|
@ -4,29 +4,16 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
|
||||
set( calamaresSources
|
||||
set(calamaresSources
|
||||
main.cpp
|
||||
CalamaresApplication.cpp
|
||||
CalamaresWindow.cpp
|
||||
|
||||
DebugWindow.cpp
|
||||
VariantModel.cpp
|
||||
|
||||
progresstree/ProgressTreeDelegate.cpp
|
||||
progresstree/ProgressTreeView.cpp
|
||||
)
|
||||
|
||||
if( NOT WITH_KF5DBus )
|
||||
set( kdsagSources
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/kdsingleapplicationguard/kdsharedmemorylocker.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/kdsingleapplicationguard/kdtoolsglobal.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp
|
||||
)
|
||||
mark_thirdparty_code( ${kdsagSources} )
|
||||
list( APPEND calamaresSources ${kdsagSources} )
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/libcalamares
|
||||
${CMAKE_SOURCE_DIR}/src/libcalamaresui
|
||||
@ -42,45 +29,30 @@ include_directories(
|
||||
# The calamares-i18n.cxx file -- full path in CALAMARES_TRANSLATIONS_SOURCE --
|
||||
# is created as a target in the lang/ directory. This is compiled to a
|
||||
# library (it's just the result of a QRC compile).
|
||||
add_executable( calamares_bin ${calamaresSources} calamares.qrc )
|
||||
target_include_directories( calamares_bin PRIVATE ${CMAKE_SOURCE_DIR} )
|
||||
set_target_properties(calamares_bin
|
||||
PROPERTIES
|
||||
ENABLE_EXPORTS TRUE
|
||||
RUNTIME_OUTPUT_NAME calamares
|
||||
)
|
||||
add_executable(calamares_bin ${calamaresSources} calamares.qrc)
|
||||
target_include_directories(calamares_bin PRIVATE ${CMAKE_SOURCE_DIR})
|
||||
set_target_properties(calamares_bin PROPERTIES ENABLE_EXPORTS TRUE RUNTIME_OUTPUT_NAME calamares)
|
||||
calamares_automoc( calamares_bin )
|
||||
calamares_autouic( calamares_bin )
|
||||
calamares_autorcc( calamares_bin )
|
||||
|
||||
if( kdsagSources )
|
||||
set_source_files_properties( ${kdsagSources} PROPERTIES AUTOMOC OFF )
|
||||
if(kdsagSources)
|
||||
set_source_files_properties(${kdsagSources} PROPERTIES AUTOMOC OFF)
|
||||
endif()
|
||||
|
||||
target_link_libraries( calamares_bin
|
||||
PRIVATE
|
||||
calamares
|
||||
calamaresui
|
||||
calamares-i18n
|
||||
Qt5::Core
|
||||
Qt5::Widgets
|
||||
KF5::CoreAddons
|
||||
target_link_libraries(
|
||||
calamares_bin
|
||||
PRIVATE calamares calamaresui calamares-i18n Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::DBusAddons
|
||||
)
|
||||
if( WITH_KF5Crash )
|
||||
target_link_libraries( calamares_bin PRIVATE KF5::Crash )
|
||||
target_compile_definitions( calamares_bin PRIVATE WITH_KF5Crash )
|
||||
endif()
|
||||
if( WITH_KF5DBus )
|
||||
target_link_libraries( calamares_bin PRIVATE KF5::DBusAddons )
|
||||
target_compile_definitions( calamares_bin PRIVATE WITH_KF5DBus )
|
||||
if(BUILD_KF5Crash)
|
||||
target_link_libraries(calamares_bin PRIVATE KF5::Crash)
|
||||
target_compile_definitions(calamares_bin PRIVATE BUILD_KF5Crash)
|
||||
endif()
|
||||
|
||||
install( TARGETS calamares_bin
|
||||
BUNDLE DESTINATION .
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
install(TARGETS calamares_bin BUNDLE DESTINATION . RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
install( FILES ${CMAKE_SOURCE_DIR}/data/images/squid.svg
|
||||
install(
|
||||
FILES ${CMAKE_SOURCE_DIR}/data/images/squid.svg
|
||||
RENAME calamares.svg
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps
|
||||
)
|
||||
@ -88,11 +60,11 @@ install( FILES ${CMAKE_SOURCE_DIR}/data/images/squid.svg
|
||||
### TESTS
|
||||
#
|
||||
#
|
||||
if( BUILD_TESTING )
|
||||
if(BUILD_TESTING)
|
||||
# Don't install, these are just for enable_testing
|
||||
add_executable( loadmodule testmain.cpp )
|
||||
target_link_libraries( loadmodule PRIVATE Qt5::Core Qt5::Widgets calamares calamaresui )
|
||||
add_executable(loadmodule testmain.cpp)
|
||||
target_link_libraries(loadmodule PRIVATE Qt5::Core Qt5::Widgets calamares calamaresui)
|
||||
|
||||
add_executable( test_conf test_conf.cpp )
|
||||
target_link_libraries( test_conf PUBLIC yamlcpp::yamlcpp Qt5::Core )
|
||||
add_executable(test_conf test_conf.cpp)
|
||||
target_link_libraries(test_conf PUBLIC yamlcpp::yamlcpp Qt5::Core)
|
||||
endif()
|
||||
|
@ -27,13 +27,6 @@
|
||||
#include "utils/Retranslator.h"
|
||||
#include "widgets/TranslationFix.h"
|
||||
|
||||
#ifdef WITH_PYTHONQT
|
||||
#include "ViewManager.h"
|
||||
#include "viewpages/PythonQtViewStep.h"
|
||||
|
||||
#include <gui/PythonQtScriptingConsole.h>
|
||||
#endif
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QSplitter>
|
||||
#include <QStringListModel>
|
||||
@ -120,80 +113,10 @@ DebugWindow::DebugWindow()
|
||||
|
||||
m_ui->moduleConfigView->setModel( m_module_model.get() );
|
||||
|
||||
#ifdef WITH_PYTHONQT
|
||||
QPushButton* pythonConsoleButton = new QPushButton;
|
||||
pythonConsoleButton->setText( "Attach Python console" );
|
||||
m_ui->modulesVerticalLayout->insertWidget( 1, pythonConsoleButton );
|
||||
pythonConsoleButton->hide();
|
||||
|
||||
QObject::connect(
|
||||
pythonConsoleButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[ this, moduleConfigModel ]
|
||||
{
|
||||
QString moduleName = m_ui->modulesListView->currentIndex().data().toString();
|
||||
Module* module = ModuleManager::instance()->moduleInstance( moduleName );
|
||||
if ( module->interface() != Module::Interface::PythonQt || module->type() != Module::Type::View )
|
||||
return;
|
||||
|
||||
for ( ViewStep* step : ViewManager::instance()->viewSteps() )
|
||||
{
|
||||
if ( step->moduleInstanceKey() == module->instanceKey() )
|
||||
{
|
||||
PythonQtViewStep* pqvs = qobject_cast< PythonQtViewStep* >( step );
|
||||
if ( pqvs )
|
||||
{
|
||||
QWidget* consoleWindow = new QWidget;
|
||||
|
||||
QWidget* console = pqvs->createScriptingConsole();
|
||||
console->setParent( consoleWindow );
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
consoleWindow->setLayout( layout );
|
||||
layout->addWidget( console );
|
||||
|
||||
QHBoxLayout* bottomLayout = new QHBoxLayout;
|
||||
layout->addLayout( bottomLayout );
|
||||
|
||||
QLabel* bottomLabel = new QLabel( consoleWindow );
|
||||
bottomLayout->addWidget( bottomLabel );
|
||||
QString line = QString( "Module: <font color=\"#008000\"><code>%1</code></font><br/>"
|
||||
"Python class: <font color=\"#008000\"><code>%2</code></font>" )
|
||||
.arg( module->instanceKey() )
|
||||
.arg( console->property( "classname" ).toString() );
|
||||
bottomLabel->setText( line );
|
||||
|
||||
QPushButton* closeButton = new QPushButton( consoleWindow );
|
||||
closeButton->setText( "&Close" );
|
||||
QObject::connect(
|
||||
closeButton, &QPushButton::clicked, [ consoleWindow ] { consoleWindow->close(); } );
|
||||
bottomLayout->addWidget( closeButton );
|
||||
bottomLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
||||
|
||||
consoleWindow->setParent( this );
|
||||
consoleWindow->setWindowFlags( Qt::Window );
|
||||
consoleWindow->setWindowTitle( "Calamares Python console" );
|
||||
consoleWindow->setAttribute( Qt::WA_DeleteOnClose, true );
|
||||
consoleWindow->showNormal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
#endif
|
||||
|
||||
connect( m_ui->modulesListView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
[ this
|
||||
#ifdef WITH_PYTHONQT
|
||||
,
|
||||
pythonConsoleButton
|
||||
#endif
|
||||
]
|
||||
{
|
||||
[this] {
|
||||
QString moduleName = m_ui->modulesListView->currentIndex().data().toString();
|
||||
Module* module
|
||||
= ModuleManager::instance()->moduleInstance( ModuleSystem::InstanceKey::fromString( moduleName ) );
|
||||
@ -204,10 +127,6 @@ DebugWindow::DebugWindow()
|
||||
m_ui->moduleConfigView->expandAll();
|
||||
m_ui->moduleTypeLabel->setText( module->typeString() );
|
||||
m_ui->moduleInterfaceLabel->setText( module->interfaceString() );
|
||||
#ifdef WITH_PYTHONQT
|
||||
pythonConsoleButton->setVisible( module->interface() == Module::Interface::PythonQt
|
||||
&& module->type() == Module::Type::View );
|
||||
#endif
|
||||
}
|
||||
} );
|
||||
|
||||
|
@ -5,7 +5,7 @@ SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</author>
|
||||
<class>Calamares::DebugWindow</class>
|
||||
<widget class="QWidget" name="Calamares::DebugWindow">
|
||||
<widget class="QWidget" name="DebugWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -46,12 +46,12 @@ Rectangle {
|
||||
Layout.fillWidth: true;
|
||||
height: 35;
|
||||
radius: 6;
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarBackgroundSelected : Branding.SidebarBackground );
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground );
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextSelected : Branding.SidebarText );
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextCurrent : Branding.SidebarText );
|
||||
text: display;
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,9 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#ifndef WITH_KF5DBus
|
||||
#include "3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.h"
|
||||
#endif
|
||||
|
||||
#include <KCoreAddons/KAboutData>
|
||||
#ifdef WITH_KF5DBus
|
||||
#include <KDBusAddons/KDBusService>
|
||||
#endif
|
||||
#ifdef WITH_KF5Crash
|
||||
#ifdef BUILD_KF5Crash
|
||||
#include <KCrash/KCrash>
|
||||
#endif
|
||||
|
||||
@ -123,37 +117,16 @@ main( int argc, char* argv[] )
|
||||
KAboutData::setApplicationData( aboutData );
|
||||
a.setApplicationDisplayName( QString() ); // To avoid putting an extra "Calamares/" into the log-file
|
||||
|
||||
#ifdef WITH_KF5Crash
|
||||
#ifdef BUILD_KF5Crash
|
||||
KCrash::initialize();
|
||||
// KCrash::setCrashHandler();
|
||||
KCrash::setDrKonqiEnabled( true );
|
||||
KCrash::setFlags( KCrash::SaferDialog | KCrash::AlwaysDirectly );
|
||||
// TODO: umount anything in /tmp/calamares-... as an emergency save function
|
||||
#endif
|
||||
|
||||
bool is_debug = handle_args( a );
|
||||
|
||||
#ifdef WITH_KF5DBus
|
||||
KDBusService service( is_debug ? KDBusService::Multiple : KDBusService::Unique );
|
||||
#else
|
||||
KDSingleApplicationGuard guard( is_debug ? KDSingleApplicationGuard::NoPolicy
|
||||
: KDSingleApplicationGuard::AutoKillOtherInstances );
|
||||
if ( !is_debug && !guard.isPrimaryInstance() )
|
||||
{
|
||||
// Here we have not yet set-up the logger system, so qDebug() is ok
|
||||
auto instancelist = guard.instances();
|
||||
qDebug() << "Calamares is already running, shutting down.";
|
||||
if ( instancelist.count() > 0 )
|
||||
{
|
||||
qDebug() << "Other running Calamares instances:";
|
||||
}
|
||||
for ( const auto& i : instancelist )
|
||||
{
|
||||
qDebug() << " " << i.isValid() << i.pid() << i.arguments();
|
||||
}
|
||||
return 69; // EX_UNAVAILABLE on FreeBSD
|
||||
}
|
||||
#endif
|
||||
|
||||
Calamares::Settings::init( is_debug );
|
||||
if ( !Calamares::Settings::instance() || !Calamares::Settings::instance()->isValid() )
|
||||
|
@ -25,50 +25,8 @@ item_fontsize()
|
||||
return CalamaresUtils::defaultFontSize() + 4;
|
||||
}
|
||||
|
||||
QSize
|
||||
ProgressTreeDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
{
|
||||
return option.rect.size();
|
||||
}
|
||||
|
||||
QFont font = qApp->font();
|
||||
|
||||
font.setPointSize( item_fontsize() );
|
||||
QFontMetrics fm( font );
|
||||
int height = fm.height();
|
||||
|
||||
height += 2 * item_margin;
|
||||
|
||||
return QSize( option.rect.width(), height );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProgressTreeDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
|
||||
painter->save();
|
||||
|
||||
initStyleOption( &opt, index );
|
||||
opt.text.clear();
|
||||
|
||||
painter->setBrush(
|
||||
QColor( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarBackground ) ) );
|
||||
painter->setPen( QColor( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarText ) ) );
|
||||
|
||||
paintViewStep( painter, opt, index );
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProgressTreeDelegate::paintViewStep( QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index ) const
|
||||
static void
|
||||
paintViewStep( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
QRect textRect = option.rect.adjusted( item_margin, item_margin, -item_margin, -item_margin );
|
||||
QFont font = qApp->font();
|
||||
@ -78,9 +36,9 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter,
|
||||
|
||||
if ( index.row() == index.data( Calamares::ViewManager::ProgressTreeItemCurrentIndex ).toInt() )
|
||||
{
|
||||
painter->setPen( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarTextSelect ) );
|
||||
painter->setPen( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarTextCurrent ) );
|
||||
QString textHighlight
|
||||
= Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarTextHighlight );
|
||||
= Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarBackgroundCurrent );
|
||||
if ( textHighlight.isEmpty() )
|
||||
{
|
||||
painter->setBrush( CalamaresApplication::instance()->mainWindow()->palette().window() );
|
||||
@ -122,3 +80,42 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter,
|
||||
}
|
||||
} while ( shrinkSteps <= maximumShrink );
|
||||
}
|
||||
|
||||
QSize
|
||||
ProgressTreeDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
{
|
||||
return option.rect.size();
|
||||
}
|
||||
|
||||
QFont font = qApp->font();
|
||||
|
||||
font.setPointSize( item_fontsize() );
|
||||
QFontMetrics fm( font );
|
||||
int height = fm.height();
|
||||
|
||||
height += 2 * item_margin;
|
||||
|
||||
return QSize( option.rect.width(), height );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProgressTreeDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
|
||||
painter->save();
|
||||
|
||||
initStyleOption( &opt, index );
|
||||
opt.text.clear();
|
||||
|
||||
painter->setBrush(
|
||||
QColor( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarBackground ) ) );
|
||||
painter->setPen( QColor( Calamares::Branding::instance()->styleString( Calamares::Branding::SidebarText ) ) );
|
||||
|
||||
paintViewStep( painter, opt, index );
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
@ -26,9 +26,6 @@ public:
|
||||
protected:
|
||||
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const override;
|
||||
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const override;
|
||||
|
||||
private:
|
||||
void paintViewStep( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
};
|
||||
|
||||
#endif // PROGRESSTREEDELEGATE_H
|
||||
|
@ -14,8 +14,11 @@
|
||||
#include <QListView>
|
||||
|
||||
/**
|
||||
* @brief The ProgressTreeView class is a modified QTreeView which displays the
|
||||
* @brief Displays progress through the list of (visible) steps
|
||||
*
|
||||
* The ProgressTreeView class is a modified QListView which displays the
|
||||
* available view steps and the user's progress through them.
|
||||
* Since Calamares doesn't support "sub steps", it isn't really a tree.
|
||||
*/
|
||||
class ProgressTreeView : public QListView
|
||||
{
|
||||
|
@ -10,20 +10,16 @@
|
||||
# (non-GUI) jobs.
|
||||
#
|
||||
|
||||
add_definitions( -DDLLEXPORT_PRO )
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
add_definitions(-DDLLEXPORT_PRO)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h )
|
||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersion.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h )
|
||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersionX.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersionX.h )
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersionX.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersionX.h)
|
||||
|
||||
set( OPTIONAL_PRIVATE_LIBRARIES "" )
|
||||
set( OPTIONAL_PUBLIC_LIBRARIES "" )
|
||||
|
||||
set( libSources
|
||||
add_library(
|
||||
calamares
|
||||
SHARED
|
||||
CalamaresAbout.cpp
|
||||
CppJob.cpp
|
||||
GlobalStorage.cpp
|
||||
@ -32,13 +28,11 @@ set( libSources
|
||||
JobQueue.cpp
|
||||
ProcessJob.cpp
|
||||
Settings.cpp
|
||||
|
||||
# GeoIP services
|
||||
geoip/Interface.cpp
|
||||
geoip/GeoIPFixed.cpp
|
||||
geoip/GeoIPJSON.cpp
|
||||
geoip/Handler.cpp
|
||||
|
||||
# Locale-data service
|
||||
locale/Global.cpp
|
||||
locale/Lookup.cpp
|
||||
@ -47,7 +41,6 @@ set( libSources
|
||||
locale/TranslatableString.cpp
|
||||
locale/Translation.cpp
|
||||
locale/TranslationsModel.cpp
|
||||
|
||||
# Modules
|
||||
modulesystem/Config.cpp
|
||||
modulesystem/Descriptor.cpp
|
||||
@ -56,19 +49,15 @@ set( libSources
|
||||
modulesystem/Preset.cpp
|
||||
modulesystem/RequirementsChecker.cpp
|
||||
modulesystem/RequirementsModel.cpp
|
||||
|
||||
# Network service
|
||||
network/Manager.cpp
|
||||
|
||||
# Packages service
|
||||
packages/Globals.cpp
|
||||
|
||||
# Partition service
|
||||
partition/Global.cpp
|
||||
partition/Mount.cpp
|
||||
partition/PartitionSize.cpp
|
||||
partition/Sync.cpp
|
||||
|
||||
# Utility service
|
||||
utils/CalamaresUtilsSystem.cpp
|
||||
utils/CommandList.cpp
|
||||
@ -80,248 +69,197 @@ set( libSources
|
||||
utils/Retranslator.cpp
|
||||
utils/Runner.cpp
|
||||
utils/String.cpp
|
||||
utils/StringExpander.cpp
|
||||
utils/UMask.cpp
|
||||
utils/Variant.cpp
|
||||
utils/Yaml.cpp
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
calamares
|
||||
PROPERTIES
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
SOVERSION ${CALAMARES_VERSION_SHORT}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_INSTALL_FULL_INCLUDEDIR}/libcalamares
|
||||
)
|
||||
target_link_libraries(calamares LINK_PUBLIC yamlcpp::yamlcpp Qt5::Core KF5::CoreAddons)
|
||||
|
||||
### OPTIONAL Automount support (requires dbus)
|
||||
#
|
||||
#
|
||||
if( Qt5DBus_FOUND)
|
||||
list( APPEND libSources partition/AutoMount.cpp )
|
||||
list( APPEND OPTIONAL_PRIVATE_LIBRARIES Qt5::DBus )
|
||||
if(Qt5DBus_FOUND)
|
||||
target_sources(calamares PRIVATE partition/AutoMount.cpp)
|
||||
target_link_libraries(calamares PRIVATE Qt5::DBus)
|
||||
endif()
|
||||
|
||||
### OPTIONAL Python support
|
||||
#
|
||||
#
|
||||
if( WITH_PYTHON )
|
||||
list( APPEND libSources
|
||||
PythonHelper.cpp
|
||||
PythonJob.cpp
|
||||
PythonJobApi.cpp
|
||||
)
|
||||
|
||||
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||
link_directories(${PYTHON_LIBRARIES})
|
||||
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
|
||||
list( APPEND OPTIONAL_PRIVATE_LIBRARIES
|
||||
${PYTHON_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
if(WITH_PYTHON)
|
||||
target_sources(calamares PRIVATE PythonHelper.cpp PythonJob.cpp PythonJobApi.cpp)
|
||||
target_link_libraries(calamares PRIVATE Python::Python Boost::python)
|
||||
endif()
|
||||
|
||||
### OPTIONAL GeoIP XML support
|
||||
#
|
||||
#
|
||||
find_package(Qt5 COMPONENTS Xml)
|
||||
if( Qt5Xml_FOUND )
|
||||
list( APPEND libSources geoip/GeoIPXML.cpp )
|
||||
list( APPEND OPTIONAL_PUBLIC_LIBRARIES Qt5::Network Qt5::Xml )
|
||||
if(Qt5Xml_FOUND)
|
||||
target_sources(calamares PRIVATE geoip/GeoIPXML.cpp)
|
||||
target_link_libraries(calamares PRIVATE Qt5::Network Qt5::Xml)
|
||||
endif()
|
||||
|
||||
### OPTIONAL KPMcore support
|
||||
#
|
||||
#
|
||||
include( KPMcoreHelper )
|
||||
include(KPMcoreHelper)
|
||||
|
||||
if ( KPMcore_FOUND )
|
||||
find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore
|
||||
find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore
|
||||
if(KPMcore_FOUND)
|
||||
find_package(Qt5 REQUIRED DBus) # Needed for KPMCore
|
||||
find_package(KF5 REQUIRED I18n WidgetsAddons) # Needed for KPMCore
|
||||
|
||||
foreach ( d ${KPMcore_API_DEFINITIONS} )
|
||||
add_definitions( -D${d} )
|
||||
foreach(d ${KPMcore_API_DEFINITIONS})
|
||||
add_definitions(-D${d})
|
||||
endforeach()
|
||||
include_directories( ${KPMCORE_INCLUDE_DIR} )
|
||||
list( APPEND libSources
|
||||
partition/FileSystem.cpp
|
||||
partition/KPMManager.cpp
|
||||
partition/PartitionIterator.cpp
|
||||
partition/PartitionQuery.cpp
|
||||
include_directories(${KPMCORE_INCLUDE_DIR})
|
||||
target_sources(
|
||||
calamares
|
||||
PRIVATE
|
||||
partition/FileSystem.cpp
|
||||
partition/KPMManager.cpp
|
||||
partition/PartitionIterator.cpp
|
||||
partition/PartitionQuery.cpp
|
||||
)
|
||||
list( APPEND OPTIONAL_PRIVATE_LIBRARIES kpmcore )
|
||||
target_link_libraries(calamares PRIVATE kpmcore)
|
||||
endif()
|
||||
|
||||
### LIBRARY
|
||||
#
|
||||
#
|
||||
add_library( calamares SHARED ${libSources} )
|
||||
set_target_properties( calamares
|
||||
PROPERTIES
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
SOVERSION ${CALAMARES_VERSION_SHORT}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_INSTALL_FULL_INCLUDEDIR}/libcalamares
|
||||
)
|
||||
calamares_automoc( calamares )
|
||||
|
||||
target_link_libraries( calamares
|
||||
LINK_PRIVATE
|
||||
${OPTIONAL_PRIVATE_LIBRARIES}
|
||||
LINK_PUBLIC
|
||||
yamlcpp::yamlcpp
|
||||
Qt5::Core
|
||||
KF5::CoreAddons
|
||||
${OPTIONAL_PUBLIC_LIBRARIES}
|
||||
)
|
||||
|
||||
add_library(Calamares::calamares ALIAS calamares)
|
||||
|
||||
### Installation
|
||||
#
|
||||
#
|
||||
install( TARGETS calamares
|
||||
install(
|
||||
TARGETS calamares
|
||||
EXPORT Calamares
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
# Make symlink lib/calamares/libcalamares.so to lib/libcalamares.so.VERSION so
|
||||
# lib/calamares can be used as module path for the Python interpreter.
|
||||
install( CODE "
|
||||
install(
|
||||
CODE
|
||||
"
|
||||
file( MAKE_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" )
|
||||
execute_process( COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../libcalamares.so.${CALAMARES_VERSION_SHORT} libcalamares.so WORKING_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" )
|
||||
")
|
||||
"
|
||||
)
|
||||
|
||||
# Install header files
|
||||
file( GLOB rootHeaders "*.h" )
|
||||
file(GLOB rootHeaders "*.h")
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h
|
||||
${rootHeaders}
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h ${rootHeaders}
|
||||
DESTINATION include/libcalamares
|
||||
)
|
||||
# Install each subdir-worth of header files
|
||||
foreach( subdir geoip locale modulesystem network partition utils )
|
||||
file( GLOB subdir_headers "${subdir}/*.h" )
|
||||
install( FILES ${subdir_headers} DESTINATION include/libcalamares/${subdir} )
|
||||
foreach(subdir geoip locale modulesystem network partition utils)
|
||||
file(GLOB subdir_headers "${subdir}/*.h")
|
||||
install(FILES ${subdir_headers} DESTINATION include/libcalamares/${subdir})
|
||||
endforeach()
|
||||
|
||||
|
||||
### TESTING
|
||||
### TRANSLATION TESTING
|
||||
#
|
||||
#
|
||||
calamares_add_test(
|
||||
libcalamarestest
|
||||
SOURCES
|
||||
Tests.cpp
|
||||
)
|
||||
# This is a support function, used just once, to help out the localetest
|
||||
function(calamares_qrc_translations basename)
|
||||
set(NAME ${ARGV0})
|
||||
set(options "")
|
||||
set(oneValueArgs SUBDIRECTORY OUTPUT_VARIABLE)
|
||||
set(multiValueArgs LANGUAGES)
|
||||
cmake_parse_arguments(_qrt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
calamares_add_test(
|
||||
libcalamaresgeoiptest
|
||||
SOURCES
|
||||
geoip/GeoIPTests.cpp
|
||||
${geoip_src}
|
||||
)
|
||||
|
||||
function ( calamares_qrc_translations basename )
|
||||
set( NAME ${ARGV0} )
|
||||
set( options "" )
|
||||
set( oneValueArgs SUBDIRECTORY OUTPUT_VARIABLE )
|
||||
set( multiValueArgs LANGUAGES )
|
||||
cmake_parse_arguments( _qrt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
|
||||
if( NOT _qrt_OUTPUT_VARIABLE )
|
||||
set( _qrt_OUTPUT_VARIABLE "qrc_translations_${basename}" )
|
||||
if(NOT _qrt_OUTPUT_VARIABLE)
|
||||
set(_qrt_OUTPUT_VARIABLE "qrc_translations_${basename}")
|
||||
endif()
|
||||
|
||||
set( translations_qrc_infile ${CMAKE_CURRENT_BINARY_DIR}/${basename}.qrc )
|
||||
set( translations_qrc_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${basename}.cxx )
|
||||
set(translations_qrc_infile ${CMAKE_CURRENT_BINARY_DIR}/${basename}.qrc)
|
||||
set(translations_qrc_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${basename}.cxx)
|
||||
|
||||
# Must use this variable name because of the @ substitution
|
||||
set( calamares_i18n_qrc_content "" )
|
||||
set( calamares_i18n_ts_filelist "" )
|
||||
foreach( lang ${_qrt_LANGUAGES} )
|
||||
string( APPEND calamares_i18n_qrc_content "<file>${basename}_${lang}.qm</file>" )
|
||||
list( APPEND calamares_i18n_ts_filelist "${CMAKE_CURRENT_SOURCE_DIR}/${_qrt_SUBDIRECTORY}/${basename}_${lang}.ts" )
|
||||
set(calamares_i18n_qrc_content "")
|
||||
set(calamares_i18n_ts_filelist "")
|
||||
foreach(lang ${_qrt_LANGUAGES})
|
||||
string(APPEND calamares_i18n_qrc_content "<file>${basename}_${lang}.qm</file>")
|
||||
list(
|
||||
APPEND
|
||||
calamares_i18n_ts_filelist
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${_qrt_SUBDIRECTORY}/${basename}_${lang}.ts"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/lang/calamares_i18n.qrc.in ${translations_qrc_infile} @ONLY )
|
||||
configure_file(${CMAKE_SOURCE_DIR}/lang/calamares_i18n.qrc.in ${translations_qrc_infile} @ONLY)
|
||||
qt5_add_translation(QM_FILES ${calamares_i18n_ts_filelist})
|
||||
|
||||
# Run the resource compiler (rcc_options should already be set)
|
||||
add_custom_command(
|
||||
OUTPUT ${translations_qrc_outfile}
|
||||
COMMAND "${Qt5Core_RCC_EXECUTABLE}"
|
||||
ARGS ${rcc_options} --format-version 1 -name ${basename} -o ${translations_qrc_outfile} ${translations_qrc_infile}
|
||||
ARGS
|
||||
${rcc_options}
|
||||
--format-version
|
||||
1
|
||||
-name
|
||||
${basename}
|
||||
-o
|
||||
${translations_qrc_outfile}
|
||||
${translations_qrc_infile}
|
||||
MAIN_DEPENDENCY ${translations_qrc_infile}
|
||||
DEPENDS ${QM_FILES}
|
||||
)
|
||||
|
||||
set( ${_qrt_OUTPUT_VARIABLE} ${translations_qrc_outfile} PARENT_SCOPE )
|
||||
set(${_qrt_OUTPUT_VARIABLE} ${translations_qrc_outfile} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
calamares_qrc_translations( localetest OUTPUT_VARIABLE localetest_qrc SUBDIRECTORY testdata LANGUAGES nl )
|
||||
calamares_add_test(
|
||||
libcalamareslocaletest
|
||||
SOURCES
|
||||
locale/Tests.cpp
|
||||
${localetest_qrc}
|
||||
)
|
||||
|
||||
calamares_add_test(
|
||||
libcalamaresmodulesystemtest
|
||||
SOURCES
|
||||
modulesystem/Tests.cpp
|
||||
)
|
||||
### TESTING
|
||||
#
|
||||
#
|
||||
calamares_add_test(libcalamarestest SOURCES Tests.cpp)
|
||||
|
||||
calamares_add_test(
|
||||
libcalamaresnetworktest
|
||||
SOURCES
|
||||
network/Tests.cpp
|
||||
)
|
||||
calamares_add_test(libcalamaresgeoiptest SOURCES geoip/GeoIPTests.cpp ${geoip_src})
|
||||
|
||||
calamares_add_test(
|
||||
libcalamarespackagestest
|
||||
SOURCES
|
||||
packages/Tests.cpp
|
||||
)
|
||||
calamares_add_test(libcalamareslocaletest SOURCES locale/Tests.cpp ${localetest_qrc})
|
||||
|
||||
calamares_add_test(
|
||||
libcalamarespartitiontest
|
||||
SOURCES
|
||||
partition/Global.cpp
|
||||
partition/Tests.cpp
|
||||
LIBRARIES
|
||||
${OPTIONAL_PRIVATE_LIBRARIES}
|
||||
)
|
||||
calamares_add_test(libcalamaresmodulesystemtest SOURCES modulesystem/Tests.cpp)
|
||||
|
||||
if( KPMcore_FOUND )
|
||||
calamares_add_test(
|
||||
libcalamarespartitionkpmtest
|
||||
SOURCES
|
||||
partition/KPMTests.cpp
|
||||
LIBRARIES
|
||||
${OPTIONAL_PRIVATE_LIBRARIES}
|
||||
)
|
||||
calamares_add_test(libcalamaresnetworktest SOURCES network/Tests.cpp)
|
||||
|
||||
calamares_add_test(libcalamarespackagestest SOURCES packages/Tests.cpp)
|
||||
|
||||
if(KPMcore_FOUND)
|
||||
calamares_add_test(libcalamarespartitiontest SOURCES partition/Global.cpp partition/Tests.cpp LIBRARIES kpmcore)
|
||||
calamares_add_test(libcalamarespartitionkpmtest SOURCES partition/KPMTests.cpp LIBRARIES kpmcore)
|
||||
endif()
|
||||
|
||||
calamares_add_test(
|
||||
libcalamaresutilstest
|
||||
SOURCES
|
||||
utils/Tests.cpp
|
||||
utils/Runner.cpp
|
||||
)
|
||||
|
||||
calamares_add_test(
|
||||
libcalamaresutilspathstest
|
||||
SOURCES
|
||||
utils/TestPaths.cpp
|
||||
)
|
||||
calamares_add_test(libcalamaresutilstest SOURCES utils/Tests.cpp utils/Runner.cpp)
|
||||
|
||||
calamares_add_test(libcalamaresutilspathstest SOURCES utils/TestPaths.cpp)
|
||||
|
||||
# This is not an actual test, it's a test / demo application
|
||||
# for experimenting with GeoIP.
|
||||
add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} )
|
||||
target_link_libraries( test_geoip Calamares::calamares Qt5::Network yamlcpp::yamlcpp )
|
||||
add_executable(test_geoip geoip/test_geoip.cpp ${geoip_src})
|
||||
target_link_libraries(test_geoip Calamares::calamares Qt5::Network yamlcpp::yamlcpp)
|
||||
calamares_automoc( test_geoip )
|
||||
|
||||
if ( Qt5DBus_FOUND )
|
||||
add_executable( test_automount partition/calautomount.cpp )
|
||||
target_link_libraries( test_automount Calamares::calamares Qt5::DBus )
|
||||
if(Qt5DBus_FOUND)
|
||||
add_executable(test_automount partition/calautomount.cpp)
|
||||
target_link_libraries(test_automount Calamares::calamares Qt5::DBus)
|
||||
endif()
|
||||
|
@ -25,7 +25,6 @@
|
||||
* which is the CMake-time side of the same configuration.
|
||||
*/
|
||||
#cmakedefine WITH_PYTHON
|
||||
#cmakedefine WITH_PYTHONQT
|
||||
#cmakedefine WITH_QML
|
||||
|
||||
#endif // CALAMARESCONFIG_H
|
||||
|
@ -262,7 +262,7 @@ host_env_process_output( const boost::python::list& args,
|
||||
std::string
|
||||
obscure( const std::string& string )
|
||||
{
|
||||
return CalamaresUtils::obscure( QString::fromStdString( string ) ).toStdString();
|
||||
return Calamares::String::obscure( QString::fromStdString( string ) ).toStdString();
|
||||
}
|
||||
|
||||
static QStringList
|
||||
|
@ -40,7 +40,6 @@ interfaceNames()
|
||||
{ QStringLiteral("process"), Interface::Process },
|
||||
{ QStringLiteral("qtplugin"), Interface::QtPlugin },
|
||||
{ QStringLiteral("python"), Interface::Python },
|
||||
{ QStringLiteral("pythonqt"), Interface::PythonQt }
|
||||
};
|
||||
// *INDENT-ON*
|
||||
// clang-format on
|
||||
@ -107,7 +106,6 @@ Descriptor::fromDescriptorData( const QVariantMap& moduleDesc, const QString& de
|
||||
consumedKeys << "load";
|
||||
break;
|
||||
case Interface::Python:
|
||||
case Interface::PythonQt:
|
||||
d.m_script = CalamaresUtils::getString( moduleDesc, "script" );
|
||||
if ( d.m_script.isEmpty() )
|
||||
{
|
||||
|
@ -42,7 +42,6 @@ enum class Interface
|
||||
QtPlugin, // Jobs or Views
|
||||
Python, // Jobs only
|
||||
Process, // Deprecated interface
|
||||
PythonQt // Views only, available as enum even if PythonQt isn't used
|
||||
};
|
||||
const NamedEnumTable< Interface >& interfaceNames();
|
||||
|
||||
@ -114,7 +113,7 @@ public:
|
||||
*/
|
||||
QString script() const
|
||||
{
|
||||
return ( m_interface == Interface::Python || m_interface == Interface::PythonQt ) ? m_script : QString();
|
||||
return m_interface == Interface::Python ? m_script : QString();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -43,7 +43,7 @@ RequirementsChecker::run()
|
||||
{
|
||||
m_progressTimer = new QTimer( this );
|
||||
connect( m_progressTimer, &QTimer::timeout, this, &RequirementsChecker::reportProgress );
|
||||
m_progressTimer->start( 1200 ); // msec
|
||||
m_progressTimer->start( std::chrono::milliseconds( 1200 ) );
|
||||
|
||||
for ( const auto& module : m_modules )
|
||||
{
|
||||
@ -76,7 +76,7 @@ RequirementsChecker::finished()
|
||||
}
|
||||
|
||||
m_model->describe();
|
||||
m_model->changeRequirementsList();
|
||||
m_model->reCheckList();
|
||||
QTimer::singleShot( 0, this, &RequirementsChecker::done );
|
||||
}
|
||||
}
|
||||
|
@ -16,17 +16,41 @@ namespace Calamares
|
||||
{
|
||||
|
||||
void
|
||||
RequirementsModel::addRequirementsList( const Calamares::RequirementsList& requirements )
|
||||
RequirementsModel::clear()
|
||||
{
|
||||
QMutexLocker l( &m_addLock );
|
||||
beginResetModel();
|
||||
m_requirements.append( requirements );
|
||||
changeRequirementsList();
|
||||
m_requirements.clear();
|
||||
endResetModel();
|
||||
reCheckList();
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsModel::changeRequirementsList()
|
||||
RequirementsModel::addRequirementsList( const Calamares::RequirementsList& requirements )
|
||||
{
|
||||
QMutexLocker l( &m_addLock );
|
||||
|
||||
beginResetModel();
|
||||
for ( const auto& r : requirements )
|
||||
{
|
||||
auto it = std::find_if( m_requirements.begin(),
|
||||
m_requirements.end(),
|
||||
[ &r ]( const Calamares::RequirementEntry& re ) { return r.name == re.name; } );
|
||||
if ( it != m_requirements.end() )
|
||||
{
|
||||
*it = r;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_requirements.append( r );
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
reCheckList();
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsModel::reCheckList()
|
||||
{
|
||||
auto isUnSatisfied = []( const Calamares::RequirementEntry& e ) { return !e.satisfied; };
|
||||
auto isMandatoryAndUnSatisfied = []( const Calamares::RequirementEntry& e ) { return e.mandatory && !e.satisfied; };
|
||||
@ -34,8 +58,8 @@ RequirementsModel::changeRequirementsList()
|
||||
m_satisfiedRequirements = std::none_of( m_requirements.begin(), m_requirements.end(), isUnSatisfied );
|
||||
m_satisfiedMandatory = std::none_of( m_requirements.begin(), m_requirements.end(), isMandatoryAndUnSatisfied );
|
||||
|
||||
emit satisfiedRequirementsChanged( m_satisfiedRequirements );
|
||||
emit satisfiedMandatoryChanged( m_satisfiedMandatory );
|
||||
Q_EMIT satisfiedRequirementsChanged( m_satisfiedRequirements );
|
||||
Q_EMIT satisfiedMandatoryChanged( m_satisfiedMandatory );
|
||||
}
|
||||
|
||||
int
|
||||
@ -98,7 +122,7 @@ void
|
||||
RequirementsModel::setProgressMessage( const QString& m )
|
||||
{
|
||||
m_progressMessage = m;
|
||||
emit progressMessageChanged( m_progressMessage );
|
||||
Q_EMIT progressMessageChanged( m_progressMessage );
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
|
@ -33,8 +33,6 @@ class RequirementsChecker;
|
||||
*/
|
||||
class DLLEXPORT RequirementsModel : public QAbstractListModel
|
||||
{
|
||||
friend class RequirementsChecker;
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( bool satisfiedRequirements READ satisfiedRequirements NOTIFY satisfiedRequirementsChanged FINAL )
|
||||
Q_PROPERTY( bool satisfiedMandatory READ satisfiedMandatory NOTIFY satisfiedMandatoryChanged FINAL )
|
||||
@ -45,11 +43,11 @@ public:
|
||||
|
||||
enum Roles : short
|
||||
{
|
||||
Name,
|
||||
NegatedText = Qt::DisplayRole,
|
||||
Details = Qt::ToolTipRole,
|
||||
Name = Qt::UserRole,
|
||||
Satisfied,
|
||||
Mandatory,
|
||||
Details,
|
||||
NegatedText,
|
||||
HasDetails
|
||||
};
|
||||
// No Q_ENUM because these are exposed through roleNames()
|
||||
@ -69,6 +67,15 @@ public:
|
||||
///@brief Debugging tool, describe the checking-state
|
||||
void describe() const;
|
||||
|
||||
///@brief Update progress message (called by the checker)
|
||||
void setProgressMessage( const QString& m );
|
||||
|
||||
///@brief Append some requirements; resets the model
|
||||
void addRequirementsList( const Calamares::RequirementsList& requirements );
|
||||
|
||||
///@brief Check the whole list, emit signals satisfied...()
|
||||
void reCheckList();
|
||||
|
||||
signals:
|
||||
void satisfiedRequirementsChanged( bool value );
|
||||
void satisfiedMandatoryChanged( bool value );
|
||||
@ -77,16 +84,10 @@ signals:
|
||||
protected:
|
||||
QHash< int, QByteArray > roleNames() const override;
|
||||
|
||||
///@brief Append some requirements; resets the model
|
||||
void addRequirementsList( const Calamares::RequirementsList& requirements );
|
||||
|
||||
///@brief Update progress message (called by the checker)
|
||||
void setProgressMessage( const QString& m );
|
||||
///@brief Clears the requirements; resets the model
|
||||
void clear();
|
||||
|
||||
private:
|
||||
///@brief Implementation for {set,add}RequirementsList
|
||||
void changeRequirementsList();
|
||||
|
||||
QString m_progressMessage;
|
||||
QMutex m_addLock;
|
||||
RequirementsList m_requirements;
|
||||
|
@ -29,16 +29,11 @@ namespace Network
|
||||
void
|
||||
RequestOptions::applyToRequest( QNetworkRequest* request ) const
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 )
|
||||
constexpr const auto RedirectPolicyAttribute = QNetworkRequest::FollowRedirectsAttribute;
|
||||
#else
|
||||
constexpr const auto RedirectPolicyAttribute = QNetworkRequest::RedirectPolicyAttribute;
|
||||
#endif
|
||||
|
||||
if ( m_flags & Flag::FollowRedirect )
|
||||
{
|
||||
// Follows all redirects except unsafe ones (https to http).
|
||||
request->setAttribute( RedirectPolicyAttribute, true );
|
||||
request->setAttribute( QNetworkRequest::RedirectPolicyAttribute, true );
|
||||
}
|
||||
|
||||
if ( m_flags & Flag::FakeUserAgent )
|
||||
|
@ -17,13 +17,10 @@
|
||||
#define PARTITION_GLOBAL_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "FileSystem.h"
|
||||
#include "JobQueue.h"
|
||||
|
||||
#ifdef WITH_KPMCORE4API
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
#endif
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
@ -78,7 +75,6 @@ isFilesystemUsedGS( const QString& filesystemType )
|
||||
return isFilesystemUsedGS( Calamares::JobQueue::instanceGlobalStorage(), filesystemType );
|
||||
}
|
||||
|
||||
#ifdef WITH_KPMCORE4API
|
||||
/** @brief Mark a particular filesystem type as used (or not)
|
||||
*
|
||||
* See useFilesystemGS(const QString&, bool); this method uses the filesystem type
|
||||
@ -100,7 +96,6 @@ isFilesystemUsedGS( FileSystem::Type filesystem )
|
||||
return isFilesystemUsedGS( untranslatedFS( filesystem ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace Partition
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#pragma clang diagnostic ignored "-Wdocumentation"
|
||||
#pragma clang diagnostic ignored "-Wsuggest-destructor-override"
|
||||
#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
|
||||
// Because of __lastType
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||
#endif
|
||||
|
||||
#include <backend/corebackend.h>
|
||||
|
@ -14,10 +14,7 @@
|
||||
|
||||
#include <kpmcore/backend/corebackend.h>
|
||||
#include <kpmcore/backend/corebackendmanager.h>
|
||||
#if defined( WITH_KPMCORE4API )
|
||||
#include <kpmcore/util/externalcommand.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@ -30,7 +27,6 @@ class InternalManager
|
||||
{
|
||||
public:
|
||||
InternalManager();
|
||||
~InternalManager();
|
||||
};
|
||||
|
||||
static bool s_kpm_loaded = false;
|
||||
@ -69,22 +65,6 @@ InternalManager::InternalManager()
|
||||
}
|
||||
}
|
||||
|
||||
InternalManager::~InternalManager()
|
||||
{
|
||||
#if defined( WITH_KPMCORE4API ) && !defined( WITH_KPMCORE42API )
|
||||
cDebug() << "Cleaning up KPMCore backend ..";
|
||||
|
||||
// From KPMcore 4.0 until KPMcore 4.2 we needed to stop
|
||||
// the helper by hand. KPMcore 4.2 ported to polkit directly,
|
||||
// which doesn't need a helper.
|
||||
auto backend_p = CoreBackendManager::self()->backend();
|
||||
if ( backend_p )
|
||||
{
|
||||
ExternalCommand::stopHelper();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::shared_ptr< InternalManager >
|
||||
getInternal()
|
||||
{
|
||||
|
@ -57,18 +57,10 @@ KPMTests::testFlagNames()
|
||||
|
||||
QCOMPARE( PartitionTable::flagName( static_cast< PartitionTable::Flag >( 1 ) ), QStringLiteral( "boot" ) );
|
||||
|
||||
#ifdef WITH_KPMCORE4API
|
||||
// KPMCore 4 unifies the flags and handles them internally
|
||||
QCOMPARE( PartitionTable::flagName( PartitionTable::Flag::Boot ), QStringLiteral( "boot" ) );
|
||||
QVERIFY( names.contains( QStringLiteral( "boot" ) ) );
|
||||
QVERIFY( !names.contains( QStringLiteral( "esp" ) ) );
|
||||
#else
|
||||
// KPMCore 3 has separate flags
|
||||
QCOMPARE( PartitionTable::flagName( PartitionTable::FlagBoot ), QStringLiteral( "boot" ) );
|
||||
QCOMPARE( PartitionTable::flagName( PartitionTable::FlagEsp ), QStringLiteral( "esp" ) );
|
||||
QVERIFY( names.contains( QStringLiteral( "boot" ) ) );
|
||||
QVERIFY( names.contains( QStringLiteral( "esp" ) ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -50,12 +50,7 @@ isPartitionFreeSpace( const Partition* partition )
|
||||
bool
|
||||
isPartitionNew( const Partition* partition )
|
||||
{
|
||||
#if defined( WITH_KPMCORE4API )
|
||||
constexpr auto NewState = Partition::State::New;
|
||||
#else
|
||||
constexpr auto NewState = Partition::StateNew;
|
||||
#endif
|
||||
return partition->state() == NewState;
|
||||
return partition->state() == Partition::State::New;
|
||||
}
|
||||
|
||||
|
||||
|
@ -230,7 +230,7 @@ System::createTargetParentDirs( const QString& filePath ) const
|
||||
}
|
||||
|
||||
|
||||
QPair< qint64, qreal >
|
||||
QPair< quint64, qreal >
|
||||
System::getTotalMemoryB() const
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
|
@ -337,7 +337,7 @@ public:
|
||||
*
|
||||
* @return size, guesstimate-factor
|
||||
*/
|
||||
DLLEXPORT QPair< qint64, qreal > getTotalMemoryB() const;
|
||||
DLLEXPORT QPair< quint64, qreal > getTotalMemoryB() const;
|
||||
|
||||
/**
|
||||
* @brief getCpuDescription returns a string describing the CPU.
|
||||
|
@ -16,6 +16,7 @@
|
||||
// #include "utils/CalamaresUtils.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/StringExpander.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
@ -67,6 +68,48 @@ get_variant_stringlist( const QVariantList& l )
|
||||
return retl;
|
||||
}
|
||||
|
||||
static Calamares::String::DictionaryExpander
|
||||
get_gs_expander( System::RunLocation location )
|
||||
{
|
||||
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
|
||||
Calamares::String::DictionaryExpander expander;
|
||||
|
||||
// Figure out the replacement for ${ROOT}
|
||||
if ( location == System::RunLocation::RunInTarget )
|
||||
{
|
||||
expander.insert( QStringLiteral( "ROOT" ), QStringLiteral( "/" ) );
|
||||
}
|
||||
else if ( gs && gs->contains( "rootMountPoint" ) )
|
||||
{
|
||||
expander.insert( QStringLiteral( "ROOT" ), gs->value( "rootMountPoint" ).toString() );
|
||||
}
|
||||
|
||||
// Replacement for ${USER}
|
||||
if ( gs && gs->contains( "username" ) )
|
||||
{
|
||||
expander.insert( QStringLiteral( "USER" ), gs->value( "username" ).toString() );
|
||||
}
|
||||
|
||||
return expander;
|
||||
}
|
||||
|
||||
CommandLine
|
||||
CommandLine::expand( KMacroExpanderBase& expander ) const
|
||||
{
|
||||
QString c = first;
|
||||
expander.expandMacrosShellQuote( c );
|
||||
return { c, second };
|
||||
}
|
||||
|
||||
CalamaresUtils::CommandLine
|
||||
CommandLine::expand() const
|
||||
{
|
||||
auto expander = get_gs_expander( System::RunLocation::RunInHost );
|
||||
return expand( expander );
|
||||
}
|
||||
|
||||
|
||||
CommandList::CommandList( bool doChroot, std::chrono::seconds timeout )
|
||||
: m_doChroot( doChroot )
|
||||
, m_timeout( timeout )
|
||||
@ -90,7 +133,7 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, std::ch
|
||||
}
|
||||
else if ( v.type() == QVariant::String )
|
||||
{
|
||||
append( v.toString() );
|
||||
append( { v.toString(), m_timeout } );
|
||||
}
|
||||
else if ( v.type() == QVariant::Map )
|
||||
{
|
||||
@ -107,61 +150,28 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, std::ch
|
||||
}
|
||||
}
|
||||
|
||||
CommandList::~CommandList() {}
|
||||
|
||||
static inline bool
|
||||
findInCommands( const CommandList& l, const QString& needle )
|
||||
{
|
||||
for ( CommandList::const_iterator i = l.cbegin(); i != l.cend(); ++i )
|
||||
if ( i->command().contains( needle ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
CommandList::run()
|
||||
{
|
||||
QLatin1String rootMagic( "@@ROOT@@" );
|
||||
QLatin1String userMagic( "@@USER@@" );
|
||||
|
||||
System::RunLocation location = m_doChroot ? System::RunLocation::RunInTarget : System::RunLocation::RunInHost;
|
||||
|
||||
/* Figure out the replacement for @@ROOT@@ */
|
||||
QString root = QStringLiteral( "/" );
|
||||
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
|
||||
bool needsRootSubstitution = findInCommands( *this, rootMagic );
|
||||
if ( needsRootSubstitution && ( location == System::RunLocation::RunInHost ) )
|
||||
auto expander = get_gs_expander( location );
|
||||
auto expandedList = expand( expander );
|
||||
if ( expander.hasErrors() )
|
||||
{
|
||||
if ( !gs || !gs->contains( "rootMountPoint" ) )
|
||||
{
|
||||
cError() << "No rootMountPoint defined.";
|
||||
return Calamares::JobResult::error(
|
||||
QCoreApplication::translate( "CommandList", "Could not run command." ),
|
||||
QCoreApplication::translate( "CommandList",
|
||||
"The command runs in the host environment and needs to know the root "
|
||||
"path, but no rootMountPoint is defined." ) );
|
||||
}
|
||||
root = gs->value( "rootMountPoint" ).toString();
|
||||
}
|
||||
|
||||
bool needsUserSubstitution = findInCommands( *this, userMagic );
|
||||
if ( needsUserSubstitution && ( !gs || !gs->contains( "username" ) ) )
|
||||
{
|
||||
cError() << "No username defined.";
|
||||
const auto missing = expander.errorNames();
|
||||
cError() << "Missing variables:" << missing;
|
||||
return Calamares::JobResult::error(
|
||||
QCoreApplication::translate( "CommandList", "Could not run command." ),
|
||||
QCoreApplication::translate( "CommandList",
|
||||
"The command needs to know the user's name, but no username is defined." ) );
|
||||
"The commands use variables that are not defined. "
|
||||
"Missing variables are: %1." )
|
||||
.arg( missing.join( ',' ) ) );
|
||||
}
|
||||
QString user = gs->value( "username" ).toString(); // may be blank if unset
|
||||
|
||||
for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i )
|
||||
for ( CommandList::const_iterator i = expandedList.cbegin(); i != expandedList.cend(); ++i )
|
||||
{
|
||||
QString processed_cmd = i->command();
|
||||
processed_cmd.replace( rootMagic, root ).replace( userMagic, user );
|
||||
bool suppress_result = false;
|
||||
if ( processed_cmd.startsWith( '-' ) )
|
||||
{
|
||||
@ -191,10 +201,24 @@ CommandList::run()
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
void
|
||||
CommandList::append( const QString& s )
|
||||
CommandList
|
||||
CommandList::expand( KMacroExpanderBase& expander ) const
|
||||
{
|
||||
append( CommandLine( s, m_timeout ) );
|
||||
// Copy and expand the list, collecting missing variables (so don't call expand())
|
||||
CommandList expandedList( m_doChroot, m_timeout );
|
||||
std::transform( cbegin(),
|
||||
cend(),
|
||||
std::back_inserter( expandedList ),
|
||||
[ &expander ]( const CommandLine& c ) { return c.expand( expander ); } );
|
||||
return expandedList;
|
||||
}
|
||||
|
||||
CommandList
|
||||
CommandList::expand() const
|
||||
{
|
||||
auto expander = get_gs_expander( System::RunLocation::RunInHost );
|
||||
return expand( expander );
|
||||
}
|
||||
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class KMacroExpanderBase;
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
|
||||
@ -50,6 +52,20 @@ struct CommandLine : public QPair< QString, std::chrono::seconds >
|
||||
std::chrono::seconds timeout() const { return second; }
|
||||
|
||||
bool isValid() const { return !first.isEmpty(); }
|
||||
|
||||
/** @brief Returns a copy of this one command, with variables expanded
|
||||
*
|
||||
* The given macro-expander is used to expand the command-line.
|
||||
* This will normally be a Calamares::String::DictionaryExpander
|
||||
* instance, which handles the ROOT and USER variables.
|
||||
*/
|
||||
CommandLine expand( KMacroExpanderBase& expander ) const;
|
||||
/** @brief As above, with a default macro-expander.
|
||||
*
|
||||
* The default macro-expander assumes RunInHost (e.g. ROOT will
|
||||
* expand to the RootMountPoint set in Global Storage).
|
||||
*/
|
||||
CommandLine expand() const;
|
||||
};
|
||||
|
||||
/** @brief Abbreviation, used internally. */
|
||||
@ -69,7 +85,6 @@ public:
|
||||
/** @brief empty command-list with timeout to apply to entries. */
|
||||
CommandList( bool doChroot = true, std::chrono::seconds timeout = std::chrono::seconds( 10 ) );
|
||||
CommandList( const QVariant& v, bool doChroot = true, std::chrono::seconds timeout = std::chrono::seconds( 10 ) );
|
||||
~CommandList();
|
||||
|
||||
bool doChroot() const { return m_doChroot; }
|
||||
|
||||
@ -81,10 +96,21 @@ public:
|
||||
using CommandList_t::const_iterator;
|
||||
using CommandList_t::count;
|
||||
using CommandList_t::isEmpty;
|
||||
using CommandList_t::push_back;
|
||||
using CommandList_t::value_type;
|
||||
|
||||
protected:
|
||||
using CommandList_t::append;
|
||||
void append( const QString& );
|
||||
/** @brief Return a copy of this command-list, with variables expanded
|
||||
*
|
||||
* Each command-line in the list is expanded with the given @p expander.
|
||||
* @see CommandLine::expand() for details.
|
||||
*/
|
||||
CommandList expand( KMacroExpanderBase& expander ) const;
|
||||
/** @brief As above, with a default macro-expander.
|
||||
*
|
||||
* Each command-line in the list is expanded with that default macro-expander.
|
||||
* @see CommandLine::expand() for details.
|
||||
*/
|
||||
CommandList expand() const;
|
||||
|
||||
private:
|
||||
bool m_doChroot;
|
||||
|
@ -53,7 +53,14 @@ setupLogLevel( unsigned int level )
|
||||
{
|
||||
level = LOGVERBOSE;
|
||||
}
|
||||
s_threshold = level + 1; // Comparison is < in log() function
|
||||
s_threshold = level + 1; // Comparison is < in logLevelEnabled() function
|
||||
}
|
||||
|
||||
unsigned int
|
||||
logLevel()
|
||||
{
|
||||
// Undo the +1 in setupLogLevel()
|
||||
return s_threshold > 0 ? s_threshold - 1 : 0;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -62,33 +69,40 @@ logLevelEnabled( unsigned int level )
|
||||
return level < s_threshold;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
logLevel()
|
||||
/** @brief Should we call the log_implementation() function with this level?
|
||||
*
|
||||
* The implementation logs everything for which logLevelEnabled() is
|
||||
* true to the file **and** to stdout; it logs everything at debug-level
|
||||
* or below to the file regardless.
|
||||
*/
|
||||
static inline bool
|
||||
log_enabled( unsigned int level )
|
||||
{
|
||||
return s_threshold > 0 ? s_threshold - 1 : 0;
|
||||
return level <= LOGDEBUG || logLevelEnabled( level );
|
||||
}
|
||||
|
||||
static void
|
||||
log( const char* msg, unsigned int debugLevel, bool withTime = true )
|
||||
log_implementation( const char* msg, unsigned int debugLevel, const bool withTime )
|
||||
{
|
||||
QMutexLocker lock( &s_mutex );
|
||||
|
||||
const auto date = QDate::currentDate().toString( Qt::ISODate );
|
||||
const auto time = QTime::currentTime().toString();
|
||||
|
||||
// If we don't format the date as a Qt::ISODate then we get a crash when
|
||||
// logging at exit as Qt tries to use QLocale to format, but QLocale is
|
||||
// on its way out.
|
||||
logfile << date.toUtf8().data() << " - " << time.toUtf8().data() << " [" << debugLevel << "]: " << msg << std::endl;
|
||||
|
||||
logfile.flush();
|
||||
|
||||
if ( logLevelEnabled( debugLevel ) )
|
||||
{
|
||||
QMutexLocker lock( &s_mutex );
|
||||
|
||||
// If we don't format the date as a Qt::ISODate then we get a crash when
|
||||
// logging at exit as Qt tries to use QLocale to format, but QLocale is
|
||||
// on its way out.
|
||||
logfile << QDate::currentDate().toString( Qt::ISODate ).toUtf8().data() << " - "
|
||||
<< QTime::currentTime().toString().toUtf8().data() << " ["
|
||||
<< QString::number( debugLevel ).toUtf8().data() << "]: " << msg << std::endl;
|
||||
|
||||
logfile.flush();
|
||||
|
||||
if ( withTime )
|
||||
{
|
||||
std::cout << QTime::currentTime().toString().toUtf8().data() << " ["
|
||||
<< QString::number( debugLevel ).toUtf8().data() << "]: ";
|
||||
std::cout << time.toUtf8().data() << " [" << debugLevel << "]: ";
|
||||
}
|
||||
// The endl is desired, since it also flushes (like the logfile, above)
|
||||
std::cout << msg << std::endl;
|
||||
}
|
||||
}
|
||||
@ -97,29 +111,30 @@ log( const char* msg, unsigned int debugLevel, bool withTime = true )
|
||||
static void
|
||||
CalamaresLogHandler( QtMsgType type, const QMessageLogContext&, const QString& msg )
|
||||
{
|
||||
static QMutex s_mutex;
|
||||
|
||||
QByteArray ba = msg.toUtf8();
|
||||
const char* message = ba.constData();
|
||||
|
||||
QMutexLocker locker( &s_mutex );
|
||||
|
||||
unsigned int level = LOGVERBOSE;
|
||||
switch ( type )
|
||||
{
|
||||
case QtInfoMsg:
|
||||
log( message, LOGVERBOSE );
|
||||
level = LOGVERBOSE;
|
||||
break;
|
||||
case QtDebugMsg:
|
||||
log( message, LOGDEBUG );
|
||||
level = LOGDEBUG;
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
log( message, LOGWARNING );
|
||||
level = LOGWARNING;
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
case QtFatalMsg:
|
||||
log( message, LOGERROR );
|
||||
level = LOGERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !log_enabled( level ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
log_implementation( msg.toUtf8().constData(), level, true );
|
||||
}
|
||||
|
||||
|
||||
@ -188,14 +203,14 @@ CDebug::CDebug( unsigned int debugLevel, const char* func )
|
||||
|
||||
CDebug::~CDebug()
|
||||
{
|
||||
if ( logLevelEnabled( m_debugLevel ) )
|
||||
if ( log_enabled( m_debugLevel ) )
|
||||
{
|
||||
if ( m_funcinfo )
|
||||
{
|
||||
m_msg.prepend( s_Continuation ); // Prepending, so back-to-front
|
||||
m_msg.prepend( m_funcinfo );
|
||||
}
|
||||
log( m_msg.toUtf8().data(), m_debugLevel, m_funcinfo );
|
||||
log_implementation( m_msg.toUtf8().data(), m_debugLevel, bool( m_funcinfo ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,6 @@
|
||||
* SPDX-FileCopyrightText: 2017-2018 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Based on KPluginFactory from KCoreAddons, KDE project
|
||||
* SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org>
|
||||
* SPDX-FileCopyrightText: 2007 Bernhard Loos <nhuh.put@web.de>
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*
|
||||
@ -16,81 +12,100 @@
|
||||
#ifndef UTILS_PLUGINFACTORY_H
|
||||
#define UTILS_PLUGINFACTORY_H
|
||||
|
||||
#include <KPluginFactory>
|
||||
#include <QObject>
|
||||
|
||||
#define CalamaresPluginFactory_iid "io.calamares.PluginFactory"
|
||||
|
||||
/** @brief Plugin factory for Calamares
|
||||
*
|
||||
* Try to re-use KPluginFactory as much as possible (since the
|
||||
* old code for PluginFactory was a fork of an old version of
|
||||
* exactly that).
|
||||
* A Calamares plugin contains just one kind of plugin -- either
|
||||
* a job, or a viewstep -- so the factory is straightforward.
|
||||
* It gets a single CreateInstanceFunction and calls that;
|
||||
* the function is set when registerPlugin() is called in a subclass.
|
||||
*
|
||||
* The current createInstance() method passes more arguments
|
||||
* to the job and viewstep constructors than we want; chasing
|
||||
* that change means modifying each Calamares module. This class
|
||||
* implements a version of createInstance() with fewer arguments
|
||||
* and overloads registerPlugin() to use that.
|
||||
*/
|
||||
class CalamaresPluginFactory : public KPluginFactory
|
||||
class CalamaresPluginFactory : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CalamaresPluginFactory()
|
||||
: KPluginFactory()
|
||||
{
|
||||
}
|
||||
explicit CalamaresPluginFactory() {}
|
||||
~CalamaresPluginFactory() override;
|
||||
|
||||
/** @brief Create an object from the factory.
|
||||
*
|
||||
* Ignores all the @p args since they are not used. Calls
|
||||
* Calamares constructors for the Jobs and ViewSteps.
|
||||
*/
|
||||
template < class impl, class ParentType >
|
||||
static QObject* createInstance( QWidget* parentWidget, QObject* parent, const QVariantList& args )
|
||||
typedef QObject* ( *CreateInstanceFunction )( QObject* );
|
||||
|
||||
template < class T >
|
||||
T* create( QObject* parent = nullptr )
|
||||
{
|
||||
Q_UNUSED( parentWidget )
|
||||
Q_UNUSED( args )
|
||||
ParentType* p = nullptr;
|
||||
if ( parent )
|
||||
auto* op = fn ? fn( parent ) : nullptr;
|
||||
if ( !op )
|
||||
{
|
||||
p = qobject_cast< ParentType* >( parent );
|
||||
Q_ASSERT( p );
|
||||
return nullptr;
|
||||
}
|
||||
return new impl( p );
|
||||
T* tp = qobject_cast< T* >( op );
|
||||
if ( !tp )
|
||||
{
|
||||
delete op;
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
/** @brief register a plugin
|
||||
*
|
||||
* The Calamares version doesn't accept keywords, and uses
|
||||
* the Calamares createInstance() version which ignores
|
||||
* the QVariantList of arguments.
|
||||
*/
|
||||
template < class T >
|
||||
void registerPlugin()
|
||||
{
|
||||
KPluginFactory::registerPlugin< T >( QString(), &createInstance< T, QObject > );
|
||||
}
|
||||
protected:
|
||||
CreateInstanceFunction fn = nullptr;
|
||||
};
|
||||
|
||||
/** @brief declare a Calamares Plugin Factory
|
||||
*
|
||||
* This would be defined as K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY,
|
||||
* except that does not actually use the base factory class that is
|
||||
* passed in.
|
||||
* There should be one declaration -- generally alongside the
|
||||
* class definition for the Job or ViewStep that the plugin is
|
||||
* going to provide, in the header -- and one definition -- in
|
||||
* the corresponding implementation.
|
||||
*/
|
||||
#define CALAMARES_PLUGIN_FACTORY_DECLARATION( name ) \
|
||||
class name : public CalamaresPluginFactory \
|
||||
{ \
|
||||
Q_OBJECT \
|
||||
Q_INTERFACES( KPluginFactory ) \
|
||||
Q_INTERFACES( CalamaresPluginFactory ) \
|
||||
Q_PLUGIN_METADATA( IID CalamaresPluginFactory_iid ) \
|
||||
public: \
|
||||
explicit name(); \
|
||||
~name() override; \
|
||||
template < class T > \
|
||||
static QObject* createInstance( QObject* parent ) \
|
||||
{ \
|
||||
return new T( parent ); \
|
||||
} \
|
||||
template < class T > \
|
||||
void registerPlugin() \
|
||||
{ \
|
||||
fn = createInstance< T >; \
|
||||
} \
|
||||
};
|
||||
|
||||
/** @brief Define a Calamares Plugin Factory
|
||||
*
|
||||
* This should be done exactly once, generally in the translation
|
||||
* unit containing the definitions for the main class of the plugin,
|
||||
* either the Job or the ViewStep definitions.
|
||||
*
|
||||
* The @p name must match the name used in the declaration, while
|
||||
* @p pluginRegistrations should be a single call to `registerPlugin<T>()`
|
||||
* where `T` is the type (subclass of Job or ViewStep) defined by the
|
||||
* plugin, eg.
|
||||
*
|
||||
* ```
|
||||
* CALAMARES_PLUGIN_FACTORY_DEFINITION( MyPlugin, registerPlugin<MyPluginJob>() )
|
||||
* ```
|
||||
*
|
||||
* Leaving out the `()` will lead to generally-weird compiler warnings.
|
||||
*/
|
||||
#define CALAMARES_PLUGIN_FACTORY_DEFINITION( name, pluginRegistrations ) \
|
||||
K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY( name, CalamaresPluginFactory, pluginRegistrations )
|
||||
name::name() \
|
||||
: CalamaresPluginFactory() \
|
||||
{ \
|
||||
pluginRegistrations; \
|
||||
} \
|
||||
name::~name() {}
|
||||
|
||||
Q_DECLARE_INTERFACE( CalamaresPluginFactory, CalamaresPluginFactory_iid )
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
QString
|
||||
removeDiacritics( const QString& string )
|
||||
@ -124,7 +126,7 @@ obscure( const QString& string )
|
||||
|
||||
|
||||
QString
|
||||
truncateMultiLine( const QString& string, CalamaresUtils::LinesStartEnd lines, CalamaresUtils::CharCount chars )
|
||||
truncateMultiLine( const QString& string, LinesStartEnd lines, CharCount chars )
|
||||
{
|
||||
const char NEWLINE = '\n';
|
||||
const int maxLines = lines.atStart + lines.atEnd;
|
||||
@ -246,4 +248,5 @@ removeTrailing( QString& string, QChar c )
|
||||
string.remove( lastIndex, string.length() );
|
||||
}
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace String
|
||||
} // namespace Calamares
|
||||
|
@ -42,10 +42,15 @@ constexpr static const auto SplitKeepEmptyParts =
|
||||
#endif
|
||||
;
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
/**
|
||||
* @brief The CalamaresUtils namespace contains utility functions.
|
||||
* @brief The Calamares::String namespace
|
||||
*
|
||||
* This namespace contains functions related to string-handling,
|
||||
* string-expansion, etc.
|
||||
*/
|
||||
namespace CalamaresUtils
|
||||
namespace String
|
||||
{
|
||||
/**
|
||||
* @brief removeDiacritics replaces letters with diacritics and ligatures with
|
||||
@ -113,6 +118,7 @@ DLLEXPORT void removeLeading( QString& string, QChar c );
|
||||
*/
|
||||
DLLEXPORT void removeTrailing( QString& string, QChar c );
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace String
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
||||
|
89
src/libcalamares/utils/StringExpander.cpp
Normal file
89
src/libcalamares/utils/StringExpander.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StringExpander.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
|
||||
struct DictionaryExpander::Private
|
||||
{
|
||||
QHash< QString, QString > dictionary;
|
||||
QStringList missing;
|
||||
};
|
||||
|
||||
DictionaryExpander::DictionaryExpander()
|
||||
: KWordMacroExpander( '$' )
|
||||
, d( std::make_unique< Private >() )
|
||||
{
|
||||
}
|
||||
|
||||
DictionaryExpander::DictionaryExpander( Calamares::String::DictionaryExpander&& other )
|
||||
: KWordMacroExpander( other.escapeChar() )
|
||||
, d( std::move( other.d ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DictionaryExpander::~DictionaryExpander() {}
|
||||
|
||||
|
||||
void
|
||||
DictionaryExpander::insert( const QString& key, const QString& value )
|
||||
{
|
||||
d->dictionary.insert( key, value );
|
||||
}
|
||||
|
||||
void
|
||||
DictionaryExpander::clearErrors()
|
||||
{
|
||||
d->missing.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DictionaryExpander::hasErrors() const
|
||||
{
|
||||
return !d->missing.isEmpty();
|
||||
}
|
||||
|
||||
QStringList
|
||||
DictionaryExpander::errorNames() const
|
||||
{
|
||||
return d->missing;
|
||||
}
|
||||
|
||||
QString
|
||||
DictionaryExpander::expand( QString s )
|
||||
{
|
||||
clearErrors();
|
||||
expandMacros( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
bool
|
||||
DictionaryExpander::expandMacro( const QString& str, QStringList& ret )
|
||||
{
|
||||
if ( d->dictionary.contains( str ) )
|
||||
{
|
||||
ret << d->dictionary[ str ];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->missing << str;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace String
|
||||
} // namespace Calamares
|
67
src/libcalamares/utils/StringExpander.h
Normal file
67
src/libcalamares/utils/StringExpander.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UTILS_STRINGEXPANDER_H
|
||||
#define UTILS_STRINGEXPANDER_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <KMacroExpander>
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
|
||||
/** @brief Expand variables in a string against a dictionary.
|
||||
*
|
||||
* This class provides a convenience API for building up a dictionary
|
||||
* and using it to expand strings. Use the `expand()` method to
|
||||
* do standard word-based expansion with `$` as macro-symbol.
|
||||
*
|
||||
* Unlike straight-up `KMacroExpander::expandMacros()`, this
|
||||
* provides an API to find out which variables were missing
|
||||
* from the dictionary during expansion. Use `hasErrors()` and
|
||||
* `errorNames()` to find out which variables those were.
|
||||
*
|
||||
* Call `clearErrors()` to reset the stored errors. Calling
|
||||
* `expand()` implicitly clears the errors before starting
|
||||
* a new expansion, as well.
|
||||
*/
|
||||
class DictionaryExpander : public KWordMacroExpander
|
||||
{
|
||||
public:
|
||||
DictionaryExpander();
|
||||
DictionaryExpander( DictionaryExpander&& );
|
||||
virtual ~DictionaryExpander() override;
|
||||
|
||||
void insert( const QString& key, const QString& value );
|
||||
|
||||
void clearErrors();
|
||||
bool hasErrors() const;
|
||||
QStringList errorNames() const;
|
||||
|
||||
QString expand( QString s );
|
||||
|
||||
protected:
|
||||
virtual bool expandMacro( const QString& str, QStringList& ret ) override;
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
std::unique_ptr< Private > d;
|
||||
};
|
||||
|
||||
} // namespace String
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
@ -10,11 +10,13 @@
|
||||
*/
|
||||
|
||||
#include "CalamaresUtilsSystem.h"
|
||||
#include "CommandList.h"
|
||||
#include "Entropy.h"
|
||||
#include "Logger.h"
|
||||
#include "RAII.h"
|
||||
#include "Runner.h"
|
||||
#include "String.h"
|
||||
#include "StringExpander.h"
|
||||
#include "Traits.h"
|
||||
#include "UMask.h"
|
||||
#include "Variant.h"
|
||||
@ -45,7 +47,10 @@ private Q_SLOTS:
|
||||
void testLoadSaveYaml(); // Just settings.conf
|
||||
void testLoadSaveYamlExtended(); // Do a find() in the src dir
|
||||
|
||||
/** @section Test running commands and command-expansion. */
|
||||
void testCommands();
|
||||
void testCommandExpansion_data();
|
||||
void testCommandExpansion(); // See also shellprocess tests
|
||||
|
||||
/** @section Test that all the UMask objects work correctly. */
|
||||
void testUmask();
|
||||
@ -75,6 +80,10 @@ private Q_SLOTS:
|
||||
void testStringRemoveTrailing_data();
|
||||
void testStringRemoveTrailing();
|
||||
|
||||
/** @section Test String expansion. */
|
||||
void testStringMacroExpander_data();
|
||||
void testStringMacroExpander(); // The KF5::CoreAddons bits
|
||||
|
||||
/** @section Test Runner directory-manipulation. */
|
||||
void testRunnerDirs();
|
||||
void testCalculateWorkingDirectory();
|
||||
@ -94,6 +103,16 @@ LibCalamaresTests::~LibCalamaresTests() {}
|
||||
void
|
||||
LibCalamaresTests::initTestCase()
|
||||
{
|
||||
Calamares::GlobalStorage* gs
|
||||
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
|
||||
if ( !gs )
|
||||
{
|
||||
cDebug() << "Creating new JobQueue";
|
||||
(void)new Calamares::JobQueue();
|
||||
gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
}
|
||||
QVERIFY( gs );
|
||||
}
|
||||
|
||||
void
|
||||
@ -251,6 +270,34 @@ LibCalamaresTests::testCommands()
|
||||
QVERIFY( r.getOutput().contains( tfn.fileName() ) );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testCommandExpansion_data()
|
||||
{
|
||||
QTest::addColumn< QString >( "command" );
|
||||
QTest::addColumn< QString >( "expected" );
|
||||
|
||||
QTest::newRow( "empty" ) << QString() << QString();
|
||||
QTest::newRow( "ls " ) << QStringLiteral( "ls" ) << QStringLiteral( "ls" );
|
||||
QTest::newRow( "user " ) << QStringLiteral( "chmod $USER" ) << QStringLiteral( "chmod alice" );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testCommandExpansion()
|
||||
{
|
||||
Calamares::GlobalStorage* gs
|
||||
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
QVERIFY( gs );
|
||||
gs->insert( QStringLiteral( "username" ), QStringLiteral( "alice" ) );
|
||||
|
||||
QFETCH( QString, command );
|
||||
QFETCH( QString, expected );
|
||||
CalamaresUtils::CommandLine c( command, std::chrono::seconds( 0 ) );
|
||||
CalamaresUtils::CommandLine e = c.expand();
|
||||
|
||||
QCOMPARE( c.command(), command );
|
||||
QCOMPARE( e.command(), expected );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testUmask()
|
||||
{
|
||||
@ -554,7 +601,7 @@ LibCalamaresTests::testStringTruncation()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
using namespace CalamaresUtils;
|
||||
using namespace Calamares::String;
|
||||
|
||||
const QString longString( R"(---
|
||||
--- src/libcalamares/utils/String.h
|
||||
@ -635,7 +682,7 @@ LibCalamaresTests::testStringTruncationShorter()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
using namespace CalamaresUtils;
|
||||
using namespace Calamares::String;
|
||||
|
||||
const QString longString( R"(Some strange string artifacts appeared, leading to `{1?}` being
|
||||
displayed in various user-facing messages. These have been removed
|
||||
@ -730,7 +777,7 @@ LibCalamaresTests::testStringTruncationDegenerate()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
using namespace CalamaresUtils;
|
||||
using namespace Calamares::String;
|
||||
|
||||
// This is quite long, 1 line only, with no newlines
|
||||
const QString longString( "The portscout new distfile checker has detected that one or more of your "
|
||||
@ -783,7 +830,7 @@ LibCalamaresTests::testStringRemoveLeading()
|
||||
QFETCH( QString, result );
|
||||
|
||||
const QString initial = string;
|
||||
CalamaresUtils::removeLeading( string, c );
|
||||
Calamares::String::removeLeading( string, c );
|
||||
QCOMPARE( string, result );
|
||||
}
|
||||
|
||||
@ -813,10 +860,64 @@ LibCalamaresTests::testStringRemoveTrailing()
|
||||
QFETCH( QString, result );
|
||||
|
||||
const QString initial = string;
|
||||
CalamaresUtils::removeTrailing( string, c );
|
||||
Calamares::String::removeTrailing( string, c );
|
||||
QCOMPARE( string, result );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testStringMacroExpander_data()
|
||||
{
|
||||
QTest::addColumn< QString >( "source" );
|
||||
QTest::addColumn< QString >( "result" );
|
||||
QTest::addColumn< QStringList >( "errors" );
|
||||
|
||||
QTest::newRow( "empty " ) << QString() << QString() << QStringList {};
|
||||
QTest::newRow( "constant" ) << QStringLiteral( "bunnies!" ) << QStringLiteral( "bunnies!" ) << QStringList {};
|
||||
QTest::newRow( "escaped " ) << QStringLiteral( "$$bun" ) << QStringLiteral( "$bun" )
|
||||
<< QStringList {}; // Double $$ is an escaped $
|
||||
QTest::newRow( "whole " ) << QStringLiteral( "${ROOT}" ) << QStringLiteral( "wortel" ) << QStringList {};
|
||||
QTest::newRow( "unbraced" ) << QStringLiteral( "$ROOT" ) << QStringLiteral( "wortel" )
|
||||
<< QStringList {}; // Does not need {}
|
||||
QTest::newRow( "bad-var1" ) << QStringLiteral( "${ROOF}" ) << QStringLiteral( "${ROOF}" )
|
||||
<< QStringList { QStringLiteral( "ROOF" ) }; // Not replaced
|
||||
QTest::newRow( "twice " ) << QStringLiteral( "${ROOT}x${ROOT}" ) << QStringLiteral( "wortelxwortel" )
|
||||
<< QStringList {};
|
||||
QTest::newRow( "bad-var2" ) << QStringLiteral( "${ROOT}x${ROPE}" ) << QStringLiteral( "wortelx${ROPE}" )
|
||||
<< QStringList { QStringLiteral( "ROPE" ) }; // Not replaced
|
||||
// This is a borked string with a "nested" variable. The variable-name-
|
||||
// scanner goes from ${ to the next } and tries to match that.
|
||||
QTest::newRow( "confuse1" ) << QStringLiteral( "${RO${ROOT}" ) << QStringLiteral( "${ROwortel" )
|
||||
<< QStringList { "RO${ROOT" };
|
||||
// This one doesn't have a { for the first name to match with
|
||||
QTest::newRow( "confuse2" ) << QStringLiteral( "$RO${ROOT}" ) << QStringLiteral( "$ROwortel" )
|
||||
<< QStringList { "RO" };
|
||||
// Here we see it just doesn't nest
|
||||
QTest::newRow( "confuse3" ) << QStringLiteral( "${RO${ROOT}}" ) << QStringLiteral( "${ROwortel}" )
|
||||
<< QStringList { "RO${ROOT" };
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testStringMacroExpander()
|
||||
{
|
||||
QHash< QString, QString > dict;
|
||||
dict.insert( QStringLiteral( "ROOT" ), QStringLiteral( "wortel" ) );
|
||||
|
||||
Calamares::String::DictionaryExpander d;
|
||||
d.insert( QStringLiteral( "ROOT" ), QStringLiteral( "wortel" ) );
|
||||
|
||||
QFETCH( QString, source );
|
||||
QFETCH( QString, result );
|
||||
QFETCH( QStringList, errors );
|
||||
|
||||
QString km_expanded = KMacroExpander::expandMacros( source, dict, '$' );
|
||||
QCOMPARE( km_expanded, result );
|
||||
|
||||
QString de_expanded = d.expand( source );
|
||||
QCOMPARE( de_expanded, result );
|
||||
QCOMPARE( d.errorNames(), errors );
|
||||
QCOMPARE( d.hasErrors(), !errors.isEmpty() );
|
||||
}
|
||||
|
||||
static QString
|
||||
dirname( const QTemporaryDir& d )
|
||||
{
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
/// @brief Type for expressing units
|
||||
using intunit_t = quint64;
|
||||
|
||||
namespace Units
|
||||
{
|
||||
@ -137,12 +139,19 @@ BytesToMiB( qint64 b )
|
||||
return int( b / 1024 / 1024 );
|
||||
}
|
||||
|
||||
// TODO: deprecate signed version
|
||||
constexpr int
|
||||
BytesToGiB( qint64 b )
|
||||
{
|
||||
return int( b / 1024 / 1024 / 1024 );
|
||||
}
|
||||
|
||||
constexpr intunit_t
|
||||
BytesToGiB( intunit_t b )
|
||||
{
|
||||
return b / 1024 / 1024 / 1024;
|
||||
}
|
||||
|
||||
constexpr qint64
|
||||
alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
|
||||
{
|
||||
|
@ -76,10 +76,8 @@ public:
|
||||
{
|
||||
SidebarBackground,
|
||||
SidebarText,
|
||||
SidebarTextSelect,
|
||||
SidebarTextSelected = SidebarTextSelect, // TODO:3.3:Remove SidebarTextSelect
|
||||
SidebarTextHighlight,
|
||||
SidebarBackgroundSelected = SidebarTextHighlight // TODO:3.3:Remove SidebarTextHighlight
|
||||
SidebarTextCurrent,
|
||||
SidebarBackgroundCurrent,
|
||||
};
|
||||
Q_ENUM( StyleEntry )
|
||||
|
||||
|
@ -8,24 +8,21 @@
|
||||
# view modules, view steps, widgets, and branding.
|
||||
|
||||
# The UI libs use the non-UI library
|
||||
include_directories( ${CMAKE_SOURCE_DIR}/src/libcalamares ${CMAKE_BINARY_DIR}/src/libcalamares ${CMAKE_SOURCE_DIR} )
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/libcalamares ${CMAKE_BINARY_DIR}/src/libcalamares ${CMAKE_SOURCE_DIR})
|
||||
|
||||
set( calamaresui_SOURCES
|
||||
set(calamaresui_SOURCES
|
||||
modulesystem/CppJobModule.cpp
|
||||
modulesystem/ModuleFactory.cpp
|
||||
modulesystem/ModuleManager.cpp
|
||||
modulesystem/ProcessJobModule.cpp
|
||||
modulesystem/ViewModule.cpp
|
||||
|
||||
utils/CalamaresUtilsGui.cpp
|
||||
utils/ImageRegistry.cpp
|
||||
utils/Paste.cpp
|
||||
|
||||
viewpages/BlankViewStep.cpp
|
||||
viewpages/ExecutionViewStep.cpp
|
||||
viewpages/Slideshow.cpp
|
||||
viewpages/ViewStep.cpp
|
||||
|
||||
widgets/ClickableLabel.cpp
|
||||
widgets/ErrorDialog.cpp
|
||||
widgets/FixedAspectRatioLabel.cpp
|
||||
@ -33,42 +30,20 @@ set( calamaresui_SOURCES
|
||||
widgets/LogWidget.cpp
|
||||
widgets/TranslationFix.cpp
|
||||
widgets/WaitingWidget.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp
|
||||
|
||||
widgets/waitingspinnerwidget.cpp
|
||||
Branding.cpp
|
||||
ViewManager.cpp
|
||||
)
|
||||
|
||||
# Don't warn about third-party sources
|
||||
mark_thirdparty_code(
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp
|
||||
)
|
||||
|
||||
if( WITH_PYTHON )
|
||||
list( APPEND calamaresui_SOURCES
|
||||
modulesystem/PythonJobModule.cpp
|
||||
)
|
||||
if(WITH_PYTHON)
|
||||
list(APPEND calamaresui_SOURCES modulesystem/PythonJobModule.cpp)
|
||||
endif()
|
||||
|
||||
if( WITH_PYTHONQT )
|
||||
list( APPEND calamaresui_SOURCES
|
||||
modulesystem/PythonQtViewModule.cpp
|
||||
utils/PythonQtUtils.cpp
|
||||
viewpages/PythonQtJob.cpp
|
||||
viewpages/PythonQtViewStep.cpp
|
||||
viewpages/PythonQtGlobalStorageWrapper.cpp
|
||||
viewpages/PythonQtUtilsWrapper.cpp
|
||||
)
|
||||
if(WITH_QML)
|
||||
list(APPEND calamaresui_SOURCES utils/Qml.cpp viewpages/QmlViewStep.cpp)
|
||||
endif()
|
||||
|
||||
if( WITH_QML )
|
||||
list( APPEND calamaresui_SOURCES
|
||||
utils/Qml.cpp
|
||||
viewpages/QmlViewStep.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
calamares_add_library( calamaresui
|
||||
calamares_add_library(calamaresui
|
||||
SOURCES ${calamaresui_SOURCES}
|
||||
EXPORT_MACRO UIDLLEXPORT_PRO
|
||||
LINK_LIBRARIES
|
||||
@ -79,22 +54,17 @@ calamares_add_library( calamaresui
|
||||
utils/ErrorDialog/ErrorDialog.ui
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
)
|
||||
target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp )
|
||||
if( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 )
|
||||
target_compile_definitions( calamaresui PRIVATE WITH_KOSRelease )
|
||||
target_link_libraries(calamaresui PRIVATE yamlcpp::yamlcpp)
|
||||
if(KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58)
|
||||
target_compile_definitions(calamaresui PRIVATE WITH_KOSRelease)
|
||||
target_link_libraries(calamaresui PRIVATE KF5::CoreAddons)
|
||||
endif()
|
||||
if( WITH_PYTHONQT )
|
||||
# *_DIRS because we also use extensions
|
||||
target_include_directories( calamaresui PRIVATE ${PYTHON_INCLUDE_DIRS} ${PYTHONQT_INCLUDE_DIRS} )
|
||||
target_link_libraries( calamaresui PRIVATE ${PYTHON_LIBRARIES} ${PYTHONQT_LIBRARIES} )
|
||||
endif()
|
||||
if( WITH_QML )
|
||||
target_link_libraries( calamaresui PUBLIC Qt5::QuickWidgets )
|
||||
if(WITH_QML)
|
||||
target_link_libraries(calamaresui PUBLIC Qt5::QuickWidgets)
|
||||
endif()
|
||||
|
||||
add_library(Calamares::calamaresui ALIAS calamaresui)
|
||||
|
||||
|
||||
### Installation
|
||||
#
|
||||
#
|
||||
@ -103,24 +73,12 @@ add_library(Calamares::calamaresui ALIAS calamaresui)
|
||||
# where libcalamares and libcalamaresui live in different branches,
|
||||
# we're going to glom it all together in the installed headers location.
|
||||
|
||||
install(
|
||||
FILES
|
||||
Branding.h
|
||||
ViewManager.h
|
||||
DESTINATION include/libcalamares
|
||||
)
|
||||
install(FILES Branding.h ViewManager.h DESTINATION include/libcalamares)
|
||||
|
||||
# Install each subdir-worth of header files
|
||||
foreach( subdir modulesystem utils viewpages widgets )
|
||||
file( GLOB subdir_headers "${subdir}/*.h" )
|
||||
install( FILES ${subdir_headers} DESTINATION include/libcalamares/${subdir} )
|
||||
foreach(subdir modulesystem utils viewpages widgets)
|
||||
file(GLOB subdir_headers "${subdir}/*.h")
|
||||
install(FILES ${subdir_headers} DESTINATION include/libcalamares/${subdir})
|
||||
endforeach()
|
||||
|
||||
calamares_add_test(
|
||||
test_libcalamaresuipaste
|
||||
SOURCES
|
||||
utils/TestPaste.cpp
|
||||
utils/Paste.cpp
|
||||
LIBRARIES
|
||||
calamaresui
|
||||
)
|
||||
calamares_add_test(test_libcalamaresuipaste SOURCES utils/TestPaste.cpp utils/Paste.cpp LIBRARIES calamaresui)
|
||||
|
@ -24,10 +24,6 @@
|
||||
#include "PythonJobModule.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHONQT
|
||||
#include "PythonQtViewModule.h"
|
||||
#endif
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@ -59,14 +55,6 @@ moduleFromDescriptor( const Calamares::ModuleSystem::Descriptor& moduleDescripto
|
||||
{
|
||||
m.reset( new ViewModule() );
|
||||
}
|
||||
else if ( moduleDescriptor.interface() == Interface::PythonQt )
|
||||
{
|
||||
#ifdef WITH_PYTHONQT
|
||||
m.reset( new PythonQtViewModule() );
|
||||
#else
|
||||
cError() << "PythonQt view modules are not supported in this version of Calamares.";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
cError() << "Bad interface"
|
||||
|
@ -349,7 +349,18 @@ ModuleManager::checkRequirements()
|
||||
connect( rq,
|
||||
&RequirementsChecker::done,
|
||||
this,
|
||||
[ = ]() { this->requirementsComplete( m_requirementsModel->satisfiedMandatory() ); } );
|
||||
[ = ]()
|
||||
{
|
||||
if ( m_requirementsModel->satisfiedMandatory() )
|
||||
{
|
||||
/* we're done */ this->requirementsComplete( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->requirementsComplete( false );
|
||||
QTimer::singleShot( std::chrono::seconds( 5 ), this, &ModuleManager::checkRequirements );
|
||||
}
|
||||
} );
|
||||
|
||||
QTimer::singleShot( 0, rq, &RequirementsChecker::run );
|
||||
}
|
||||
|
@ -1,184 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Raul Rodrigo Segura <raurodse@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtViewModule.h"
|
||||
|
||||
#include "CalamaresConfig.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "ViewManager.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "viewpages/PythonQtGlobalStorageWrapper.h"
|
||||
#include "viewpages/PythonQtUtilsWrapper.h"
|
||||
#include "viewpages/PythonQtViewStep.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include <PythonQt.h>
|
||||
#include <PythonQt_QtAll.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
static QPointer< GlobalStorage > s_gs = nullptr;
|
||||
static QPointer< Utils > s_utils = nullptr;
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
Module::Type
|
||||
PythonQtViewModule::type() const
|
||||
{
|
||||
return Module::Type::View;
|
||||
}
|
||||
|
||||
|
||||
Module::Interface
|
||||
PythonQtViewModule::interface() const
|
||||
{
|
||||
return Module::Interface::PythonQt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonQtViewModule::loadSelf()
|
||||
{
|
||||
if ( !m_scriptFileName.isEmpty() )
|
||||
{
|
||||
if ( PythonQt::self() == nullptr )
|
||||
{
|
||||
if ( Py_IsInitialized() )
|
||||
PythonQt::init( PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut
|
||||
| PythonQt::PythonAlreadyInitialized );
|
||||
else
|
||||
{
|
||||
PythonQt::init();
|
||||
}
|
||||
|
||||
PythonQt_QtAll::init();
|
||||
cDebug() << "Initializing PythonQt bindings."
|
||||
<< "This should only happen once.";
|
||||
|
||||
//TODO: register classes here into the PythonQt environment, like this:
|
||||
//PythonQt::self()->registerClass( &PythonQtViewStep::staticMetaObject,
|
||||
// "calamares" );
|
||||
|
||||
// We only do the following to force PythonQt to create a submodule
|
||||
// "calamares" for us to put our static objects in
|
||||
PythonQt::self()->registerClass( &::GlobalStorage::staticMetaObject, "calamares" );
|
||||
|
||||
// Get a PythonQtObjectPtr to the PythonQt.calamares submodule
|
||||
PythonQtObjectPtr pqtm = PythonQt::priv()->pythonQtModule();
|
||||
PythonQtObjectPtr cala = PythonQt::self()->lookupObject( pqtm, "calamares" );
|
||||
|
||||
// Prepare GlobalStorage object, in module PythonQt.calamares
|
||||
if ( !s_gs )
|
||||
{
|
||||
s_gs = new ::GlobalStorage( Calamares::JobQueue::instance()->globalStorage() );
|
||||
}
|
||||
cala.addObject( "global_storage", s_gs );
|
||||
|
||||
// Prepare Utils object, in module PythonQt.calamares
|
||||
if ( !s_utils )
|
||||
{
|
||||
s_utils = new ::Utils( Calamares::JobQueue::instance()->globalStorage() );
|
||||
}
|
||||
cala.addObject( "utils", s_utils );
|
||||
|
||||
// Append configuration object, in module PythonQt.calamares
|
||||
cala.addVariable( "configuration", m_configurationMap );
|
||||
|
||||
// Basic stdout/stderr handling
|
||||
QObject::connect( PythonQt::self(),
|
||||
&PythonQt::pythonStdOut,
|
||||
[]( const QString& message ) { cDebug() << "PythonQt OUT>" << message; } );
|
||||
QObject::connect( PythonQt::self(),
|
||||
&PythonQt::pythonStdErr,
|
||||
[]( const QString& message ) { cDebug() << "PythonQt ERR>" << message; } );
|
||||
}
|
||||
|
||||
QDir workingDir( m_workingPath );
|
||||
if ( !workingDir.exists() )
|
||||
{
|
||||
cDebug() << "Invalid working directory" << m_workingPath << "for module" << name();
|
||||
return;
|
||||
}
|
||||
|
||||
QString fullPath = workingDir.absoluteFilePath( m_scriptFileName );
|
||||
QFileInfo scriptFileInfo( fullPath );
|
||||
if ( !scriptFileInfo.isReadable() )
|
||||
{
|
||||
cDebug() << "Invalid main script file path" << fullPath << "for module" << name();
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct empty Python module with the given name
|
||||
PythonQtObjectPtr cxt = PythonQt::self()->createModuleFromScript( name() );
|
||||
if ( cxt.isNull() )
|
||||
{
|
||||
cDebug() << "Cannot load PythonQt context from file" << fullPath << "for module" << name();
|
||||
return;
|
||||
}
|
||||
|
||||
static const QLatin1String calamares_module_annotation(
|
||||
"_calamares_module_typename = ''\n"
|
||||
"def calamares_module(viewmodule_type):\n"
|
||||
" global _calamares_module_typename\n"
|
||||
" _calamares_module_typename = viewmodule_type.__name__\n"
|
||||
" return viewmodule_type\n" );
|
||||
|
||||
// Load in the decorator
|
||||
PythonQt::self()->evalScript( cxt, calamares_module_annotation );
|
||||
|
||||
// Load the module
|
||||
PythonQt::self()->evalFile( cxt, fullPath );
|
||||
|
||||
m_viewStep = new PythonQtViewStep( cxt );
|
||||
|
||||
cDebug() << "PythonQtViewModule loading self for instance" << instanceKey() << "\nPythonQtViewModule at address"
|
||||
<< this << "\nViewStep at address" << m_viewStep;
|
||||
|
||||
m_viewStep->setModuleInstanceKey( instanceKey() );
|
||||
m_viewStep->setConfigurationMap( m_configurationMap );
|
||||
ViewManager::instance()->addViewStep( m_viewStep );
|
||||
m_loaded = true;
|
||||
cDebug() << "PythonQtViewModule" << instanceKey() << "loading complete.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JobList
|
||||
PythonQtViewModule::jobs() const
|
||||
{
|
||||
return m_viewStep->jobs();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonQtViewModule::initFrom( const QVariantMap& moduleDescriptor )
|
||||
{
|
||||
QDir directory( location() );
|
||||
m_workingPath = directory.absolutePath();
|
||||
|
||||
if ( !moduleDescriptor.value( "script" ).toString().isEmpty() )
|
||||
{
|
||||
m_scriptFileName = moduleDescriptor.value( "script" ).toString();
|
||||
}
|
||||
}
|
||||
|
||||
PythonQtViewModule::PythonQtViewModule()
|
||||
: Module()
|
||||
{
|
||||
}
|
||||
|
||||
PythonQtViewModule::~PythonQtViewModule() {}
|
||||
|
||||
} // namespace Calamares
|
@ -1,50 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALAMARES_PYTHONQTVIEWMODULE_H
|
||||
#define CALAMARES_PYTHONQTVIEWMODULE_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "Module.h"
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class ViewStep;
|
||||
|
||||
class UIDLLEXPORT PythonQtViewModule : public Module
|
||||
{
|
||||
public:
|
||||
Type type() const override;
|
||||
Interface interface() const override;
|
||||
|
||||
void loadSelf() override;
|
||||
JobList jobs() const override;
|
||||
|
||||
protected:
|
||||
void initFrom( const QVariantMap& moduleDescriptor ) override;
|
||||
|
||||
private:
|
||||
explicit PythonQtViewModule();
|
||||
virtual ~PythonQtViewModule();
|
||||
|
||||
ViewStep* m_viewStep = nullptr;
|
||||
|
||||
QString m_scriptFileName;
|
||||
QString m_workingPath;
|
||||
|
||||
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
|
||||
const QString& instanceId,
|
||||
const QString& configFileName,
|
||||
const QString& moduleDirectory );
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_PYTHONQTVIEWMODULE_H
|
@ -128,62 +128,12 @@ defaultPixmap( ImageType type, ImageMode mode, const QSize& size )
|
||||
}
|
||||
|
||||
|
||||
QPixmap
|
||||
createRoundedImage( const QPixmap& pixmap, const QSize& size, float frameWidthPct )
|
||||
{
|
||||
int height;
|
||||
int width;
|
||||
|
||||
if ( !size.isEmpty() )
|
||||
{
|
||||
height = size.height();
|
||||
width = size.width();
|
||||
}
|
||||
else
|
||||
{
|
||||
height = pixmap.height();
|
||||
width = pixmap.width();
|
||||
}
|
||||
|
||||
if ( !height || !width )
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QPixmap scaledAvatar = pixmap.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
if ( frameWidthPct == 0.00f )
|
||||
{
|
||||
return scaledAvatar;
|
||||
}
|
||||
|
||||
QPixmap frame( width, height );
|
||||
frame.fill( Qt::transparent );
|
||||
|
||||
QPainter painter( &frame );
|
||||
painter.setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
QRect outerRect( 0, 0, width, height );
|
||||
QBrush brush( scaledAvatar );
|
||||
QPen pen;
|
||||
pen.setColor( Qt::transparent );
|
||||
pen.setJoinStyle( Qt::RoundJoin );
|
||||
|
||||
painter.setBrush( brush );
|
||||
painter.setPen( pen );
|
||||
painter.drawRoundedRect(
|
||||
outerRect, qreal( frameWidthPct ) * 100.0, qreal( frameWidthPct ) * 100.0, Qt::RelativeSize );
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
unmarginLayout( QLayout* layout )
|
||||
{
|
||||
if ( layout )
|
||||
{
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
layout->setMargin( 0 );
|
||||
layout->setSpacing( 0 );
|
||||
|
||||
for ( int i = 0; i < layout->count(); i++ )
|
||||
@ -224,15 +174,6 @@ defaultFontHeight()
|
||||
}
|
||||
|
||||
|
||||
QFont
|
||||
defaultFont()
|
||||
{
|
||||
QFont f;
|
||||
f.setPointSize( defaultFontSize() );
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
QFont
|
||||
largeFont()
|
||||
{
|
||||
@ -257,24 +198,4 @@ defaultIconSize()
|
||||
return QSize( w, w );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
clearLayout( QLayout* layout )
|
||||
{
|
||||
while ( QLayoutItem* item = layout->takeAt( 0 ) )
|
||||
{
|
||||
if ( QWidget* widget = item->widget() )
|
||||
{
|
||||
widget->deleteLater();
|
||||
}
|
||||
|
||||
if ( QLayout* childLayout = item->layout() )
|
||||
{
|
||||
clearLayout( childLayout );
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -63,7 +63,6 @@ enum ImageMode
|
||||
CoverInCase,
|
||||
Grid,
|
||||
DropShadow,
|
||||
RoundedCorners
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,35 +77,15 @@ UIDLLEXPORT QPixmap defaultPixmap( ImageType type,
|
||||
ImageMode mode = CalamaresUtils::Original,
|
||||
const QSize& size = QSize( 0, 0 ) );
|
||||
|
||||
// TODO:3.3:This has only one consumer, move to ImageRegistry, make static
|
||||
/**
|
||||
* @brief createRoundedImage returns a rounded version of a pixmap.
|
||||
* @param avatar the input pixmap.
|
||||
* @param size the new size.
|
||||
* @param frameWidthPct the frame size, as percentage of width.
|
||||
* @return the transformed pixmap.
|
||||
* This one is currently unused.
|
||||
*/
|
||||
UIDLLEXPORT QPixmap createRoundedImage( const QPixmap& avatar, const QSize& size, float frameWidthPct = 0.20f );
|
||||
|
||||
/**
|
||||
* @brief unmarginLayout recursively walks the QLayout tree and removes all margins.
|
||||
* @param layout the layout to unmargin.
|
||||
*/
|
||||
UIDLLEXPORT void unmarginLayout( QLayout* layout );
|
||||
|
||||
// TODO:3.3:This has only one consumer, move to LicensePage, make static
|
||||
/**
|
||||
* @brief clearLayout recursively walks the QLayout tree and deletes all the child
|
||||
* widgets and layouts.
|
||||
* @param layout the layout to clear.
|
||||
*/
|
||||
UIDLLEXPORT void clearLayout( QLayout* layout );
|
||||
|
||||
UIDLLEXPORT void setDefaultFontSize( int points );
|
||||
UIDLLEXPORT int defaultFontSize(); // in points
|
||||
UIDLLEXPORT int defaultFontHeight(); // in pixels, DPI-specific
|
||||
UIDLLEXPORT QFont defaultFont(); // TODO:3.3:This has one consumer, move to BlankViewStep
|
||||
UIDLLEXPORT QFont largeFont();
|
||||
UIDLLEXPORT QSize defaultIconSize();
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ImageRegistry.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
#include <QSvgRenderer>
|
||||
@ -89,11 +90,6 @@ ImageRegistry::pixmap( const QString& image, const QSize& size, CalamaresUtils::
|
||||
|
||||
if ( !pixmap.isNull() )
|
||||
{
|
||||
if ( mode == CalamaresUtils::RoundedCorners )
|
||||
{
|
||||
pixmap = CalamaresUtils::createRoundedImage( pixmap, size );
|
||||
}
|
||||
|
||||
if ( !size.isNull() && pixmap.size() != size )
|
||||
{
|
||||
if ( size.width() == 0 )
|
||||
|
@ -1,37 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtUtils.h"
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
|
||||
QVariant
|
||||
lookupAndCall( PyObject* object,
|
||||
const QStringList& candidateNames,
|
||||
const QVariantList& args,
|
||||
const QVariantMap& kwargs )
|
||||
{
|
||||
Q_ASSERT( object );
|
||||
Q_ASSERT( !candidateNames.isEmpty() );
|
||||
|
||||
for ( const QString& name : candidateNames )
|
||||
{
|
||||
PythonQtObjectPtr callable = PythonQt::self()->lookupCallable( object, name );
|
||||
if ( callable )
|
||||
{
|
||||
return callable.call( args, kwargs );
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't found a callable with the given names, we force an error:
|
||||
return PythonQt::self()->call( object, candidateNames.first(), args, kwargs );
|
||||
}
|
||||
|
||||
} // namespace CalamaresUtils
|
@ -1,29 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PYTHONQTUTILS_H
|
||||
#define PYTHONQTUTILS_H
|
||||
|
||||
#include <PythonQt.h>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
//NOTE: when running this, it is assumed that Python is initialized and
|
||||
// PythonQt::self() is valid.
|
||||
QVariant lookupAndCall( PyObject* object,
|
||||
const QStringList& candidateNames,
|
||||
const QVariantList& args = QVariantList(),
|
||||
const QVariantMap& kwargs = QVariantMap() );
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif // PYTHONQTUTILS_H
|
@ -1,61 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtGlobalStorageWrapper.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
|
||||
|
||||
GlobalStorage::GlobalStorage( Calamares::GlobalStorage* gs )
|
||||
: QObject( gs )
|
||||
, m_gs( gs )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GlobalStorage::contains( const QString& key ) const
|
||||
{
|
||||
return m_gs->contains( key );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GlobalStorage::count() const
|
||||
{
|
||||
return m_gs->count();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GlobalStorage::insert( const QString& key, const QVariant& value )
|
||||
{
|
||||
m_gs->insert( key, value );
|
||||
}
|
||||
|
||||
|
||||
QStringList
|
||||
GlobalStorage::keys() const
|
||||
{
|
||||
return m_gs->keys();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GlobalStorage::remove( const QString& key )
|
||||
{
|
||||
return m_gs->remove( key );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
GlobalStorage::value( const QString& key ) const
|
||||
{
|
||||
return m_gs->value( key );
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PYTHONQTGLOBALSTORAGEWRAPPER_H
|
||||
#define PYTHONQTGLOBALSTORAGEWRAPPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
class GlobalStorage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This GlobalStorage class is a namespace-free wrapper for
|
||||
* Calamares::GlobalStorage. This is unfortunately a necessity
|
||||
* because PythonQt doesn't like namespaces.
|
||||
*/
|
||||
class GlobalStorage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GlobalStorage( Calamares::GlobalStorage* gs );
|
||||
virtual ~GlobalStorage() {}
|
||||
|
||||
public slots:
|
||||
bool contains( const QString& key ) const;
|
||||
int count() const;
|
||||
void insert( const QString& key, const QVariant& value );
|
||||
QStringList keys() const;
|
||||
int remove( const QString& key );
|
||||
QVariant value( const QString& key ) const;
|
||||
|
||||
private:
|
||||
Calamares::GlobalStorage* m_gs;
|
||||
};
|
||||
|
||||
#endif // PYTHONQTGLOBALSTORAGEWRAPPER_H
|
@ -1,62 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtJob.h"
|
||||
|
||||
#include "utils/PythonQtUtils.h"
|
||||
|
||||
PythonQtJob::PythonQtJob( PythonQtObjectPtr cxt, PythonQtObjectPtr pyJob, QObject* parent )
|
||||
: Calamares::Job( parent )
|
||||
, m_cxt( cxt )
|
||||
, m_pyJob( pyJob )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
PythonQtJob::prettyName() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_pyJob, { "prettyName", "prettyname", "pretty_name" } ).toString();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
PythonQtJob::prettyDescription() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_pyJob, { "prettyDescription", "prettydescription", "pretty_description" } )
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
PythonQtJob::prettyStatusMessage() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_pyJob,
|
||||
{ "prettyStatusMessage", "prettystatusmessage", "pretty_status_message" } )
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
||||
Calamares::JobResult
|
||||
PythonQtJob::exec()
|
||||
{
|
||||
QVariant response = m_pyJob.call( "exec" );
|
||||
if ( response.isNull() )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
QVariantMap map = response.toMap();
|
||||
if ( map.isEmpty() || map.value( "ok" ).toBool() )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( map.value( "message" ).toString(), map.value( "details" ).toString() );
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PYTHONQTJOB_H
|
||||
#define PYTHONQTJOB_H
|
||||
|
||||
#include "Job.h"
|
||||
|
||||
#include <PythonQt.h>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
class PythonQtViewStep;
|
||||
}
|
||||
|
||||
class PythonQtJobResult : public QObject, public Calamares::JobResult
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PythonQtJobResult( bool ok, const QString& message, const QString& details )
|
||||
: QObject( nullptr )
|
||||
, Calamares::JobResult( message, details, ok ? 0 : Calamares::JobResult::GenericError )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PythonQtJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~PythonQtJob() {}
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyDescription() const override;
|
||||
QString prettyStatusMessage() const override;
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
private:
|
||||
explicit PythonQtJob( PythonQtObjectPtr cxt, PythonQtObjectPtr pyJob, QObject* parent = nullptr );
|
||||
friend class Calamares::PythonQtViewStep; // only this one can call the ctor
|
||||
|
||||
PythonQtObjectPtr m_cxt;
|
||||
PythonQtObjectPtr m_pyJob;
|
||||
};
|
||||
|
||||
#endif // PYTHONQTJOB_H
|
@ -1,116 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtUtilsWrapper.h"
|
||||
|
||||
#include "partition/Mount.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/String.h"
|
||||
|
||||
#include <PythonQt.h>
|
||||
|
||||
|
||||
Utils::Utils( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_exceptionCxt( PythonQt::self()->createUniqueModule() )
|
||||
{
|
||||
PythonQt::self()->evalScript( m_exceptionCxt, "import subprocess" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Utils::debug( const QString& s ) const
|
||||
{
|
||||
cDebug() << "PythonQt DBG>" << s;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::mount( const QString& device_path,
|
||||
const QString& mount_point,
|
||||
const QString& filesystem_name,
|
||||
const QString& options ) const
|
||||
{
|
||||
return CalamaresUtils::Partition::mount( device_path, mount_point, filesystem_name, options );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::target_env_call( const QString& command, const QString& stdin, int timeout ) const
|
||||
{
|
||||
return CalamaresUtils::System::instance()->targetEnvCall(
|
||||
command, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::target_env_call( const QStringList& args, const QString& stdin, int timeout ) const
|
||||
{
|
||||
return CalamaresUtils::System::instance()->targetEnvCall(
|
||||
args, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::check_target_env_call( const QString& command, const QString& stdin, int timeout ) const
|
||||
{
|
||||
int ec = target_env_call( command, stdin, timeout );
|
||||
return _handle_check_target_env_call_error( ec, command );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::check_target_env_call( const QStringList& args, const QString& stdin, int timeout ) const
|
||||
{
|
||||
int ec = target_env_call( args, stdin, timeout );
|
||||
return _handle_check_target_env_call_error( ec, args.join( ' ' ) );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Utils::check_target_env_output( const QString& command, const QString& stdin, int timeout ) const
|
||||
{
|
||||
QString output;
|
||||
int ec = CalamaresUtils::System::instance()->targetEnvOutput(
|
||||
command, output, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
|
||||
_handle_check_target_env_call_error( ec, command );
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Utils::check_target_env_output( const QStringList& args, const QString& stdin, int timeout ) const
|
||||
{
|
||||
QString output;
|
||||
int ec = CalamaresUtils::System::instance()->targetEnvOutput(
|
||||
args, output, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
|
||||
_handle_check_target_env_call_error( ec, args.join( ' ' ) );
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Utils::obscure( const QString& string ) const
|
||||
{
|
||||
return CalamaresUtils::obscure( string );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Utils::_handle_check_target_env_call_error( int ec, const QString& cmd ) const
|
||||
{
|
||||
if ( ec )
|
||||
{
|
||||
QString raise = QString( "raise subprocess.CalledProcessError(%1,\"%2\")" ).arg( ec ).arg( cmd );
|
||||
PythonQt::self()->evalScript( m_exceptionCxt, raise );
|
||||
}
|
||||
return ec;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PYTHONQTUTILSWRAPPER_H
|
||||
#define PYTHONQTUTILSWRAPPER_H
|
||||
|
||||
#include <PythonQtObjectPtr.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Utils class wraps around functions from CalamaresUtils to make them
|
||||
* available in the PythonQt interface.
|
||||
*/
|
||||
class Utils : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Utils( QObject* parent = nullptr );
|
||||
virtual ~Utils() {}
|
||||
|
||||
public slots:
|
||||
void debug( const QString& s ) const;
|
||||
|
||||
int mount( const QString& device_path,
|
||||
const QString& mount_point,
|
||||
const QString& filesystem_name,
|
||||
const QString& options ) const;
|
||||
|
||||
int target_env_call( const QString& command, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
int target_env_call( const QStringList& args, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
int check_target_env_call( const QString& command, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
int check_target_env_call( const QStringList& args, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
QString check_target_env_output( const QString& command, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
QString check_target_env_output( const QStringList& args, const QString& stdin = QString(), int timeout = 0 ) const;
|
||||
|
||||
QString obscure( const QString& string ) const;
|
||||
|
||||
private:
|
||||
inline int _handle_check_target_env_call_error( int ec, const QString& cmd ) const;
|
||||
|
||||
PythonQtObjectPtr m_exceptionCxt;
|
||||
};
|
||||
|
||||
#endif // PYTHONQTUTILSWRAPPER_H
|
@ -1,203 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PythonQtViewStep.h"
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/PythonQtUtils.h"
|
||||
#include "utils/Retranslator.h"
|
||||
#include "viewpages/PythonQtJob.h"
|
||||
|
||||
#include <gui/PythonQtScriptingConsole.h>
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
PythonQtViewStep::PythonQtViewStep( PythonQtObjectPtr cxt, QObject* parent )
|
||||
: ViewStep( parent )
|
||||
, m_widget( new QWidget() )
|
||||
, m_cxt( cxt )
|
||||
{
|
||||
PythonQt* pq = PythonQt::self();
|
||||
Q_ASSERT( pq );
|
||||
|
||||
// The @calamares_module decorator should have filled _calamares_module_typename
|
||||
// for us.
|
||||
QString className = m_cxt.getVariable( "_calamares_module_typename" ).toString();
|
||||
|
||||
// Instantiate an object of the class marked with @calamares_module and
|
||||
// store it as _calamares_module.
|
||||
pq->evalScript( m_cxt, QString( "_calamares_module = %1()" ).arg( className ) );
|
||||
m_obj = pq->lookupObject( m_cxt, "_calamares_module" );
|
||||
|
||||
Q_ASSERT( !m_obj.isNull() ); // no entry point, no party
|
||||
|
||||
// Prepare the base widget for the module's pages
|
||||
m_widget->setLayout( new QVBoxLayout );
|
||||
CalamaresUtils::unmarginLayout( m_widget->layout() );
|
||||
m_cxt.addObject( "_calamares_module_basewidget", m_widget );
|
||||
|
||||
CALAMARES_RETRANSLATE_FOR(
|
||||
m_widget,
|
||||
CalamaresUtils::lookupAndCall( m_obj, { "retranslate" }, { CalamaresUtils::translatorLocaleName() } ); )
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
PythonQtViewStep::prettyName() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_obj, { "prettyName", "prettyname", "pretty_name" } ).toString();
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
PythonQtViewStep::widget()
|
||||
{
|
||||
if ( m_widget->layout()->count() > 1 )
|
||||
cWarning() << "PythonQtViewStep wrapper widget has more than 1 child. "
|
||||
"This should never happen.";
|
||||
|
||||
bool nothingChanged
|
||||
= m_cxt.evalScript( "_calamares_module.widget() in _calamares_module_basewidget.children()" ).toBool();
|
||||
if ( nothingChanged )
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
// Else, we either don't have a child widget, or we have a child widget that
|
||||
// was previously set and doesn't apply any more since the Python module
|
||||
// set a new one.
|
||||
|
||||
// First we clear the layout, which should only ever have 1 item.
|
||||
// We only remove from the layout and not delete because Python is in charge
|
||||
// of memory management for these widgets.
|
||||
while ( m_widget->layout()->itemAt( 0 ) )
|
||||
{
|
||||
m_widget->layout()->takeAt( 0 );
|
||||
}
|
||||
|
||||
m_cxt.evalScript( "_calamares_module_basewidget.layout().addWidget(_calamares_module.widget())" );
|
||||
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonQtViewStep::next()
|
||||
{
|
||||
CalamaresUtils::lookupAndCall( m_obj, { "next" } );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonQtViewStep::back()
|
||||
{
|
||||
CalamaresUtils::lookupAndCall( m_obj, { "back" } );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PythonQtViewStep::isNextEnabled() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_obj, { "isNextEnabled", "isnextenabled", "is_next_enabled" } ).toBool();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PythonQtViewStep::isBackEnabled() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_obj, { "isBackEnabled", "isbackenabled", "is_back_enabled" } ).toBool();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PythonQtViewStep::isAtBeginning() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_obj, { "isAtBeginning", "isatbeginning", "is_at_beginning" } ).toBool();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PythonQtViewStep::isAtEnd() const
|
||||
{
|
||||
return CalamaresUtils::lookupAndCall( m_obj, { "isAtEnd", "isatend", "is_at_end" } ).toBool();
|
||||
}
|
||||
|
||||
void
|
||||
PythonQtViewStep::onActivate()
|
||||
{
|
||||
CalamaresUtils::lookupAndCall( m_obj, { "onActivate", "onactivate", "on_activate" } );
|
||||
}
|
||||
|
||||
void
|
||||
PythonQtViewStep::onLeave()
|
||||
{
|
||||
CalamaresUtils::lookupAndCall( m_obj, { "onLeave", "onleave", "on_leave" } );
|
||||
}
|
||||
|
||||
|
||||
JobList
|
||||
PythonQtViewStep::jobs() const
|
||||
{
|
||||
JobList jobs;
|
||||
|
||||
PythonQtObjectPtr jobsCallable = PythonQt::self()->lookupCallable( m_obj, "jobs" );
|
||||
if ( jobsCallable.isNull() )
|
||||
{
|
||||
return jobs;
|
||||
}
|
||||
|
||||
PythonQtObjectPtr response = PythonQt::self()->callAndReturnPyObject( jobsCallable );
|
||||
if ( response.isNull() )
|
||||
{
|
||||
return jobs;
|
||||
}
|
||||
|
||||
PythonQtObjectPtr listPopCallable = PythonQt::self()->lookupCallable( response, "pop" );
|
||||
if ( listPopCallable.isNull() )
|
||||
{
|
||||
return jobs;
|
||||
}
|
||||
|
||||
forever
|
||||
{
|
||||
PythonQtObjectPtr aJob = PythonQt::self()->callAndReturnPyObject( listPopCallable, { 0 } );
|
||||
if ( aJob.isNull() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
jobs.append( Calamares::job_ptr( new PythonQtJob( m_cxt, aJob ) ) );
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonQtViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
m_obj.addVariable( "configuration", configurationMap );
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
PythonQtViewStep::createScriptingConsole()
|
||||
{
|
||||
PythonQtScriptingConsole* console = new PythonQtScriptingConsole( nullptr, m_cxt );
|
||||
console->setProperty( "classname", m_cxt.getVariable( "_calamares_module_typename" ).toString() );
|
||||
return console;
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
@ -1,57 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PYTHONQTVIEWSTEP_H
|
||||
#define PYTHONQTVIEWSTEP_H
|
||||
|
||||
#include "ViewStep.h"
|
||||
|
||||
#include <PythonQt.h>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class PythonQtViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PythonQtViewStep( PythonQtObjectPtr cxt, QObject* parent = nullptr );
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
|
||||
void next() override;
|
||||
void back() override;
|
||||
void onLeave() override;
|
||||
void onActivate() override;
|
||||
|
||||
bool isNextEnabled() const override;
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
JobList jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
QWidget* createScriptingConsole();
|
||||
|
||||
protected:
|
||||
QWidget* m_widget;
|
||||
|
||||
private:
|
||||
PythonQtObjectPtr m_cxt;
|
||||
PythonQtObjectPtr m_obj;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // PYTHONQTVIEWSTEP_H
|
@ -29,8 +29,7 @@ namespace Calamares
|
||||
* A view module is a Calamares module which has at least one UI page (exposed as
|
||||
* ViewStep::widget), and can optionally create Calamares jobs at runtime.
|
||||
* As of early 2020, a view module can be implemented by deriving from ViewStep
|
||||
* in C++ (as a Qt Plugin or a Qml ViewStep) or in Python with the PythonQt interface
|
||||
* (which also mimics the ViewStep class).
|
||||
* in C++ (as a Qt Plugin or a Qml ViewStep).
|
||||
*
|
||||
* A ViewStep can describe itself in human-readable format for the SummaryPage
|
||||
* (which shows all of the things which have been collected to be done in the
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
|
||||
ClickableLabel::ClickableLabel( QWidget* parent )
|
||||
: QLabel( parent )
|
||||
@ -47,5 +48,5 @@ ClickableLabel::mouseReleaseEvent( QMouseEvent* event )
|
||||
emit clicked();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Widgets
|
||||
} // namespace Calamares
|
||||
|
@ -8,8 +8,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBCALAMARESUI_CLICKABLELABEL_H
|
||||
#define LIBCALAMARESUI_CLICKABLELABEL_H
|
||||
#ifndef LIBCALAMARESUI_WIDGETS_CLICKABLELABEL_H
|
||||
#define LIBCALAMARESUI_WIDGETS_CLICKABLELABEL_H
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QLabel>
|
||||
@ -18,7 +18,8 @@
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
namespace Widgets
|
||||
{
|
||||
/** @brief A Label where the whole label area is clickable
|
||||
*
|
||||
* When clicking anywhere on the Label (text, background, whatever)
|
||||
@ -44,7 +45,7 @@ protected:
|
||||
private:
|
||||
QElapsedTimer m_time;
|
||||
};
|
||||
|
||||
} // namespace Widgets
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // LIBCALAMARESUI_CLICKABLELABEL_H
|
||||
#endif // LIBCALAMARESUI_WIDGETS_CLICKABLELABEL_H
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Widgets
|
||||
{
|
||||
|
||||
PrettyRadioButton::PrettyRadioButton( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
@ -124,5 +126,5 @@ PrettyRadioButton::toggleOptions( bool toggle )
|
||||
m_optionsLayout->parentWidget()->setVisible( toggle );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Widgets
|
||||
} // namespace Calamares
|
||||
|
@ -7,8 +7,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBCALAMARESUI_PRETTYRADIOBUTTON_H
|
||||
#define LIBCALAMARESUI_PRETTYRADIOBUTTON_H
|
||||
#ifndef LIBCALAMARESUI_WIDGETS_PRETTYRADIOBUTTON_H
|
||||
#define LIBCALAMARESUI_WIDGETS_PRETTYRADIOBUTTON_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
@ -21,6 +21,8 @@ class QHBoxLayout;
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Widgets
|
||||
{
|
||||
class ClickableLabel;
|
||||
|
||||
/** @brief A radio button with fancy label next to it.
|
||||
@ -72,6 +74,6 @@ protected:
|
||||
QGridLayout* m_mainLayout;
|
||||
QHBoxLayout* m_optionsLayout;
|
||||
};
|
||||
|
||||
} // namespace Widgets
|
||||
} // namespace Calamares
|
||||
#endif // LIBCALAMARESUI_PRETTYRADIOBUTTON_H
|
||||
#endif // LIBCALAMARESUI_WIDGETS_PRETTYRADIOBUTTON_H
|
||||
|
@ -12,46 +12,108 @@
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
|
||||
#include "3rdparty/waitingspinnerwidget.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
|
||||
WaitingWidget::WaitingWidget( const QString& text, QWidget* parent )
|
||||
: QWidget( parent )
|
||||
: WaitingSpinnerWidget( parent, false, false )
|
||||
{
|
||||
QBoxLayout* waitingLayout = new QVBoxLayout;
|
||||
setLayout( waitingLayout );
|
||||
waitingLayout->addStretch();
|
||||
QBoxLayout* pbLayout = new QHBoxLayout;
|
||||
waitingLayout->addLayout( pbLayout );
|
||||
pbLayout->addStretch();
|
||||
|
||||
WaitingSpinnerWidget* spnr = new WaitingSpinnerWidget();
|
||||
pbLayout->addWidget( spnr );
|
||||
|
||||
pbLayout->addStretch();
|
||||
|
||||
m_waitingLabel = new QLabel( text );
|
||||
|
||||
int spnrSize = m_waitingLabel->fontMetrics().height() * 4;
|
||||
spnr->setFixedSize( spnrSize, spnrSize );
|
||||
spnr->setInnerRadius( spnrSize / 2 );
|
||||
spnr->setLineLength( spnrSize / 2 );
|
||||
spnr->setLineWidth( spnrSize / 8 );
|
||||
spnr->start();
|
||||
|
||||
m_waitingLabel->setAlignment( Qt::AlignCenter );
|
||||
waitingLayout->addSpacing( spnrSize / 2 );
|
||||
waitingLayout->addWidget( m_waitingLabel );
|
||||
waitingLayout->addStretch();
|
||||
|
||||
CalamaresUtils::unmarginLayout( waitingLayout );
|
||||
int spnrSize = CalamaresUtils::defaultFontHeight() * 4;
|
||||
setFixedSize( spnrSize, spnrSize );
|
||||
setInnerRadius( spnrSize / 2 );
|
||||
setLineLength( spnrSize / 2 );
|
||||
setLineWidth( spnrSize / 8 );
|
||||
setAlignment( Qt::AlignmentFlag::AlignBottom );
|
||||
setText( text );
|
||||
start();
|
||||
}
|
||||
|
||||
WaitingWidget::~WaitingWidget() {}
|
||||
|
||||
struct CountdownWaitingWidget::Private
|
||||
{
|
||||
std::chrono::seconds duration;
|
||||
// int because we count down, need to be able to show a 0,
|
||||
// and then wrap around to duration a second later.
|
||||
int count = 0;
|
||||
QTimer* timer = nullptr;
|
||||
|
||||
Private( std::chrono::seconds seconds, QWidget* parent )
|
||||
: duration( seconds )
|
||||
, timer( new QTimer( parent ) )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CountdownWaitingWidget::CountdownWaitingWidget( std::chrono::seconds duration, QWidget* parent )
|
||||
: WaitingSpinnerWidget( parent, false, false )
|
||||
, d( std::make_unique< Private >( duration, this ) )
|
||||
{
|
||||
// Set up the label first for sizing
|
||||
const int labelHeight = qBound( 16, CalamaresUtils::defaultFontHeight() * 3 / 2, 64 );
|
||||
|
||||
// Set up the spinner
|
||||
setFixedSize( labelHeight, labelHeight );
|
||||
setRevolutionsPerSecond( 1.0 / double( duration.count() ) );
|
||||
setInnerRadius( labelHeight / 2 );
|
||||
setLineLength( labelHeight / 2 );
|
||||
setLineWidth( labelHeight / 8 );
|
||||
setAlignment( Qt::AlignmentFlag::AlignVCenter );
|
||||
|
||||
// Last because it updates the text
|
||||
setInterval( duration );
|
||||
|
||||
d->timer->setInterval( std::chrono::seconds( 1 ) );
|
||||
connect( d->timer, &QTimer::timeout, this, &CountdownWaitingWidget::tick );
|
||||
}
|
||||
|
||||
CountdownWaitingWidget::~CountdownWaitingWidget()
|
||||
{
|
||||
d->timer->stop();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingWidget::setText( const QString& text )
|
||||
CountdownWaitingWidget::setInterval( std::chrono::seconds duration )
|
||||
{
|
||||
m_waitingLabel->setText( text );
|
||||
d->duration = duration;
|
||||
d->count = int( duration.count() );
|
||||
tick();
|
||||
}
|
||||
|
||||
void
|
||||
CountdownWaitingWidget::start()
|
||||
{
|
||||
// start it from the top
|
||||
if ( d->count <= 0 )
|
||||
{
|
||||
d->count = int( d->duration.count() );
|
||||
tick();
|
||||
}
|
||||
d->timer->start();
|
||||
WaitingSpinnerWidget::start();
|
||||
}
|
||||
|
||||
void
|
||||
CountdownWaitingWidget::stop()
|
||||
{
|
||||
d->timer->stop();
|
||||
WaitingSpinnerWidget::stop();
|
||||
}
|
||||
|
||||
void
|
||||
CountdownWaitingWidget::tick()
|
||||
{
|
||||
// We do want to **display** a 0 which is why we wrap around only
|
||||
// after counting down from 0.
|
||||
d->count--;
|
||||
if ( d->count < 0 )
|
||||
{
|
||||
d->count = int( d->duration.count() );
|
||||
}
|
||||
setText( QString::number( d->count ) );
|
||||
if ( d->count == 0 )
|
||||
{
|
||||
timeout();
|
||||
}
|
||||
}
|
||||
|
@ -10,20 +10,61 @@
|
||||
#ifndef WAITINGWIDGET_H
|
||||
#define WAITINGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "widgets/waitingspinnerwidget.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
class QLabel;
|
||||
class QTimer;
|
||||
|
||||
class WaitingWidget : public QWidget
|
||||
/** @brief A spinner and a label below it
|
||||
*
|
||||
* The spinner has a fixed size of 4* the font height,
|
||||
* and the text is displayed centered below it. Use this
|
||||
* to display a long-term waiting situation with a status report.
|
||||
*/
|
||||
class WaitingWidget : public WaitingSpinnerWidget
|
||||
{
|
||||
public:
|
||||
/// Create a WaitingWidget with initial @p text label.
|
||||
explicit WaitingWidget( const QString& text, QWidget* parent = nullptr );
|
||||
~WaitingWidget() override;
|
||||
};
|
||||
|
||||
/** @brief A spinner and a countdown next to it
|
||||
*
|
||||
* The spinner is sized to the text-height and displays a
|
||||
* numeric countdown next to it. The countdown is updated
|
||||
* every second. The signal timeout() is sent every time
|
||||
* the countdown reaches 0.
|
||||
*/
|
||||
class CountdownWaitingWidget : public WaitingSpinnerWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WaitingWidget( const QString& text, QWidget* parent = nullptr );
|
||||
/// Create a countdown widget with a given @p duration
|
||||
explicit CountdownWaitingWidget( std::chrono::seconds duration = std::chrono::seconds( 5 ),
|
||||
QWidget* parent = nullptr );
|
||||
~CountdownWaitingWidget() override;
|
||||
|
||||
void setText( const QString& text );
|
||||
/// Changes the duration used and resets the countdown
|
||||
void setInterval( std::chrono::seconds duration );
|
||||
|
||||
/// Start the countdown, resets to the full duration
|
||||
void start();
|
||||
/// Stop the countdown
|
||||
void stop();
|
||||
|
||||
Q_SIGNALS:
|
||||
void timeout();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void tick();
|
||||
|
||||
private:
|
||||
QLabel* m_waitingLabel;
|
||||
struct Private;
|
||||
std::unique_ptr< Private > d;
|
||||
};
|
||||
|
||||
#endif // WAITINGWIDGET_H
|
||||
|
390
src/libcalamaresui/widgets/waitingspinnerwidget.cpp
Normal file
390
src/libcalamaresui/widgets/waitingspinnerwidget.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
|
||||
* SPDX-FileCopyrightText: 2014 William Hallatt
|
||||
* SPDX-FileCopyrightText: 2015 Jacob Dawid
|
||||
* SPDX-FileCopyrightText: 2018 huxingyi
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
|
||||
Modified 2014 by William Hallatt
|
||||
Modified 2015 by Jacob Dawid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "waitingspinnerwidget.h"
|
||||
|
||||
#include <qmath.h>
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
static bool
|
||||
isAlignCenter( Qt::AlignmentFlag a )
|
||||
{
|
||||
return a == Qt::AlignmentFlag::AlignVCenter;
|
||||
}
|
||||
|
||||
static int
|
||||
lineCountDistanceFromPrimary( int current, int primary, int totalNrOfLines )
|
||||
{
|
||||
int distance = primary - current;
|
||||
if ( distance < 0 )
|
||||
{
|
||||
distance += totalNrOfLines;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
static QColor
|
||||
currentLineColor( int countDistance, int totalNrOfLines, qreal trailFadePerc, qreal minOpacity, QColor color )
|
||||
{
|
||||
if ( countDistance == 0 )
|
||||
{
|
||||
return color;
|
||||
}
|
||||
const qreal minAlphaF = minOpacity / 100.0;
|
||||
int distanceThreshold = static_cast< int >( qCeil( ( totalNrOfLines - 1 ) * trailFadePerc / 100.0 ) );
|
||||
if ( countDistance > distanceThreshold )
|
||||
{
|
||||
color.setAlphaF( minAlphaF );
|
||||
}
|
||||
else
|
||||
{
|
||||
qreal alphaDiff = color.alphaF() - minAlphaF;
|
||||
qreal gradient = alphaDiff / static_cast< qreal >( distanceThreshold + 1 );
|
||||
qreal resultAlpha = color.alphaF() - gradient * countDistance;
|
||||
|
||||
// If alpha is out of bounds, clip it.
|
||||
resultAlpha = qBound( 0.0, resultAlpha, 1.0 );
|
||||
color.setAlphaF( resultAlpha );
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
WaitingSpinnerWidget::WaitingSpinnerWidget( QWidget* parent, bool centerOnParent, bool disableParentWhenSpinning )
|
||||
: WaitingSpinnerWidget( Qt::WindowModality::NonModal, parent, centerOnParent, disableParentWhenSpinning )
|
||||
{
|
||||
}
|
||||
|
||||
WaitingSpinnerWidget::WaitingSpinnerWidget( Qt::WindowModality modality,
|
||||
QWidget* parent,
|
||||
bool centerOnParent,
|
||||
bool disableParentWhenSpinning )
|
||||
: QWidget( parent,
|
||||
modality == Qt::WindowModality::NonModal ? Qt::WindowFlags() : Qt::Dialog | Qt::FramelessWindowHint )
|
||||
, _centerOnParent( centerOnParent )
|
||||
, _disableParentWhenSpinning( disableParentWhenSpinning )
|
||||
{
|
||||
_timer = new QTimer( this );
|
||||
connect( _timer, SIGNAL( timeout() ), this, SLOT( rotate() ) );
|
||||
updateSize();
|
||||
updateTimer();
|
||||
hide();
|
||||
|
||||
// We need to set the window modality AFTER we've hidden the
|
||||
// widget for the first time since changing this property while
|
||||
// the widget is visible has no effect.
|
||||
//
|
||||
// Non-modal windows don't need any work
|
||||
if ( modality != Qt::WindowModality::NonModal )
|
||||
{
|
||||
setWindowModality( modality );
|
||||
setAttribute( Qt::WA_TranslucentBackground );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::paintEvent( QPaintEvent* )
|
||||
{
|
||||
updatePosition();
|
||||
QPainter painter( this );
|
||||
painter.fillRect( this->rect(), Qt::transparent );
|
||||
painter.setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
if ( _currentCounter >= _numberOfLines )
|
||||
{
|
||||
_currentCounter = 0;
|
||||
}
|
||||
|
||||
painter.setPen( Qt::NoPen );
|
||||
for ( int i = 0; i < _numberOfLines; ++i )
|
||||
{
|
||||
painter.save();
|
||||
painter.translate( _innerRadius + _lineLength, _innerRadius + _lineLength );
|
||||
painter.translate( ( width() - _imageSize.width() ) / 2, 0 );
|
||||
qreal rotateAngle = static_cast< qreal >( 360 * i ) / static_cast< qreal >( _numberOfLines );
|
||||
painter.rotate( rotateAngle );
|
||||
painter.translate( _innerRadius, 0 );
|
||||
int distance = lineCountDistanceFromPrimary( i, _currentCounter, _numberOfLines );
|
||||
QColor color = currentLineColor( distance, _numberOfLines, _trailFadePercentage, _minimumTrailOpacity, _color );
|
||||
painter.setBrush( color );
|
||||
// TODO improve the way rounded rect is painted
|
||||
painter.drawRoundedRect(
|
||||
QRect( 0, -_lineWidth / 2, _lineLength, _lineWidth ), _roundness, _roundness, Qt::RelativeSize );
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
if ( !_text.isEmpty() )
|
||||
{
|
||||
painter.setPen( QPen( _textColor ) );
|
||||
if ( isAlignCenter( alignment() ) )
|
||||
{
|
||||
painter.drawText( QRect( 0, 0, width(), height() ), Qt::AlignVCenter | Qt::AlignHCenter, _text );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.drawText( QRect( 0, _imageSize.height(), width(), height() - _imageSize.height() ),
|
||||
Qt::AlignBottom | Qt::AlignHCenter,
|
||||
_text );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::start()
|
||||
{
|
||||
updatePosition();
|
||||
_isSpinning = true;
|
||||
show();
|
||||
|
||||
if ( parentWidget() && _disableParentWhenSpinning )
|
||||
{
|
||||
parentWidget()->setEnabled( false );
|
||||
}
|
||||
|
||||
if ( !_timer->isActive() )
|
||||
{
|
||||
_timer->start();
|
||||
_currentCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::stop()
|
||||
{
|
||||
_isSpinning = false;
|
||||
hide();
|
||||
|
||||
if ( parentWidget() && _disableParentWhenSpinning )
|
||||
{
|
||||
parentWidget()->setEnabled( true );
|
||||
}
|
||||
|
||||
if ( _timer->isActive() )
|
||||
{
|
||||
_timer->stop();
|
||||
_currentCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setNumberOfLines( int lines )
|
||||
{
|
||||
_numberOfLines = lines;
|
||||
_currentCounter = 0;
|
||||
updateTimer();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setLineLength( int length )
|
||||
{
|
||||
_lineLength = length;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setLineWidth( int width )
|
||||
{
|
||||
_lineWidth = width;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setInnerRadius( int radius )
|
||||
{
|
||||
_innerRadius = radius;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setText( const QString& text )
|
||||
{
|
||||
_text = text;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setAlignment( Qt::AlignmentFlag align )
|
||||
{
|
||||
_alignment = align;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
QColor
|
||||
WaitingSpinnerWidget::color() const
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
|
||||
QColor
|
||||
WaitingSpinnerWidget::textColor() const
|
||||
{
|
||||
return _textColor;
|
||||
}
|
||||
|
||||
QString
|
||||
WaitingSpinnerWidget::text() const
|
||||
{
|
||||
return _text;
|
||||
}
|
||||
|
||||
qreal
|
||||
WaitingSpinnerWidget::roundness() const
|
||||
{
|
||||
return _roundness;
|
||||
}
|
||||
|
||||
qreal
|
||||
WaitingSpinnerWidget::minimumTrailOpacity() const
|
||||
{
|
||||
return _minimumTrailOpacity;
|
||||
}
|
||||
|
||||
qreal
|
||||
WaitingSpinnerWidget::trailFadePercentage() const
|
||||
{
|
||||
return _trailFadePercentage;
|
||||
}
|
||||
|
||||
qreal
|
||||
WaitingSpinnerWidget::revolutionsPersSecond() const
|
||||
{
|
||||
return _revolutionsPerSecond;
|
||||
}
|
||||
|
||||
int
|
||||
WaitingSpinnerWidget::numberOfLines() const
|
||||
{
|
||||
return _numberOfLines;
|
||||
}
|
||||
|
||||
int
|
||||
WaitingSpinnerWidget::lineLength() const
|
||||
{
|
||||
return _lineLength;
|
||||
}
|
||||
|
||||
int
|
||||
WaitingSpinnerWidget::lineWidth() const
|
||||
{
|
||||
return _lineWidth;
|
||||
}
|
||||
|
||||
int
|
||||
WaitingSpinnerWidget::innerRadius() const
|
||||
{
|
||||
return _innerRadius;
|
||||
}
|
||||
|
||||
bool
|
||||
WaitingSpinnerWidget::isSpinning() const
|
||||
{
|
||||
return _isSpinning;
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setRoundness( qreal roundness )
|
||||
{
|
||||
_roundness = qBound( 0.0, roundness, 100.0 );
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setColor( QColor color )
|
||||
{
|
||||
_color = color;
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setTextColor( QColor color )
|
||||
{
|
||||
_textColor = color;
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setRevolutionsPerSecond( qreal revolutionsPerSecond )
|
||||
{
|
||||
_revolutionsPerSecond = revolutionsPerSecond;
|
||||
updateTimer();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setTrailFadePercentage( qreal trail )
|
||||
{
|
||||
_trailFadePercentage = trail;
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::setMinimumTrailOpacity( qreal minimumTrailOpacity )
|
||||
{
|
||||
_minimumTrailOpacity = minimumTrailOpacity;
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::rotate()
|
||||
{
|
||||
++_currentCounter;
|
||||
if ( _currentCounter >= _numberOfLines )
|
||||
{
|
||||
_currentCounter = 0;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::updateSize()
|
||||
{
|
||||
int size = ( _innerRadius + _lineLength ) * 2;
|
||||
_imageSize = QSize( size, size );
|
||||
if ( _text.isEmpty() || isAlignCenter( alignment() ) )
|
||||
{
|
||||
setFixedSize( size, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
QFontMetrics fm( font() );
|
||||
QSize textSize = QSize( fm.horizontalAdvance( _text ), fm.height() );
|
||||
setFixedSize( qMax( size, textSize.width() ), size + size / 4 + textSize.height() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::updateTimer()
|
||||
{
|
||||
// Old-style interval in milliseconds; force to int to suppress warning
|
||||
_timer->setInterval( int( 1000 / ( _numberOfLines * _revolutionsPerSecond ) ) );
|
||||
}
|
||||
|
||||
void
|
||||
WaitingSpinnerWidget::updatePosition()
|
||||
{
|
||||
if ( parentWidget() && _centerOnParent )
|
||||
{
|
||||
move( parentWidget()->width() / 2 - width() / 2, parentWidget()->height() / 2 - height() / 2 );
|
||||
}
|
||||
}
|
157
src/libcalamaresui/widgets/waitingspinnerwidget.h
Normal file
157
src/libcalamaresui/widgets/waitingspinnerwidget.h
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
|
||||
* SPDX-FileCopyrightText: 2014 William Hallatt
|
||||
* SPDX-FileCopyrightText: 2015 Jacob Dawid
|
||||
* SPDX-FileCopyrightText: 2018 huxingyi
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
|
||||
Modified 2014 by William Hallatt
|
||||
Modified 2015 by Jacob Dawid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Qt includes
|
||||
#include <QColor>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
class WaitingSpinnerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** @brief Constructor for "standard" widget behaviour
|
||||
*
|
||||
* Use this constructor if you wish to, e.g. embed your widget in another.
|
||||
*/
|
||||
WaitingSpinnerWidget( QWidget* parent = nullptr,
|
||||
bool centerOnParent = true,
|
||||
bool disableParentWhenSpinning = true );
|
||||
|
||||
/** @brief Constructor
|
||||
*
|
||||
* Use this constructor to automatically create a modal
|
||||
* ("blocking") spinner on top of the calling widget/window. If a valid
|
||||
* parent widget is provided, "centreOnParent" will ensure that
|
||||
* QtWaitingSpinner automatically centres itself on it, if not,
|
||||
* @p centerOnParent is ignored.
|
||||
*/
|
||||
WaitingSpinnerWidget( Qt::WindowModality modality,
|
||||
QWidget* parent = nullptr,
|
||||
bool centerOnParent = true,
|
||||
bool disableParentWhenSpinning = true );
|
||||
|
||||
WaitingSpinnerWidget( const WaitingSpinnerWidget& ) = delete;
|
||||
WaitingSpinnerWidget& operator=( const WaitingSpinnerWidget& ) = delete;
|
||||
|
||||
void setColor( QColor color );
|
||||
void setTextColor( QColor color );
|
||||
void setRoundness( qreal roundness );
|
||||
void setMinimumTrailOpacity( qreal minimumTrailOpacity );
|
||||
void setTrailFadePercentage( qreal trail );
|
||||
void setRevolutionsPerSecond( qreal revolutionsPerSecond );
|
||||
void setNumberOfLines( int lines );
|
||||
void setLineLength( int length );
|
||||
void setLineWidth( int width );
|
||||
void setInnerRadius( int radius );
|
||||
|
||||
/** @brief Sets the text displayed in or below the spinner
|
||||
*
|
||||
* If the text is empty, no text is displayed. The text is displayed
|
||||
* in or below the spinner depending on the value of alignment().
|
||||
* With AlignBottom, the text is displayed below the spinner,
|
||||
* centered horizontally relative to the spinner; any other alignment
|
||||
* will put the text in the middle of the spinner itself.
|
||||
*/
|
||||
void setText( const QString& text );
|
||||
/** @brief Sets the alignment of text for the spinner
|
||||
*
|
||||
* The only meaningful values are AlignBottom and AlignVCenter,
|
||||
* for text below the spinner and text in the middle.
|
||||
*/
|
||||
void setAlignment( Qt::AlignmentFlag align );
|
||||
/// Convenience to set text-in-the-middle (@c true) or text-at-bottom (@c false)
|
||||
void setCenteredText( bool centered )
|
||||
{
|
||||
setAlignment( centered ? Qt::AlignmentFlag::AlignVCenter : Qt::AlignmentFlag::AlignBottom );
|
||||
}
|
||||
|
||||
QColor color() const;
|
||||
QColor textColor() const;
|
||||
QString text() const;
|
||||
Qt::AlignmentFlag alignment() const { return _alignment; }
|
||||
qreal roundness() const;
|
||||
qreal minimumTrailOpacity() const;
|
||||
qreal trailFadePercentage() const;
|
||||
qreal revolutionsPersSecond() const;
|
||||
int numberOfLines() const;
|
||||
int lineLength() const;
|
||||
int lineWidth() const;
|
||||
int innerRadius() const;
|
||||
|
||||
bool isSpinning() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
private Q_SLOTS:
|
||||
void rotate();
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* paintEvent ) override;
|
||||
|
||||
private:
|
||||
void updateSize();
|
||||
void updateTimer();
|
||||
void updatePosition();
|
||||
|
||||
private:
|
||||
// PI, leading to a full fade in one whole revolution
|
||||
static constexpr const auto radian = 3.14159265358979323846;
|
||||
|
||||
// Spinner-wheel related settings
|
||||
QColor _color = Qt::black;
|
||||
qreal _roundness = 100.0; // 0..100
|
||||
qreal _minimumTrailOpacity = radian;
|
||||
qreal _trailFadePercentage = 80.0;
|
||||
qreal _revolutionsPerSecond = radian / 2;
|
||||
int _numberOfLines = 20;
|
||||
int _lineLength = 10;
|
||||
int _lineWidth = 2;
|
||||
int _innerRadius = 10;
|
||||
QSize _imageSize;
|
||||
|
||||
// Text-related settings
|
||||
Qt::AlignmentFlag _alignment = Qt::AlignmentFlag::AlignBottom;
|
||||
QString _text;
|
||||
QColor _textColor = Qt::black;
|
||||
|
||||
// Environment settings
|
||||
bool _centerOnParent = true;
|
||||
bool _disableParentWhenSpinning = true;
|
||||
|
||||
// Internal bits
|
||||
QTimer* _timer = nullptr;
|
||||
int _currentCounter = 0;
|
||||
bool _isSpinning = false;
|
||||
};
|
@ -8,7 +8,7 @@
|
||||
# individual modules can also decide they must be skipped (e.g. OS-specific
|
||||
# modules, or ones with unmet dependencies). Collect the skipped modules
|
||||
# in this list.
|
||||
set( LIST_SKIPPED_MODULES "" )
|
||||
set(LIST_SKIPPED_MODULES "")
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/libcalamares
|
||||
@ -16,29 +16,46 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/libcalamaresui
|
||||
)
|
||||
|
||||
string( REPLACE " " ";" SKIP_LIST "${SKIP_MODULES}" )
|
||||
string(REPLACE " " ";" SKIP_LIST "${SKIP_MODULES}")
|
||||
|
||||
file( GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*" )
|
||||
list( SORT SUBDIRECTORIES )
|
||||
file(GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
|
||||
list(SORT SUBDIRECTORIES)
|
||||
|
||||
foreach( SUBDIRECTORY ${SUBDIRECTORIES} )
|
||||
foreach(SUBDIRECTORY ${SUBDIRECTORIES})
|
||||
calamares_add_module_subdirectory( ${SUBDIRECTORY} LIST_SKIPPED_MODULES )
|
||||
endforeach()
|
||||
|
||||
# TODO:3.3: Use FindPython3
|
||||
if ( BUILD_TESTING AND BUILD_SCHEMA_TESTING AND PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE )
|
||||
if(BUILD_TESTING AND BUILD_SCHEMA_TESTING AND Python_Interpreter_FOUND)
|
||||
# The tests for each config file are independent of whether the
|
||||
# module is enabled or not: the config file should match its schema
|
||||
# regardless.
|
||||
foreach( SUBDIRECTORY ${SUBDIRECTORIES} )
|
||||
set( _schema_file "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.schema.yaml" )
|
||||
set( _conf_file "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.conf" )
|
||||
if ( EXISTS "${_schema_file}" AND EXISTS "${_conf_file}" )
|
||||
add_test(
|
||||
NAME validate-${SUBDIRECTORY}
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" "${_schema_file}" "${_conf_file}"
|
||||
)
|
||||
foreach(SUBDIRECTORY ${SUBDIRECTORIES})
|
||||
set(_schema_file "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.schema.yaml")
|
||||
# Collect config files from the module-directory and from a tests/ subdir,
|
||||
# using the same mechanism to find those test-config-files as function
|
||||
# calamares_add_module_subdirectory() would do.
|
||||
set(_conf_files "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.conf")
|
||||
set(_count 1)
|
||||
set(_testdir "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/tests")
|
||||
while(EXISTS "${_testdir}/${_count}.global" OR EXISTS "${_testdir}/${_count}.job")
|
||||
if(EXISTS "${_testdir}/${_count}.job")
|
||||
list(APPEND _conf_files "${_testdir}/${_count}.job")
|
||||
endif()
|
||||
math(EXPR _count "${_count} + 1")
|
||||
endwhile()
|
||||
|
||||
if(EXISTS "${_schema_file}")
|
||||
foreach(_conf_file ${_conf_files})
|
||||
if(EXISTS ${_conf_file})
|
||||
get_filename_component(_conf_base "${_conf_file}" NAME_WE)
|
||||
add_test(
|
||||
NAME validate-${SUBDIRECTORY}-${_conf_base}
|
||||
COMMAND
|
||||
${Python_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" "${_schema_file}"
|
||||
"${_conf_file}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
@ -180,26 +180,40 @@ it is possible to take the whole installation-process into account
|
||||
for determining the relative weights there.
|
||||
|
||||
|
||||
## Global storage keys
|
||||
## Global Storage keys
|
||||
|
||||
Some modules place values in global storage so that they can be referenced later by other modules or even other parts of the same module. The following table represents a partial list of the values available as well as where they originate from and which module consume them.
|
||||
Some modules place values in Global Storage so that they can be referenced later by other modules or even other parts of the same module. The following table represents a partial list of the values available as well as where they originate from and which module consume them.
|
||||
Keys whose name is followed by a `+` are **structured** data, and have
|
||||
entries (which start with `+`) below the parent key describing subkeys.
|
||||
Some structured keys refer to other documentation sources.
|
||||
|
||||
Key |Source |Consumers|Description
|
||||
------------------|----------------|---|---
|
||||
btrfsSubvolumes |mount |fstab|List of maps containing the mountpoint and btrtfs subvolume
|
||||
Key |Source |Consumers |Description
|
||||
------------------|----------------|---------------|---
|
||||
bootloader + |partition | |Bootloader location
|
||||
\+ installPath | | |Device (e.g. `/dev/sda`) where the bootloader is installed
|
||||
branding + | | |See `src/branding/README.md`
|
||||
btrfsSubvolumes |mount |fstab |List of maps containing the mountpoint and btrtfs subvolume
|
||||
btrfsRootSubvolume|mount |bootloader, luksopenswaphook|String containing the subvolume mounted at root
|
||||
efiSystemPartition|partition |bootloader, fstab|String containing the path to the ESP relative to the installed system
|
||||
extraMounts |mount |unpackfs|List of maps holding metadata for the temporary mountpoints used by the installer
|
||||
fullname |users ||The full username (e.g. "Jane Q. Public")
|
||||
hostname |users ||A string containing the hostname of the new system
|
||||
netinstallAdd |packagechooser |netinstall|Data to add to netinstall tree. Same format as netinstall.yaml
|
||||
netinstallSelect |packagechooser |netinstall|List of group names to select in the netinstall tree
|
||||
partitions |partition, rawfs|numerous modules|List of maps of metadata about each partition
|
||||
rootMountPoint |mount |numerous modules|A string with the absolute path to the root mountpoint
|
||||
fullname |users | |The full username (e.g. "Jane Q. Public")
|
||||
hostname |users | |A string containing the hostname of the new system
|
||||
netinstallAdd |packagechooser |netinstall |Data to add to netinstall tree. Same format as netinstall.yaml
|
||||
netinstallSelect |packagechooser |netinstall |List of group names to select in the netinstall tree
|
||||
packageOperations +|packagechooser, netinstall|packages|Operations to perform
|
||||
\+ (list data) | | |See `packages.conf`
|
||||
partitions + |partition, rawfs|(many) |List of maps of metadata about each partition
|
||||
\+ device | | |path to the partition device
|
||||
\+ fs | | |the name of the file system
|
||||
\+ mountPoint | | |where the device should be mounted
|
||||
\+ uuid | | |the UUID of the partition device
|
||||
rootMountPoint |mount |(many) |A string with the absolute path to the root mountpoint
|
||||
username |users |networkcfg, plasmainf, preservefiles|A string containing the username of the new user
|
||||
zfsDatasets |zfs |bootloader, grubcfg, mount|List of maps of zfs datasets including the name and mount information
|
||||
zfsInfo |partition |mount, zfs|List of encrypted zfs partitions and the encription info
|
||||
zfsPoolInfo |zfs |mount, umount|List of maps of zfs pool info including the name and mountpoint
|
||||
zfsInfo |partition |mount, zfs |List of encrypted zfs partitions and the encription info
|
||||
zfsPoolInfo |zfs |mount, umount |List of maps of zfs pool info including the name and mountpoint
|
||||
|
||||
|
||||
|
||||
|
||||
## C++ modules
|
||||
|
@ -13,19 +13,21 @@
|
||||
# Possible options are 'grub', 'sb-shim' and 'systemd-boot'.
|
||||
efiBootLoader: "grub"
|
||||
|
||||
# systemd-boot configuration files settings, set kernel and initramfs file names
|
||||
# systemd-boot configuration files settings, set kernel search path, kernel name
|
||||
# and amount of time before default selection boots
|
||||
kernel: "/vmlinuz-linux"
|
||||
img: "/initramfs-linux.img"
|
||||
fallback: "/initramfs-linux-fallback.img"
|
||||
kernelSearchPath: "/usr/lib/modules"
|
||||
kernelName: "vmlinuz"
|
||||
timeout: "10"
|
||||
|
||||
# Optionally set the menu entry name and kernel name to use in systemd-boot.
|
||||
# additionalInitrdFiles is a comma seperated list of file names
|
||||
additionalInitrdFiles:
|
||||
- "/boot/amd-ucode"
|
||||
- "/boot/intel-ucode"
|
||||
|
||||
# Optionally set the menu entry name to use in systemd-boot.
|
||||
# If not specified here, these settings will be taken from branding.desc.
|
||||
#
|
||||
# bootloaderEntryName: "Generic GNU/Linux"
|
||||
# kernelLine: ", with Stable-Kernel"
|
||||
# fallbackKernelLine: ", with Stable-Kernel (fallback initramfs)"
|
||||
|
||||
# GRUB 2 binary names and boot directory
|
||||
# Some distributions (e.g. Fedora) use grub2-* (resp. /boot/grub2/) names.
|
||||
|
@ -7,10 +7,13 @@ additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
efiBootLoader: { type: string }
|
||||
kernel: { type: string }
|
||||
img: { type: string }
|
||||
fallback: { type: string }
|
||||
kernelSearchPath: { type: string }
|
||||
kernelName: { type: string }
|
||||
timeout: { type: string } # Inserted verbatim
|
||||
additionalInitrdFiles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
bootloaderEntryName: { type: string }
|
||||
kernelLine: { type: string }
|
||||
fallbackKernelLine: { type: string }
|
||||
@ -27,9 +30,10 @@ properties:
|
||||
|
||||
required:
|
||||
- efiBootLoader
|
||||
- kernel
|
||||
- img
|
||||
- kernelSearchPath
|
||||
- kernelName
|
||||
- grubInstall
|
||||
- grubMkconfig
|
||||
- grubCfg
|
||||
- grubProbe
|
||||
- machineid
|
||||
|
@ -136,18 +136,18 @@ def is_zfs_root(partition):
|
||||
return partition["mountPoint"] == "/" and partition["fs"] == "zfs"
|
||||
|
||||
|
||||
def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, kernel_type):
|
||||
def create_systemd_boot_conf(installation_root_path, efi_dir, uuid, entry, kernel, kernel_type, kernel_version):
|
||||
"""
|
||||
Creates systemd-boot configuration files based on given parameters.
|
||||
|
||||
:param install_path:
|
||||
:param efi_dir:
|
||||
:param uuid:
|
||||
:param entry:
|
||||
:param entry_name:
|
||||
:param kernel_type:
|
||||
:param installation_root_path: A string containing the absolute path to the root of the installation
|
||||
:param efi_dir: A string containing the path to the efi dir relative to the root of the installation
|
||||
:param uuid: A string containing the UUID of the root volume
|
||||
:param entry: A string containing the name of the entry as it will be displayed on boot
|
||||
:param kernel: A string containing the path to the kernel relative to the root of the installation
|
||||
:param kernel_type: A string which should be set if there is a special version of the entry, for example "fallback"
|
||||
:param kernel_version: The kernel version string
|
||||
"""
|
||||
kernel = libcalamares.job.configuration["kernel"]
|
||||
kernel_params = ["quiet"]
|
||||
|
||||
partitions = libcalamares.globalstorage.value("partitions")
|
||||
@ -208,42 +208,59 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker
|
||||
kernel_params.append("resume=/dev/mapper/{!s}".format(
|
||||
swap_outer_mappername))
|
||||
|
||||
kernel_line = get_kernel_line(kernel_type)
|
||||
libcalamares.utils.debug("Configure: \"{!s}\"".format(kernel_line))
|
||||
libcalamares.utils.debug("Configure: \"{!s}\"".format(f"{entry} {kernel_version}"))
|
||||
|
||||
if kernel_type == "fallback":
|
||||
img = libcalamares.job.configuration["fallback"]
|
||||
entry_name = entry_name + "-fallback"
|
||||
version_string = kernel_version + "-fallback"
|
||||
initrd = "initrd-fallback"
|
||||
else:
|
||||
img = libcalamares.job.configuration["img"]
|
||||
version_string = kernel_version
|
||||
initrd = "initrd"
|
||||
|
||||
conf_path = os.path.join(install_path + efi_dir,
|
||||
# get the machine-id
|
||||
with open(os.path.join(installation_root_path, "etc", "machine-id"), 'r') as machineid_file:
|
||||
machine_id = machineid_file.read().rstrip('\n')
|
||||
|
||||
# Copy kernel to a subdirectory of /efi partition
|
||||
machine_dir = os.path.join(installation_root_path + efi_dir, machine_id)
|
||||
os.makedirs(machine_dir, exist_ok=True)
|
||||
|
||||
target_efi_files_dir = os.path.join(machine_dir, kernel_version)
|
||||
os.makedirs(target_efi_files_dir, exist_ok=True)
|
||||
|
||||
kernel_path = os.path.join(installation_root_path, kernel)
|
||||
kernel_name = os.path.basename(kernel_path)
|
||||
shutil.copyfile(kernel_path, os.path.join(target_efi_files_dir, "linux"))
|
||||
|
||||
# write the entry
|
||||
lines = [
|
||||
'## Generated by Calamares\n',
|
||||
'\n',
|
||||
"title {!s}\n".format(entry),
|
||||
"version {!s}\n".format(version_string),
|
||||
"machine-id {!s}\n".format(machine_id),
|
||||
"linux {!s}\n".format(os.path.join("/", machine_id, kernel_version, "linux")),
|
||||
]
|
||||
|
||||
try:
|
||||
additional_initrd_files = libcalamares.job.configuration["additionalInitrdFiles"]
|
||||
for initrd_file in additional_initrd_files:
|
||||
libcalamares.utils.debug("Attempting to handle initrd image " + initrd_file)
|
||||
if os.path.isfile(os.path.join(installation_root_path, initrd_file.lstrip('/'))):
|
||||
libcalamares.utils.debug("Found image " + initrd_file)
|
||||
shutil.copyfile(os.path.join(installation_root_path, initrd_file.lstrip('/')), os.path.join(target_efi_files_dir, os.path.basename(initrd_file)))
|
||||
lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, os.path.basename(initrd_file))))
|
||||
except KeyError: # If the configuration option isn't set, we can just move on
|
||||
libcalamares.utils.debug("Failed to find key additionalInitrdFiles")
|
||||
pass
|
||||
|
||||
lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, initrd)))
|
||||
lines.append("options {!s} rw\n".format(" ".join(kernel_params)))
|
||||
|
||||
conf_path = os.path.join(installation_root_path + efi_dir,
|
||||
"loader",
|
||||
"entries",
|
||||
entry_name + ".conf")
|
||||
|
||||
# Copy kernel and initramfs to a subdirectory of /efi partition
|
||||
files_dir = os.path.join(install_path + efi_dir, entry_name)
|
||||
os.makedirs(files_dir, exist_ok=True)
|
||||
|
||||
kernel_path = install_path + kernel
|
||||
kernel_name = os.path.basename(kernel_path)
|
||||
shutil.copyfile(kernel_path, os.path.join(files_dir, kernel_name))
|
||||
|
||||
img_path = install_path + img
|
||||
img_name = os.path.basename(img_path)
|
||||
shutil.copyfile(img_path, os.path.join(files_dir, img_name))
|
||||
|
||||
lines = [
|
||||
'## This is just an example config file.\n',
|
||||
'## Please edit the paths and kernel parameters according\n',
|
||||
'## to your system.\n',
|
||||
'\n',
|
||||
"title {!s}{!s}\n".format(entry, kernel_line),
|
||||
"linux {!s}\n".format(os.path.join("/", entry_name, kernel_name)),
|
||||
"initrd {!s}\n".format(os.path.join("/", entry_name, img_name)),
|
||||
"options {!s} rw\n".format(" ".join(kernel_params)),
|
||||
]
|
||||
machine_id + "-" + version_string + ".conf")
|
||||
|
||||
with open(conf_path, 'w') as conf_file:
|
||||
for line in lines:
|
||||
@ -465,6 +482,30 @@ def efi_boot_next():
|
||||
if boot_entry:
|
||||
subprocess.call([boot_mgr, "-n", boot_entry])
|
||||
|
||||
def get_kernels(installation_root_path):
|
||||
"""
|
||||
Gets a list of kernels and associated values for each kernel. This will work as is for many distros.
|
||||
If not, it should be safe to modify it to better support your distro
|
||||
|
||||
:param installation_root_path: A string with the absolute path to the root of the installation
|
||||
|
||||
Returns a list of 3-tuples
|
||||
|
||||
Each 3-tuple contains the kernel, kernel_type and kernel_version
|
||||
"""
|
||||
kernel_search_path = libcalamares.job.configuration["kernelSearchPath"]
|
||||
source_kernel_name = libcalamares.job.configuration["kernelName"]
|
||||
kernel_list = []
|
||||
|
||||
# find all the installed kernels and generate default and fallback entries for each
|
||||
for root, dirs, files in os.walk(os.path.join(installation_root_path, kernel_search_path.lstrip('/'))):
|
||||
for file in files:
|
||||
if file == source_kernel_name:
|
||||
rel_root = os.path.relpath(root, installation_root_path)
|
||||
kernel_list.append((os.path.join(rel_root, file),"default",os.path.basename(root)))
|
||||
kernel_list.append((os.path.join(rel_root, file),"fallback",os.path.basename(root)))
|
||||
|
||||
return kernel_list
|
||||
|
||||
def install_systemd_boot(efi_directory):
|
||||
"""
|
||||
@ -473,8 +514,8 @@ def install_systemd_boot(efi_directory):
|
||||
:param efi_directory:
|
||||
"""
|
||||
libcalamares.utils.debug("Bootloader: systemd-boot")
|
||||
install_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = install_path + efi_directory
|
||||
installation_root_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = installation_root_path + efi_directory
|
||||
uuid = get_uuid()
|
||||
distribution = get_bootloader_entry_name()
|
||||
distribution_translated = distribution.translate(file_name_sanitizer)
|
||||
@ -484,21 +525,17 @@ def install_systemd_boot(efi_directory):
|
||||
subprocess.call(["bootctl",
|
||||
"--path={!s}".format(install_efi_directory),
|
||||
"install"])
|
||||
create_systemd_boot_conf(install_path,
|
||||
efi_directory,
|
||||
uuid,
|
||||
distribution,
|
||||
distribution_translated,
|
||||
"default")
|
||||
if "fallback" in libcalamares.job.configuration:
|
||||
create_systemd_boot_conf(install_path,
|
||||
efi_directory,
|
||||
uuid,
|
||||
distribution,
|
||||
distribution_translated,
|
||||
"fallback")
|
||||
create_loader(loader_path, distribution_translated)
|
||||
|
||||
for (kernel, kernel_type, kernel_version) in get_kernels(installation_root_path):
|
||||
create_systemd_boot_conf(installation_root_path,
|
||||
efi_directory,
|
||||
uuid,
|
||||
distribution,
|
||||
kernel,
|
||||
kernel_type,
|
||||
kernel_version)
|
||||
|
||||
create_loader(loader_path, distribution_translated)
|
||||
|
||||
def get_grub_efi_parameters():
|
||||
"""
|
||||
@ -616,8 +653,8 @@ def install_grub(efi_directory, fw_type):
|
||||
|
||||
if fw_type == "efi":
|
||||
libcalamares.utils.debug("Bootloader: grub (efi)")
|
||||
install_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = install_path + efi_directory
|
||||
installation_root_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = installation_root_path + efi_directory
|
||||
|
||||
if not os.path.isdir(install_efi_directory):
|
||||
os.makedirs(install_efi_directory)
|
||||
@ -668,8 +705,8 @@ def install_secureboot(efi_directory):
|
||||
"""
|
||||
efi_bootloader_id = efi_label(efi_directory)
|
||||
|
||||
install_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = install_path + efi_directory
|
||||
installation_root_path = libcalamares.globalstorage.value("rootMountPoint")
|
||||
install_efi_directory = installation_root_path + efi_directory
|
||||
|
||||
if efi_word_size() == "64":
|
||||
install_efi_bin = "shimx64.efi"
|
||||
@ -761,8 +798,12 @@ def run():
|
||||
|
||||
fw_type = libcalamares.globalstorage.value("firmwareType")
|
||||
|
||||
if (libcalamares.globalstorage.value("bootLoader") is None and fw_type != "efi"):
|
||||
libcalamares.utils.warning( "Non-EFI system, and no bootloader is set." )
|
||||
if libcalamares.globalstorage.value("bootLoader") is None:
|
||||
# Don't want a bootloader, but do log that this has an effect:
|
||||
if fw_type != "efi":
|
||||
libcalamares.utils.warning( "Non-EFI system, and no bootloader is set." )
|
||||
else:
|
||||
libcalamares.utils.warning( "EFI system, and no bootloader is set." )
|
||||
return None
|
||||
|
||||
partitions = libcalamares.globalstorage.value("partitions")
|
||||
|
@ -3,7 +3,7 @@
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
calamares_add_plugin( contextualprocess
|
||||
calamares_add_plugin(contextualprocess
|
||||
TYPE job
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
@ -15,7 +15,6 @@ calamares_add_test(
|
||||
contextualprocesstest
|
||||
SOURCES
|
||||
Tests.cpp
|
||||
ContextualProcessJob.cpp # Builds it a second time
|
||||
LIBRARIES
|
||||
yamlcpp::yamlcpp
|
||||
ContextualProcessJob.cpp # Builds it a second time
|
||||
LIBRARIES yamlcpp::yamlcpp
|
||||
)
|
||||
|
@ -22,7 +22,6 @@ displaymanagers:
|
||||
- gdm
|
||||
- mdm
|
||||
- lxdm
|
||||
- kdm
|
||||
- greetd
|
||||
|
||||
# Enable the following settings to force a desktop environment
|
||||
|
@ -10,7 +10,7 @@ properties:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm, greetd]
|
||||
enum: [slim, sddm, lightdm, gdm, mdm, lxdm, greetd]
|
||||
minItems: 1 # Must be non-empty, if present at all
|
||||
defaultDesktopEnvironment:
|
||||
type: object
|
||||
|
@ -481,84 +481,6 @@ class DMgdm(DisplayManager):
|
||||
pass
|
||||
|
||||
|
||||
class DMkdm(DisplayManager):
|
||||
name = "kdm"
|
||||
executable = "kdm"
|
||||
|
||||
def set_autologin(self, username, do_autologin, default_desktop_environment):
|
||||
# Systems with KDM as Desktop Manager
|
||||
kdm_conf_path = os.path.join(
|
||||
self.root_mount_point, "usr/share/config/kdm/kdmrc"
|
||||
)
|
||||
# Check which path is in use: SUSE does something else.
|
||||
# Also double-check the default setting. Pick the first
|
||||
# one that exists in the target.
|
||||
for candidate_kdmrc in (
|
||||
"usr/share/config/kdm/kdmrc",
|
||||
"usr/share/kde4/config/kdm/kdmrc",
|
||||
):
|
||||
p = os.path.join(self.root_mount_point, candidate_kdmrc)
|
||||
if os.path.exists(p):
|
||||
kdm_conf_path = p
|
||||
break
|
||||
text = []
|
||||
|
||||
if os.path.exists(kdm_conf_path):
|
||||
with open(kdm_conf_path, 'r') as kdm_conf:
|
||||
text = kdm_conf.readlines()
|
||||
|
||||
with open(kdm_conf_path, 'w') as kdm_conf:
|
||||
for line in text:
|
||||
if 'AutoLoginEnable=' in line:
|
||||
if do_autologin:
|
||||
line = 'AutoLoginEnable=true\n'
|
||||
else:
|
||||
line = 'AutoLoginEnable=false\n'
|
||||
|
||||
if do_autologin and 'AutoLoginUser=' in line:
|
||||
line = "AutoLoginUser={!s}\n".format(username)
|
||||
|
||||
kdm_conf.write(line)
|
||||
else:
|
||||
return (
|
||||
_("Cannot write KDM configuration file"),
|
||||
_("KDM config file {!s} does not exist").format(kdm_conf_path)
|
||||
)
|
||||
|
||||
def basic_setup(self):
|
||||
if libcalamares.utils.target_env_call(
|
||||
['getent', 'group', 'kdm']
|
||||
) != 0:
|
||||
libcalamares.utils.target_env_call(
|
||||
['groupadd', '-g', '135', 'kdm']
|
||||
)
|
||||
|
||||
if libcalamares.utils.target_env_call(
|
||||
['getent', 'passwd', 'kdm']
|
||||
) != 0:
|
||||
libcalamares.utils.target_env_call(
|
||||
['useradd',
|
||||
'-u', '135',
|
||||
'-g', 'kdm',
|
||||
'-d', '/var/lib/kdm',
|
||||
'-s', '/bin/false',
|
||||
'-r',
|
||||
'-M',
|
||||
'kdm'
|
||||
]
|
||||
)
|
||||
|
||||
libcalamares.utils.target_env_call(
|
||||
['chown', '-R', '135:135', 'var/lib/kdm']
|
||||
)
|
||||
|
||||
def desktop_environment_setup(self, desktop_environment):
|
||||
pass
|
||||
|
||||
def greeter_setup(self):
|
||||
pass
|
||||
|
||||
|
||||
class DMlxdm(DisplayManager):
|
||||
name = "lxdm"
|
||||
executable = "lxdm"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user