Finally use of qtsingleapplication adapted to qt5
This commit is contained in:
parent
42aafd247a
commit
4d0e413fb9
28
3rdparty/qtsingleapplication/CMakeLists.txt
vendored
Normal file
28
3rdparty/qtsingleapplication/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
set(SINGLEAPP-SOURCES
|
||||||
|
qtlocalpeer.cpp
|
||||||
|
qtsingleapplication.cpp
|
||||||
|
qtsinglecoreapplication.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SINGLEAPP-MOC-HEADERS
|
||||||
|
qtlocalpeer.h
|
||||||
|
qtsingleapplication.h
|
||||||
|
qtsinglecoreapplication.h
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(SINGLEAPP-SOURCES ${SINGLEAPP-SOURCES} qtlockedfile_win.cpp)
|
||||||
|
elseif(WIN32)
|
||||||
|
set(SINGLEAPP-SOURCES ${SINGLEAPP-SOURCES} qtlockedfile_unix.cpp)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
QT5_WRAP_CPP(SINGLEAPP-SOURCES-MOC ${SINGLEAPP-MOC-HEADERS})
|
||||||
|
|
||||||
|
ADD_LIBRARY(qtsingleapplication STATIC
|
||||||
|
${SINGLEAPP-SOURCES}
|
||||||
|
${SINGLEAPP-SOURCES-MOC}
|
||||||
|
)
|
||||||
|
|
||||||
|
QT5_USE_MODULES(qtsingleapplication Core Widgets Network)
|
504
3rdparty/qtsingleapplication/LICENSE.LGPL
vendored
Normal file
504
3rdparty/qtsingleapplication/LICENSE.LGPL
vendored
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 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 Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
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 Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
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 and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
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 other code 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.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
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, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser 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 combine 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) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) 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.
|
||||||
|
|
||||||
|
d) 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.
|
||||||
|
|
||||||
|
e) 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 materials to be 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 with
|
||||||
|
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 Lesser 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 Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser 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!
|
||||||
|
|
||||||
|
|
200
3rdparty/qtsingleapplication/qtlocalpeer.cpp
vendored
Normal file
200
3rdparty/qtsingleapplication/qtlocalpeer.cpp
vendored
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qtlocalpeer.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QTime>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
#include <QLibrary>
|
||||||
|
#include <qt_windows.h>
|
||||||
|
typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
|
||||||
|
static PProcessIdToSessionId pProcessIdToSessionId = 0;
|
||||||
|
#endif
|
||||||
|
#if defined(Q_OS_UNIX)
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QtLP_Private {
|
||||||
|
#include "qtlockedfile.cpp"
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
#include "qtlockedfile_win.cpp"
|
||||||
|
#else
|
||||||
|
#include "qtlockedfile_unix.cpp"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* QtLocalPeer::ack = "ack";
|
||||||
|
|
||||||
|
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||||
|
: QObject(parent), id(appId)
|
||||||
|
{
|
||||||
|
QString prefix = id;
|
||||||
|
if (id.isEmpty()) {
|
||||||
|
id = QCoreApplication::applicationFilePath();
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
id = id.toLower();
|
||||||
|
#endif
|
||||||
|
prefix = id.section(QLatin1Char('/'), -1);
|
||||||
|
}
|
||||||
|
prefix.remove(QRegExp("[^a-zA-Z]"));
|
||||||
|
prefix.truncate(6);
|
||||||
|
|
||||||
|
QByteArray idc = id.toUtf8();
|
||||||
|
quint16 idNum = qChecksum(idc.constData(), idc.size());
|
||||||
|
socketName = QLatin1String("qtsingleapp-") + prefix
|
||||||
|
+ QLatin1Char('-') + QString::number(idNum, 16);
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
if (!pProcessIdToSessionId) {
|
||||||
|
QLibrary lib("kernel32");
|
||||||
|
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
|
||||||
|
}
|
||||||
|
if (pProcessIdToSessionId) {
|
||||||
|
DWORD sessionId = 0;
|
||||||
|
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
|
||||||
|
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server = new QLocalServer(this);
|
||||||
|
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
||||||
|
+ QLatin1Char('/') + socketName
|
||||||
|
+ QLatin1String("-lockfile");
|
||||||
|
lockFile.setFileName(lockName);
|
||||||
|
lockFile.open(QIODevice::ReadWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLocalPeer::isClient()
|
||||||
|
{
|
||||||
|
if (lockFile.isLocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool res = server->listen(socketName);
|
||||||
|
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
|
||||||
|
// ### Workaround
|
||||||
|
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
|
||||||
|
QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
|
||||||
|
res = server->listen(socketName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!res)
|
||||||
|
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||||
|
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLocalPeer::sendMessage(const QString &message, int timeout)
|
||||||
|
{
|
||||||
|
if (!isClient())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QLocalSocket socket;
|
||||||
|
bool connOk = false;
|
||||||
|
for(int i = 0; i < 2; i++) {
|
||||||
|
// Try twice, in case the other instance is just starting up
|
||||||
|
socket.connectToServer(socketName);
|
||||||
|
connOk = socket.waitForConnected(timeout/2);
|
||||||
|
if (connOk || i)
|
||||||
|
break;
|
||||||
|
int ms = 250;
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
Sleep(DWORD(ms));
|
||||||
|
#else
|
||||||
|
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!connOk)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QByteArray uMsg(message.toUtf8());
|
||||||
|
QDataStream ds(&socket);
|
||||||
|
ds.writeBytes(uMsg.constData(), uMsg.size());
|
||||||
|
bool res = socket.waitForBytesWritten(timeout);
|
||||||
|
if (res) {
|
||||||
|
res &= socket.waitForReadyRead(timeout); // wait for ack
|
||||||
|
if (res)
|
||||||
|
res &= (socket.read(qstrlen(ack)) == ack);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QtLocalPeer::receiveConnection()
|
||||||
|
{
|
||||||
|
QLocalSocket* socket = server->nextPendingConnection();
|
||||||
|
if (!socket)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (socket->bytesAvailable() < (int)sizeof(quint32))
|
||||||
|
socket->waitForReadyRead();
|
||||||
|
QDataStream ds(socket);
|
||||||
|
QByteArray uMsg;
|
||||||
|
quint32 remaining;
|
||||||
|
ds >> remaining;
|
||||||
|
uMsg.resize(remaining);
|
||||||
|
int got = 0;
|
||||||
|
char* uMsgBuf = uMsg.data();
|
||||||
|
do {
|
||||||
|
got = ds.readRawData(uMsgBuf, remaining);
|
||||||
|
remaining -= got;
|
||||||
|
uMsgBuf += got;
|
||||||
|
} while (remaining && got >= 0 && socket->waitForReadyRead(2000));
|
||||||
|
if (got < 0) {
|
||||||
|
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
|
||||||
|
delete socket;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString message(QString::fromUtf8(uMsg));
|
||||||
|
socket->write(ack, qstrlen(ack));
|
||||||
|
socket->waitForBytesWritten(1000);
|
||||||
|
delete socket;
|
||||||
|
emit messageReceived(message); //### (might take a long time to return)
|
||||||
|
}
|
76
3rdparty/qtsingleapplication/qtlocalpeer.h
vendored
Normal file
76
3rdparty/qtsingleapplication/qtlocalpeer.h
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTLOCALPEER_H
|
||||||
|
#define QTLOCALPEER_H
|
||||||
|
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "qtlockedfile.h"
|
||||||
|
|
||||||
|
class QtLocalPeer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
|
||||||
|
bool isClient();
|
||||||
|
bool sendMessage(const QString &message, int timeout);
|
||||||
|
QString applicationId() const
|
||||||
|
{ return id; }
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void messageReceived(const QString &message);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void receiveConnection();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString id;
|
||||||
|
QString socketName;
|
||||||
|
QLocalServer* server;
|
||||||
|
QtLP_Private::QtLockedFile lockFile;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char* ack;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTLOCALPEER_H
|
192
3rdparty/qtsingleapplication/qtlockedfile.cpp
vendored
Normal file
192
3rdparty/qtsingleapplication/qtlockedfile.cpp
vendored
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qtlockedfile.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtLockedFile
|
||||||
|
|
||||||
|
\brief The QtLockedFile class extends QFile with advisory locking
|
||||||
|
functions.
|
||||||
|
|
||||||
|
A file may be locked in read or write mode. Multiple instances of
|
||||||
|
\e QtLockedFile, created in multiple processes running on the same
|
||||||
|
machine, may have a file locked in read mode. Exactly one instance
|
||||||
|
may have it locked in write mode. A read and a write lock cannot
|
||||||
|
exist simultaneously on the same file.
|
||||||
|
|
||||||
|
The file locks are advisory. This means that nothing prevents
|
||||||
|
another process from manipulating a locked file using QFile or
|
||||||
|
file system functions offered by the OS. Serialization is only
|
||||||
|
guaranteed if all processes that access the file use
|
||||||
|
QLockedFile. Also, while holding a lock on a file, a process
|
||||||
|
must not open the same file again (through any API), or locks
|
||||||
|
can be unexpectedly lost.
|
||||||
|
|
||||||
|
The lock provided by an instance of \e QtLockedFile is released
|
||||||
|
whenever the program terminates. This is true even when the
|
||||||
|
program crashes and no destructors are called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \enum QtLockedFile::LockMode
|
||||||
|
|
||||||
|
This enum describes the available lock modes.
|
||||||
|
|
||||||
|
\value ReadLock A read lock.
|
||||||
|
\value WriteLock A write lock.
|
||||||
|
\value NoLock Neither a read lock nor a write lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an unlocked \e QtLockedFile object. This constructor
|
||||||
|
behaves in the same way as \e QFile::QFile().
|
||||||
|
|
||||||
|
\sa QFile::QFile()
|
||||||
|
*/
|
||||||
|
QtLockedFile::QtLockedFile()
|
||||||
|
: QFile()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
wmutex = 0;
|
||||||
|
rmutex = 0;
|
||||||
|
#endif
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an unlocked QtLockedFile object with file \a name. This
|
||||||
|
constructor behaves in the same way as \e QFile::QFile(const
|
||||||
|
QString&).
|
||||||
|
|
||||||
|
\sa QFile::QFile()
|
||||||
|
*/
|
||||||
|
QtLockedFile::QtLockedFile(const QString &name)
|
||||||
|
: QFile(name)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
wmutex = 0;
|
||||||
|
rmutex = 0;
|
||||||
|
#endif
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Opens the file in OpenMode \a mode.
|
||||||
|
|
||||||
|
This is identical to QFile::open(), with the one exception that the
|
||||||
|
Truncate mode flag is disallowed. Truncation would conflict with the
|
||||||
|
advisory file locking, since the file would be modified before the
|
||||||
|
write lock is obtained. If truncation is required, use resize(0)
|
||||||
|
after obtaining the write lock.
|
||||||
|
|
||||||
|
Returns true if successful; otherwise false.
|
||||||
|
|
||||||
|
\sa QFile::open(), QFile::resize()
|
||||||
|
*/
|
||||||
|
bool QtLockedFile::open(OpenMode mode)
|
||||||
|
{
|
||||||
|
if (mode & QIODevice::Truncate) {
|
||||||
|
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return QFile::open(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns \e true if this object has a in read or write lock;
|
||||||
|
otherwise returns \e false.
|
||||||
|
|
||||||
|
\sa lockMode()
|
||||||
|
*/
|
||||||
|
bool QtLockedFile::isLocked() const
|
||||||
|
{
|
||||||
|
return m_lock_mode != NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the type of lock currently held by this object, or \e
|
||||||
|
QtLockedFile::NoLock.
|
||||||
|
|
||||||
|
\sa isLocked()
|
||||||
|
*/
|
||||||
|
QtLockedFile::LockMode QtLockedFile::lockMode() const
|
||||||
|
{
|
||||||
|
return m_lock_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QtLockedFile::lock(LockMode mode, bool block = true)
|
||||||
|
|
||||||
|
Obtains a lock of type \a mode. The file must be opened before it
|
||||||
|
can be locked.
|
||||||
|
|
||||||
|
If \a block is true, this function will block until the lock is
|
||||||
|
aquired. If \a block is false, this function returns \e false
|
||||||
|
immediately if the lock cannot be aquired.
|
||||||
|
|
||||||
|
If this object already has a lock of type \a mode, this function
|
||||||
|
returns \e true immediately. If this object has a lock of a
|
||||||
|
different type than \a mode, the lock is first released and then a
|
||||||
|
new lock is obtained.
|
||||||
|
|
||||||
|
This function returns \e true if, after it executes, the file is
|
||||||
|
locked by this object, and \e false otherwise.
|
||||||
|
|
||||||
|
\sa unlock(), isLocked(), lockMode()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QtLockedFile::unlock()
|
||||||
|
|
||||||
|
Releases a lock.
|
||||||
|
|
||||||
|
If the object has no lock, this function returns immediately.
|
||||||
|
|
||||||
|
This function returns \e true if, after it executes, the file is
|
||||||
|
not locked by this object, and \e false otherwise.
|
||||||
|
|
||||||
|
\sa lock(), isLocked(), lockMode()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QtLockedFile::~QtLockedFile()
|
||||||
|
|
||||||
|
Destroys the \e QtLockedFile object. If any locks were held, they
|
||||||
|
are released.
|
||||||
|
*/
|
96
3rdparty/qtsingleapplication/qtlockedfile.h
vendored
Normal file
96
3rdparty/qtsingleapplication/qtlockedfile.h
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTLOCKEDFILE_H
|
||||||
|
#define QTLOCKEDFILE_H
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <QtCore/QVector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_WS_WIN) || defined(Q_OS_WIN)
|
||||||
|
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# elif defined(QT_QTLOCKEDFILE_IMPORT)
|
||||||
|
# if defined(QT_QTLOCKEDFILE_EXPORT)
|
||||||
|
# undef QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# endif
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
|
||||||
|
# elif defined(QT_QTLOCKEDFILE_EXPORT)
|
||||||
|
# undef QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QtLP_Private {
|
||||||
|
|
||||||
|
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum LockMode { NoLock = 0, ReadLock, WriteLock };
|
||||||
|
|
||||||
|
QtLockedFile();
|
||||||
|
QtLockedFile(const QString &name);
|
||||||
|
~QtLockedFile();
|
||||||
|
|
||||||
|
bool open(OpenMode mode);
|
||||||
|
|
||||||
|
bool lock(LockMode mode, bool block = true);
|
||||||
|
bool unlock();
|
||||||
|
bool isLocked() const;
|
||||||
|
LockMode lockMode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Qt::HANDLE wmutex;
|
||||||
|
Qt::HANDLE rmutex;
|
||||||
|
QVector<Qt::HANDLE> rmutexes;
|
||||||
|
QString mutexname;
|
||||||
|
|
||||||
|
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
|
||||||
|
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
LockMode m_lock_mode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
114
3rdparty/qtsingleapplication/qtlockedfile_unix.cpp
vendored
Normal file
114
3rdparty/qtsingleapplication/qtlockedfile_unix.cpp
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "qtlockedfile.h"
|
||||||
|
|
||||||
|
bool QtLockedFile::lock(LockMode mode, bool block)
|
||||||
|
{
|
||||||
|
if (!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::lock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == NoLock)
|
||||||
|
return unlock();
|
||||||
|
|
||||||
|
if (mode == m_lock_mode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m_lock_mode != NoLock)
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
struct flock fl;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
|
||||||
|
int cmd = block ? F_SETLKW : F_SETLK;
|
||||||
|
int ret = fcntl(handle(), cmd, &fl);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
|
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
m_lock_mode = mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLockedFile::unlock()
|
||||||
|
{
|
||||||
|
if (!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::unlock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLocked())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
struct flock fl;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
fl.l_type = F_UNLCK;
|
||||||
|
int ret = fcntl(handle(), F_SETLKW, &fl);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtLockedFile::~QtLockedFile()
|
||||||
|
{
|
||||||
|
if (isOpen())
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
214
3rdparty/qtsingleapplication/qtlockedfile_win.cpp
vendored
Normal file
214
3rdparty/qtsingleapplication/qtlockedfile_win.cpp
vendored
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qtlockedfile.h"
|
||||||
|
#include <qt_windows.h>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#define MUTEX_PREFIX "QtLockedFile mutex "
|
||||||
|
// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
|
||||||
|
#define MAX_READERS MAXIMUM_WAIT_OBJECTS
|
||||||
|
|
||||||
|
Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
|
||||||
|
{
|
||||||
|
if (mutexname.isEmpty()) {
|
||||||
|
QFileInfo fi(*this);
|
||||||
|
mutexname = QString::fromLatin1(MUTEX_PREFIX)
|
||||||
|
+ fi.absoluteFilePath().toLower();
|
||||||
|
}
|
||||||
|
QString mname(mutexname);
|
||||||
|
if (idx >= 0)
|
||||||
|
mname += QString::number(idx);
|
||||||
|
|
||||||
|
Qt::HANDLE mutex;
|
||||||
|
if (doCreate) {
|
||||||
|
#if (QT_VERSION < 0x050000)
|
||||||
|
QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
|
||||||
|
{ mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
|
||||||
|
#else
|
||||||
|
mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16());
|
||||||
|
#endif
|
||||||
|
if (!mutex) {
|
||||||
|
qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if (QT_VERSION < 0x050000)
|
||||||
|
QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
|
||||||
|
{ mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
|
||||||
|
#else
|
||||||
|
mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16());
|
||||||
|
#endif
|
||||||
|
if (!mutex) {
|
||||||
|
if (GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||||
|
qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
|
||||||
|
{
|
||||||
|
Q_ASSERT(mutex);
|
||||||
|
DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
|
||||||
|
switch (res) {
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLockedFile::lock(LockMode mode, bool block)
|
||||||
|
{
|
||||||
|
if (!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::lock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == NoLock)
|
||||||
|
return unlock();
|
||||||
|
|
||||||
|
if (mode == m_lock_mode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m_lock_mode != NoLock)
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!waitMutex(wmutex, block))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mode == ReadLock) {
|
||||||
|
int idx = 0;
|
||||||
|
for (; idx < MAX_READERS; idx++) {
|
||||||
|
rmutex = getMutexHandle(idx, false);
|
||||||
|
if (!rmutex || waitMutex(rmutex, false))
|
||||||
|
break;
|
||||||
|
CloseHandle(rmutex);
|
||||||
|
}
|
||||||
|
bool ok = true;
|
||||||
|
if (idx >= MAX_READERS) {
|
||||||
|
qWarning("QtLockedFile::lock(): too many readers");
|
||||||
|
rmutex = 0;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
else if (!rmutex) {
|
||||||
|
rmutex = getMutexHandle(idx, true);
|
||||||
|
if (!rmutex || !waitMutex(rmutex, false))
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!ok && rmutex) {
|
||||||
|
CloseHandle(rmutex);
|
||||||
|
rmutex = 0;
|
||||||
|
}
|
||||||
|
ReleaseMutex(wmutex);
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Q_ASSERT(rmutexes.isEmpty());
|
||||||
|
for (int i = 0; i < MAX_READERS; i++) {
|
||||||
|
Qt::HANDLE mutex = getMutexHandle(i, false);
|
||||||
|
if (mutex)
|
||||||
|
rmutexes.append(mutex);
|
||||||
|
}
|
||||||
|
if (rmutexes.size()) {
|
||||||
|
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
|
||||||
|
TRUE, block ? INFINITE : 0);
|
||||||
|
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
|
||||||
|
if (res != WAIT_TIMEOUT)
|
||||||
|
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
|
||||||
|
m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lock_mode = mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtLockedFile::unlock()
|
||||||
|
{
|
||||||
|
if (!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::unlock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLocked())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m_lock_mode == ReadLock) {
|
||||||
|
ReleaseMutex(rmutex);
|
||||||
|
CloseHandle(rmutex);
|
||||||
|
rmutex = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach(Qt::HANDLE mutex, rmutexes) {
|
||||||
|
ReleaseMutex(mutex);
|
||||||
|
CloseHandle(mutex);
|
||||||
|
}
|
||||||
|
rmutexes.clear();
|
||||||
|
ReleaseMutex(wmutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lock_mode = QtLockedFile::NoLock;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtLockedFile::~QtLockedFile()
|
||||||
|
{
|
||||||
|
if (isOpen())
|
||||||
|
unlock();
|
||||||
|
if (wmutex)
|
||||||
|
CloseHandle(wmutex);
|
||||||
|
}
|
331
3rdparty/qtsingleapplication/qtsingleapplication.cpp
vendored
Normal file
331
3rdparty/qtsingleapplication/qtsingleapplication.cpp
vendored
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qtsingleapplication.h"
|
||||||
|
#include "qtlocalpeer.h"
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtSingleApplication qtsingleapplication.h
|
||||||
|
\brief The QtSingleApplication class provides an API to detect and
|
||||||
|
communicate with running instances of an application.
|
||||||
|
|
||||||
|
This class allows you to create applications where only one
|
||||||
|
instance should be running at a time. I.e., if the user tries to
|
||||||
|
launch another instance, the already running instance will be
|
||||||
|
activated instead. Another usecase is a client-server system,
|
||||||
|
where the first started instance will assume the role of server,
|
||||||
|
and the later instances will act as clients of that server.
|
||||||
|
|
||||||
|
By default, the full path of the executable file is used to
|
||||||
|
determine whether two processes are instances of the same
|
||||||
|
application. You can also provide an explicit identifier string
|
||||||
|
that will be compared instead.
|
||||||
|
|
||||||
|
The application should create the QtSingleApplication object early
|
||||||
|
in the startup phase, and call isRunning() to find out if another
|
||||||
|
instance of this application is already running. If isRunning()
|
||||||
|
returns false, it means that no other instance is running, and
|
||||||
|
this instance has assumed the role as the running instance. In
|
||||||
|
this case, the application should continue with the initialization
|
||||||
|
of the application user interface before entering the event loop
|
||||||
|
with exec(), as normal.
|
||||||
|
|
||||||
|
The messageReceived() signal will be emitted when the running
|
||||||
|
application receives messages from another instance of the same
|
||||||
|
application. When a message is received it might be helpful to the
|
||||||
|
user to raise the application so that it becomes visible. To
|
||||||
|
facilitate this, QtSingleApplication provides the
|
||||||
|
setActivationWindow() function and the activateWindow() slot.
|
||||||
|
|
||||||
|
If isRunning() returns true, another instance is already
|
||||||
|
running. It may be alerted to the fact that another instance has
|
||||||
|
started by using the sendMessage() function. Also data such as
|
||||||
|
startup parameters (e.g. the name of the file the user wanted this
|
||||||
|
new instance to open) can be passed to the running instance with
|
||||||
|
this function. Then, the application should terminate (or enter
|
||||||
|
client mode).
|
||||||
|
|
||||||
|
If isRunning() returns true, but sendMessage() fails, that is an
|
||||||
|
indication that the running instance is frozen.
|
||||||
|
|
||||||
|
Here's an example that shows how to convert an existing
|
||||||
|
application to use QtSingleApplication. It is very simple and does
|
||||||
|
not make use of all QtSingleApplication's functionality (see the
|
||||||
|
examples for that).
|
||||||
|
|
||||||
|
\code
|
||||||
|
// Original
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
MyMainWidget mmw;
|
||||||
|
mmw.show();
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single instance
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QtSingleApplication app(argc, argv);
|
||||||
|
|
||||||
|
if (app.isRunning())
|
||||||
|
return !app.sendMessage(someDataString);
|
||||||
|
|
||||||
|
MyMainWidget mmw;
|
||||||
|
app.setActivationWindow(&mmw);
|
||||||
|
mmw.show();
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Once this QtSingleApplication instance is destroyed (normally when
|
||||||
|
the process exits or crashes), when the user next attempts to run the
|
||||||
|
application this instance will not, of course, be encountered. The
|
||||||
|
next instance to call isRunning() or sendMessage() will assume the
|
||||||
|
role as the new running instance.
|
||||||
|
|
||||||
|
For console (non-GUI) applications, QtSingleCoreApplication may be
|
||||||
|
used instead of this class, to avoid the dependency on the QtGui
|
||||||
|
library.
|
||||||
|
|
||||||
|
\sa QtSingleCoreApplication
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void QtSingleApplication::sysInit(const QString &appId)
|
||||||
|
{
|
||||||
|
actWin = 0;
|
||||||
|
peer = new QtLocalPeer(this, appId);
|
||||||
|
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleApplication object. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a argc, \a
|
||||||
|
argv, and \a GUIenabled are passed on to the QAppliation constructor.
|
||||||
|
|
||||||
|
If you are creating a console application (i.e. setting \a
|
||||||
|
GUIenabled to false), you may consider using
|
||||||
|
QtSingleCoreApplication instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
|
||||||
|
: QApplication(argc, argv, GUIenabled)
|
||||||
|
{
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleApplication object with the application
|
||||||
|
identifier \a appId. \a argc and \a argv are passed on to the
|
||||||
|
QAppliation constructor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
|
||||||
|
: QApplication(argc, argv)
|
||||||
|
{
|
||||||
|
sysInit(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(Q_WS_X11)
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
|
||||||
|
and \a cmap are passed on to the QApplication constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, visual, cmap)
|
||||||
|
{
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
|
||||||
|
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||||
|
constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, argc, argv, visual, cmap)
|
||||||
|
{
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be \a appId. \a dpy, \a argc, \a
|
||||||
|
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||||
|
constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, argc, argv, visual, cmap)
|
||||||
|
{
|
||||||
|
sysInit(appId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if another instance of this application is running;
|
||||||
|
otherwise false.
|
||||||
|
|
||||||
|
This function does not find instances of this application that are
|
||||||
|
being run by a different user (on Windows: that are running in
|
||||||
|
another session).
|
||||||
|
|
||||||
|
\sa sendMessage()
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool QtSingleApplication::isRunning()
|
||||||
|
{
|
||||||
|
return peer->isClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Tries to send the text \a message to the currently running
|
||||||
|
instance. The QtSingleApplication object in the running instance
|
||||||
|
will emit the messageReceived() signal when it receives the
|
||||||
|
message.
|
||||||
|
|
||||||
|
This function returns true if the message has been sent to, and
|
||||||
|
processed by, the current instance. If there is no instance
|
||||||
|
currently running, or if the running instance fails to process the
|
||||||
|
message within \a timeout milliseconds, this function return false.
|
||||||
|
|
||||||
|
\sa isRunning(), messageReceived()
|
||||||
|
*/
|
||||||
|
bool QtSingleApplication::sendMessage(const QString &message, int timeout)
|
||||||
|
{
|
||||||
|
return peer->sendMessage(message, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the application identifier. Two processes with the same
|
||||||
|
identifier will be regarded as instances of the same application.
|
||||||
|
*/
|
||||||
|
QString QtSingleApplication::id() const
|
||||||
|
{
|
||||||
|
return peer->applicationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the activation window of this application to \a aw. The
|
||||||
|
activation window is the widget that will be activated by
|
||||||
|
activateWindow(). This is typically the application's main window.
|
||||||
|
|
||||||
|
If \a activateOnMessage is true (the default), the window will be
|
||||||
|
activated automatically every time a message is received, just prior
|
||||||
|
to the messageReceived() signal being emitted.
|
||||||
|
|
||||||
|
\sa activateWindow(), messageReceived()
|
||||||
|
*/
|
||||||
|
|
||||||
|
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
|
||||||
|
{
|
||||||
|
actWin = aw;
|
||||||
|
if (activateOnMessage)
|
||||||
|
connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
|
||||||
|
else
|
||||||
|
disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the applications activation window if one has been set by
|
||||||
|
calling setActivationWindow(), otherwise returns 0.
|
||||||
|
|
||||||
|
\sa setActivationWindow()
|
||||||
|
*/
|
||||||
|
QWidget* QtSingleApplication::activationWindow() const
|
||||||
|
{
|
||||||
|
return actWin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
De-minimizes, raises, and activates this application's activation window.
|
||||||
|
This function does nothing if no activation window has been set.
|
||||||
|
|
||||||
|
This is a convenience function to show the user that this
|
||||||
|
application instance has been activated when he has tried to start
|
||||||
|
another instance.
|
||||||
|
|
||||||
|
This function should typically be called in response to the
|
||||||
|
messageReceived() signal. By default, that will happen
|
||||||
|
automatically, if an activation window has been set.
|
||||||
|
|
||||||
|
\sa setActivationWindow(), messageReceived(), initialize()
|
||||||
|
*/
|
||||||
|
void QtSingleApplication::activateWindow()
|
||||||
|
{
|
||||||
|
if (actWin) {
|
||||||
|
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
|
||||||
|
actWin->raise();
|
||||||
|
actWin->activateWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QtSingleApplication::messageReceived(const QString& message)
|
||||||
|
|
||||||
|
This signal is emitted when the current instance receives a \a
|
||||||
|
message from another instance of this application.
|
||||||
|
|
||||||
|
\sa sendMessage(), setActivationWindow(), activateWindow()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QtSingleApplication::initialize(bool dummy = true)
|
||||||
|
|
||||||
|
\obsolete
|
||||||
|
*/
|
101
3rdparty/qtsingleapplication/qtsingleapplication.h
vendored
Normal file
101
3rdparty/qtsingleapplication/qtsingleapplication.h
vendored
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTSINGLEAPPLICATION_H
|
||||||
|
#define QTSINGLEAPPLICATION_H
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
class QtLocalPeer;
|
||||||
|
|
||||||
|
#if defined(Q_WS_WIN) || defined(Q_OS_WIN32)
|
||||||
|
# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||||
|
# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||||
|
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# endif
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
|
||||||
|
# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||||
|
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
|
||||||
|
QtSingleApplication(const QString &id, int &argc, char **argv);
|
||||||
|
#if defined(Q_WS_X11)
|
||||||
|
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||||
|
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
|
||||||
|
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool isRunning();
|
||||||
|
QString id() const;
|
||||||
|
|
||||||
|
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
|
||||||
|
QWidget* activationWindow() const;
|
||||||
|
|
||||||
|
// Obsolete:
|
||||||
|
void initialize(bool dummy = true)
|
||||||
|
{ isRunning(); Q_UNUSED(dummy) }
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
bool sendMessage(const QString &message, int timeout = 5000);
|
||||||
|
void activateWindow();
|
||||||
|
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void messageReceived(const QString &message);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sysInit(const QString &appId = QString());
|
||||||
|
QtLocalPeer *peer;
|
||||||
|
QWidget *actWin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTSINGLEAPPLICATION_H
|
148
3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp
vendored
Normal file
148
3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp
vendored
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qtsinglecoreapplication.h"
|
||||||
|
#include "qtlocalpeer.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtSingleCoreApplication qtsinglecoreapplication.h
|
||||||
|
\brief A variant of the QtSingleApplication class for non-GUI applications.
|
||||||
|
|
||||||
|
This class is a variant of QtSingleApplication suited for use in
|
||||||
|
console (non-GUI) applications. It is an extension of
|
||||||
|
QCoreApplication (instead of QApplication). It does not require
|
||||||
|
the QtGui library.
|
||||||
|
|
||||||
|
The API and usage is identical to QtSingleApplication, except that
|
||||||
|
functions relating to the "activation window" are not present, for
|
||||||
|
obvious reasons. Please refer to the QtSingleApplication
|
||||||
|
documentation for explanation of the usage.
|
||||||
|
|
||||||
|
A QtSingleCoreApplication instance can communicate to a
|
||||||
|
QtSingleApplication instance if they share the same application
|
||||||
|
id. Hence, this class can be used to create a light-weight
|
||||||
|
command-line tool that sends commands to a GUI application.
|
||||||
|
|
||||||
|
\sa QtSingleApplication
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleCoreApplication object. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a argc and \a
|
||||||
|
argv are passed on to the QCoreAppliation constructor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
|
||||||
|
: QCoreApplication(argc, argv)
|
||||||
|
{
|
||||||
|
peer = new QtLocalPeer(this);
|
||||||
|
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleCoreApplication object with the application
|
||||||
|
identifier \a appId. \a argc and \a argv are passed on to the
|
||||||
|
QCoreAppliation constructor.
|
||||||
|
*/
|
||||||
|
QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
|
||||||
|
: QCoreApplication(argc, argv)
|
||||||
|
{
|
||||||
|
peer = new QtLocalPeer(this, appId);
|
||||||
|
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if another instance of this application is running;
|
||||||
|
otherwise false.
|
||||||
|
|
||||||
|
This function does not find instances of this application that are
|
||||||
|
being run by a different user (on Windows: that are running in
|
||||||
|
another session).
|
||||||
|
|
||||||
|
\sa sendMessage()
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool QtSingleCoreApplication::isRunning()
|
||||||
|
{
|
||||||
|
return peer->isClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Tries to send the text \a message to the currently running
|
||||||
|
instance. The QtSingleCoreApplication object in the running instance
|
||||||
|
will emit the messageReceived() signal when it receives the
|
||||||
|
message.
|
||||||
|
|
||||||
|
This function returns true if the message has been sent to, and
|
||||||
|
processed by, the current instance. If there is no instance
|
||||||
|
currently running, or if the running instance fails to process the
|
||||||
|
message within \a timeout milliseconds, this function return false.
|
||||||
|
|
||||||
|
\sa isRunning(), messageReceived()
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
|
||||||
|
{
|
||||||
|
return peer->sendMessage(message, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the application identifier. Two processes with the same
|
||||||
|
identifier will be regarded as instances of the same application.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString QtSingleCoreApplication::id() const
|
||||||
|
{
|
||||||
|
return peer->applicationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QtSingleCoreApplication::messageReceived(const QString& message)
|
||||||
|
|
||||||
|
This signal is emitted when the current instance receives a \a
|
||||||
|
message from another instance of this application.
|
||||||
|
|
||||||
|
\sa sendMessage()
|
||||||
|
*/
|
70
3rdparty/qtsingleapplication/qtsinglecoreapplication.h
vendored
Normal file
70
3rdparty/qtsingleapplication/qtsinglecoreapplication.h
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of a Qt Solutions component.
|
||||||
|
**
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTSINGLECOREAPPLICATION_H
|
||||||
|
#define QTSINGLECOREAPPLICATION_H
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
class QtLocalPeer;
|
||||||
|
|
||||||
|
class QtSingleCoreApplication : public QCoreApplication
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtSingleCoreApplication(int &argc, char **argv);
|
||||||
|
QtSingleCoreApplication(const QString &id, int &argc, char **argv);
|
||||||
|
|
||||||
|
bool isRunning();
|
||||||
|
QString id() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
bool sendMessage(const QString &message, int timeout = 5000);
|
||||||
|
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void messageReceived(const QString &message);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QtLocalPeer* peer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTSINGLECOREAPPLICATION_H
|
20
3rdparty/singleapplication/CMakeLists.txt
vendored
20
3rdparty/singleapplication/CMakeLists.txt
vendored
@ -1,20 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
set(SINGLEAPP-SOURCES
|
|
||||||
singleapplication.cpp
|
|
||||||
singlecoreapplication.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(SINGLEAPP-MOC-HEADERS
|
|
||||||
singleapplication.h
|
|
||||||
singlecoreapplication.h
|
|
||||||
)
|
|
||||||
|
|
||||||
QT5_WRAP_CPP(SINGLEAPP-SOURCES-MOC ${SINGLEAPP-MOC-HEADERS})
|
|
||||||
|
|
||||||
ADD_LIBRARY(singleapplication STATIC
|
|
||||||
${SINGLEAPP-SOURCES}
|
|
||||||
${SINGLEAPP-SOURCES-MOC}
|
|
||||||
)
|
|
||||||
|
|
||||||
QT5_USE_MODULES(singleapplication Core Network Widgets)
|
|
21
3rdparty/singleapplication/LICENSE
vendored
21
3rdparty/singleapplication/LICENSE
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015 Itay Grudev
|
|
||||||
|
|
||||||
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.
|
|
48
3rdparty/singleapplication/singleapplication.cpp
vendored
48
3rdparty/singleapplication/singleapplication.cpp
vendored
@ -1,48 +0,0 @@
|
|||||||
#include "singleapplication.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor. Checks and fires up LocalServer or closes the program
|
|
||||||
* if another instance already exists
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
SingleApplication::SingleApplication(int &argc, char **argv)
|
|
||||||
: QApplication(argc, argv)
|
|
||||||
{
|
|
||||||
QString serverName = QApplication::organizationName() + QApplication::applicationName();
|
|
||||||
serverName.replace(QRegExp("[^\\w\\-. ]"), "");
|
|
||||||
|
|
||||||
// Attempt to connect to the LocalServer
|
|
||||||
socket = new QLocalSocket();
|
|
||||||
socket->connectToServer(serverName);
|
|
||||||
if(socket->waitForConnected(1000)){
|
|
||||||
socket->close();
|
|
||||||
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function
|
|
||||||
} else {
|
|
||||||
// If the connection is insuccessful, this is the main process
|
|
||||||
// So we create a Local Server
|
|
||||||
server = new QLocalServer();
|
|
||||||
server->removeServer(serverName);
|
|
||||||
server->listen(serverName);
|
|
||||||
QObject::connect(server, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Destructor
|
|
||||||
*/
|
|
||||||
SingleApplication::~SingleApplication()
|
|
||||||
{
|
|
||||||
server->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executed when the showUp command is sent to LocalServer
|
|
||||||
*/
|
|
||||||
void SingleApplication::slotConnectionEstablished()
|
|
||||||
{
|
|
||||||
server->nextPendingConnection();
|
|
||||||
emit showUp();
|
|
||||||
}
|
|
||||||
|
|
32
3rdparty/singleapplication/singleapplication.h
vendored
32
3rdparty/singleapplication/singleapplication.h
vendored
@ -1,32 +0,0 @@
|
|||||||
#ifndef SINGLE_APPLICATION_H
|
|
||||||
#define SINGLE_APPLICATION_H
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <QLocalServer>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The SingleApplication class handles multipe instances of the same Application
|
|
||||||
* @see QApplication
|
|
||||||
*/
|
|
||||||
class SingleApplication : public QApplication
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SingleApplication(int &, char **);
|
|
||||||
~SingleApplication();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void showUp();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotConnectionEstablished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QLocalSocket *socket;
|
|
||||||
QLocalServer *server;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SINGLE_APPLICATION_H
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
#include "singlecoreapplication.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructor. Checks and fires up LocalServer or closes the program
|
|
||||||
* if another instance already exists
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
SingleCoreApplication::SingleCoreApplication(int &argc, char **argv)
|
|
||||||
: QCoreApplication(argc, argv)
|
|
||||||
{
|
|
||||||
QString serverName = QCoreApplication::organizationName() + QCoreApplication::applicationName();
|
|
||||||
serverName.replace(QRegExp("[^\\w\\-. ]"), "");
|
|
||||||
|
|
||||||
// Attempt to connect to the LocalServer
|
|
||||||
socket = new QLocalSocket();
|
|
||||||
socket->connectToServer(serverName);
|
|
||||||
if(socket->waitForConnected(1000)){
|
|
||||||
socket->close();
|
|
||||||
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function
|
|
||||||
} else {
|
|
||||||
// If the connection is insuccessful, this is the main process
|
|
||||||
// So we create a Local Server
|
|
||||||
server = new QLocalServer();
|
|
||||||
server->removeServer(serverName);
|
|
||||||
server->listen(serverName);
|
|
||||||
QObject::connect(server, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Destructor
|
|
||||||
*/
|
|
||||||
SingleCoreApplication::~SingleCoreApplication()
|
|
||||||
{
|
|
||||||
server->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executed when the showUp command is sent to LocalServer
|
|
||||||
*/
|
|
||||||
void SingleCoreApplication::slotConnectionEstablished()
|
|
||||||
{
|
|
||||||
server->nextPendingConnection();
|
|
||||||
emit showUp();
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
#ifndef SINGLE_CORE_APPLICATION_H
|
|
||||||
#define SINGLE_CORE_APPLICATION_H
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <QLocalServer>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The SingleCoreApplication class handles multipe instances of the same Application
|
|
||||||
* @see QApplication
|
|
||||||
*/
|
|
||||||
class SingleCoreApplication : public QCoreApplication
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SingleCoreApplication(int &, char **);
|
|
||||||
~SingleCoreApplication();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void showUp();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotConnectionEstablished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QLocalSocket *socket;
|
|
||||||
QLocalServer *server;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SINGLE_CORE_APPLICATION_H
|
|
||||||
|
|
@ -322,9 +322,18 @@ endif(ENABLE_VISUALISATIONS)
|
|||||||
add_subdirectory(3rdparty/qsqlite)
|
add_subdirectory(3rdparty/qsqlite)
|
||||||
include_directories("3rdparty/qsqlite")
|
include_directories("3rdparty/qsqlite")
|
||||||
|
|
||||||
add_subdirectory(3rdparty/singleapplication)
|
# When/if upstream accepts our patches then these options can be used to link
|
||||||
set(SINGLEAPPLICATION_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/singleapplication)
|
# to system installed qtsingleapplication instead.
|
||||||
set(SINGLEAPPLICATION_LIBRARIES singleapplication)
|
option(USE_SYSTEM_QTSINGLEAPPLICATION "Don't set this option unless your system QtSingleApplication library has been compiled with the Clementine patches in 3rdparty" OFF)
|
||||||
|
if(USE_SYSTEM_QTSINGLEAPPLICATION)
|
||||||
|
find_path(QTSINGLEAPPLICATION_INCLUDE_DIRS qtsingleapplication.h PATH_SUFFIXES QtSolutions)
|
||||||
|
find_library(QTSINGLEAPPLICATION_LIBRARIES QtSolutions_SingleApplication-2.6)
|
||||||
|
find_library(QTSINGLECOREAPPLICATION_LIBRARIES QtSolutions_SingleCoreApplication-2.6)
|
||||||
|
else(USE_SYSTEM_QTSINGLEAPPLICATION)
|
||||||
|
add_subdirectory(3rdparty/qtsingleapplication)
|
||||||
|
set(QTSINGLEAPPLICATION_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qtsingleapplication)
|
||||||
|
set(QTSINGLEAPPLICATION_LIBRARIES qtsingleapplication)
|
||||||
|
endif(USE_SYSTEM_QTSINGLEAPPLICATION)
|
||||||
|
|
||||||
# QtIoCompressor isn't patched, so we can use a system version if it's
|
# QtIoCompressor isn't patched, so we can use a system version if it's
|
||||||
# available
|
# available
|
||||||
|
@ -32,7 +32,7 @@ include_directories(${GLIB_INCLUDE_DIRS})
|
|||||||
include_directories(${LIBXML_INCLUDE_DIRS})
|
include_directories(${LIBXML_INCLUDE_DIRS})
|
||||||
include_directories(${GOBJECT_INCLUDE_DIRS})
|
include_directories(${GOBJECT_INCLUDE_DIRS})
|
||||||
include_directories(${LIBPROJECTM_INCLUDE_DIRS})
|
include_directories(${LIBPROJECTM_INCLUDE_DIRS})
|
||||||
include_directories(${SINGLEAPPLICATION_INCLUDE_DIRS})
|
include_directories(${QTSINGLEAPPLICATION_INCLUDE_DIRS})
|
||||||
include_directories(${QTIOCOMPRESSOR_INCLUDE_DIRS})
|
include_directories(${QTIOCOMPRESSOR_INCLUDE_DIRS})
|
||||||
include_directories(${QXT_INCLUDE_DIRS})
|
include_directories(${QXT_INCLUDE_DIRS})
|
||||||
include_directories(${ECHONEST5_INCLUDE_DIRS})
|
include_directories(${ECHONEST5_INCLUDE_DIRS})
|
||||||
@ -1240,8 +1240,7 @@ target_link_libraries(clementine_lib
|
|||||||
${GSTREAMER_LIBRARIES}
|
${GSTREAMER_LIBRARIES}
|
||||||
${GSTREAMER_APP_LIBRARIES}
|
${GSTREAMER_APP_LIBRARIES}
|
||||||
${GSTREAMER_TAG_LIBRARIES}
|
${GSTREAMER_TAG_LIBRARIES}
|
||||||
${SINGLEAPPLICATION_LIBRARIES}
|
${QTSINGLEAPPLICATION_LIBRARIES}
|
||||||
${QTSINGLECOREAPPLICATION_LIBRARIES}
|
|
||||||
${QTIOCOMPRESSOR_LIBRARIES}
|
${QTIOCOMPRESSOR_LIBRARIES}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
${SQLITE_LIBRARIES}
|
${SQLITE_LIBRARIES}
|
||||||
@ -1349,7 +1348,7 @@ if (UNIX AND NOT APPLE)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_dependencies(clementine_lib singleapplication)
|
add_dependencies(clementine_lib qtsingleapplication)
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
26
src/main.cpp
26
src/main.cpp
@ -69,8 +69,8 @@
|
|||||||
|
|
||||||
#include "tagreadermessages.pb.h"
|
#include "tagreadermessages.pb.h"
|
||||||
|
|
||||||
#include "singleapplication.h"
|
#include "qtsingleapplication.h"
|
||||||
#include "singlecoreapplication.h"
|
#include "qtsinglecoreapplication.h"
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
@ -288,7 +288,7 @@ int main(int argc, char* argv[]) {
|
|||||||
// Clementine running without needing an X server.
|
// Clementine running without needing an X server.
|
||||||
// This MUST be done before parsing the commandline options so QTextCodec
|
// This MUST be done before parsing the commandline options so QTextCodec
|
||||||
// gets the right system locale for filenames.
|
// gets the right system locale for filenames.
|
||||||
SingleCoreApplication a(argc, argv);
|
QtSingleCoreApplication a(argc, argv);
|
||||||
CheckPortable();
|
CheckPortable();
|
||||||
crash_reporting.SetApplicationPath(a.applicationFilePath());
|
crash_reporting.SetApplicationPath(a.applicationFilePath());
|
||||||
|
|
||||||
@ -297,6 +297,16 @@ int main(int argc, char* argv[]) {
|
|||||||
if (!options.Parse()) return 1;
|
if (!options.Parse()) return 1;
|
||||||
logging::SetLevels(options.log_levels());
|
logging::SetLevels(options.log_levels());
|
||||||
|
|
||||||
|
if (a.isRunning()) {
|
||||||
|
if (options.is_empty()) {
|
||||||
|
qLog(Info)
|
||||||
|
<< "Clementine is already running - activating existing window";
|
||||||
|
}
|
||||||
|
if (a.sendMessage(options.Serialize(), 5000)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Couldn't send the message so start anyway
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
@ -324,7 +334,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
IncreaseFDLimit();
|
IncreaseFDLimit();
|
||||||
|
|
||||||
SingleApplication a(argc, argv);
|
QtSingleApplication a(argc, argv);
|
||||||
|
|
||||||
// A bug in Qt means the wheel_scroll_lines setting gets ignored and replaced
|
// A bug in Qt means the wheel_scroll_lines setting gets ignored and replaced
|
||||||
// with the default value of 3 in QApplicationPrivate::initialize.
|
// with the default value of 3 in QApplicationPrivate::initialize.
|
||||||
@ -342,6 +352,10 @@ int main(int argc, char* argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
a.setQuitOnLastWindowClosed(false);
|
a.setQuitOnLastWindowClosed(false);
|
||||||
|
// Do this check again because another instance might have started by now
|
||||||
|
if (a.isRunning() && a.sendMessage(options.Serialize(), 5000)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_DARWIN
|
#ifndef Q_OS_DARWIN
|
||||||
// Gnome on Ubuntu has menu icons disabled by default. I think that's a bad
|
// Gnome on Ubuntu has menu icons disabled by default. I think that's a bad
|
||||||
@ -466,8 +480,10 @@ int main(int argc, char* argv[]) {
|
|||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
QObject::connect(&mpris, SIGNAL(RaiseMainWindow()), &w, SLOT(Raise()));
|
QObject::connect(&mpris, SIGNAL(RaiseMainWindow()), &w, SLOT(Raise()));
|
||||||
#endif
|
#endif
|
||||||
|
QObject::connect(&a, SIGNAL(messageReceived(QString)), &w,
|
||||||
|
SLOT(CommandlineOptionsReceived(QString)));
|
||||||
w.CommandlineOptionsReceived(options);
|
w.CommandlineOptionsReceived(options);
|
||||||
|
|
||||||
int ret = a.exec();
|
int ret = a.exec();
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
|
@ -1943,14 +1943,14 @@ void MainWindow::PlaylistEditFinished(const QModelIndex& index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::CommandlineOptionsReceived(
|
void MainWindow::CommandlineOptionsReceived(
|
||||||
const QByteArray& serialized_options) {
|
const QString& serialized_options) {
|
||||||
if (serialized_options == "wake up!") {
|
if (serialized_options == "wake up!") {
|
||||||
// Old versions of Clementine sent this - just ignore it
|
// Old versions of Clementine sent this - just ignore it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandlineOptions options;
|
CommandlineOptions options;
|
||||||
options.Load(serialized_options);
|
options.Load(serialized_options.toLatin1());
|
||||||
|
|
||||||
if (options.is_empty()) {
|
if (options.is_empty()) {
|
||||||
show();
|
show();
|
||||||
|
@ -222,7 +222,7 @@ signals:
|
|||||||
void AddCDTracks();
|
void AddCDTracks();
|
||||||
void AddPodcast();
|
void AddPodcast();
|
||||||
|
|
||||||
void CommandlineOptionsReceived(const QByteArray& serialized_options);
|
void CommandlineOptionsReceived(const QString &serialized_options);
|
||||||
|
|
||||||
void CheckForUpdates();
|
void CheckForUpdates();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user