yakuake: import with changes to build and work
|
@ -63,3 +63,4 @@ macro_optional_add_subdirectory (print-manager)
|
|||
macro_optional_add_subdirectory (skanlite)
|
||||
macro_optional_add_subdirectory (svgpart)
|
||||
macro_optional_add_subdirectory (thumbnailers)
|
||||
macro_optional_add_subdirectory (yakuake)
|
||||
|
|
2
yakuake/AUTHORS
Normal file
|
@ -0,0 +1,2 @@
|
|||
Eike Hein <hein@kde.org>
|
||||
Francois Chazal (Inactive; KDE 3 version)
|
12
yakuake/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
project(yakuake)
|
||||
|
||||
set(KDE_MIN_VERSION "4.7.1")
|
||||
|
||||
find_package(KDE4 ${KDE_MIN_VERSION} REQUIRED)
|
||||
|
||||
include(KDE4Defaults)
|
||||
|
||||
add_subdirectory( app )
|
||||
add_subdirectory( data )
|
||||
# FIXME: move to kde-l10n
|
||||
# add_subdirectory( po )
|
340
yakuake/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies 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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
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 program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
397
yakuake/COPYING.DOC
Normal file
|
@ -0,0 +1,397 @@
|
|||
GNU Free Documentation License
|
||||
Version 1.2, November 2002
|
||||
|
||||
|
||||
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
|
||||
51 Franklin St, 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.
|
||||
|
||||
|
||||
0. PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other
|
||||
functional and useful document "free" in the sense of freedom: to
|
||||
assure everyone the effective freedom to copy and redistribute it,
|
||||
with or without modifying it, either commercially or noncommercially.
|
||||
Secondarily, this License preserves for the author and publisher a way
|
||||
to get credit for their work, while not being considered responsible
|
||||
for modifications made by others.
|
||||
|
||||
This License is a kind of "copyleft", which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
|
||||
1. APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work, in any medium, that
|
||||
contains a notice placed by the copyright holder saying it can be
|
||||
distributed under the terms of this License. Such a notice grants a
|
||||
world-wide, royalty-free license, unlimited in duration, to use that
|
||||
work under the conditions stated herein. The "Document", below,
|
||||
refers to any such manual or work. Any member of the public is a
|
||||
licensee, and is addressed as "you". You accept the license if you
|
||||
copy, modify or distribute the work in a way requiring permission
|
||||
under copyright law.
|
||||
|
||||
A "Modified Version" of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
A "Secondary Section" is a named appendix or a front-matter section of
|
||||
the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall subject
|
||||
(or to related matters) and contains nothing that could fall directly
|
||||
within that overall subject. (Thus, if the Document is in part a
|
||||
textbook of mathematics, a Secondary Section may not explain any
|
||||
mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
The "Invariant Sections" are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License. If a
|
||||
section does not fit the above definition of Secondary then it is not
|
||||
allowed to be designated as Invariant. The Document may contain zero
|
||||
Invariant Sections. If the Document does not identify any Invariant
|
||||
Sections then there are none.
|
||||
|
||||
The "Cover Texts" are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License. A Front-Cover Text may
|
||||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||||
|
||||
A "Transparent" copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, that is suitable for revising the document
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup, or absence of markup, has been arranged to thwart
|
||||
or discourage subsequent modification by readers is not Transparent.
|
||||
An image format is not Transparent if used for any substantial amount
|
||||
of text. A copy that is not "Transparent" is called "Opaque".
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain
|
||||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||||
or XML using a publicly available DTD, and standard-conforming simple
|
||||
HTML, PostScript or PDF designed for human modification. Examples of
|
||||
transparent image formats include PNG, XCF and JPG. Opaque formats
|
||||
include proprietary formats that can be read and edited only by
|
||||
proprietary word processors, SGML or XML for which the DTD and/or
|
||||
processing tools are not generally available, and the
|
||||
machine-generated HTML, PostScript or PDF produced by some word
|
||||
processors for output purposes only.
|
||||
|
||||
The "Title Page" means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, "Title Page" means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
A section "Entitled XYZ" means a named subunit of the Document whose
|
||||
title either is precisely XYZ or contains XYZ in parentheses following
|
||||
text that translates XYZ in another language. (Here XYZ stands for a
|
||||
specific section name mentioned below, such as "Acknowledgements",
|
||||
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
|
||||
of such a section when you modify the Document means that it remains a
|
||||
section "Entitled XYZ" according to this definition.
|
||||
|
||||
The Document may include Warranty Disclaimers next to the notice which
|
||||
states that this License applies to the Document. These Warranty
|
||||
Disclaimers are considered to be included by reference in this
|
||||
License, but only as regards disclaiming warranties: any other
|
||||
implication that these Warranty Disclaimers may have is void and has
|
||||
no effect on the meaning of this License.
|
||||
|
||||
|
||||
2. VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no other
|
||||
conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
|
||||
3. COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies (or copies in media that commonly have
|
||||
printed covers) of the Document, numbering more than 100, and the
|
||||
Document's license notice requires Cover Texts, you must enclose the
|
||||
copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a computer-network location from which the general network-using
|
||||
public has access to download using public-standard network protocols
|
||||
a complete Transparent copy of the Document, free of added material.
|
||||
If you use the latter option, you must take reasonably prudent steps,
|
||||
when you begin distribution of Opaque copies in quantity, to ensure
|
||||
that this Transparent copy will remain thus accessible at the stated
|
||||
location until at least one year after the last time you distribute an
|
||||
Opaque copy (directly or through your agents or retailers) of that
|
||||
edition to the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to give
|
||||
them a chance to provide you with an updated version of the Document.
|
||||
|
||||
|
||||
4. MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
B. List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has fewer than five),
|
||||
unless they release you from this requirement.
|
||||
C. State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
D. Preserve all the copyright notices of the Document.
|
||||
E. Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
F. Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
G. Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
H. Include an unaltered copy of this License.
|
||||
I. Preserve the section Entitled "History", Preserve its Title, and add
|
||||
to it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section Entitled "History" in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
J. Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the "History" section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
K. For any section Entitled "Acknowledgements" or "Dedications",
|
||||
Preserve the Title of the section, and preserve in the section all
|
||||
the substance and tone of each of the contributor acknowledgements
|
||||
and/or dedications given therein.
|
||||
L. Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
M. Delete any section Entitled "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
N. Do not retitle any existing section to be Entitled "Endorsements"
|
||||
or to conflict in title with any Invariant Section.
|
||||
O. Preserve any Warranty Disclaimers.
|
||||
|
||||
If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section Entitled "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties--for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
|
||||
5. COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice, and that you preserve all their Warranty Disclaimers.
|
||||
|
||||
The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections Entitled "History"
|
||||
in the various original documents, forming one section Entitled
|
||||
"History"; likewise combine any sections Entitled "Acknowledgements",
|
||||
and any sections Entitled "Dedications". You must delete all sections
|
||||
Entitled "Endorsements".
|
||||
|
||||
|
||||
6. COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other documents
|
||||
released under this License, and replace the individual copies of this
|
||||
License in the various documents with a single copy that is included in
|
||||
the collection, provided that you follow the rules of this License for
|
||||
verbatim copying of each of the documents in all other respects.
|
||||
|
||||
You may extract a single document from such a collection, and distribute
|
||||
it individually under this License, provided you insert a copy of this
|
||||
License into the extracted document, and follow this License in all
|
||||
other respects regarding verbatim copying of that document.
|
||||
|
||||
|
||||
7. AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, is called an "aggregate" if the copyright
|
||||
resulting from the compilation is not used to limit the legal rights
|
||||
of the compilation's users beyond what the individual works permit.
|
||||
When the Document is included in an aggregate, this License does not
|
||||
apply to the other works in the aggregate which are not themselves
|
||||
derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one half of
|
||||
the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that bracket the Document within the aggregate, or the
|
||||
electronic equivalent of covers if the Document is in electronic form.
|
||||
Otherwise they must appear on printed covers that bracket the whole
|
||||
aggregate.
|
||||
|
||||
|
||||
8. TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License, and all the license notices in the
|
||||
Document, and any Warranty Disclaimers, provided that you also include
|
||||
the original English version of this License and the original versions
|
||||
of those notices and disclaimers. In case of a disagreement between
|
||||
the translation and the original version of this License or a notice
|
||||
or disclaimer, the original version will prevail.
|
||||
|
||||
If a section in the Document is Entitled "Acknowledgements",
|
||||
"Dedications", or "History", the requirement (section 4) to Preserve
|
||||
its Title (section 1) will typically require changing the actual
|
||||
title.
|
||||
|
||||
|
||||
9. TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document except
|
||||
as expressly provided for under this License. Any other attempt to
|
||||
copy, modify, sublicense or distribute the Document 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.
|
||||
|
||||
|
||||
10. FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions
|
||||
of the GNU Free Documentation 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. See
|
||||
http://www.gnu.org/copyleft/.
|
||||
|
||||
Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation.
|
||||
|
||||
|
||||
ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
Copyright (c) YEAR YOUR NAME.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
A copy of the license is included in the section entitled "GNU
|
||||
Free Documentation License".
|
||||
|
||||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||||
replace the "with...Texts." line with this:
|
||||
|
||||
with the Invariant Sections being LIST THEIR TITLES, with the
|
||||
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||||
|
||||
If you have Invariant Sections without Cover Texts, or some other
|
||||
combination of the three, merge those two alternatives to suit the
|
||||
situation.
|
||||
|
||||
If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
457
yakuake/ChangeLog
Normal file
|
@ -0,0 +1,457 @@
|
|||
Changes in 2.9.9:
|
||||
* Yakuake now sports a standard KDE "Configure Notifications..." item in
|
||||
its menu. The startup notification popup configuration has moved there,
|
||||
and newly-added notification events covered below are found there.
|
||||
* It is now possible to monitor sessions (or individual terminals within
|
||||
them) for activity or silence. See the tab context menu or the keyboard
|
||||
shortcuts to toggle monitoring, and the new "Configure Notifications"
|
||||
dialog mentioned above to configure what happens when activity or silence
|
||||
are detected in a monitored session or terminal (by default a desktop
|
||||
notification popup is triggered for each).
|
||||
Note that repeated activity in a terminal does not result in repeated
|
||||
notifications for that terminal: After the first notification, activity
|
||||
monitoring has to be disabled or reenabled, or the active session
|
||||
switched, or the window closed - only then another activity notification
|
||||
will be shown.
|
||||
* Support for Get Hot New Stuff for skins has been added. See the new "Get
|
||||
New Skins..." button below the skin list in the Appearance page of the
|
||||
config dialog.
|
||||
* When the window is set not to show on all virtual desktops and is not
|
||||
residing on the current virtual desktop, but is open (i.e. set to stay
|
||||
open regardless of focus loss), the Open/Retract action normally used
|
||||
to either retract it, or, when the option to also use the action to
|
||||
focus the window is enabled, cause the window manager to switch to the
|
||||
virtual desktop the window resides on. The former case, i.e. when the
|
||||
option to also use the action to focus the window is disabled, has now
|
||||
been changed to move the window to the current virtual desktop and focus
|
||||
it, rather than retract it.
|
||||
* Yakuake now automatically retracts after the last open tab closes.
|
||||
* A number of default keyboard shortcuts have been changed to reestablish
|
||||
consistency with Konsole, which introduced changed defaults in KDE Soft-
|
||||
ware Compilation v4.6.
|
||||
* Invoking the window manager maximization feature now results in a
|
||||
Yakuake window with 100% width and height instead of the unresized win-
|
||||
dow getting moved to the top-left corner of the screen. However, restore
|
||||
is not supported as it doesn't easily fit with Yakuake's window size
|
||||
state model.
|
||||
* Tweaks to the code Yakuake uses to make itself the active window when
|
||||
invoked should improve compatibility with more window managers, particu-
|
||||
larly xfwm.
|
||||
* The D-Bus API has been expanded further to cover the new activity and
|
||||
silence monitoring options, as well as with additional methods related
|
||||
to retrieving information about the keyboard input enabled state for
|
||||
sessions and terminals.
|
||||
* The addSession* and split* D-Bus calls now return the id of the newly-
|
||||
created session or terminal, or -1 if creating a new session or terminal
|
||||
was not possible.
|
||||
* Made sure that the activeTerminalId D-Bus call always returns something
|
||||
useful after an addSessionTwo*/Quad call, even when the window is closed
|
||||
while the call is made. Previously, activeTerminalId could return -1 in
|
||||
this situation because there technically is no active terminal until the
|
||||
window is opened and a focus event causes one to become active. Now the
|
||||
terminal that will receive focus once the window is opened is immediate-
|
||||
ly declared the active terminal.
|
||||
* The "Help" button was removed from the configuration dialog since there
|
||||
currently is no handbook included.
|
||||
* Fixes to the window geometry and placement calculation in multi-screen
|
||||
setups and with panels located on screen edges other than the bottom
|
||||
edge.
|
||||
* Fixed a bug causing the "Disable Keyboard Input -> For This Session"
|
||||
checkbox in the context menu of a multi-terminal session to become
|
||||
enabled when keyboard input was disabled for any of the individual ter-
|
||||
minals, rather than only when all terminals have it disabled (i.e. what
|
||||
enabling the checkbox manually actually does).
|
||||
* Fixed errors in the tab stop order in several pages of the configuration
|
||||
dialog.
|
||||
* Fixed the message shown on stderr when Yakuake is already running to
|
||||
refer to toggling rather than opening the window, since that is what a
|
||||
repeated execution actually does - if the window is already open, it
|
||||
will be closed at this time.
|
||||
* Code cleanups, including porting away from recently deprecated KDE Plat-
|
||||
form APIs for future-compatibility.
|
||||
* The KDE4FAQ document included in the tarball has been updated.
|
||||
* Yakuake now depends on KDE Platform 4.7.1 or newer.
|
||||
|
||||
|
||||
Changes in 2.9.8:
|
||||
* Added a new "Ask the window manager to perform the animation" option to
|
||||
the animation settings (only shown if Yakuake is running in a KDE Plasma
|
||||
Workspace v4.6 or newer). If this option is enabled (it is by default)
|
||||
and the KDE Desktop Effect "Sliding Popups" is enabled as well, the ani-
|
||||
mation will be performed by KDE's window manager KWin, for much improved
|
||||
smoothness on many systems.
|
||||
* Added keyboard shortcuts to attempt to grow the active terminal in the
|
||||
left, right, top or bottom direction by 10px, as well as D-Bus calls to
|
||||
attempt to grow any particular terminal by a given amount of pixels in
|
||||
one of these directions.
|
||||
* Skin authors can now control whether the title bar text is set in a bold
|
||||
weight or not with the 'bold' key in the 'Text' group of title.skin. The
|
||||
default is to use a bold weight to preserve existing behavior.
|
||||
* Fixed a bug causing the "Keep above other windows" preference not to be
|
||||
respected immediately when toggling the "Keep window open when it loses
|
||||
focus" preference from the title bar or the main menu.
|
||||
* The contents of the "Screen" sub-menu in the main menu now get updated
|
||||
when the number of screens attached to the system changes.
|
||||
* Yakuake now depends on KDE 4.3.
|
||||
|
||||
|
||||
Changes in 2.9.7:
|
||||
* Fixed compilation with gcc 4.4 (missing cstdio include).
|
||||
* Fixed quit action bypassing the "Confirm quit when more than one session
|
||||
is open" setting.
|
||||
* When "Prevent Closing" is toggled for a tab an appropriate icon will now
|
||||
be shown on the tab label. The icon can be provided by the skin, or, if
|
||||
the skin does not provide one, it will be procured from the system icon
|
||||
theme.
|
||||
* Thanks to API improvements in the KDE libraries in KDE SC 4.4 a KNotify
|
||||
notification is now used for announcing that Yakuake was started success-
|
||||
fully, rather than the passive popup in the top-left desktop corner used
|
||||
with older versions of the KDE platform.
|
||||
* Middle-clicking a tab closes it now, consistent with many other KDE apps.
|
||||
* Tabs can now also be dragged using middle-mouse, again for consistency
|
||||
with many other KDE apps.
|
||||
* Fixed a bug where dragging an inactive tab to a new position on the tab
|
||||
bar would show the tab as selected after the drop, but the terminal
|
||||
area wouldn't actually show the corresponding terminal(s).
|
||||
* Fixed a bug causing the empty area of the tab bar to become draggable as
|
||||
if if was the last tab that had been clicked.
|
||||
* Fixed a bug causing the title bar corner images of a theme not to be shown
|
||||
when they don't have an alpha channel.
|
||||
* Fixed a bug causing the window to appear at a distance away from the top
|
||||
edge of the screen matching the height of a panel at the top edge of
|
||||
another screen in a multi-screen setup.
|
||||
|
||||
|
||||
Changes in 2.9.6:
|
||||
* Fixed interactive rename of sessions not working reliably - either failing
|
||||
to implement a rename or renaming the wrong session - once tabs had been
|
||||
moved or sessions closed, due to a mixup of tab indices and session IDs in
|
||||
the rename code.
|
||||
* Updated the application icon in the bottom-left corner graphic of the de-
|
||||
fault skin.
|
||||
* Updated the icon for the default skin in the configuration dialog's skin
|
||||
list to the new application icon.
|
||||
|
||||
|
||||
Changes in 2.9.5:
|
||||
* Added a new framework, referred to as the visual event overlay, to display
|
||||
notifications (and potentially other information) on top of the terminals.
|
||||
It's used for a number of new features found in this release, as described
|
||||
in their separate entries.
|
||||
* Added an option to visually indicate the newly-focussed terminal when mo-
|
||||
ving focus in a session with multiple terminals (i.e. via splits), or the
|
||||
currently focussed terminal when switching to a session with multiple ter-
|
||||
minals. This make the lives of users easier who prefer to use the "I-Beam"
|
||||
or "Underline" cursors styles in the terminal, as those cursor styles do
|
||||
not indicate terminal focus as the "Block" style does. The visual indica-
|
||||
tion used here is a brief, translucent overlay in the global color scheme's
|
||||
hover decoration color. This feature is realized using the new visual event
|
||||
overlay described in a separate entry.
|
||||
* Added a feature to disable keyboard input for all or individual terminals
|
||||
in a session. Both variants are available from the tab context menu; the
|
||||
session-wide toggle is also available in the keyboard shortcuts configura-
|
||||
tion. When typing into a terminal that has keyboard input disabled the
|
||||
terminal will briefly flash red. When hovering one of the per-terminal
|
||||
toggles in the context menu, the affected terminal will be highlighted
|
||||
in the global color scheme's hover decoration color. The latter two aspects
|
||||
of this new feature have been realized using the new visual event overlay
|
||||
described in a separate entry. Furthermore, new D-Bus interfaces have been
|
||||
added to get/set this state bit for both sessions and terminals.
|
||||
* Added a feature to lock a session to prevent it from being closed acciden-
|
||||
tally, available from the tab context menu as well as in the keyboard short-
|
||||
cuts configuration. When trying to close a locked session or its active ter-
|
||||
minal via Yakuake's own actions/shortcuts, a warning dialog will be display-
|
||||
ed, and also when trying to quit Yakuake with any locked sessions. Note that
|
||||
this doesn't cover closing a terminal from within the Konsole KPart provi-
|
||||
ding the terminal (such as running "exit" or via the terminal's context
|
||||
menu), however. New D-Bus interfaces have been added to get/set this state
|
||||
bit for sessions.
|
||||
* Added support for moving tabs on the tab bar by drag and drop.
|
||||
* Added an option to open the application window after program start.
|
||||
* Improved graphics for the window state lock button in the default skin.
|
||||
* Added a slightly improved version of the application icon (again done by
|
||||
Oxygen lead artist Nuno Pinheiro) along with a 256x256px variant.
|
||||
* Added D-Bus interfaces for splitting.
|
||||
* Added the frequently-requested 'sessionIdForTerminalId(int terminalId)'
|
||||
and 'terminalIdsForSessionId(int sessionId)' D-Bus interfaces.
|
||||
* The auto-open-on-mouse-pointer-hitting-the-screen edge feature now checks
|
||||
the position of the mouse pointer against the actual position and width of
|
||||
the window rather than triggering on the entire screen edge. This way, the
|
||||
screen corners are freed up e.g. for KWin Desktop Effects triggers with
|
||||
the default Yakuake window width of 90% work area width.
|
||||
* Rewrote fullscreen handling, fixing bugs such as exiting fullscreen mode
|
||||
on virtual desktop switch.
|
||||
* Rewrote the translucency support not to use X11-specific code on KDE 4.3 or
|
||||
higher.
|
||||
* Fixed a regression from the background painting changes in 2.9.4 that
|
||||
caused splitter handles between terminals to appear in the user-confi-
|
||||
gured background color.
|
||||
* Fixed crashes when closing sessions with certain split setups (also on quit).
|
||||
* Fixed crash when changing window width/height from the menu with Qt 4.5
|
||||
(also generally improves efficiency of window size changes).
|
||||
* Fixed the 'removeTerminal(int terminalId)' D-Bus call always closing the
|
||||
active terminal of the session containing the target terminal, rather than
|
||||
the target terminal.
|
||||
* Fixed interactive tab rename always renaming the active tab, rather than
|
||||
the tab the line edit was invoked for and shown on top of.
|
||||
* Fixed the interactive rename line edit possibly getting hidden also when a
|
||||
session other than the one that is being renamed gets deleted, rather than
|
||||
just when the session that is being renamed gets deleted.
|
||||
* Slightly improved options layout on the Behavior page of the configuration
|
||||
dialog and made sure that the skin list on the Appearance page scrolls so
|
||||
that the selected skin is visible when the list is shown.
|
||||
* On KDE 4.2 and higher, the first-run dialog now no longer allows setting
|
||||
a multi-key shortcut to open/close the window, consistent with the short-
|
||||
cut configuration dialog (the required API is new in 4.2). The reason
|
||||
multi-key global shortcuts are not allowed in KDE is that they don't work.
|
||||
* Fixed linking with the new gold linker in binutils.
|
||||
* Updated KDE4FAQ file (animation performance).
|
||||
|
||||
|
||||
Changes in 2.9.4:
|
||||
* Added a new Oxygen-style application icon made by Nuno Pinheiro. In addi-
|
||||
tion to fitting much better into KDE 4 visually, it's now also available
|
||||
in all standard sizes up to 128px plus as SVG (whereas the old icon was
|
||||
only available in 16px and 32px), meaning you won't see a blurry Yakuake
|
||||
icon in various places in KDE 4 anymore as you did before.
|
||||
* Added a setting to fill with the configurable background color at a given
|
||||
opacity before painting the skin elements. In effect, this allows some con-
|
||||
trol over the opacity and color tint of translucent areas of the skin.
|
||||
* Fixed a bug that made it impossible to move a session located at the
|
||||
start or end of the tab bar back after moving it left/right using the
|
||||
keyboard shortcuts.
|
||||
* Various updates to the KDE4FAQ file related to performance and rendering.
|
||||
|
||||
|
||||
Changes in 2.9.3:
|
||||
* Added an option to focus individual sub-terminals as the mouse pointer is
|
||||
moved over them.
|
||||
* Added an option to explicitly control whether the window will be shown on
|
||||
all (virtual) desktops. Defaults to true, as before.
|
||||
* Made the error condition when Yakuake is unable to load the Konsole KPart
|
||||
component non-destructive, i.e. being unable to load the KPart will no
|
||||
longer end in an unavoidable application quit. Instead, a good-looking
|
||||
warning will be shown where the terminal would normally be. This also
|
||||
takes care of the edge case in which Konsole is uninstalled while Yakuake
|
||||
is already running, so that existing terminals won't be lost.
|
||||
* Fixed a regression that caused the "Show title bar contents in tab labels"
|
||||
preference to no longer work.
|
||||
* Fixed tab label not immediately being updated upon creating a new session
|
||||
when "Show title bar contents in tab labels" is enabled.
|
||||
|
||||
|
||||
Changes in 2.9.2:
|
||||
* The item background in the skin list is now determined by the style en-
|
||||
gine if on KDE 4.1 (including pre-release versions) and hence Qt 4.4.
|
||||
* Fixed title bar not immediately being updated upon creating a new single-
|
||||
terminal session.
|
||||
* Fixed shortcuts with versions of KDE 4 trunk (4.1) from April 22nd 2008
|
||||
and newer. The Konsole KPart now defaults to overriding shortcuts, and
|
||||
Yakuake must do additional work to continue to receive them.
|
||||
|
||||
|
||||
Changes in 2.9.1:
|
||||
* Starting Yakuake a second time now toggles the window state, making it
|
||||
possible to open and retract Yakuake from a panel button or by simply
|
||||
running the executable.
|
||||
* Disabled standard startup notifications ("Launch Feedback") for Yakuake.
|
||||
* Fixed Open/Retract action not working with versions of KDE 4 trunk (4.1)
|
||||
after March 10th, 2008.
|
||||
* Fixed a bug that could cause actions also available from the tab context
|
||||
menu to operate on the wrong session when triggered by keyboard shortcut
|
||||
and the context menu had been used previously.
|
||||
* Fixed the "Close Active Terminal", "Split Left/Right" and "Split Top/Bot-
|
||||
tom" actions not operating on the correct session when activated from the
|
||||
context menu of a tab other than the active tab.
|
||||
* Some additions to the KDE4FAQ file.
|
||||
|
||||
|
||||
Changes in 2.9 (KDE 4):
|
||||
- Changes since 2.9-beta1:
|
||||
* Changed default shortcut of the "Quit" action to Ctrl+Shift+Q for consis-
|
||||
tency with Konsole and to avoid clashing with the KPart's "Resume output"
|
||||
action.
|
||||
* Fixed a bug that caused the "Previous Session" action not to work when
|
||||
trying to move from a newer to an older session after closing sessions
|
||||
created and located inbetween.
|
||||
* Fixed in Konsole: Addressed a shortcut overload that prevented the "Next
|
||||
Session" and "Previous Session" default shortcuts from working when using
|
||||
Qt 4.4. The fix will be included in KDE 4.0.3 and higher.
|
||||
* Expanded KDE4FAQ file to cover problems with certain graphics drivers and
|
||||
kwin effects.
|
||||
* Greatly expanded translation coverage.
|
||||
|
||||
- Changes in 2.9-beta1:
|
||||
* Rewritten from scratch for KDE 4.
|
||||
* Changed license from "GPL v2 or later" to "GPL v2 or v3 or any later ver-
|
||||
sion accepted by the membership of KDE e.V.".
|
||||
* Replaced pseudo-translucency with XComposite translucency (aka "real trans-
|
||||
lucency") support (see KDE4FAQ for caveats).
|
||||
* The context menus of tabs and the main menu now sport additional actions
|
||||
to manipulate Konsole profile settings.
|
||||
* The tab bar itself has gained a context menu as well.
|
||||
* An option to dynamically update tab labels with information about the
|
||||
content of the active terminal has been added.
|
||||
* The skin engine is now more robust when it comes to processing invalid or
|
||||
corrupted skins.
|
||||
* Skins are now stored in the skins/ sub-directory of the app's data dir.
|
||||
* The window geometry is now updated dynamically when the work area of the
|
||||
screen changes.
|
||||
* The window title bar now appropriately uses the window title font from the
|
||||
KDE font settings rather than the general UI font.
|
||||
* Changes to the KDE font settings are now applied at runtime.
|
||||
* Support for right-to-left layouts in the configuration dialog has been
|
||||
improved.
|
||||
* A bug where the "Rename Session..." action would operate on the wrong
|
||||
session has been fixed.
|
||||
* Yakuake no longer crashes when Konsole is not installed, but instead can-
|
||||
cels startup with a preceding error dialog.
|
||||
* Lots of internal cleanup.
|
||||
|
||||
|
||||
Changes in 2.8.1 (KDE 3):
|
||||
* Added an option to control whether the Yakuake window keeps above other
|
||||
windows.
|
||||
* Improved experience for non-KDE users by disabling KRootPixmap-based
|
||||
pseudo-translucency for them. Gets rid of rendering errors with skins
|
||||
that make use of the alpha channel. Replaced by configurable skin back-
|
||||
ground color.
|
||||
* Fix leftover gap below the window at 100% height or in fullscreen mode.
|
||||
* Added option to automatically open the Yakuake window when the pointer
|
||||
touches the screen edge it lives on.
|
||||
|
||||
|
||||
Changes in 2.8:
|
||||
- Changes since 2.8-beta1:
|
||||
* Made the new behavior of the Open/Retract action focussing an already
|
||||
open Yakuake window optional.
|
||||
* The Xinerama screen setting is now updated when the window is moved to
|
||||
a different screen using facilities outside of Yakuake itself, such as
|
||||
the new shortcuts provided by Lubos Lunak's Xinerama Improvements patch-
|
||||
set for KWin 3.5.x. The window size and position get updated to fit the
|
||||
new bounding box accordingly.
|
||||
* Initial session tab label naming is now consistent with Konsole. Instead
|
||||
of naively incrementing the shell number, the lowest available number is
|
||||
used.
|
||||
* Swapped horizontal and vertical split actions for consistency with Kate.
|
||||
* Added slotSessionName() and slotSessionName(int session_id) DCOP Calls.
|
||||
* Added sessionIdList() and terminalIdList(int session_id) DCOP calls.
|
||||
* Naming consistency improvements in the DCOP interface.
|
||||
* Added more What's This help in the config dialog.
|
||||
* Minor interface wording improvements.
|
||||
* Greatly expanded translation coverage.
|
||||
|
||||
- Changes in 2.8-beta1:
|
||||
* Added a proper config dialog. Scale and position settings are previewed in
|
||||
real-time as the controls are moved.
|
||||
* Added a Skins page to the config dialog, allowing to list, choose, install and
|
||||
remove (given the necessary write permissions) skins. The skin format has been
|
||||
slightly augmented to allow skins to ship a preview icon for the list. Skins can
|
||||
be switched at runtime without a restart.
|
||||
* The Plastik skin by Daniel 'suslik' D. has been added to the base package.
|
||||
* Added support for splitting a session into multiple terminals. Horizontal and
|
||||
vertical splits can be added and removed at will, as well as resized and
|
||||
collapsed. To add a split at the active terminal's position, use the keyboard
|
||||
shortcuts or the session tab context menu. To open a session preconfigred with
|
||||
a certain split layout click and hold the New Session button on the tab bar,
|
||||
then choose from the list, or set up keyboard shortcuts for the preconfigured
|
||||
session types in the shortcut dialog.
|
||||
* The main menu has been redesigned to conform more to established KDE practices
|
||||
in layout and naming. Several items have been added corresponding to new Yakuake
|
||||
features.
|
||||
* Added a fullscreen mode.
|
||||
* Improved support for Xinerama multi-head setups.
|
||||
* Added a first-run dialog to allow changing the open/close shortcut before it
|
||||
is needed. Note: First-time users of this Yakuake version will be greeted by
|
||||
this dialog as well.
|
||||
* Added an About dialog.
|
||||
* The startup notification popup can now be disabled in the config dialog.
|
||||
* Activating the open/close shortcut will now bring the Yakuake window to the
|
||||
foreground and focus it if it was already open but unfocussed, at popular
|
||||
request.
|
||||
* Opening dialogs from Yakuake will no longer cause the window to retract.
|
||||
* Tabs can now be moved. Added corresponding keyboard shortcuts.
|
||||
* Tabs now have context menus containing several relevant actions, such as
|
||||
moving and closing them.
|
||||
* Double-clicking the tab-bar will now open a new session, consistent with
|
||||
Konsole and other KDE applications.
|
||||
* Renaming a tab using the in-line edit feature now requires a double-click on
|
||||
the tab, consistent with established KDE behavior.
|
||||
* The in-line tab renaming control can now be cancelled with ESC.
|
||||
* Fixed the interaction model of the tab bar and the buttons to allow cancelling
|
||||
activations by releasing the mouse button outside of them.
|
||||
* Added various new keyboard shortcuts corresponding to new Yakuake features and
|
||||
improved consistency with Konsole in existing shortcuts (e.g. added the
|
||||
alternate new session shortcut from Konsole).
|
||||
* Added keyboard shortcuts to switch to session 1 through 12.
|
||||
* Added keyboard shortcuts to adjust the width and height of the window.
|
||||
* Added an action and shortcut to paste the X11 selection buffer.
|
||||
* Added an action to quit Yakuake.
|
||||
* Made the quit warning with multiple open sessions behave consistently with
|
||||
Konsole.
|
||||
* Greatly expanded DCOP interface. Added various new calls corresponding to new
|
||||
Yakuake features. Made it easier to get information about the application's
|
||||
state out of it, e.g. the title text of a session or sub-terminal. Fixed bugs
|
||||
that caused related calls to reply with incorrect information.
|
||||
* Added What's This help and tooltips to interface elements.
|
||||
* Optimized the title bar to avoid unnecessary repaints.
|
||||
* Fixed crashes when using the slotRunCommandInSession DCOP call due to lack of
|
||||
bounds-checking. Fixed a similar problem with slotRenameSession.
|
||||
* Bugs that caused the background updating of translucent parts of the Yakuake
|
||||
window to stop have been fixed.
|
||||
* Adding a translucent session while the window is closed should no longer
|
||||
result in a corrupted terminal background when opening the Yakuake window.
|
||||
* Yakuake will now fall back to the default skin on startup if the skin stored
|
||||
in the settings cannot be found, rather than crash.
|
||||
* Fixed a crash when loading non-translucent button images from skins.
|
||||
* Bugs that caused the quick access options in the menu to come out of sync with
|
||||
the actual settings have been fixed.
|
||||
* Fixed " - " postfix showing after the session title text when using skins
|
||||
without their own postfix.
|
||||
* Fixed a crash when a terminal in a tab other than the currently selected tab
|
||||
exits.
|
||||
* Ported preferences handling to KDE's KConfigXT framework. Aside from cleaner
|
||||
code, this improves over the old preferences handling by avoiding unnecessary
|
||||
disk activity (and thus spurious hard drive spin-ups on laptop computers and
|
||||
other battery-bound devices).
|
||||
* Disabled startup notifications (i.e. KDE's bouncing cursor) for Yakuake.
|
||||
* Updated the installation colation of the .desktop menu file to conform to
|
||||
modern XDG standards.
|
||||
|
||||
|
||||
Changes in 2.7.5:
|
||||
* Further translations have been added.
|
||||
* Yakuake no longer spawns login shells in new sessions.
|
||||
* A keyboard shortcut to rename the selected session has been added.
|
||||
* The default keyboard shortcuts and their names are now consistent with
|
||||
Konsole.
|
||||
* A bug that led to the tab bar not updating after a slotSelectSession DCOP
|
||||
call was issued has been fixed.
|
||||
* A bug that could lead to the slotRenameSession DCOP call failing to set a
|
||||
session label after an older session had been closed has been fixed.
|
||||
* Upon attempting to set an all-whitespace session label, the label will now
|
||||
fall back to its prior setting rather than a default label.
|
||||
* Yakuake will now display a warning before quitting the application with
|
||||
multiple tabs open.
|
||||
|
||||
|
||||
Changes in 2.7.4:
|
||||
* A bug in the Makefiles that led to the configure script being run twice has
|
||||
been fixed.
|
||||
* The source code is now localizable. First translations are included.
|
||||
* A bug that could result in a crash on quit has been fixed.
|
||||
* A bug that could prevent the first line in a new session from being used up to
|
||||
the full width of the terminal has been fixed.
|
||||
* The COLORTERM environment variable is now being set in new sessions,
|
||||
triggering the color detection of Midnight Commander.
|
||||
* The default session labels are now consistent with Konsole.
|
||||
* Whitespace at the beginning or end of session labels will now be trimmed.
|
||||
* Setting all-whitespace session labels is no longer possible.
|
||||
|
||||
|
||||
Changes in 2.7.3:
|
||||
* Inline renaming of tabs by double-clicking on the tab label
|
||||
* Processes can now interact with titlebar text
|
||||
* DCOP call slotToggleState to open/close Yakuake
|
||||
* DCOP call slotGetSelectedSession
|
||||
* DCOP call slotSetTitleText
|
72
yakuake/KDE4FAQ
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
Yakuake KDE 4 FAQ (Last update: March 7th, 2011)
|
||||
==================================================
|
||||
|
||||
Q: The open/retract animation is very jerky for me. Why is that?
|
||||
|
||||
A: First of, Yakuake currently employs two entirely different animation
|
||||
strategies depending on user settings and the environment it is run
|
||||
in. By default, when running in a KDE Plasma workspace v4.6 or newer
|
||||
that has OpenGL Desktop Effects (i.e., compositing) and specifically
|
||||
the "Slide" effect enabled, Yakuake will ask KDE's window manager to
|
||||
perform the animation on its behalf. There are currently no known
|
||||
performance problems with this animation strategy.
|
||||
|
||||
When Yakuake is run in an older version of the KDE Plasma workspace,
|
||||
a KDE Plasma workspace with Desktop Effects or the "Slide" effect dis-
|
||||
abled (or set to use XRender instead of OpenGL), or outside a KDE
|
||||
Plasma workspace, it will fall back to the older animation strategy of
|
||||
progressively adjusting (growing or shrinking) the window's mask and
|
||||
moving the title bar along the mask's lower edge to simulate movement.
|
||||
It will also fall back to this strategy when the user explicitly dis-
|
||||
ables the window manager-assisted animation strategy in the configura-
|
||||
tion dialog.
|
||||
|
||||
This older animation strategy appears to have performance problems
|
||||
in combination with older versions of the proprietary nVidia graphics
|
||||
driver, especially when the terminal is set to use a bitmap font and
|
||||
font anti-aliasing is disabled. Oddly, despite anti-aliasing not
|
||||
being applicable to bitmap fonts, enabling anti-aliasing seems to
|
||||
improve performance (probably because it changes the driver-internal
|
||||
code path for glyph blending or memory management), as does switching
|
||||
to a scalable font like DejaVu Sans Mono.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Q: The terminal display corrupts in odd ways when I scroll. Anything I can
|
||||
do?
|
||||
|
||||
A: This is usually caused by using compositing (aka "Desktop Effects") with
|
||||
an older version of the proprietary nVidia graphics driver, which has a
|
||||
known rendering bug with Qt 4 scrollviews on an ARGB visual. nVidia
|
||||
fixed the problem in version 169.07 of the driver.
|
||||
|
||||
If a fixed driver is not available for your hardware or you are having
|
||||
this problem despite not using nVidia hardware or their proprietary dri-
|
||||
vers, exporting QT_USE_NATIVE_WINDOWS=1 has been known to help some
|
||||
users. This comes at the cost of increasing flickering during window re-
|
||||
size operations as it disables the use of windowless widgets in Qt.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Q: Translucent areas of my skin look rather different from how they used
|
||||
to look in the KDE 3 version. Why is that?
|
||||
|
||||
A: While the KDE 4 incarnation of Yakuake tries hard to preserve compati-
|
||||
bility with existing skins, the replacement of pseudo-translucency with
|
||||
XComposite translucency results in different blending behavior between
|
||||
skin elements and their background. Unfortunately this is outside the
|
||||
area of influence of the Yakuake code at this time. Translucent areas
|
||||
in skins may have to be adjusted accordingly, or the background tinting
|
||||
option in the configuration dialog can be used to compensate.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Q: I am using KWin Desktop Effects and have the "Shadows" option enabled,
|
||||
but the Yakuake window does not have a shadow. How come?
|
||||
|
||||
A: KWin's Shadow effect currently doesn't paint shadows for shaped windows
|
||||
(aka windows with a "mask") for performance reasons. This is unlikely
|
||||
to change in the near future. To compensate Yakuake may introduce sup-
|
||||
port for shadows in skins in the future, similar to what Plasma already
|
||||
does today.
|
4
yakuake/Messages.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#! /usr/bin/env bash
|
||||
$EXTRACTRC `find . -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp
|
||||
$XGETTEXT rc.cpp app/config/*.cpp app/*.cpp app/*.h -o $podir/yakuake.pot
|
||||
rm -f rc.cpp
|
53
yakuake/NEWS
Normal file
|
@ -0,0 +1,53 @@
|
|||
Thu Oct 19 00:50:00 CEST 2012
|
||||
Released Yakuake 2.9.9.
|
||||
|
||||
Thu Jan 27 19:30:00 CET 2011
|
||||
Released Yakuake 2.9.8.
|
||||
|
||||
Sat Jul 17 09:00:00 CEST 2010
|
||||
Released Yakuake 2.9.7.
|
||||
|
||||
Tue May 19 06:00:00 CEST 2009
|
||||
Released Yakuake 2.9.6.
|
||||
|
||||
Mon May 11 00:30:00 CEST 2009
|
||||
Released Yakuake 2.9.5.
|
||||
|
||||
Thu Sep 04 16:00:00 CEST 2008
|
||||
Released Yakuake 2.9.4.
|
||||
|
||||
Thu Jun 05 19:45:00 CEST 2008
|
||||
Released Yakuake 2.9.3.
|
||||
|
||||
Sat Apr 23 14:45:00 CEST 2008
|
||||
Released Yakuake 2.9.2.
|
||||
|
||||
Sat Mar 19 15:30:00 CEST 2008
|
||||
Released Yakuake 2.9.1.
|
||||
|
||||
Sat Mar 01 18:00:00 CEST 2008
|
||||
Released Yakuake 2.9.
|
||||
|
||||
Wed Jan 17 20:05:00 CEST 2008
|
||||
Released Yakuake 2.9-beta1.
|
||||
|
||||
Wed Jan 17 20:00:00 CEST 2008
|
||||
Released Yakuake 2.8.1.
|
||||
|
||||
Mon Oct 01 23:00:00 CEST 2007
|
||||
Released Yakuake 2.8.
|
||||
|
||||
Sun May 06 12:00:00 CEST 2007
|
||||
Released Yakuake 2.8-beta1.
|
||||
|
||||
Sun Mar 19 12:00:00 CEST 2006
|
||||
Released Yakuake 2.7.5.
|
||||
|
||||
Sat Mar 18 12:00:00 CEST 2006
|
||||
Released Yakuake 2.7.4.
|
||||
|
||||
Tue Mar 14 20:00:00 CEST 2006
|
||||
After Francois Chazal has announced that he is unable to continue
|
||||
Yakuake development due to time constraints, maintainership has
|
||||
passed on to Eike Hein. Yakuake is to be imported into the KDE.org
|
||||
Extragear module for future development.
|
33
yakuake/README
Normal file
|
@ -0,0 +1,33 @@
|
|||
Yakuake is a drop-down terminal emulator based on KDE Konsole technology.
|
||||
|
||||
|
||||
It's a KDE Extragear application released under GPL v2, GPL v3 or any later
|
||||
version accepted by the membership of KDE e.V.
|
||||
|
||||
The current maintainer of Yakuake is Eike Hein <hein@kde.org>.
|
||||
|
||||
|
||||
The Yakuake website is located at: http://yakuake.kde.org/
|
||||
|
||||
Report bugs and wishes at: http://bugs.kde.org/
|
||||
|
||||
You can browse the latest and older sources at:
|
||||
http://projects.kde.org/projects/extragear/utils/yakuake/repository
|
||||
|
||||
|
||||
Yakuake requires kdelibs and Konsole from KDE Software Compilation 4.4.0 or
|
||||
higher.
|
||||
|
||||
|
||||
Basic build and installation instructions:
|
||||
|
||||
1. tar xfvj yakuake-<version>.tar.bz2
|
||||
2. cd yakuake-<version>
|
||||
3. mkdir build
|
||||
4. cd build
|
||||
5. cmake -DCMAKE_INSTALL_PREFIX=<path to install to> ../
|
||||
6. make
|
||||
7. sudo make install
|
||||
|
||||
For more, please see the KDE Techbase wiki (http://techbase.kde.org/) and
|
||||
the CMake documentation (at http://www.cmake.org/).
|
3
yakuake/TODO
Normal file
|
@ -0,0 +1,3 @@
|
|||
Planned for future releases:
|
||||
- Session management (requires Konsole changes).
|
||||
- More flexible skin engine.
|
42
yakuake/app/CMakeLists.txt
Normal file
|
@ -0,0 +1,42 @@
|
|||
include_directories( ${KDE4_INCLUDES} )
|
||||
|
||||
set(yakuake_SRCS
|
||||
main.cpp
|
||||
application.cpp
|
||||
mainwindow.cpp
|
||||
skin.cpp
|
||||
titlebar.cpp
|
||||
tabbar.cpp
|
||||
sessionstack.cpp
|
||||
session.cpp
|
||||
terminal.cpp
|
||||
splitter.cpp
|
||||
firstrundialog.cpp
|
||||
visualeventoverlay.cpp
|
||||
config/windowsettings.cpp
|
||||
config/appearancesettings.cpp
|
||||
config/skinlistdelegate.cpp
|
||||
)
|
||||
|
||||
kde4_add_kcfg_files(yakuake_SRCS config/settings.kcfgc)
|
||||
|
||||
kde4_add_ui_files(yakuake_SRCS
|
||||
firstrundialog.ui
|
||||
config/windowsettings.ui
|
||||
config/behaviorsettings.ui
|
||||
config/appearancesettings.ui
|
||||
)
|
||||
|
||||
kde4_add_app_icon(yakuake_SRCS "icons/hi*-app-yakuake.png")
|
||||
|
||||
kde4_add_executable(yakuake ${yakuake_SRCS})
|
||||
|
||||
target_link_libraries(yakuake ${KDE4_KNOTIFYCONFIG_LIBRARY} ${KDE4_KPARTS_LIBS} ${KDE4_KNEWSTUFF3_LIBS})
|
||||
|
||||
if(Q_WS_X11)
|
||||
target_link_libraries(yakuake ${X11_X11_LIB})
|
||||
endif(Q_WS_X11)
|
||||
|
||||
install(TARGETS yakuake ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
||||
install(FILES yakuake.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
|
47
yakuake/app/application.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "application.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
|
||||
Application::Application() : KUniqueApplication()
|
||||
{
|
||||
m_mainWindow = 0;
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
}
|
||||
|
||||
int Application::newInstance()
|
||||
{
|
||||
if (!m_mainWindow)
|
||||
{
|
||||
m_mainWindow = new MainWindow();
|
||||
|
||||
m_mainWindow->hide();
|
||||
}
|
||||
else
|
||||
m_mainWindow->toggleWindowState();
|
||||
|
||||
return 0;
|
||||
}
|
47
yakuake/app/application.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
|
||||
#include <KUniqueApplication>
|
||||
|
||||
|
||||
class MainWindow;
|
||||
|
||||
|
||||
class Application : public KUniqueApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Application();
|
||||
virtual ~Application();
|
||||
|
||||
virtual int newInstance();
|
||||
|
||||
|
||||
private:
|
||||
MainWindow* m_mainWindow;
|
||||
};
|
||||
|
||||
#endif
|
479
yakuake/app/config/appearancesettings.cpp
Normal file
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "appearancesettings.h"
|
||||
#include "settings.h"
|
||||
#include "skinlistdelegate.h"
|
||||
|
||||
#include <KApplication>
|
||||
#include <KFileDialog>
|
||||
#include <KIO/DeleteJob>
|
||||
#include <KIO/NetAccess>
|
||||
#include <KMessageBox>
|
||||
#include <KStandardDirs>
|
||||
#include <KTar>
|
||||
#include <KUrl>
|
||||
|
||||
#include <QFile>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
AppearanceSettings::AppearanceSettings(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
kcfg_Skin->hide();
|
||||
kcfg_SkinInstalledWithKns->hide();
|
||||
|
||||
m_skins = new QStandardItemModel(this);
|
||||
|
||||
m_skinListDelegate = new SkinListDelegate(this);
|
||||
|
||||
skinList->setModel(m_skins);
|
||||
skinList->setItemDelegate(m_skinListDelegate);
|
||||
|
||||
connect(skinList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||
this, SLOT(updateSkinSetting()));
|
||||
connect(skinList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||
this, SLOT(updateRemoveSkinButton()));
|
||||
connect(installButton, SIGNAL(clicked()), this, SLOT(installSkin()));
|
||||
connect(removeButton, SIGNAL(clicked()), this, SLOT(removeSelectedSkin()));
|
||||
|
||||
installButton->setIcon(KIcon("folder"));
|
||||
removeButton->setIcon(KIcon("edit-delete"));
|
||||
ghnsButton->setIcon(KIcon("get-hot-new-stuff"));
|
||||
|
||||
m_selectedSkinId = Settings::skin();
|
||||
|
||||
// Get all local skin directories.
|
||||
// One for manually installed skins, one for skins installed
|
||||
// through KNS3.
|
||||
m_localSkinsDir = KStandardDirs::locateLocal("data", "yakuake/skins/");
|
||||
m_knsSkinDir = KStandardDirs::locateLocal("data", "yakuake/kns_skins/");
|
||||
|
||||
populateSkinList();
|
||||
}
|
||||
|
||||
AppearanceSettings::~AppearanceSettings()
|
||||
{
|
||||
}
|
||||
|
||||
void AppearanceSettings::showEvent(QShowEvent* event)
|
||||
{
|
||||
populateSkinList();
|
||||
|
||||
if (skinList->currentIndex().isValid())
|
||||
skinList->scrollTo(skinList->currentIndex());
|
||||
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void AppearanceSettings::populateSkinList()
|
||||
{
|
||||
m_skins->clear();
|
||||
|
||||
QStringList titleDirs = KGlobal::dirs()->findAllResources("data", "yakuake/skins/*/title.skin")
|
||||
+ KGlobal::dirs()->findAllResources("data", m_knsSkinDir + "*/title.skin");
|
||||
QStringList tabDirs = KGlobal::dirs()->findAllResources("data", "yakuake/skins/*/tabs.skin")
|
||||
+ KGlobal::dirs()->findAllResources("data", m_knsSkinDir + "*/tabs.skin");
|
||||
|
||||
QStringList skinDirs;
|
||||
QStringListIterator i(titleDirs);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
const QString& titleDir = i.next();
|
||||
const QString& skinDir(titleDir.section('/', 0, -2));
|
||||
|
||||
if (tabDirs.contains(skinDir + "/tabs.skin")
|
||||
&& !skinDirs.filter(QRegExp(QRegExp::escape(skinDir.section('/', -2, -1)) + '$')).count())
|
||||
{
|
||||
skinDirs << skinDir;
|
||||
}
|
||||
}
|
||||
|
||||
if (skinDirs.count() == 0)
|
||||
return;
|
||||
|
||||
QStringListIterator i2(skinDirs);
|
||||
|
||||
while (i2.hasNext())
|
||||
{
|
||||
const QString& skinDir = i2.next();
|
||||
|
||||
QStandardItem* skin = createSkinItem(skinDir);
|
||||
|
||||
if (!skin)
|
||||
continue;
|
||||
|
||||
m_skins->appendRow(skin);
|
||||
|
||||
if (skin->data(SkinId).toString() == m_selectedSkinId)
|
||||
skinList->setCurrentIndex(skin->index());
|
||||
}
|
||||
|
||||
m_skins->sort(0);
|
||||
|
||||
updateRemoveSkinButton();
|
||||
}
|
||||
|
||||
QStandardItem* AppearanceSettings::createSkinItem(const QString& skinDir)
|
||||
{
|
||||
QString skinId = skinDir.section('/', -1, -1);
|
||||
QString titleName, tabName, skinName;
|
||||
QString titleAuthor, tabAuthor, skinAuthor;
|
||||
QString titleIcon, tabIcon;
|
||||
QIcon skinIcon;
|
||||
|
||||
// Check if the skin dir starts with the path where all
|
||||
// KNS3 skins are found in.
|
||||
bool isKnsSkin = skinDir.startsWith(m_knsSkinDir);
|
||||
|
||||
KConfig titleConfig(skinDir + "/title.skin", KConfig::SimpleConfig);
|
||||
KConfigGroup titleDescription = titleConfig.group("Description");
|
||||
|
||||
KConfig tabConfig(skinDir + "/tabs.skin", KConfig::SimpleConfig);
|
||||
KConfigGroup tabDescription = tabConfig.group("Description");
|
||||
|
||||
titleName = titleDescription.readEntry("Skin", "");
|
||||
titleAuthor = titleDescription.readEntry("Author", "");
|
||||
titleIcon = skinDir + titleDescription.readEntry("Icon", "");
|
||||
|
||||
tabName = tabDescription.readEntry("Skin", "");
|
||||
tabAuthor = tabDescription.readEntry("Author", "");
|
||||
tabIcon = skinDir + tabDescription.readEntry("Icon", "");
|
||||
|
||||
skinName = titleName.isEmpty() ? tabName : titleName;
|
||||
skinAuthor = titleAuthor.isEmpty() ? tabAuthor : titleAuthor;
|
||||
titleIcon.isEmpty() ? skinIcon.addPixmap(tabIcon) : skinIcon.addPixmap(titleIcon);
|
||||
|
||||
if (skinName.isEmpty() || skinAuthor.isEmpty())
|
||||
skinName = skinId;
|
||||
|
||||
if (skinAuthor.isEmpty())
|
||||
skinAuthor = i18nc("@item:inlistbox Unknown skin author", "Unknown");
|
||||
|
||||
QStandardItem* skin = new QStandardItem(skinName);
|
||||
|
||||
skin->setData(skinId, SkinId);
|
||||
skin->setData(skinDir, SkinDir);
|
||||
skin->setData(skinName, SkinName);
|
||||
skin->setData(skinAuthor, SkinAuthor);
|
||||
skin->setData(skinIcon, SkinIcon);
|
||||
skin->setData(isKnsSkin, SkinInstalledWithKns);
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
void AppearanceSettings::updateSkinSetting()
|
||||
{
|
||||
QString skinId = skinList->currentIndex().data(SkinId).toString();
|
||||
|
||||
if (!skinId.isEmpty())
|
||||
{
|
||||
m_selectedSkinId = skinId;
|
||||
kcfg_Skin->setText(skinId);
|
||||
kcfg_SkinInstalledWithKns->setChecked(skinList->currentIndex().data(SkinInstalledWithKns).toBool());
|
||||
}
|
||||
}
|
||||
|
||||
void AppearanceSettings::resetSelection()
|
||||
{
|
||||
m_selectedSkinId = Settings::skin();
|
||||
|
||||
QModelIndexList skins = m_skins->match(m_skins->index(0, 0), SkinId,
|
||||
Settings::skin(), 1, Qt::MatchExactly | Qt::MatchWrap);
|
||||
|
||||
if (skins.count() > 0) skinList->setCurrentIndex(skins.at(0));
|
||||
}
|
||||
|
||||
void AppearanceSettings::installSkin()
|
||||
{
|
||||
QString mimeFilter = "application/x-tar application/x-compressed-tar "
|
||||
"application/x-bzip-compressed-tar application/zip";
|
||||
|
||||
KUrl skinUrl = KFileDialog::getOpenUrl(KUrl(), mimeFilter, parentWidget());
|
||||
|
||||
if (skinUrl.isEmpty()) return;
|
||||
|
||||
if (!KIO::NetAccess::download(skinUrl, m_installSkinFile, KApplication::activeWindow()))
|
||||
{
|
||||
KMessageBox::error(parentWidget(), KIO::NetAccess::lastErrorString(),
|
||||
i18nc("@title:window", "Failed to Download Skin"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QDir skinDir(m_installSkinFile);
|
||||
|
||||
if (!skinDir.exists())
|
||||
{
|
||||
KIO::ListJob* job = KIO::listRecursive(KUrl(m_installSkinFile), KIO::HideProgressInfo, false);
|
||||
|
||||
connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
|
||||
this, SLOT(listSkinArchive(KIO::Job*,KIO::UDSEntryList)));
|
||||
|
||||
connect(job, SIGNAL(result(KJob*)), this, SLOT(validateSkinArchive(KJob*)));
|
||||
}
|
||||
else
|
||||
failInstall(i18nc("@info", "The installer was given a directory, not a file."));
|
||||
}
|
||||
|
||||
void AppearanceSettings::listSkinArchive(KIO::Job* /* job */, const KIO::UDSEntryList& list)
|
||||
{
|
||||
if (list.count() == 0) return;
|
||||
|
||||
QListIterator<KIO::UDSEntry> i(list);
|
||||
|
||||
while (i.hasNext())
|
||||
m_installSkinFileList.append(i.next().stringValue(KIO::UDSEntry::UDS_NAME));
|
||||
}
|
||||
|
||||
void AppearanceSettings::validateSkinArchive(KJob* job)
|
||||
{
|
||||
if (!job->error())
|
||||
{
|
||||
m_installSkinId = m_installSkinFileList.at(0);
|
||||
|
||||
if (validateSkin(m_installSkinId, m_installSkinFileList))
|
||||
checkForExistingSkin();
|
||||
else
|
||||
failInstall(i18nc("@info", "Unable to locate required files in the skin archive.<nl/><nl/>The archive appears to be invalid."));
|
||||
}
|
||||
else
|
||||
failInstall(i18nc("@info", "Unable to list the skin archive contents.") + "\n\n" + job->errorString());
|
||||
}
|
||||
|
||||
bool AppearanceSettings::validateSkin(const QString &skinId, const QStringList& fileList)
|
||||
{
|
||||
bool titleFileFound = false;
|
||||
bool tabsFileFound = false;
|
||||
QString titleFileName = skinId + "/title.skin";
|
||||
QString tabsFileName = skinId + "/tabs.skin";
|
||||
|
||||
foreach (const QString& fileName, fileList)
|
||||
{
|
||||
if (fileName.endsWith(titleFileName))
|
||||
{
|
||||
titleFileFound = true;
|
||||
}
|
||||
else if (fileName.endsWith(tabsFileName))
|
||||
{
|
||||
tabsFileFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
return titleFileFound && tabsFileFound;
|
||||
}
|
||||
|
||||
void AppearanceSettings::checkForExistingSkin()
|
||||
{
|
||||
QModelIndexList skins = m_skins->match(m_skins->index(0, 0), SkinId,
|
||||
m_installSkinId, 1, Qt::MatchExactly | Qt::MatchWrap);
|
||||
|
||||
int exists = skins.count();
|
||||
|
||||
foreach (const QModelIndex& skin, skins)
|
||||
{
|
||||
if (m_skins->item(skin.row())->data(SkinInstalledWithKns).toBool())
|
||||
--exists;
|
||||
}
|
||||
|
||||
if (exists > 0)
|
||||
{
|
||||
QString skinDir = skins.at(0).data(SkinDir).toString();
|
||||
QFile skin(skinDir + "/titles.skin");
|
||||
|
||||
if (!skin.open(QIODevice::ReadWrite))
|
||||
{
|
||||
failInstall(i18nc("@info", "This skin appears to be already installed and you lack the required permissions to overwrite it."));
|
||||
}
|
||||
else
|
||||
{
|
||||
skin.close();
|
||||
|
||||
int remove = KMessageBox::warningContinueCancel(parentWidget(),
|
||||
i18nc("@info", "This skin appears to be already installed. Do you want to overwrite it?"),
|
||||
i18nc("@title:window", "Skin Already Exists"),
|
||||
KGuiItem(i18nc("@action:button", "Reinstall Skin")));
|
||||
|
||||
if (remove == KMessageBox::Continue)
|
||||
{
|
||||
unlink(QFile::encodeName(skinDir));
|
||||
KIO::DeleteJob* job = KIO::del(KUrl(skinDir), KIO::HideProgressInfo);
|
||||
connect(job, SIGNAL(result(KJob*)), this, SLOT(installSkinArchive(KJob*)));
|
||||
}
|
||||
else
|
||||
cleanupAfterInstall();
|
||||
}
|
||||
}
|
||||
else
|
||||
installSkinArchive();
|
||||
}
|
||||
|
||||
void AppearanceSettings::installSkinArchive(KJob* deleteJob)
|
||||
{
|
||||
if (deleteJob && deleteJob->error())
|
||||
{
|
||||
KMessageBox::error(parentWidget(), deleteJob->errorString(), i18nc("@title:Window", "Could Not Delete Skin"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
KTar skinArchive(m_installSkinFile);
|
||||
|
||||
if (skinArchive.open(QIODevice::ReadOnly))
|
||||
{
|
||||
const KArchiveDirectory* skinDir = skinArchive.directory();
|
||||
skinDir->copyTo(m_localSkinsDir);
|
||||
skinArchive.close();
|
||||
|
||||
populateSkinList();
|
||||
|
||||
if (Settings::skin() == m_installSkinId)
|
||||
emit settingsChanged();
|
||||
|
||||
cleanupAfterInstall();
|
||||
}
|
||||
else
|
||||
failInstall(i18nc("@info", "The skin archive file could not be opened."));
|
||||
}
|
||||
|
||||
void AppearanceSettings::failInstall(const QString& error)
|
||||
{
|
||||
KMessageBox::error(parentWidget(), error, i18nc("@title:window", "Cannot Install Skin"));
|
||||
|
||||
cleanupAfterInstall();
|
||||
}
|
||||
|
||||
void AppearanceSettings::cleanupAfterInstall()
|
||||
{
|
||||
KIO::NetAccess::removeTempFile(m_installSkinFile);
|
||||
m_installSkinId.clear();
|
||||
m_installSkinFile.clear();
|
||||
m_installSkinFileList.clear();
|
||||
}
|
||||
|
||||
void AppearanceSettings::updateRemoveSkinButton()
|
||||
{
|
||||
if (m_skins->rowCount() <= 1)
|
||||
{
|
||||
removeButton->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QString skinDir;
|
||||
|
||||
QVariant value = skinList->currentIndex().data(SkinDir);
|
||||
if (value.isValid())
|
||||
skinDir = value.toString();
|
||||
|
||||
value = skinList->currentIndex().data(SkinInstalledWithKns);
|
||||
bool isKnsSkin = value.toBool();
|
||||
|
||||
// We don't allow the user to remove the default skin
|
||||
// or any skin which was installed through KNS3.
|
||||
if (skinDir.isEmpty() || isKnsSkin)
|
||||
{
|
||||
removeButton->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QFile titleSkin(skinDir + "/title.skin");
|
||||
|
||||
if (!titleSkin.open(QIODevice::ReadWrite))
|
||||
removeButton->setEnabled(false);
|
||||
else
|
||||
removeButton->setEnabled(true);
|
||||
|
||||
titleSkin.close();
|
||||
}
|
||||
|
||||
void AppearanceSettings::removeSelectedSkin()
|
||||
{
|
||||
if (m_skins->rowCount() <= 1) return;
|
||||
|
||||
QString skinId = skinList->currentIndex().data(SkinId).toString();
|
||||
QString skinDir = skinList->currentIndex().data(SkinDir).toString();
|
||||
QString skinName = skinList->currentIndex().data(SkinName).toString();
|
||||
QString skinAuthor = skinList->currentIndex().data(SkinAuthor).toString();
|
||||
|
||||
if (skinDir.isEmpty()) return;
|
||||
|
||||
int remove = KMessageBox::warningContinueCancel(parentWidget(),
|
||||
i18nc("@info", "Do you want to remove \"%1\" by %2?", skinName, skinAuthor),
|
||||
i18nc("@title:window", "Remove Skin"),
|
||||
KStandardGuiItem::del());
|
||||
|
||||
if (remove == KMessageBox::Continue)
|
||||
{
|
||||
unlink(QFile::encodeName(skinDir));
|
||||
|
||||
bool deleted = KIO::NetAccess::del(KUrl(skinDir), KApplication::activeWindow());
|
||||
|
||||
if (deleted)
|
||||
{
|
||||
if (skinId == Settings::skin())
|
||||
{
|
||||
Settings::setSkin("default");
|
||||
Settings::setSkinInstalledWithKns(false);
|
||||
Settings::self()->writeConfig();
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
resetSelection();
|
||||
populateSkinList();
|
||||
}
|
||||
else
|
||||
KMessageBox::error(parentWidget(), i18nc("@info", "Could not remove skin \"%1\".", skinName));
|
||||
}
|
||||
}
|
||||
|
||||
QSet<QString> AppearanceSettings::extractKnsSkinIds(const QStringList& fileList)
|
||||
{
|
||||
QSet<QString> skinIdList;
|
||||
|
||||
foreach (const QString& file, fileList)
|
||||
{
|
||||
// We only care about files/directories which are subdirectories of our KNS skins dir.
|
||||
if (file.startsWith(m_knsSkinDir, Qt::CaseInsensitive))
|
||||
{
|
||||
// Get the relative filename (this removes the KNS install dir from the filename).
|
||||
QString relativeName = QString(file).remove(m_knsSkinDir, Qt::CaseInsensitive);
|
||||
|
||||
// Get everything before the first slash - that should be our skins ID.
|
||||
QString skinId = relativeName.section('/', 0, QString::SectionSkipEmpty);
|
||||
|
||||
// Skip all other entries in the file list if we found what we were searching for.
|
||||
if (!skinId.isEmpty())
|
||||
{
|
||||
// First remove all remaining slashes (as there could be leading or trailing ones).
|
||||
skinId = skinId.replace('/', QString());
|
||||
|
||||
skinIdList.insert(skinId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skinIdList;
|
||||
}
|
||||
|
125
yakuake/app/config/appearancesettings.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef APPEARANCESETTINGS_H
|
||||
#define APPEARANCESETTINGS_H
|
||||
|
||||
|
||||
#include "ui_appearancesettings.h"
|
||||
|
||||
#include <KIO/Job>
|
||||
|
||||
|
||||
class SkinListDelegate;
|
||||
|
||||
class QStandardItem;
|
||||
class QStandardItemModel;
|
||||
|
||||
class AppearanceSettings : public QWidget, private Ui::AppearanceSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AppearanceSettings(QWidget* parent = 0);
|
||||
~AppearanceSettings();
|
||||
|
||||
enum DataRole
|
||||
{
|
||||
SkinId = Qt::UserRole + 1,
|
||||
SkinDir = Qt::UserRole + 2,
|
||||
SkinName = Qt::UserRole + 3,
|
||||
SkinAuthor = Qt::UserRole + 4,
|
||||
SkinIcon = Qt::UserRole + 5,
|
||||
SkinInstalledWithKns = Qt::UserRole + 6
|
||||
};
|
||||
|
||||
|
||||
public slots:
|
||||
void resetSelection();
|
||||
|
||||
|
||||
signals:
|
||||
void settingsChanged();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* event);
|
||||
|
||||
|
||||
private slots:
|
||||
void populateSkinList();
|
||||
|
||||
void updateSkinSetting();
|
||||
|
||||
void installSkin();
|
||||
void listSkinArchive(KIO::Job* job, const KIO::UDSEntryList& list);
|
||||
void validateSkinArchive(KJob* job);
|
||||
void installSkinArchive(KJob* deleteJob = 0);
|
||||
|
||||
/**
|
||||
* Validates the given skin.
|
||||
* This method checks if the fileList of the skin
|
||||
* contains all required files.
|
||||
*
|
||||
* @param skinId The SkinID of the skin which will be validated.
|
||||
* @param fileList The filelist of the skin.
|
||||
*
|
||||
* @return True if the skin is valid, otherwise false.
|
||||
*/
|
||||
bool validateSkin(const QString &skinId, const QStringList& fileList);
|
||||
|
||||
/**
|
||||
* Extracts the skin IDs from the given fileList.
|
||||
* There can be multiple skins, but only one skin per directory.
|
||||
* The files need to be located in the m_knsSkinDir.
|
||||
*
|
||||
* @param fileList All files which were installed.
|
||||
*
|
||||
* @return The list of skin IDs which were extracted from the
|
||||
* given fileList.
|
||||
*/
|
||||
QSet<QString> extractKnsSkinIds(const QStringList& fileList);
|
||||
|
||||
void updateRemoveSkinButton();
|
||||
void removeSelectedSkin();
|
||||
|
||||
|
||||
private:
|
||||
QStandardItem* createSkinItem(const QString& skinDir);
|
||||
|
||||
void checkForExistingSkin();
|
||||
void failInstall(const QString& error);
|
||||
void cleanupAfterInstall();
|
||||
|
||||
QString m_selectedSkinId;
|
||||
|
||||
QStandardItemModel* m_skins;
|
||||
SkinListDelegate* m_skinListDelegate;
|
||||
|
||||
QString m_localSkinsDir;
|
||||
QString m_knsSkinDir;
|
||||
QString m_installSkinId;
|
||||
QString m_installSkinFile;
|
||||
QStringList m_installSkinFileList;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
277
yakuake/app/config/appearancesettings.ui
Normal file
|
@ -0,0 +1,277 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AppearanceSettings</class>
|
||||
<widget class="QWidget" name="AppearanceSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>386</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string comment="@title:group Group box label">General</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_1">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="kcfg_TerminalHighlightOnManualActivation">
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">Enabling this option will make Yakuake briefly display a colored overlay above the newly focused terminal when moving focus between multple terminals in a session, as well as over the currently focused terminal when switching to a session with multiple terminals.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Highlight terminals when moving focus between them</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Window Background</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="backgroundColorLabel">
|
||||
<property name="text">
|
||||
<string comment="@label:chooser">Background color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KColorButton" name="kcfg_BackgroundColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>41</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="kcfg_Translucency">
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">Translucency requires support by the selected skin as well as your desktop environment. The default skin supports translucency.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Use skin translucency if supported</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="backgroundColorOpacityLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@label:spinbox">Background color opacity:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="kcfg_BackgroundColorOpacity">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">When using translucency, the background color will be filled in using the given opacity before the skin elements are painted on top of the background. This allows influencing the opacity and color tint of translucent areas of the skin.</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string comment="@label Spinbox unit suffix">%</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Skin</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="KPushButton" name="ghnsButton">
|
||||
<property name="text">
|
||||
<string comment="@action:button">Get New Skins...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QListView" name="skinList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="KLineEdit" name="kcfg_Skin">
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="KPushButton" name="removeButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@action:button">Remove Skin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="KPushButton" name="installButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@action:button">Install Skin...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="kcfg_SkinInstalledWithKns">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>kcolorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>klineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KPushButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>kpushbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>kcfg_TerminalHighlightOnManualActivation</tabstop>
|
||||
<tabstop>kcfg_BackgroundColor</tabstop>
|
||||
<tabstop>kcfg_Translucency</tabstop>
|
||||
<tabstop>kcfg_BackgroundColorOpacity</tabstop>
|
||||
<tabstop>skinList</tabstop>
|
||||
<tabstop>installButton</tabstop>
|
||||
<tabstop>removeButton</tabstop>
|
||||
<tabstop>ghnsButton</tabstop>
|
||||
<tabstop>kcfg_Skin</tabstop>
|
||||
<tabstop>kcfg_SkinInstalledWithKns</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>kcfg_Translucency</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>kcfg_BackgroundColorOpacity</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>152</x>
|
||||
<y>76</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>192</x>
|
||||
<y>106</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>kcfg_Translucency</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>backgroundColorOpacityLabel</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>152</x>
|
||||
<y>76</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>95</x>
|
||||
<y>106</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
190
yakuake/app/config/behaviorsettings.ui
Normal file
|
@ -0,0 +1,190 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BehaviorSettings</class>
|
||||
<widget class="QWidget" name="BehaviorSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>364</width>
|
||||
<height>308</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string comment="@title:group Group box label">General</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_OpenAfterStart">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Open window after program start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_PollMouse">
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">If this option is enabled, the window will automatically open when the mouse pointer is moved to the same edge of the screen that it would open on when using the shortcut.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Open window when the mouse pointer touches the screen edge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_KeepOpen">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Keep window open when it loses focus</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_KeepAbove">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Keep window above other windows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ToggleToFocus">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">If this option is enabled, the shortcut normally used to open and retract the window will give it focus, rather than close it, if it has previously lost focus. Unless the window is set to show on all virtual desktops, this may cause the window manager to switch to the virtual desktop it currently resides on.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Use Open/Retract action to focus window</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_FocusFollowsMouse">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Focus terminals when the mouse pointer is moved over them</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Dialogs</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="kcfg_ConfirmQuit">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Confirm quit when more than one session is open</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>kcfg_KeepOpen</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>kcfg_KeepAbove</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>32</x>
|
||||
<y>59</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>82</x>
|
||||
<y>86</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>kcfg_KeepOpen</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>kcfg_ToggleToFocus</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>24</x>
|
||||
<y>59</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>74</x>
|
||||
<y>113</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
7
yakuake/app/config/settings.kcfgc
Normal file
|
@ -0,0 +1,7 @@
|
|||
File=yakuake.kcfg
|
||||
ClassName=Settings
|
||||
Singleton=true
|
||||
MemberVariables=private
|
||||
ItemAccessors=true
|
||||
Mutators=true
|
||||
GlobalEnums=true
|
201
yakuake/app/config/skinlistdelegate.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "skinlistdelegate.h"
|
||||
#include "appearancesettings.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QModelIndex>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
#define MARGIN 3
|
||||
#define ICON 32
|
||||
#define KNS_ICON_SIZE (ICON / 2)
|
||||
|
||||
|
||||
SkinListDelegate::SkinListDelegate(QObject* parent) : QAbstractItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SkinListDelegate::~SkinListDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
void SkinListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const
|
||||
{
|
||||
painter->save();
|
||||
|
||||
paintBackground(painter, option);
|
||||
|
||||
paintIcon(painter, option, index);
|
||||
|
||||
paintText(painter, option, index);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void SkinListDelegate::paintBackground(QPainter* painter, const QStyleOptionViewItem& option) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||
}
|
||||
|
||||
void SkinListDelegate::paintIcon(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const
|
||||
{
|
||||
QVariant value;
|
||||
|
||||
value = index.data(AppearanceSettings::SkinIcon);
|
||||
|
||||
if (value.isValid() && value.type() == QVariant::Icon)
|
||||
{
|
||||
int x = option.rect.x() + MARGIN;
|
||||
int y = option.rect.y() + (option.rect.height() / 2) - (ICON / 2);
|
||||
|
||||
if (option.direction == Qt::RightToLeft)
|
||||
x = option.rect.right() - ICON - MARGIN;
|
||||
|
||||
qvariant_cast<QIcon>(value).paint(painter, x, y, ICON, ICON);
|
||||
}
|
||||
}
|
||||
|
||||
void SkinListDelegate::paintText(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const
|
||||
{
|
||||
QFont font = option.font;
|
||||
int initialY = option.rect.y();
|
||||
int x = option.rect.x() + ICON + (3 * MARGIN);
|
||||
int y = initialY;
|
||||
int textWidth = 0;
|
||||
int width = option.rect.width() - ICON - (3 * MARGIN);
|
||||
|
||||
if (option.state & QStyle::State_Selected)
|
||||
painter->setPen(option.palette.color(QPalette::HighlightedText));
|
||||
|
||||
QVariant value;
|
||||
|
||||
value = index.data(AppearanceSettings::SkinName);
|
||||
|
||||
if (value.isValid())
|
||||
{
|
||||
font.setBold(true);
|
||||
painter->setFont(font);
|
||||
QFontMetrics fontMetrics(font);
|
||||
|
||||
QRect textRect = fontMetrics.boundingRect(value.toString());
|
||||
textWidth = textRect.width();
|
||||
|
||||
if (option.direction == Qt::RightToLeft)
|
||||
{
|
||||
if (width < textWidth)
|
||||
x = option.rect.x() + MARGIN;
|
||||
else
|
||||
x = option.rect.right() - ICON - (3 * MARGIN) - textWidth;
|
||||
}
|
||||
|
||||
y += textRect.height();
|
||||
|
||||
painter->drawText(x, y, fontMetrics.elidedText(value.toString(), option.textElideMode, width));
|
||||
|
||||
value = index.data(AppearanceSettings::SkinInstalledWithKns);
|
||||
|
||||
if (value.isValid() && value.toBool())
|
||||
{
|
||||
KIcon ghnsIcon("get-hot-new-stuff");
|
||||
int knsIconX = x;
|
||||
int iconSize = qMin(textRect.height(), KNS_ICON_SIZE);
|
||||
|
||||
if (option.direction == Qt::RightToLeft)
|
||||
// In RTL mode we have to correct our position
|
||||
// so there's room for the icon and enough space
|
||||
// between the text and the icon.
|
||||
knsIconX -= (iconSize + MARGIN);
|
||||
else
|
||||
// Otherwise we just have to make sure that we
|
||||
// start painting after the text and add some margin.
|
||||
knsIconX += textWidth + MARGIN;
|
||||
|
||||
ghnsIcon.paint(painter, knsIconX, initialY + MARGIN, iconSize, iconSize);
|
||||
}
|
||||
}
|
||||
|
||||
value = index.data(AppearanceSettings::SkinAuthor);
|
||||
|
||||
if (value.isValid())
|
||||
{
|
||||
QString skinAuthor = i18nc("@item:intext", "by %1", value.toString());
|
||||
|
||||
font.setBold(false);
|
||||
painter->setFont(font);
|
||||
QFontMetrics fontMetrics(font);
|
||||
|
||||
QRect textRect = fontMetrics.boundingRect(skinAuthor);
|
||||
|
||||
if (option.direction == Qt::RightToLeft)
|
||||
{
|
||||
if (width < textRect.width())
|
||||
x = option.rect.x() + MARGIN;
|
||||
else
|
||||
x = option.rect.right() - ICON - (3 * MARGIN) - textRect.width();
|
||||
}
|
||||
|
||||
y += textRect.height();
|
||||
|
||||
painter->drawText(x, y, fontMetrics.elidedText(skinAuthor, option.textElideMode, width));
|
||||
}
|
||||
}
|
||||
|
||||
QSize SkinListDelegate::sizeHint(const QStyleOptionViewItem&option, const QModelIndex& index) const
|
||||
{
|
||||
QFont font = option.font;
|
||||
QRect name, author;
|
||||
int width, height;
|
||||
|
||||
QVariant value;
|
||||
|
||||
value = index.data(AppearanceSettings::SkinName);
|
||||
|
||||
if (value.isValid())
|
||||
{
|
||||
font.setBold(true);
|
||||
QFontMetrics fontMetrics(font);
|
||||
name = fontMetrics.boundingRect(value.toString());
|
||||
}
|
||||
|
||||
value = index.data(Qt::UserRole + 1);
|
||||
|
||||
if (value.isValid())
|
||||
{
|
||||
QString skinAuthor = i18nc("@item:intext", "by %1", value.toString());
|
||||
|
||||
font.setBold(false);
|
||||
QFontMetrics fontMetrics(font);
|
||||
author = fontMetrics.boundingRect(skinAuthor);
|
||||
}
|
||||
|
||||
width = qMax(name.width(), author.width());
|
||||
QRect textRect(0, 0, width, name.height() + author.height());
|
||||
|
||||
width = ICON + (3 * MARGIN) + textRect.width() + MARGIN;;
|
||||
height = qMax(ICON + (2 * MARGIN), textRect.height() + (2 * MARGIN));
|
||||
|
||||
return QSize(width, height);
|
||||
}
|
45
yakuake/app/config/skinlistdelegate.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SKINLISTDELEGATE_H
|
||||
#define SKINLISTDELEGATE_H
|
||||
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
|
||||
|
||||
class SkinListDelegate : public QAbstractItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit SkinListDelegate(QObject* parent = 0);
|
||||
~SkinListDelegate();
|
||||
|
||||
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
|
||||
private:
|
||||
void paintBackground(QPainter* painter, const QStyleOptionViewItem& option) const;
|
||||
void paintIcon(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const;
|
||||
void paintText(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const;
|
||||
};
|
||||
|
||||
#endif
|
96
yakuake/app/config/windowsettings.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "windowsettings.h"
|
||||
#include "application.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QDesktopWidget>
|
||||
|
||||
WindowSettings::WindowSettings(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
for (int i = 2; i <= QApplication::desktop()->numScreens(); i++)
|
||||
kcfg_Screen->insertItem(i, i18nc("@item:inlistbox", "Screen <numid>%1</numid>", i));
|
||||
|
||||
if (QApplication::desktop()->numScreens() > 1)
|
||||
{
|
||||
screenLabel->setEnabled(true);
|
||||
kcfg_Screen->setEnabled(true);
|
||||
}
|
||||
|
||||
connect(kcfg_Width, SIGNAL(valueChanged(int)), this, SLOT(updateWidthSlider(int)));
|
||||
connect(widthSlider, SIGNAL(valueChanged(int)), this, SLOT(updateWidthSpinBox(int)));
|
||||
|
||||
connect(kcfg_Height, SIGNAL(valueChanged(int)), this, SLOT(updateHeightSlider(int)));
|
||||
connect(heightSlider, SIGNAL(valueChanged(int)), this, SLOT(updateHeightSpinBox(int)));
|
||||
|
||||
connect(kcfg_Frames, SIGNAL(valueChanged(int)), this, SLOT(updateFramesSpinBox(int)));
|
||||
connect(framesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateFramesSlider(int)));
|
||||
|
||||
connect(kcfg_Position, SIGNAL(valueChanged(int)), this, SLOT(updatePosition(int)));
|
||||
|
||||
updateFramesSpinBox(Settings::frames() * 10);
|
||||
}
|
||||
|
||||
WindowSettings::~WindowSettings()
|
||||
{
|
||||
}
|
||||
|
||||
void WindowSettings::updateWidthSlider(int width)
|
||||
{
|
||||
widthSlider->setValue(width/10);
|
||||
|
||||
emit updateWindowGeometry(width, kcfg_Height->value(), kcfg_Position->value());
|
||||
}
|
||||
|
||||
void WindowSettings::updateWidthSpinBox(int width)
|
||||
{
|
||||
kcfg_Width->setValue(width*10);
|
||||
}
|
||||
|
||||
void WindowSettings::updateHeightSlider(int height)
|
||||
{
|
||||
heightSlider->setValue(height/10);
|
||||
|
||||
emit updateWindowGeometry(kcfg_Width->value(), height, kcfg_Position->value());
|
||||
}
|
||||
|
||||
void WindowSettings::updateHeightSpinBox(int height)
|
||||
{
|
||||
kcfg_Height->setValue(height*10);
|
||||
}
|
||||
|
||||
void WindowSettings::updateFramesSlider(int speed)
|
||||
{
|
||||
kcfg_Frames->setValue(speed/10);
|
||||
}
|
||||
|
||||
void WindowSettings::updateFramesSpinBox(int speed)
|
||||
{
|
||||
framesSpinBox->setValue(speed*10);
|
||||
}
|
||||
|
||||
void WindowSettings::updatePosition(int position)
|
||||
{
|
||||
emit updateWindowGeometry(kcfg_Width->value(), kcfg_Height->value(), position);
|
||||
}
|
55
yakuake/app/config/windowsettings.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WINDOWSETTINGS_H
|
||||
#define WINDOWSETTINGS_H
|
||||
|
||||
|
||||
#include "ui_windowsettings.h"
|
||||
|
||||
|
||||
class WindowSettings : public QWidget, private Ui::WindowSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WindowSettings(QWidget* parent = 0);
|
||||
~WindowSettings();
|
||||
|
||||
|
||||
signals:
|
||||
void updateWindowGeometry(int width, int height, int position);
|
||||
|
||||
|
||||
private slots:
|
||||
void updateWidthSlider(int width);
|
||||
void updateWidthSpinBox(int width);
|
||||
|
||||
void updateHeightSlider(int height);
|
||||
void updateHeightSpinBox(int height);
|
||||
|
||||
void updateFramesSlider(int height);
|
||||
void updateFramesSpinBox(int height);
|
||||
|
||||
void updatePosition(int position);
|
||||
};
|
||||
|
||||
#endif
|
407
yakuake/app/config/windowsettings.ui
Normal file
|
@ -0,0 +1,407 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WindowSettings</class>
|
||||
<widget class="QWidget" name="WindowSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>289</width>
|
||||
<height>441</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Tab Bar</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_ShowTabBar">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Show the tab bar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_DynamicTabTitles">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">If this option is enabled, the information about the active terminal's contents that is normally shown in the title bar will also be shown on the tab bar. You can modify the format of the information in the terminal profile.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Show title bar contents in tab labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Size and Animation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="widthLabel">
|
||||
<property name="text">
|
||||
<string comment="@label:slider">Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSlider" name="widthSlider">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="kcfg_Width">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string comment="@label Spinbox unit suffix">%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>90</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="heightLabel">
|
||||
<property name="text">
|
||||
<string comment="@label:slider">Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="heightSlider">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="kcfg_Height">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string comment="@label Spinbox unit suffix">%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="durationLabel">
|
||||
<property name="text">
|
||||
<string comment="@label:slider">Duration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSlider" name="kcfg_Frames">
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="framesSpinBox">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string comment="@label Spinbox unit suffix">ms</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string comment="@label Spinbox unit prefix">~</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="kcfg_UseWMAssist">
|
||||
<property name="whatsThis">
|
||||
<string comment="@info:whatsthis">If this option is enabled, Yakuake will ask the window manager to perform the window open/retract animation. If the window manager is unable to provide the requested service, Yakuake will fall back to an animation strategy of progressively adjusting the window mask.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@option:check">Ask the window manager to perform the animation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string comment="@title:group">Position</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="leftLabel">
|
||||
<property name="text">
|
||||
<string comment="@item:inrange Direction to move the window in">Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="kcfg_Position">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="tracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rightLabel">
|
||||
<property name="text">
|
||||
<string comment="@item:inrange Direction to move the window in">Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="screenLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string comment="@label:listbox">Open on screen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KComboBox" name="kcfg_Screen">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox">At mouse location</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox">Screen 1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="kcfg_ShowOnAllDesktops">
|
||||
<property name="text">
|
||||
<string comment="@option:check">Show on all desktops</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>kcombobox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>kcfg_ShowTabBar</tabstop>
|
||||
<tabstop>kcfg_DynamicTabTitles</tabstop>
|
||||
<tabstop>widthSlider</tabstop>
|
||||
<tabstop>kcfg_Width</tabstop>
|
||||
<tabstop>heightSlider</tabstop>
|
||||
<tabstop>kcfg_Height</tabstop>
|
||||
<tabstop>kcfg_Frames</tabstop>
|
||||
<tabstop>framesSpinBox</tabstop>
|
||||
<tabstop>kcfg_UseWMAssist</tabstop>
|
||||
<tabstop>kcfg_Position</tabstop>
|
||||
<tabstop>kcfg_Screen</tabstop>
|
||||
<tabstop>kcfg_ShowOnAllDesktops</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>kcfg_ShowTabBar</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>kcfg_DynamicTabTitles</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>91</x>
|
||||
<y>40</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>109</x>
|
||||
<y>71</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
182
yakuake/app/config/yakuake.kcfg
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name="yakuakerc" />
|
||||
<group name="Window">
|
||||
<entry name="Screen" type="Int">
|
||||
<label context="@label">Screen to use</label>
|
||||
<whatsthis context="@info:whatsthis">The screen on which the application window will appear. 0 is understood to be the screen the mouse pointer is on.</whatsthis>
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="Width" type="Int">
|
||||
<label context="@label">Window width</label>
|
||||
<whatsthis context="@info:whatsthis">Width of the application window as a percentage of the screen.</whatsthis>
|
||||
<default>90</default>
|
||||
<min>10</min>
|
||||
<max>100</max>
|
||||
</entry>
|
||||
<entry name="Height" type="Int">
|
||||
<label context="@label">Window height</label>
|
||||
<whatsthis context="@info:whatsthis">Height of the application window as a percentage of the screen.</whatsthis>
|
||||
<default>50</default>
|
||||
<min>10</min>
|
||||
<max>100</max>
|
||||
</entry>
|
||||
<entry name="Position" type="Int">
|
||||
<label context="@label">Window position</label>
|
||||
<whatsthis context="@info:whatsthis">Center point of the application window, as a percentage, measured from the left-hand edge of the screen.</whatsthis>
|
||||
<default>50</default>
|
||||
<min>0</min>
|
||||
<max>100</max>
|
||||
</entry>
|
||||
<entry name="ShowOnAllDesktops" type="Bool">
|
||||
<label context="@label">Show window on all desktops</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to show the window on all desktops.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="KeepOpen" type="Bool">
|
||||
<label context="@label">Keep window open</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to keep the application window open when it loses focus.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ToggleToFocus" type="Bool">
|
||||
<label context="@label">Use open/retract shortcut to focus window</label>
|
||||
<whatsthis context="@info:whatsthis">Whether the open/retract keyboard shortcut can be used to focus the application window when it is already open.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="KeepAbove" type="Bool">
|
||||
<label context="@label">Keep window on top</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to keep the application window above other windows on the screen.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowTabBar" type="Bool">
|
||||
<label context="@label">Show tab bar</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to show the tab bar in the application window.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="DynamicTabTitles" type="Bool">
|
||||
<label context="@label">Dynamic tab titles</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to update tab titles along with the title bar.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Behavior">
|
||||
<entry name="FocusFollowsMouse" type="Bool">
|
||||
<label context="@label">Focus follows mouse</label>
|
||||
<whatsthis context="@info:whatsthis">Whether an individual terminal in a session will be given focus when the mouse pointer is moved above it.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="OpenAfterStart" type="Bool">
|
||||
<label context="@label">Open after start</label>
|
||||
<whatsthis context="@info:whatsthis">Whether the application window should be opened after program start.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Appearance">
|
||||
<entry name="Skin" type="String">
|
||||
<label context="@label">Skin</label>
|
||||
<whatsthis context="@info:whatsthis">The skin to be used by the application window.</whatsthis>
|
||||
<default>default</default>
|
||||
</entry>
|
||||
<entry name="SkinInstalledWithKns" type="Bool">
|
||||
<label context="@label">Skin installed by KNS</label>
|
||||
<whatsthis context="@info:whatsthis">Whether the currently active skin was installed via KNS.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="Translucency" type="Bool">
|
||||
<label context="@label">Use translucent background</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to make use of XComposite ARGB translucency.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="BackgroundColor" type="Color">
|
||||
<label context="@label">Window background color</label>
|
||||
<whatsthis context="@info:whatsthis">Background color painted below skin elements.</whatsthis>
|
||||
<default>#000000</default>
|
||||
</entry>
|
||||
<entry name="BackgroundColorOpacity" type="Int">
|
||||
<label context="@label">Background color opacity</label>
|
||||
<whatsthis context="@info:whatsthis">The opacity of the background color fill when using translucency.</whatsthis>
|
||||
<default>50</default>
|
||||
<min>0</min>
|
||||
<max>100</max>
|
||||
</entry>
|
||||
<entry name="TerminalHighlightOnManualActivation" type="Bool">
|
||||
<label context="@label">Highlight newly focused terminals</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to briefly display a colored overlay above the newly focused terminal when moving focus between multiple terminals in a session, as well as over the currently focused terminal when switching to a session with multiple terminals.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="TerminalHighlightOpacity" type="Double">
|
||||
<label context="@label">Terminal highlight opacity</label>
|
||||
<whatsthis context="@info:whatsthis">The opacity of the colored overlay used to highlight a terminal.</whatsthis>
|
||||
<default>0.4</default>
|
||||
<min>0</min>
|
||||
<max>1.0</max>
|
||||
</entry>
|
||||
<entry name="TerminalHighlightDuration" type="Int">
|
||||
<label context="@label">Terminal highlight duration</label>
|
||||
<whatsthis context="@info:whatsthis">The duration of the terminal highlight overlay.</whatsthis>
|
||||
<default>250</default>
|
||||
<min>0</min>
|
||||
<max>86400000</max>
|
||||
</entry>
|
||||
<entry name="KeyboardInputBlockIndicatorColor" type="Color">
|
||||
<label context="@label">Keyboard input block indicator color</label>
|
||||
<whatsthis context="@info:whatsthis">The color of the keyboard input block indicator overlay.</whatsthis>
|
||||
<default>#FF0000</default>
|
||||
</entry>
|
||||
<entry name="KeyboardInputBlockIndicatorOpacity" type="Double">
|
||||
<label context="@label">Keyboard input block indicator opacity</label>
|
||||
<whatsthis context="@info:whatsthis">The opacity of the keyboard input block indicator overlay.</whatsthis>
|
||||
<default>0.5</default>
|
||||
<min>0</min>
|
||||
<max>1.0</max>
|
||||
</entry>
|
||||
<entry name="KeyboardInputBlockIndicatorDuration" type="Int">
|
||||
<label context="@label">Keyboard input block indicator duration</label>
|
||||
<whatsthis context="@info:whatsthis">The duration of the keyboard input block indicator overlay.</whatsthis>
|
||||
<default>250</default>
|
||||
<min>0</min>
|
||||
<max>86400000</max>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Animation">
|
||||
<entry name="UseWMAssist" type="Bool">
|
||||
<label context="@label">Attempt to use the window manager to animate the window</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to try and let the window manager perform the window open/retract animation. Yakuake will fall back to an animation strategy of progressively adjusting the window mask if the window manager is unable to provide the requested service.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="Frames" type="Int">
|
||||
<label context="@label">Animation frames</label>
|
||||
<whatsthis context="@info:whatsthis">The number of frames of the open/retract animation. One frame is taken to be 10 miliseconds.</whatsthis>
|
||||
<default>17</default>
|
||||
<min>0</min>
|
||||
<max>50</max>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="AutoOpen">
|
||||
<entry name="PollMouse" type="Bool">
|
||||
<label context="@label">Auto-open window</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to automatically open the application window when the mouse pointer is found at the edge of the screen.</whatsthis>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="PollInterval" type="Int">
|
||||
<label context="@label">Mouse pointer poll interval</label>
|
||||
<whatsthis context="@info:whatsthis">The interval during which the mouse pointer position will be checked to determine whether or not it is at the same edge of the screen as the window.</whatsthis>
|
||||
<default>500</default>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Dialogs">
|
||||
<entry name="FirstRun" type="Bool">
|
||||
<label context="@label">Application first run</label>
|
||||
<whatsthis context="@info:whatsthis">Whether this is the first time the application is run.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ConfirmQuit" type="Bool">
|
||||
<label context="@label">Confirm quit with multiple sessions</label>
|
||||
<whatsthis context="@info:whatsthis">Whether to prompt the user before quitting the application when multiple sessions are open.</whatsthis>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
89
yakuake/app/firstrundialog.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "firstrundialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui_firstrundialog.h"
|
||||
|
||||
#include <KGlobalAccel>
|
||||
#include <KActionCollection>
|
||||
|
||||
|
||||
FirstRunDialog::FirstRunDialog(MainWindow* mainWindow) : KDialog(mainWindow)
|
||||
{
|
||||
m_mainWindow = mainWindow;
|
||||
|
||||
setCaption(i18nc("@title:window", "First Run"));
|
||||
setButtons(KDialog::Ok | KDialog::Cancel);
|
||||
|
||||
QWidget* widget = new QWidget(this);
|
||||
|
||||
m_ui = new Ui::FirstRunDialog();
|
||||
m_ui->setupUi(widget);
|
||||
m_ui->titleWidget->setPixmap(KIcon("yakuake").pixmap(22, 22));
|
||||
|
||||
widget->layout()->setSpacing(spacingHint());
|
||||
widget->setMinimumSize(widget->sizeHint());
|
||||
setMainWidget(widget);
|
||||
|
||||
initKeyButton();
|
||||
|
||||
connect(m_ui->keyButton, SIGNAL(keySequenceChanged(QKeySequence)),
|
||||
this, SLOT(validateKeySequence(QKeySequence)));
|
||||
}
|
||||
|
||||
FirstRunDialog::~FirstRunDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void FirstRunDialog::initKeyButton()
|
||||
{
|
||||
m_ui->keyButton->setMultiKeyShortcutsAllowed(false);
|
||||
|
||||
m_ui->keyButton->blockSignals(true);
|
||||
|
||||
KAction* action = static_cast<KAction*>(m_mainWindow->actionCollection()->action("toggle-window-state"));
|
||||
|
||||
m_keySequence = action->globalShortcut().primary();
|
||||
|
||||
m_ui->keyButton->setKeySequence(m_keySequence);
|
||||
|
||||
m_ui->keyButton->blockSignals(false);
|
||||
}
|
||||
|
||||
void FirstRunDialog::validateKeySequence(const QKeySequence& keySequence)
|
||||
{
|
||||
if (!KGlobalAccel::isGlobalShortcutAvailable(keySequence))
|
||||
{
|
||||
bool steal = KGlobalAccel::promptStealShortcutSystemwide(this,
|
||||
KGlobalAccel::getGlobalShortcutsByKey(keySequence), keySequence);
|
||||
|
||||
if (!steal)
|
||||
initKeyButton();
|
||||
else
|
||||
{
|
||||
KGlobalAccel::stealShortcutSystemwide(keySequence);
|
||||
m_keySequence = m_ui->keyButton->keySequence();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_keySequence = m_ui->keyButton->keySequence();
|
||||
}
|
57
yakuake/app/firstrundialog.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FIRSTRUNDIALOG_H
|
||||
#define FIRSTRUNDIALOG_H
|
||||
|
||||
|
||||
#include <KDialog>
|
||||
|
||||
|
||||
class MainWindow;
|
||||
class Ui_FirstRunDialog;
|
||||
|
||||
|
||||
class FirstRunDialog : public KDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FirstRunDialog(MainWindow* mainWindow);
|
||||
~FirstRunDialog();
|
||||
|
||||
QKeySequence keySequence() { return m_keySequence; }
|
||||
|
||||
|
||||
private slots:
|
||||
void validateKeySequence(const QKeySequence& keySequence);
|
||||
|
||||
|
||||
private:
|
||||
void initKeyButton();
|
||||
|
||||
Ui_FirstRunDialog* m_ui;
|
||||
MainWindow* m_mainWindow;
|
||||
|
||||
QKeySequence m_keySequence;
|
||||
};
|
||||
|
||||
#endif
|
153
yakuake/app/firstrundialog.ui
Normal file
|
@ -0,0 +1,153 @@
|
|||
<ui version="4.0" >
|
||||
<class>FirstRunDialog</class>
|
||||
<widget class="QWidget" name="FirstRunDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>223</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalSpacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="3" >
|
||||
<widget class="KTitleWidget" name="titleWidget" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>42</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string comment="@title" >Welcome to Yakuake</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3" >
|
||||
<widget class="QLabel" name="introLabel" >
|
||||
<property name="text" >
|
||||
<string comment="@info" >Before starting to use the application, you might want to change the keyboard shortcut used to open and retract the Yakuake window:</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1" >
|
||||
<widget class="KKeySequenceWidget" name="keyButton" />
|
||||
</item>
|
||||
<item row="3" column="2" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3" >
|
||||
<widget class="QLabel" name="outroLabel" >
|
||||
<property name="text" >
|
||||
<string comment="@info" >You can change the shortcut later at any time via the menu.</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KKeySequenceWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>kkeysequencewidget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KTitleWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>ktitlewidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
73
yakuake/app/main.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include <KAboutData>
|
||||
#include <KCmdLineArgs>
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
KAboutData aboutData("yakuake",
|
||||
0,
|
||||
ki18nc("@title", "<application>Yakuake</application>"),
|
||||
"2.9.9",
|
||||
ki18nc("@title", "A drop-down terminal emulator based on KDE Konsole technology."),
|
||||
KAboutData::License_GPL,
|
||||
ki18nc("@info:credit", "(c) 2008-2012 The Yakuake Team"),
|
||||
ki18n(0),
|
||||
"http://yakuake.kde.org/");
|
||||
|
||||
aboutData.setProductName("yakuake");
|
||||
|
||||
aboutData.addAuthor(ki18nc("@info:credit", "Eike Hein"),
|
||||
ki18nc("@info:credit", "Maintainer, Lead Developer"), "hein@kde.org");
|
||||
aboutData.addAuthor(ki18nc("@info:credit", "Francois Chazal"),
|
||||
ki18nc("@info:credit", "Project Founder, Default skin (Inactive)"));
|
||||
aboutData.addCredit(ki18nc("@info:credit", "Daniel 'suslik' D."),
|
||||
ki18nc("@info:credit", "Plastik skin"), "dd@accentsolution.com");
|
||||
aboutData.addCredit(ki18nc("@info:credit", "Juan Carlos Torres"),
|
||||
ki18nc("@info:credit", "Tab bar drag and drop support, Prevent Closing toggle"), "carlosdgtorres@gmail.com");
|
||||
aboutData.addCredit(ki18nc("@info:credit", "Gustavo Ribeiro Croscato"),
|
||||
ki18nc("@info:credit", "Icon on tabs with Prevent Closing enabled"), "croscato@gmail.com");
|
||||
aboutData.addCredit(ki18nc("@info:credit", "Danilo Cesar Lemes de Paula"),
|
||||
ki18nc("@info:credit", "Actions to grow terminals"), "danilo.eu@gmail.com");
|
||||
|
||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
||||
|
||||
if (!KUniqueApplication::start())
|
||||
{
|
||||
QTextStream err(stderr);
|
||||
|
||||
err << i18nc("@info:shell", "Yakuake is already running, toggling window ...") << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Application app;
|
||||
|
||||
return app.exec();
|
||||
}
|
1370
yakuake/app/mainwindow.cpp
Normal file
192
yakuake/app/mainwindow.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <KMainWindow>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
class FirstRunDialog;
|
||||
class SessionStack;
|
||||
class Skin;
|
||||
class TabBar;
|
||||
class Terminal;
|
||||
class TitleBar;
|
||||
|
||||
class KHelpMenu;
|
||||
class KMenu;
|
||||
class KAction;
|
||||
class KActionCollection;
|
||||
|
||||
|
||||
class MainWindow : public KMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.yakuake")
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
KActionCollection* actionCollection() { return m_actionCollection; }
|
||||
SessionStack* sessionStack() { return m_sessionStack; }
|
||||
|
||||
Skin* skin() { return m_skin; }
|
||||
KMenu* menu() { return m_menu; }
|
||||
|
||||
bool useTranslucency() { return m_useTranslucency; }
|
||||
|
||||
void setContextDependentActionsQuiet(bool quiet);
|
||||
|
||||
|
||||
public slots:
|
||||
Q_SCRIPTABLE void toggleWindowState();
|
||||
|
||||
void handleContextDependentAction(QAction* action = 0, int sessionId = -1);
|
||||
void handleContextDependentToggleAction(bool checked, QAction* action = 0, int sessionId = -1);
|
||||
void handleToggleTerminalKeyboardInput(bool checked);
|
||||
void handleToggleTerminalMonitorActivity(bool checked);
|
||||
void handleToggleTerminalMonitorSilence(bool checked);
|
||||
void handleTerminalActivity(Terminal* terminal);
|
||||
void handleTerminalSilence(Terminal* terminal);
|
||||
void handleLastTabClosed();
|
||||
|
||||
|
||||
signals:
|
||||
void windowOpened();
|
||||
void windowClosed();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
virtual void moveEvent(QMoveEvent*);
|
||||
virtual void changeEvent(QEvent* event);
|
||||
|
||||
virtual bool queryClose();
|
||||
|
||||
|
||||
private slots:
|
||||
void applySettings();
|
||||
void applySkin();
|
||||
void applyWindowProperties();
|
||||
|
||||
void applyWindowGeometry();
|
||||
void setWindowGeometry(int width, int height, int position);
|
||||
|
||||
void updateScreenMenu();
|
||||
void setScreen(QAction* action);
|
||||
|
||||
void setWindowWidth(int width);
|
||||
void setWindowHeight(int height);
|
||||
void setWindowWidth(QAction* action);
|
||||
void setWindowHeight(QAction* action);
|
||||
|
||||
void increaseWindowWidth();
|
||||
void decreaseWindowWidth();
|
||||
void increaseWindowHeight();
|
||||
void decreaseWindowHeight();
|
||||
|
||||
void xshapeOpenWindow();
|
||||
void xshapeRetractWindow();
|
||||
|
||||
void activate();
|
||||
|
||||
void toggleMousePoll(bool poll);
|
||||
void pollMouse();
|
||||
|
||||
void setKeepOpen(bool keepOpen);
|
||||
|
||||
void setFullScreen(bool state);
|
||||
|
||||
void handleSwitchToAction();
|
||||
|
||||
void whatsThis();
|
||||
|
||||
void configureKeys();
|
||||
void configureNotifications();
|
||||
void configureApp();
|
||||
|
||||
void showFirstRunDialog();
|
||||
void firstRunDialogFinished();
|
||||
void firstRunDialogOk();
|
||||
|
||||
|
||||
private:
|
||||
void setupActions();
|
||||
|
||||
void setupMenu();
|
||||
|
||||
void updateWindowSizeMenus();
|
||||
void updateWindowHeightMenu();
|
||||
void updateWindowWidthMenu();
|
||||
|
||||
#if defined(Q_WS_X11)
|
||||
void kwinAssistToggleWindowState(bool visible);
|
||||
void kwinAssistPropCleanup();
|
||||
bool m_kwinAssistPropSet;
|
||||
#endif
|
||||
|
||||
void xshapeToggleWindowState(bool visible);
|
||||
|
||||
void sharedPreOpenWindow();
|
||||
void sharedAfterOpenWindow();
|
||||
void sharedPreHideWindow();
|
||||
void sharedAfterHideWindow();
|
||||
|
||||
void updateMask();
|
||||
|
||||
int getScreen();
|
||||
QRect getDesktopGeometry();
|
||||
|
||||
void showStartupPopup();
|
||||
|
||||
void updateUseTranslucency();
|
||||
bool m_useTranslucency;
|
||||
|
||||
KActionCollection* m_actionCollection;
|
||||
QList<KAction*> m_contextDependentActions;
|
||||
|
||||
Skin* m_skin;
|
||||
TitleBar* m_titleBar;
|
||||
TabBar* m_tabBar;
|
||||
SessionStack* m_sessionStack;
|
||||
|
||||
KMenu* m_menu;
|
||||
KHelpMenu* m_helpMenu;
|
||||
KMenu* m_screenMenu;
|
||||
KMenu* m_windowWidthMenu;
|
||||
KMenu* m_windowHeightMenu;
|
||||
|
||||
FirstRunDialog* m_firstRunDialog;
|
||||
|
||||
QTimer m_animationTimer;
|
||||
QTimer m_mousePoller;
|
||||
int m_animationFrame;
|
||||
int m_animationStepSize;
|
||||
|
||||
bool m_listenForActivationChanges;
|
||||
};
|
||||
|
||||
#endif
|
654
yakuake/app/session.cpp
Normal file
|
@ -0,0 +1,654 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "session.h"
|
||||
#include "terminal.h"
|
||||
|
||||
|
||||
int Session::m_availableSessionId = 0;
|
||||
|
||||
Session::Session(SessionType type, QWidget* parent) : QObject(parent)
|
||||
{
|
||||
m_sessionId = m_availableSessionId;
|
||||
m_availableSessionId++;
|
||||
|
||||
m_activeTerminalId = -1;
|
||||
|
||||
m_closable = true;
|
||||
|
||||
m_baseSplitter = new Splitter(Qt::Horizontal, parent);
|
||||
connect(m_baseSplitter, SIGNAL(destroyed()), this, SLOT(prepareShutdown()));
|
||||
|
||||
setupSession(type);
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
if (m_baseSplitter) delete m_baseSplitter;
|
||||
|
||||
emit destroyed(m_sessionId);
|
||||
}
|
||||
|
||||
void Session::setupSession(SessionType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Single:
|
||||
{
|
||||
Terminal* terminal = addTerminal(m_baseSplitter);
|
||||
setActiveTerminal(terminal->id());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TwoHorizontal:
|
||||
{
|
||||
int splitterWidth = m_baseSplitter->width();
|
||||
|
||||
Terminal* terminal = addTerminal(m_baseSplitter);
|
||||
addTerminal(m_baseSplitter);
|
||||
|
||||
QList<int> newSplitterSizes;
|
||||
newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2);
|
||||
m_baseSplitter->setSizes(newSplitterSizes);
|
||||
|
||||
QWidget* terminalWidget = terminal->terminalWidget();
|
||||
|
||||
if (terminalWidget)
|
||||
{
|
||||
terminalWidget->setFocus();
|
||||
setActiveTerminal(terminal->id());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TwoVertical:
|
||||
{
|
||||
m_baseSplitter->setOrientation(Qt::Vertical);
|
||||
|
||||
int splitterHeight = m_baseSplitter->height();
|
||||
|
||||
Terminal* terminal = addTerminal(m_baseSplitter);
|
||||
addTerminal(m_baseSplitter);
|
||||
|
||||
QList<int> newSplitterSizes;
|
||||
newSplitterSizes << (splitterHeight / 2) << (splitterHeight / 2);
|
||||
m_baseSplitter->setSizes(newSplitterSizes);
|
||||
|
||||
QWidget* terminalWidget = terminal->terminalWidget();
|
||||
|
||||
if (terminalWidget)
|
||||
{
|
||||
terminalWidget->setFocus();
|
||||
setActiveTerminal(terminal->id());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Quad:
|
||||
{
|
||||
int splitterWidth = m_baseSplitter->width();
|
||||
int splitterHeight = m_baseSplitter->height();
|
||||
|
||||
m_baseSplitter->setOrientation(Qt::Vertical);
|
||||
|
||||
Splitter* upperSplitter = new Splitter(Qt::Horizontal, m_baseSplitter);
|
||||
connect(upperSplitter, SIGNAL(destroyed()), this, SLOT(cleanup()));
|
||||
|
||||
Splitter* lowerSplitter = new Splitter(Qt::Horizontal, m_baseSplitter);
|
||||
connect(lowerSplitter, SIGNAL(destroyed()), this, SLOT(cleanup()));
|
||||
|
||||
Terminal* terminal = addTerminal(upperSplitter);
|
||||
addTerminal(upperSplitter);
|
||||
|
||||
addTerminal(lowerSplitter);
|
||||
addTerminal(lowerSplitter);
|
||||
|
||||
QList<int> newSplitterSizes;
|
||||
newSplitterSizes << (splitterHeight / 2) << (splitterHeight / 2);
|
||||
m_baseSplitter->setSizes(newSplitterSizes);
|
||||
|
||||
newSplitterSizes.clear();
|
||||
newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2);
|
||||
upperSplitter->setSizes(newSplitterSizes);
|
||||
lowerSplitter->setSizes(newSplitterSizes);
|
||||
|
||||
QWidget* terminalWidget = terminal->terminalWidget();
|
||||
|
||||
if (terminalWidget)
|
||||
{
|
||||
terminalWidget->setFocus();
|
||||
setActiveTerminal(terminal->id());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
addTerminal(m_baseSplitter);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Terminal* Session::addTerminal(QWidget* parent)
|
||||
{
|
||||
Terminal* terminal = new Terminal(parent);
|
||||
connect(terminal, SIGNAL(activated(int)), this, SLOT(setActiveTerminal(int)));
|
||||
connect(terminal, SIGNAL(manuallyActivated(Terminal*)), this, SIGNAL(terminalManuallyActivated(Terminal*)));
|
||||
connect(terminal, SIGNAL(titleChanged(int,QString)), this, SLOT(setTitle(int,QString)));
|
||||
connect(terminal, SIGNAL(keyboardInputBlocked(Terminal*)), this, SIGNAL(keyboardInputBlocked(Terminal*)));
|
||||
connect(terminal, SIGNAL(silenceDetected(Terminal*)), this, SIGNAL(silenceDetected(Terminal*)));
|
||||
connect(terminal, SIGNAL(destroyed(int)), this, SLOT(cleanup(int)));
|
||||
|
||||
m_terminals.insert(terminal->id(), terminal);
|
||||
|
||||
QWidget* terminalWidget = terminal->terminalWidget();
|
||||
if (terminalWidget) terminalWidget->setFocus();
|
||||
|
||||
return terminal;
|
||||
}
|
||||
|
||||
void Session::closeTerminal(int terminalId)
|
||||
{
|
||||
if (terminalId == -1) terminalId = m_activeTerminalId;
|
||||
if (terminalId == -1) return;
|
||||
if (!m_terminals.contains(terminalId)) return;
|
||||
|
||||
m_terminals.value(terminalId)->deletePart();
|
||||
}
|
||||
|
||||
void Session::focusPreviousTerminal()
|
||||
{
|
||||
if (m_activeTerminalId == -1) return;
|
||||
if (!m_terminals.contains(m_activeTerminalId)) return;
|
||||
|
||||
QMapIterator<int, Terminal*> it(m_terminals);
|
||||
|
||||
it.toBack();
|
||||
|
||||
while (it.hasPrevious())
|
||||
{
|
||||
it.previous();
|
||||
|
||||
if (it.key() == m_activeTerminalId)
|
||||
{
|
||||
if (it.hasPrevious())
|
||||
{
|
||||
QWidget* terminalWidget = it.peekPrevious().value()->terminalWidget();
|
||||
if (terminalWidget) terminalWidget->setFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
it.toBack();
|
||||
|
||||
QWidget* terminalWidget = it.peekPrevious().value()->terminalWidget();
|
||||
if (terminalWidget) terminalWidget->setFocus();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::focusNextTerminal()
|
||||
{
|
||||
if (m_activeTerminalId == -1) return;
|
||||
if (!m_terminals.contains(m_activeTerminalId)) return;
|
||||
|
||||
QMapIterator<int, Terminal*> it(m_terminals);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
if (it.key() == m_activeTerminalId)
|
||||
{
|
||||
if (it.hasNext())
|
||||
{
|
||||
QWidget* terminalWidget = it.peekNext().value()->terminalWidget();
|
||||
if (terminalWidget) terminalWidget->setFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
it.toFront();
|
||||
|
||||
QWidget* terminalWidget = it.peekNext().value()->terminalWidget();
|
||||
if (terminalWidget) terminalWidget->setFocus();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Session::splitLeftRight(int terminalId)
|
||||
{
|
||||
if (terminalId == -1) terminalId = m_activeTerminalId;
|
||||
if (terminalId == -1) return -1;
|
||||
if (!m_terminals.contains(terminalId)) return -1;
|
||||
|
||||
Terminal* terminal = m_terminals.value(terminalId);
|
||||
|
||||
if (terminal)
|
||||
return split(terminal, Qt::Horizontal);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Session::splitTopBottom(int terminalId)
|
||||
{
|
||||
if (terminalId == -1) terminalId = m_activeTerminalId;
|
||||
if (terminalId == -1) return -1;
|
||||
if (!m_terminals.contains(terminalId)) return -1;
|
||||
|
||||
Terminal* terminal = m_terminals.value(terminalId);
|
||||
|
||||
if (terminal)
|
||||
return split(terminal, Qt::Vertical);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Session::split(Terminal* terminal, Qt::Orientation orientation)
|
||||
{
|
||||
Splitter* splitter = static_cast<Splitter*>(terminal->splitter());
|
||||
|
||||
if (splitter->count() == 1)
|
||||
{
|
||||
int splitterWidth = splitter->width();
|
||||
|
||||
if (splitter->orientation() != orientation)
|
||||
splitter->setOrientation(orientation);
|
||||
|
||||
terminal = addTerminal(splitter);
|
||||
|
||||
QList<int> newSplitterSizes;
|
||||
newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2);
|
||||
splitter->setSizes(newSplitterSizes);
|
||||
|
||||
QWidget* partWidget = terminal->partWidget();
|
||||
if (partWidget) partWidget->show();
|
||||
|
||||
m_activeTerminalId = terminal->id();
|
||||
}
|
||||
else
|
||||
{
|
||||
QList<int> splitterSizes = splitter->sizes();
|
||||
|
||||
Splitter* newSplitter = new Splitter(orientation, splitter);
|
||||
connect(newSplitter, SIGNAL(destroyed()), this, SLOT(cleanup()));
|
||||
|
||||
if (splitter->indexOf(terminal->partWidget()) == 0)
|
||||
splitter->insertWidget(0, newSplitter);
|
||||
|
||||
QWidget* partWidget = terminal->partWidget();
|
||||
if (partWidget) partWidget->setParent(newSplitter);
|
||||
|
||||
terminal->setSplitter(newSplitter);
|
||||
|
||||
terminal = addTerminal(newSplitter);
|
||||
|
||||
splitter->setSizes(splitterSizes);
|
||||
QList<int> newSplitterSizes;
|
||||
newSplitterSizes << (splitterSizes[1] / 2) << (splitterSizes[1] / 2);
|
||||
newSplitter->setSizes(newSplitterSizes);
|
||||
|
||||
newSplitter->show();
|
||||
|
||||
partWidget = terminal->partWidget();
|
||||
if (partWidget) partWidget->show();
|
||||
|
||||
m_activeTerminalId = terminal->id();
|
||||
}
|
||||
|
||||
return m_activeTerminalId;
|
||||
}
|
||||
|
||||
int Session::tryGrowTerminal(int terminalId, GrowthDirection direction, uint pixels)
|
||||
{
|
||||
Terminal* terminal = getTerminal(terminalId);
|
||||
Splitter* splitter = static_cast<Splitter*>(terminal->splitter());
|
||||
QWidget* child = terminal->partWidget();
|
||||
|
||||
while (splitter)
|
||||
{
|
||||
bool isHorizontal = (direction == Right || direction == Left);
|
||||
bool isForward = (direction == Down || direction == Right);
|
||||
|
||||
// Detecting correct orientation.
|
||||
if ((splitter->orientation() == Qt::Horizontal && isHorizontal)
|
||||
|| (splitter->orientation() == Qt::Vertical && !isHorizontal))
|
||||
{
|
||||
|
||||
int currentPos = splitter->indexOf(child);
|
||||
|
||||
if (currentPos != -1 // Next/Prev movable element detection.
|
||||
&& (currentPos != 0 || isForward)
|
||||
&& (currentPos != splitter->count() - 1 || !isForward))
|
||||
{
|
||||
QList<int> currentSizes = splitter->sizes();
|
||||
int oldSize = currentSizes[currentPos];
|
||||
|
||||
int affected = isForward ? currentPos + 1: currentPos -1;
|
||||
currentSizes[currentPos] += pixels;
|
||||
currentSizes[affected] -= pixels;
|
||||
splitter->setSizes(currentSizes);
|
||||
|
||||
return splitter->sizes()[currentPos] - oldSize;
|
||||
}
|
||||
}
|
||||
// Try with a higher level.
|
||||
child = splitter;
|
||||
splitter = static_cast<Splitter*>(splitter->parentWidget());
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Session::setActiveTerminal(int terminalId)
|
||||
{
|
||||
m_activeTerminalId = terminalId;
|
||||
|
||||
setTitle(m_activeTerminalId, m_terminals.value(m_activeTerminalId)->title());
|
||||
}
|
||||
|
||||
void Session::setTitle(int terminalId, const QString& title)
|
||||
{
|
||||
if (terminalId == m_activeTerminalId)
|
||||
{
|
||||
m_title = title;
|
||||
|
||||
emit titleChanged(m_title);
|
||||
emit titleChanged(m_sessionId, m_title);
|
||||
}
|
||||
}
|
||||
|
||||
void Session::cleanup(int terminalId)
|
||||
{
|
||||
if (m_activeTerminalId == terminalId && m_terminals.count() > 1)
|
||||
focusPreviousTerminal();
|
||||
|
||||
m_terminals.remove(terminalId);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void Session::cleanup()
|
||||
{
|
||||
if (!m_baseSplitter) return;
|
||||
|
||||
m_baseSplitter->recursiveCleanup();
|
||||
|
||||
if (m_terminals.count() == 0)
|
||||
m_baseSplitter->deleteLater();
|
||||
}
|
||||
|
||||
void Session::prepareShutdown()
|
||||
{
|
||||
m_baseSplitter = NULL;
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
const QString Session::terminalIdList()
|
||||
{
|
||||
QList<int> keyList = m_terminals.uniqueKeys();
|
||||
QStringList idList;
|
||||
|
||||
QListIterator<int> i(keyList);
|
||||
|
||||
while (i.hasNext())
|
||||
idList << QString::number(i.next());
|
||||
|
||||
return idList.join(",");
|
||||
}
|
||||
|
||||
bool Session::hasTerminal(int terminalId)
|
||||
{
|
||||
return m_terminals.contains(terminalId);
|
||||
}
|
||||
|
||||
Terminal* Session::getTerminal(int terminalId)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return 0;
|
||||
|
||||
return m_terminals.value(terminalId);
|
||||
}
|
||||
|
||||
void Session::runCommand(const QString& command, int terminalId)
|
||||
{
|
||||
if (terminalId == -1) terminalId = m_activeTerminalId;
|
||||
if (terminalId == -1) return;
|
||||
if (!m_terminals.contains(terminalId)) return;
|
||||
|
||||
m_terminals.value(terminalId)->runCommand(command);
|
||||
}
|
||||
|
||||
void Session::manageProfiles()
|
||||
{
|
||||
if ( m_activeTerminalId == -1) return;
|
||||
if (!m_terminals.contains(m_activeTerminalId)) return;
|
||||
|
||||
m_terminals.value(m_activeTerminalId)->manageProfiles();
|
||||
}
|
||||
|
||||
void Session::editProfile()
|
||||
{
|
||||
if ( m_activeTerminalId == -1) return;
|
||||
if (!m_terminals.contains(m_activeTerminalId)) return;
|
||||
|
||||
m_terminals.value(m_activeTerminalId)->editProfile();
|
||||
}
|
||||
|
||||
bool Session::keyboardInputEnabled()
|
||||
{
|
||||
int keyboardInputEnabledCount = 0;
|
||||
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->keyboardInputEnabled())
|
||||
++keyboardInputEnabledCount;
|
||||
|
||||
return m_terminals.count() == keyboardInputEnabledCount;
|
||||
}
|
||||
|
||||
void Session::setKeyboardInputEnabled(bool enabled)
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
setKeyboardInputEnabled(i.next().key(), enabled);
|
||||
}
|
||||
|
||||
bool Session::keyboardInputEnabled(int terminalId)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return false;
|
||||
|
||||
return m_terminals.value(terminalId)->keyboardInputEnabled();
|
||||
}
|
||||
|
||||
void Session::setKeyboardInputEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return;
|
||||
|
||||
m_terminals.value(terminalId)->setKeyboardInputEnabled(enabled);
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithKeyboardInputEnabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->keyboardInputEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithKeyboardInputDisabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (!i.next().value()->keyboardInputEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Session::monitorActivityEnabled()
|
||||
{
|
||||
int monitorActivityEnabledCount = 0;
|
||||
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->monitorActivityEnabled())
|
||||
++monitorActivityEnabledCount;
|
||||
|
||||
return m_terminals.count() == monitorActivityEnabledCount;
|
||||
}
|
||||
|
||||
void Session::setMonitorActivityEnabled(bool enabled)
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
setMonitorActivityEnabled(i.next().key(), enabled);
|
||||
}
|
||||
|
||||
bool Session::monitorActivityEnabled(int terminalId)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return false;
|
||||
|
||||
return m_terminals.value(terminalId)->monitorActivityEnabled();
|
||||
}
|
||||
|
||||
void Session::setMonitorActivityEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return;
|
||||
|
||||
Terminal* terminal = m_terminals.value(terminalId);
|
||||
|
||||
connect(terminal, SIGNAL(activityDetected(Terminal*)), this, SIGNAL(activityDetected(Terminal*)),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
terminal->setMonitorActivityEnabled(enabled);
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithMonitorActivityEnabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->monitorActivityEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithMonitorActivityDisabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (!i.next().value()->monitorActivityEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Session::reconnectMonitorActivitySignals()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
|
||||
connect(i.value(), SIGNAL(activityDetected(Terminal*)), this, SIGNAL(activityDetected(Terminal*)),
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
}
|
||||
|
||||
bool Session::monitorSilenceEnabled()
|
||||
{
|
||||
int monitorSilenceEnabledCount = 0;
|
||||
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->monitorSilenceEnabled())
|
||||
++monitorSilenceEnabledCount;
|
||||
|
||||
return m_terminals.count() == monitorSilenceEnabledCount;
|
||||
}
|
||||
|
||||
void Session::setMonitorSilenceEnabled(bool enabled)
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
setMonitorSilenceEnabled(i.next().key(), enabled);
|
||||
}
|
||||
|
||||
bool Session::monitorSilenceEnabled(int terminalId)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return false;
|
||||
|
||||
return m_terminals.value(terminalId)->monitorSilenceEnabled();
|
||||
}
|
||||
|
||||
void Session::setMonitorSilenceEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
if (!m_terminals.contains(terminalId)) return;
|
||||
|
||||
m_terminals.value(terminalId)->setMonitorSilenceEnabled(enabled);
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithMonitorSilenceDisabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (!i.next().value()->monitorSilenceEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Session::hasTerminalsWithMonitorSilenceEnabled()
|
||||
{
|
||||
QMapIterator<int, Terminal*> i(m_terminals);
|
||||
|
||||
while (i.hasNext())
|
||||
if (i.next().value()->monitorSilenceEnabled())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
139
yakuake/app/session.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SESSION_H
|
||||
#define SESSION_H
|
||||
|
||||
|
||||
#include "splitter.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
class Terminal;
|
||||
|
||||
|
||||
class Session : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum SessionType { Single, TwoHorizontal, TwoVertical, Quad };
|
||||
enum GrowthDirection { Up, Right, Down, Left };
|
||||
|
||||
explicit Session(SessionType type = Single, QWidget* parent = 0);
|
||||
~Session();
|
||||
|
||||
int id() { return m_sessionId; }
|
||||
const QString title() { return m_title; }
|
||||
QWidget* widget() { return m_baseSplitter; }
|
||||
|
||||
int activeTerminalId() { return m_activeTerminalId; }
|
||||
const QString terminalIdList();
|
||||
int terminalCount() { return m_terminals.count(); }
|
||||
bool hasTerminal(int terminalId);
|
||||
Terminal* getTerminal(int terminalId);
|
||||
|
||||
bool closable() { return m_closable; }
|
||||
void setClosable(bool closable) { m_closable = closable; }
|
||||
|
||||
bool keyboardInputEnabled();
|
||||
void setKeyboardInputEnabled(bool enabled);
|
||||
bool keyboardInputEnabled(int terminalId);
|
||||
void setKeyboardInputEnabled(int terminalId, bool enabled);
|
||||
bool hasTerminalsWithKeyboardInputEnabled();
|
||||
bool hasTerminalsWithKeyboardInputDisabled();
|
||||
|
||||
bool monitorActivityEnabled();
|
||||
void setMonitorActivityEnabled(bool enabled);
|
||||
bool monitorActivityEnabled(int terminalId);
|
||||
void setMonitorActivityEnabled(int terminalId, bool enabled);
|
||||
bool hasTerminalsWithMonitorActivityEnabled();
|
||||
bool hasTerminalsWithMonitorActivityDisabled();
|
||||
|
||||
bool monitorSilenceEnabled();
|
||||
void setMonitorSilenceEnabled(bool enabled);
|
||||
bool monitorSilenceEnabled(int terminalId);
|
||||
void setMonitorSilenceEnabled(int terminalId, bool enabled);
|
||||
bool hasTerminalsWithMonitorSilenceEnabled();
|
||||
bool hasTerminalsWithMonitorSilenceDisabled();
|
||||
|
||||
|
||||
public slots:
|
||||
void closeTerminal(int terminalId = -1);
|
||||
|
||||
void focusNextTerminal();
|
||||
void focusPreviousTerminal();
|
||||
|
||||
int splitLeftRight(int terminalId = -1);
|
||||
int splitTopBottom(int terminalId = -1);
|
||||
|
||||
int tryGrowTerminal(int terminalId, GrowthDirection direction, uint pixels);
|
||||
|
||||
void runCommand(const QString& command, int terminalId = -1);
|
||||
|
||||
void manageProfiles();
|
||||
void editProfile();
|
||||
|
||||
void reconnectMonitorActivitySignals();
|
||||
|
||||
|
||||
signals:
|
||||
void titleChanged(const QString& title);
|
||||
void titleChanged(int sessionId, const QString& title);
|
||||
void terminalManuallyActivated(Terminal* terminal);
|
||||
void keyboardInputBlocked(Terminal* terminal);
|
||||
void activityDetected(Terminal* terminal);
|
||||
void silenceDetected(Terminal* terminal);
|
||||
void destroyed(int sessionId);
|
||||
|
||||
|
||||
private slots:
|
||||
void setActiveTerminal(int terminalId);
|
||||
void setTitle(int terminalId, const QString& title);
|
||||
|
||||
void cleanup(int terminalId);
|
||||
void cleanup();
|
||||
void prepareShutdown();
|
||||
|
||||
|
||||
private:
|
||||
void setupSession(SessionType type);
|
||||
|
||||
Terminal* addTerminal(QWidget* parent);
|
||||
int split(Terminal* terminal, Qt::Orientation orientation);
|
||||
|
||||
static int m_availableSessionId;
|
||||
int m_sessionId;
|
||||
|
||||
Splitter* m_baseSplitter;
|
||||
|
||||
int m_activeTerminalId;
|
||||
QMap<int, Terminal*> m_terminals;
|
||||
|
||||
QString m_title;
|
||||
|
||||
bool m_closable;
|
||||
};
|
||||
|
||||
#endif
|
631
yakuake/app/sessionstack.cpp
Normal file
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "sessionstack.h"
|
||||
#include "settings.h"
|
||||
#include "visualeventoverlay.h"
|
||||
|
||||
#include <KMessageBox>
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
SessionStack::SessionStack(QWidget* parent) : QStackedWidget(parent)
|
||||
{
|
||||
QDBusConnection::sessionBus().registerObject("/yakuake/sessions", this, QDBusConnection::ExportScriptableSlots);
|
||||
|
||||
m_activeSessionId = -1;
|
||||
|
||||
m_visualEventOverlay = new VisualEventOverlay(this);
|
||||
connect(this, SIGNAL(removeTerminalHighlight()), m_visualEventOverlay, SLOT(removeTerminalHighlight()));
|
||||
}
|
||||
|
||||
SessionStack::~SessionStack()
|
||||
{
|
||||
}
|
||||
|
||||
int SessionStack::addSession(Session::SessionType type)
|
||||
{
|
||||
Session* session = new Session(type, this);
|
||||
connect(session, SIGNAL(titleChanged(int,QString)), this, SIGNAL(titleChanged(int,QString)));
|
||||
connect(session, SIGNAL(terminalManuallyActivated(Terminal*)), this, SLOT(handleManualTerminalActivation(Terminal*)));
|
||||
connect(session, SIGNAL(keyboardInputBlocked(Terminal*)), m_visualEventOverlay, SLOT(indicateKeyboardInputBlocked(Terminal*)));
|
||||
connect(session, SIGNAL(activityDetected(Terminal*)), parentWidget(), SLOT(handleTerminalActivity(Terminal*)));
|
||||
connect(session, SIGNAL(silenceDetected(Terminal*)), parentWidget(), SLOT(handleTerminalSilence(Terminal*)));
|
||||
connect(parentWidget(), SIGNAL(windowClosed()), session, SLOT(reconnectMonitorActivitySignals()));
|
||||
connect(session, SIGNAL(destroyed(int)), this, SLOT(cleanup(int)));
|
||||
|
||||
addWidget(session->widget());
|
||||
|
||||
m_sessions.insert(session->id(), session);
|
||||
|
||||
if (Settings::dynamicTabTitles())
|
||||
emit sessionAdded(session->id(), session->title());
|
||||
else
|
||||
emit sessionAdded(session->id());
|
||||
|
||||
return session->id();
|
||||
}
|
||||
|
||||
int SessionStack::addSessionTwoHorizontal()
|
||||
{
|
||||
return addSession(Session::TwoHorizontal);
|
||||
}
|
||||
|
||||
int SessionStack::addSessionTwoVertical()
|
||||
{
|
||||
return addSession(Session::TwoVertical);
|
||||
}
|
||||
|
||||
int SessionStack::addSessionQuad()
|
||||
{
|
||||
return addSession(Session::Quad);
|
||||
}
|
||||
|
||||
void SessionStack::raiseSession(int sessionId)
|
||||
{
|
||||
if (sessionId == -1 || !m_sessions.contains(sessionId)) return;
|
||||
Session* session = m_sessions.value(sessionId);
|
||||
|
||||
if (!m_visualEventOverlay->isHidden())
|
||||
m_visualEventOverlay->hide();
|
||||
|
||||
if (m_activeSessionId != -1 && m_sessions.contains(m_activeSessionId))
|
||||
{
|
||||
Session* oldActiveSession = m_sessions.value(m_activeSessionId);
|
||||
|
||||
disconnect(oldActiveSession, SLOT(closeTerminal()));
|
||||
disconnect(oldActiveSession, SLOT(focusPreviousTerminal()));
|
||||
disconnect(oldActiveSession, SLOT(focusNextTerminal()));
|
||||
disconnect(oldActiveSession, SLOT(manageProfiles()));
|
||||
disconnect(oldActiveSession, SIGNAL(titleChanged(QString)),
|
||||
this, SIGNAL(activeTitleChanged(QString)));
|
||||
|
||||
oldActiveSession->reconnectMonitorActivitySignals();
|
||||
}
|
||||
|
||||
m_activeSessionId = sessionId;
|
||||
|
||||
setCurrentWidget(session->widget());
|
||||
|
||||
if (session->widget()->focusWidget())
|
||||
session->widget()->focusWidget()->setFocus();
|
||||
|
||||
if (session->hasTerminalsWithKeyboardInputDisabled())
|
||||
m_visualEventOverlay->show();
|
||||
|
||||
connect(this, SIGNAL(closeTerminal()), session, SLOT(closeTerminal()));
|
||||
connect(this, SIGNAL(previousTerminal()), session, SLOT(focusPreviousTerminal()));
|
||||
connect(this, SIGNAL(nextTerminal()), session, SLOT(focusNextTerminal()));
|
||||
connect(this, SIGNAL(manageProfiles()), session, SLOT(manageProfiles()));
|
||||
connect(session, SIGNAL(titleChanged(QString)), this, SIGNAL(activeTitleChanged(QString)));
|
||||
|
||||
emit sessionRaised(sessionId);
|
||||
|
||||
emit activeTitleChanged(session->title());
|
||||
}
|
||||
|
||||
void SessionStack::removeSession(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
if (queryClose(sessionId, QueryCloseSession))
|
||||
m_sessions.value(sessionId)->deleteLater();
|
||||
}
|
||||
|
||||
void SessionStack::removeTerminal(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (terminalId == -1)
|
||||
{
|
||||
if (m_activeSessionId == -1) return;
|
||||
if (!m_sessions.contains(m_activeSessionId)) return;
|
||||
|
||||
if (m_sessions.value(m_activeSessionId)->closable())
|
||||
m_sessions.value(m_activeSessionId)->closeTerminal();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sessions.value(sessionId)->closable())
|
||||
m_sessions.value(sessionId)->closeTerminal(terminalId);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionStack::closeActiveTerminal(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
if (queryClose(sessionId, QueryCloseTerminal))
|
||||
m_sessions.value(sessionId)->closeTerminal();
|
||||
}
|
||||
|
||||
|
||||
void SessionStack::cleanup(int sessionId)
|
||||
{
|
||||
if (sessionId == m_activeSessionId) m_activeSessionId = -1;
|
||||
|
||||
m_sessions.remove(sessionId);
|
||||
|
||||
emit sessionRemoved(sessionId);
|
||||
}
|
||||
|
||||
int SessionStack::activeTerminalId()
|
||||
{
|
||||
if (!m_sessions.contains(m_activeSessionId)) return -1;
|
||||
|
||||
return m_sessions.value(m_activeSessionId)->activeTerminalId();
|
||||
}
|
||||
|
||||
const QString SessionStack::sessionIdList()
|
||||
{
|
||||
QList<int> keyList = m_sessions.uniqueKeys();
|
||||
QStringList idList;
|
||||
|
||||
QListIterator<int> i(keyList);
|
||||
|
||||
while (i.hasNext())
|
||||
idList << QString::number(i.next());
|
||||
|
||||
return idList.join(",");
|
||||
}
|
||||
|
||||
const QString SessionStack::terminalIdList()
|
||||
{
|
||||
QStringList idList;
|
||||
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
idList << it.value()->terminalIdList();
|
||||
}
|
||||
|
||||
return idList.join(",");
|
||||
}
|
||||
|
||||
const QString SessionStack::terminalIdsForSessionId(int sessionId)
|
||||
{
|
||||
if (!m_sessions.contains(sessionId)) return QString::number(-1);
|
||||
|
||||
return m_sessions.value(sessionId)->terminalIdList();
|
||||
}
|
||||
|
||||
int SessionStack::sessionIdForTerminalId(int terminalId)
|
||||
{
|
||||
int sessionId = -1;
|
||||
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
if (it.value()->hasTerminal(terminalId))
|
||||
{
|
||||
sessionId = it.key();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
void SessionStack::runCommand(const QString& command)
|
||||
{
|
||||
if (m_activeSessionId == -1) return;
|
||||
if (!m_sessions.contains(m_activeSessionId)) return;
|
||||
|
||||
m_sessions.value(m_activeSessionId)->runCommand(command);
|
||||
}
|
||||
|
||||
void SessionStack::runCommandInTerminal(int terminalId, const QString& command)
|
||||
{
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
it.value()->runCommand(command, terminalId);
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionStack::isSessionClosable(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->closable();
|
||||
}
|
||||
|
||||
void SessionStack::setSessionClosable(int sessionId, bool closable)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setClosable(closable);
|
||||
}
|
||||
|
||||
bool SessionStack::hasUnclosableSessions() const
|
||||
{
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
if (!it.value()->closable())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SessionStack::isSessionKeyboardInputEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->keyboardInputEnabled();
|
||||
}
|
||||
|
||||
void SessionStack::setSessionKeyboardInputEnabled(int sessionId, bool enabled)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setKeyboardInputEnabled(enabled);
|
||||
|
||||
if (sessionId == m_activeSessionId)
|
||||
{
|
||||
if (enabled)
|
||||
m_visualEventOverlay->hide();
|
||||
else
|
||||
m_visualEventOverlay->show();
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionStack::isTerminalKeyboardInputEnabled(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->keyboardInputEnabled(terminalId);
|
||||
}
|
||||
|
||||
void SessionStack::setTerminalKeyboardInputEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setKeyboardInputEnabled(terminalId, enabled);
|
||||
|
||||
if (sessionId == m_activeSessionId)
|
||||
{
|
||||
if (enabled)
|
||||
m_visualEventOverlay->hide();
|
||||
else
|
||||
m_visualEventOverlay->show();
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithKeyboardInputEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputEnabled();
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithKeyboardInputDisabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputDisabled();
|
||||
}
|
||||
|
||||
bool SessionStack::isSessionMonitorActivityEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->monitorActivityEnabled();
|
||||
}
|
||||
|
||||
void SessionStack::setSessionMonitorActivityEnabled(int sessionId, bool enabled)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setMonitorActivityEnabled(enabled);
|
||||
}
|
||||
|
||||
bool SessionStack::isTerminalMonitorActivityEnabled(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->monitorActivityEnabled(terminalId);
|
||||
}
|
||||
|
||||
void SessionStack::setTerminalMonitorActivityEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setMonitorActivityEnabled(terminalId, enabled);
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithMonitorActivityEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityEnabled();
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithMonitorActivityDisabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityDisabled();
|
||||
}
|
||||
|
||||
bool SessionStack::isSessionMonitorSilenceEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->monitorSilenceEnabled();
|
||||
}
|
||||
|
||||
void SessionStack::setSessionMonitorSilenceEnabled(int sessionId, bool enabled)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setMonitorSilenceEnabled(enabled);
|
||||
}
|
||||
|
||||
bool SessionStack::isTerminalMonitorSilenceEnabled(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->monitorSilenceEnabled(terminalId);
|
||||
}
|
||||
|
||||
void SessionStack::setTerminalMonitorSilenceEnabled(int terminalId, bool enabled)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->setMonitorSilenceEnabled(terminalId, enabled);
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithMonitorSilenceEnabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceEnabled();
|
||||
}
|
||||
|
||||
bool SessionStack::hasTerminalsWithMonitorSilenceDisabled(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return false;
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceDisabled();
|
||||
}
|
||||
|
||||
void SessionStack::editProfile(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) sessionId = m_activeSessionId;
|
||||
if (sessionId == -1) return;
|
||||
if (!m_sessions.contains(sessionId)) return;
|
||||
|
||||
m_sessions.value(sessionId)->editProfile();
|
||||
}
|
||||
|
||||
int SessionStack::splitSessionLeftRight(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) return -1;
|
||||
if (!m_sessions.contains(sessionId)) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->splitLeftRight();
|
||||
}
|
||||
|
||||
int SessionStack::splitSessionTopBottom(int sessionId)
|
||||
{
|
||||
if (sessionId == -1) return -1;
|
||||
if (!m_sessions.contains(sessionId)) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->splitTopBottom();
|
||||
}
|
||||
|
||||
int SessionStack::splitTerminalLeftRight(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->splitLeftRight(terminalId);
|
||||
}
|
||||
|
||||
int SessionStack::splitTerminalTopBottom(int terminalId)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->splitTopBottom(terminalId);
|
||||
}
|
||||
|
||||
int SessionStack::tryGrowTerminalRight(int terminalId, uint pixels)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Right, pixels);
|
||||
}
|
||||
|
||||
int SessionStack::tryGrowTerminalLeft(int terminalId, uint pixels)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Left, pixels);
|
||||
}
|
||||
|
||||
int SessionStack::tryGrowTerminalTop(int terminalId, uint pixels)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Up, pixels);
|
||||
}
|
||||
|
||||
int SessionStack::tryGrowTerminalBottom(int terminalId, uint pixels)
|
||||
{
|
||||
int sessionId = sessionIdForTerminalId(terminalId);
|
||||
|
||||
if (sessionId == -1) return -1;
|
||||
|
||||
return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Down, pixels);
|
||||
}
|
||||
|
||||
void SessionStack::emitTitles()
|
||||
{
|
||||
QString title;
|
||||
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
title = it.value()->title();
|
||||
|
||||
if (!title.isEmpty())
|
||||
emit titleChanged(it.value()->id(), title);
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionStack::requiresVisualEventOverlay()
|
||||
{
|
||||
if (m_activeSessionId == -1) return false;
|
||||
if (!m_sessions.contains(m_activeSessionId)) return false;
|
||||
|
||||
return m_sessions.value(m_activeSessionId)->hasTerminalsWithKeyboardInputDisabled();
|
||||
}
|
||||
|
||||
void SessionStack::handleTerminalHighlightRequest(int terminalId)
|
||||
{
|
||||
Terminal* terminal = 0;
|
||||
|
||||
QHashIterator<int, Session*> it(m_sessions);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
terminal = it.value()->getTerminal(terminalId);
|
||||
|
||||
if (terminal && it.value()->id() == m_activeSessionId)
|
||||
{
|
||||
m_visualEventOverlay->highlightTerminal(terminal, true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SessionStack::handleManualTerminalActivation(Terminal* terminal)
|
||||
{
|
||||
if (!Settings::terminalHighlightOnManualActivation())
|
||||
return;
|
||||
|
||||
Session* session = qobject_cast<Session*>(QObject::sender());
|
||||
|
||||
if (session->terminalCount() > 1)
|
||||
m_visualEventOverlay->highlightTerminal(terminal, false);
|
||||
}
|
||||
|
||||
bool SessionStack::queryClose(int sessionId, QueryCloseType type)
|
||||
{
|
||||
if (!m_sessions.contains(sessionId)) return false;
|
||||
|
||||
if (!m_sessions.value(sessionId)->closable())
|
||||
{
|
||||
QString closeQuestionIntro = i18nc("@info", "<warning>You have locked this session to prevent accidental closing of terminals.</warning>");
|
||||
QString closeQuestion;
|
||||
|
||||
if (type == QueryCloseSession)
|
||||
closeQuestion = i18nc("@info", "Are you sure you want to close this session?");
|
||||
else if (type == QueryCloseTerminal)
|
||||
closeQuestion = i18nc("@info", "Are you sure you want to close this terminal?");
|
||||
|
||||
int result = KMessageBox::warningContinueCancel(this,
|
||||
closeQuestionIntro + "<br/><br/>" + closeQuestion,
|
||||
i18nc("@title:window", "Really Close?"), KStandardGuiItem::close(), KStandardGuiItem::cancel());
|
||||
|
||||
if (result != KMessageBox::Continue)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
150
yakuake/app/sessionstack.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SESSIONSTACK_H
|
||||
#define SESSIONSTACK_H
|
||||
|
||||
|
||||
#include "session.h"
|
||||
|
||||
|
||||
#include <QHash>
|
||||
#include <QStackedWidget>
|
||||
|
||||
|
||||
class Session;
|
||||
class VisualEventOverlay;
|
||||
|
||||
class SessionStack : public QStackedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.yakuake")
|
||||
|
||||
public:
|
||||
explicit SessionStack(QWidget* parent = 0);
|
||||
~SessionStack();
|
||||
|
||||
void closeActiveTerminal(int sessionId = -1);
|
||||
|
||||
void editProfile(int sessionId = -1);
|
||||
|
||||
void emitTitles();
|
||||
|
||||
bool requiresVisualEventOverlay();
|
||||
|
||||
|
||||
public slots:
|
||||
Q_SCRIPTABLE int addSession(Session::SessionType type = Session::Single);
|
||||
Q_SCRIPTABLE int addSessionTwoHorizontal();
|
||||
Q_SCRIPTABLE int addSessionTwoVertical();
|
||||
Q_SCRIPTABLE int addSessionQuad();
|
||||
|
||||
Q_SCRIPTABLE void raiseSession(int sessionId);
|
||||
|
||||
Q_SCRIPTABLE void removeSession(int sessionId);
|
||||
Q_SCRIPTABLE void removeTerminal(int terminalId);
|
||||
|
||||
Q_SCRIPTABLE int splitSessionLeftRight(int sessionId);
|
||||
Q_SCRIPTABLE int splitSessionTopBottom(int sessionId);
|
||||
Q_SCRIPTABLE int splitTerminalLeftRight(int terminalId);
|
||||
Q_SCRIPTABLE int splitTerminalTopBottom(int terminalId);
|
||||
|
||||
Q_SCRIPTABLE int tryGrowTerminalRight(int terminalId, uint pixels = 10);
|
||||
Q_SCRIPTABLE int tryGrowTerminalLeft(int terminalId, uint pixels = 10);
|
||||
Q_SCRIPTABLE int tryGrowTerminalTop(int terminalId, uint pixels = 10);
|
||||
Q_SCRIPTABLE int tryGrowTerminalBottom(int terminalId, uint pixels = 10);
|
||||
|
||||
Q_SCRIPTABLE int activeSessionId() { return m_activeSessionId; }
|
||||
Q_SCRIPTABLE int activeTerminalId();
|
||||
|
||||
Q_SCRIPTABLE const QString sessionIdList();
|
||||
Q_SCRIPTABLE const QString terminalIdList();
|
||||
Q_SCRIPTABLE const QString terminalIdsForSessionId(int sessionId);
|
||||
Q_SCRIPTABLE int sessionIdForTerminalId(int terminalId);
|
||||
|
||||
Q_SCRIPTABLE void runCommand(const QString& command);
|
||||
Q_SCRIPTABLE void runCommandInTerminal(int terminalId, const QString& command);
|
||||
|
||||
Q_SCRIPTABLE bool isSessionClosable(int sessionId);
|
||||
Q_SCRIPTABLE void setSessionClosable(int sessionId, bool closable);
|
||||
Q_SCRIPTABLE bool hasUnclosableSessions() const;
|
||||
|
||||
Q_SCRIPTABLE bool isSessionKeyboardInputEnabled(int sessionId);
|
||||
Q_SCRIPTABLE void setSessionKeyboardInputEnabled(int sessionId, bool enabled);
|
||||
Q_SCRIPTABLE bool isTerminalKeyboardInputEnabled(int terminalId);
|
||||
Q_SCRIPTABLE void setTerminalKeyboardInputEnabled(int terminalId, bool enabled);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithKeyboardInputEnabled(int sessionId);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithKeyboardInputDisabled(int sessionId);
|
||||
|
||||
Q_SCRIPTABLE bool isSessionMonitorActivityEnabled(int sessionId);
|
||||
Q_SCRIPTABLE void setSessionMonitorActivityEnabled(int sessionId, bool enabled);
|
||||
Q_SCRIPTABLE bool isTerminalMonitorActivityEnabled(int terminalId);
|
||||
Q_SCRIPTABLE void setTerminalMonitorActivityEnabled(int terminalId, bool enabled);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithMonitorActivityEnabled(int sessionId);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithMonitorActivityDisabled(int sessionId);
|
||||
|
||||
Q_SCRIPTABLE bool isSessionMonitorSilenceEnabled(int sessionId);
|
||||
Q_SCRIPTABLE void setSessionMonitorSilenceEnabled(int sessionId, bool enabled);
|
||||
Q_SCRIPTABLE bool isTerminalMonitorSilenceEnabled(int terminalId);
|
||||
Q_SCRIPTABLE void setTerminalMonitorSilenceEnabled(int terminalId, bool enabled);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithMonitorSilenceEnabled(int sessionId);
|
||||
Q_SCRIPTABLE bool hasTerminalsWithMonitorSilenceDisabled(int sessionId);
|
||||
|
||||
void handleTerminalHighlightRequest(int terminalId);
|
||||
|
||||
|
||||
signals:
|
||||
void sessionAdded(int sessionId, const QString& title = 0);
|
||||
void sessionRaised(int sessionId);
|
||||
void sessionRemoved(int sessionId);
|
||||
|
||||
void activeTitleChanged(const QString& title);
|
||||
void titleChanged(int sessionId, const QString& title);
|
||||
|
||||
void closeTerminal();
|
||||
|
||||
void previousTerminal();
|
||||
void nextTerminal();
|
||||
|
||||
void manageProfiles();
|
||||
|
||||
void removeTerminalHighlight();
|
||||
|
||||
|
||||
private slots:
|
||||
void handleManualTerminalActivation(Terminal*);
|
||||
|
||||
void cleanup(int sessionId);
|
||||
|
||||
|
||||
private:
|
||||
enum QueryCloseType { QueryCloseSession, QueryCloseTerminal };
|
||||
bool queryClose(int sessionId, QueryCloseType type);
|
||||
|
||||
VisualEventOverlay* m_visualEventOverlay;
|
||||
|
||||
int m_activeSessionId;
|
||||
|
||||
QHash<int, Session*> m_sessions;
|
||||
};
|
||||
|
||||
#endif
|
241
yakuake/app/skin.cpp
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "skin.h"
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KIcon>
|
||||
#include <KGlobalSettings>
|
||||
#include <KStandardDirs>
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
|
||||
Skin::Skin()
|
||||
{
|
||||
m_borderWidth = 0;
|
||||
}
|
||||
|
||||
Skin::~Skin()
|
||||
{
|
||||
}
|
||||
|
||||
bool Skin::load(const QString& name, bool kns)
|
||||
{
|
||||
QString dir = kns ? "kns_skins/" : "skins/";
|
||||
|
||||
QString titlePath = KStandardDirs::locate("appdata", dir + name + "/title.skin");
|
||||
QString tabPath = KStandardDirs::locate("appdata", dir + name + "/tabs.skin");
|
||||
|
||||
if (!QFile::exists(titlePath) || !QFile::exists(tabPath))
|
||||
return false;
|
||||
|
||||
connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), this, SLOT(systemIconsChanged(int)),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
QString titleDir(QFileInfo(titlePath).absolutePath());
|
||||
QString tabDir(QFileInfo(tabPath).absolutePath());
|
||||
|
||||
KConfig titleConfig(titlePath, KConfig::SimpleConfig);
|
||||
KConfig tabConfig(tabPath, KConfig::SimpleConfig);
|
||||
|
||||
|
||||
KConfigGroup border = titleConfig.group("Border");
|
||||
|
||||
m_borderColor = QColor(border.readEntry("red", 0),
|
||||
border.readEntry("green", 0),
|
||||
border.readEntry("blue", 0));
|
||||
|
||||
m_borderWidth = border.readEntry("width", 1);
|
||||
|
||||
|
||||
KConfigGroup titleBarBackground = titleConfig.group("Background");
|
||||
|
||||
m_titleBarBackgroundImage.load(titleDir + titleBarBackground.readEntry("back_image", ""));
|
||||
m_titleBarLeftCornerImage.load(titleDir + titleBarBackground.readEntry("left_corner", ""));
|
||||
m_titleBarRightCornerImage.load(titleDir + titleBarBackground.readEntry("right_corner", ""));
|
||||
|
||||
|
||||
KConfigGroup titleBarFocusButton = titleConfig.group("FocusButton");
|
||||
|
||||
m_titleBarFocusButtonPosition.setX(titleBarFocusButton.readEntry("x", 0));
|
||||
m_titleBarFocusButtonPosition.setY(titleBarFocusButton.readEntry("y", 0));
|
||||
|
||||
m_titleBarFocusButtonStyleSheet = buttonStyleSheet(titleDir + titleBarFocusButton.readEntry("up_image", ""),
|
||||
titleDir + titleBarFocusButton.readEntry("over_image", ""),
|
||||
titleDir + titleBarFocusButton.readEntry("down_image", ""));
|
||||
|
||||
|
||||
KConfigGroup titleBarMenuButton = titleConfig.group("ConfigButton");
|
||||
|
||||
m_titleBarMenuButtonPosition.setX(titleBarMenuButton.readEntry("x", 0));
|
||||
m_titleBarMenuButtonPosition.setY(titleBarMenuButton.readEntry("y", 0));
|
||||
|
||||
m_titleBarMenuButtonStyleSheet = buttonStyleSheet(titleDir + titleBarMenuButton.readEntry("up_image", ""),
|
||||
titleDir + titleBarMenuButton.readEntry("over_image", ""),
|
||||
titleDir + titleBarMenuButton.readEntry("down_image", ""));
|
||||
|
||||
|
||||
KConfigGroup titleBarQuitButton = titleConfig.group("QuitButton");
|
||||
|
||||
m_titleBarQuitButtonPosition.setX(titleBarQuitButton.readEntry("x", 0));
|
||||
m_titleBarQuitButtonPosition.setY(titleBarQuitButton.readEntry("y", 0));
|
||||
|
||||
m_titleBarQuitButtonStyleSheet = buttonStyleSheet(titleDir + titleBarQuitButton.readEntry("up_image", ""),
|
||||
titleDir + titleBarQuitButton.readEntry("over_image", ""),
|
||||
titleDir + titleBarQuitButton.readEntry("down_image", ""));
|
||||
|
||||
|
||||
KConfigGroup titleBarText = titleConfig.group("Text");
|
||||
|
||||
m_titleBarText = titleBarText.readEntry("text", "");
|
||||
|
||||
m_titleBarTextPosition.setX(titleBarText.readEntry("x", 0));
|
||||
m_titleBarTextPosition.setY(titleBarText.readEntry("y", 0));
|
||||
|
||||
m_titleBarTextColor = QColor(titleBarText.readEntry("red", 0),
|
||||
titleBarText.readEntry("green", 0),
|
||||
titleBarText.readEntry("blue", 0));
|
||||
|
||||
m_titleBarTextBold = titleBarText.readEntry("bold", true);
|
||||
|
||||
|
||||
KConfigGroup tabBar = tabConfig.group("Tabs");
|
||||
|
||||
m_tabBarPosition.setX(tabBar.readEntry("x", 0));
|
||||
m_tabBarPosition.setY(tabBar.readEntry("y", 0));
|
||||
|
||||
m_tabBarTextColor = QColor(tabBar.readEntry("red", 0),
|
||||
tabBar.readEntry("green", 0),
|
||||
tabBar.readEntry("blue", 0));
|
||||
|
||||
m_tabBarSeparatorImage.load(tabDir + tabBar.readEntry("separator_image", ""));
|
||||
m_tabBarUnselectedBackgroundImage.load(tabDir + tabBar.readEntry("unselected_background", ""));
|
||||
m_tabBarSelectedBackgroundImage.load(tabDir + tabBar.readEntry("selected_background", ""));
|
||||
m_tabBarSelectedLeftCornerImage.load(tabDir + tabBar.readEntry("selected_left_corner", ""));
|
||||
m_tabBarSelectedRightCornerImage.load(tabDir + tabBar.readEntry("selected_right_corner", ""));
|
||||
|
||||
m_tabBarPreventClosingImage.load(tabDir + tabBar.readEntry("prevent_closing_image", ""));
|
||||
m_tabBarPreventClosingImagePosition.setX(tabBar.readEntry("prevent_closing_image_x", 0));
|
||||
m_tabBarPreventClosingImagePosition.setY(tabBar.readEntry("prevent_closing_image_y", 0));
|
||||
|
||||
|
||||
KConfigGroup tabBarBackground = tabConfig.group("Background");
|
||||
|
||||
m_tabBarBackgroundImage.load(tabDir + tabBarBackground.readEntry("back_image", ""));
|
||||
m_tabBarLeftCornerImage.load(tabDir + tabBarBackground.readEntry("left_corner", ""));
|
||||
m_tabBarRightCornerImage.load(tabDir + tabBarBackground.readEntry("right_corner", ""));
|
||||
|
||||
|
||||
KConfigGroup tabBarNewTabButton = tabConfig.group("PlusButton");
|
||||
|
||||
m_tabBarNewTabButtonPosition.setX(tabBarNewTabButton.readEntry("x", 0));
|
||||
m_tabBarNewTabButtonPosition.setY(tabBarNewTabButton.readEntry("y", 0));
|
||||
|
||||
m_tabBarNewTabButtonStyleSheet = buttonStyleSheet(tabDir + tabBarNewTabButton.readEntry("up_image", ""),
|
||||
tabDir + tabBarNewTabButton.readEntry("over_image", ""),
|
||||
tabDir + tabBarNewTabButton.readEntry("down_image", ""));
|
||||
|
||||
|
||||
KConfigGroup tabBarCloseTabButton = tabConfig.group("MinusButton");
|
||||
|
||||
m_tabBarCloseTabButtonPosition.setX(tabBarCloseTabButton.readEntry("x", 0));
|
||||
m_tabBarCloseTabButtonPosition.setY(tabBarCloseTabButton.readEntry("y", 0));
|
||||
|
||||
m_tabBarCloseTabButtonStyleSheet = buttonStyleSheet(tabDir + tabBarCloseTabButton.readEntry("up_image", ""),
|
||||
tabDir + tabBarCloseTabButton.readEntry("over_image", ""),
|
||||
tabDir + tabBarCloseTabButton.readEntry("down_image", ""));
|
||||
|
||||
if (m_tabBarPreventClosingImage.isNull())
|
||||
updateTabBarPreventClosingImageCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const QString Skin::buttonStyleSheet(const QString& up, const QString& over, const QString& down)
|
||||
{
|
||||
QString styleSheet;
|
||||
|
||||
QString borderBit("border: none;");
|
||||
|
||||
QPixmap buttonImage(up);
|
||||
QString w(QString::number(buttonImage.width()));
|
||||
QString h(QString::number(buttonImage.height()));
|
||||
|
||||
QString sizeBit("min-width:" + w + "; min-height:" + h + "; max-width:" + w + "; max-height:" + h + ';');
|
||||
|
||||
styleSheet.append("KPushButton {" + borderBit + "image:url(" + up + ");" + sizeBit + '}');
|
||||
styleSheet.append("KPushButton::hover {" + borderBit + "image:url(" + over + ");" + sizeBit + '}');
|
||||
styleSheet.append("KPushButton::pressed {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("KPushButton::checked {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("KPushButton::open {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("KPushButton::menu-indicator { left: " + w + " }");
|
||||
|
||||
styleSheet.append("QToolButton {" + borderBit + "image:url(" + up + ");" + sizeBit + '}');
|
||||
styleSheet.append("QToolButton::hover {" + borderBit + "image:url(" + over + ");" + sizeBit + '}');
|
||||
styleSheet.append("QToolButton::pressed {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("QToolButton::checked {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("QToolButton::open {" + borderBit + "image:url(" + down + ");" + sizeBit + '}');
|
||||
styleSheet.append("QToolButton::menu-indicator { left: " + w + " }");
|
||||
|
||||
return styleSheet;
|
||||
}
|
||||
|
||||
const QPixmap Skin::tabBarPreventClosingImage()
|
||||
{
|
||||
if (m_tabBarPreventClosingImage.isNull())
|
||||
return m_tabBarPreventClosingImageCached;
|
||||
|
||||
return m_tabBarPreventClosingImage;
|
||||
}
|
||||
|
||||
void Skin::updateTabBarPreventClosingImageCache()
|
||||
{
|
||||
// Get the target image size from the tabBar height, acquired from
|
||||
// background image, minus (2 * y position) of the lock icon.
|
||||
int m_IconSize = m_tabBarBackgroundImage.height() -
|
||||
(2 * m_tabBarPreventClosingImagePosition.y());
|
||||
|
||||
// Get the system lock icon in a generous size.
|
||||
m_tabBarPreventClosingImageCached = KIcon("object-locked.png").pixmap(48, 48);
|
||||
|
||||
// Resize the image if it's too tall.
|
||||
if (m_IconSize < m_tabBarPreventClosingImageCached.height())
|
||||
{
|
||||
m_tabBarPreventClosingImageCached =
|
||||
m_tabBarPreventClosingImageCached.scaled(m_IconSize,
|
||||
m_IconSize, Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
}
|
||||
|
||||
void Skin::systemIconsChanged(int group)
|
||||
{
|
||||
Q_UNUSED(group);
|
||||
|
||||
if (m_tabBarPreventClosingImage.isNull())
|
||||
{
|
||||
updateTabBarPreventClosingImageCache();
|
||||
|
||||
emit iconChanged();
|
||||
}
|
||||
}
|
147
yakuake/app/skin.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SKIN_H
|
||||
#define SKIN_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
|
||||
|
||||
class Skin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Skin();
|
||||
~Skin();
|
||||
|
||||
bool load(const QString& name, bool kns = false);
|
||||
|
||||
|
||||
const QColor& borderColor() { return m_borderColor; }
|
||||
int borderWidth() { return m_borderWidth; }
|
||||
|
||||
|
||||
const QPixmap& titleBarBackgroundImage() { return m_titleBarBackgroundImage; }
|
||||
const QPixmap& titleBarLeftCornerImage() { return m_titleBarLeftCornerImage; }
|
||||
const QPixmap& titleBarRightCornerImage() { return m_titleBarRightCornerImage; }
|
||||
|
||||
const QPoint& titleBarFocusButtonPosition() { return m_titleBarFocusButtonPosition; }
|
||||
const QString titleBarFocusButtonStyleSheet() { return m_titleBarFocusButtonStyleSheet; }
|
||||
|
||||
const QPoint& titleBarMenuButtonPosition() { return m_titleBarMenuButtonPosition; }
|
||||
const QString titleBarMenuButtonStyleSheet() { return m_titleBarMenuButtonStyleSheet; }
|
||||
|
||||
const QPoint& titleBarQuitButtonPosition() { return m_titleBarQuitButtonPosition; }
|
||||
const QString titleBarQuitButtonStyleSheet() { return m_titleBarQuitButtonStyleSheet; }
|
||||
|
||||
const QString titleBarText() { return m_titleBarText; }
|
||||
const QPoint& titleBarTextPosition() { return m_titleBarTextPosition; }
|
||||
const QColor& titleBarTextColor() { return m_titleBarTextColor; }
|
||||
bool titleBarTextBold() { return m_titleBarTextBold; }
|
||||
|
||||
|
||||
const QPoint& tabBarPosition() { return m_tabBarPosition; }
|
||||
const QColor& tabBarTextColor() { return m_tabBarTextColor; }
|
||||
|
||||
const QPixmap& tabBarSeparatorImage() { return m_tabBarSeparatorImage; }
|
||||
const QPixmap& tabBarUnselectedBackgroundImage() { return m_tabBarUnselectedBackgroundImage; }
|
||||
const QPixmap& tabBarSelectedBackgroundImage() { return m_tabBarSelectedBackgroundImage; }
|
||||
const QPixmap& tabBarSelectedLeftCornerImage() { return m_tabBarSelectedLeftCornerImage; }
|
||||
const QPixmap& tabBarSelectedRightCornerImage() { return m_tabBarSelectedRightCornerImage; }
|
||||
|
||||
const QPixmap tabBarPreventClosingImage();
|
||||
const QPoint& tabBarPreventClosingImagePosition() { return m_tabBarPreventClosingImagePosition; }
|
||||
|
||||
const QPixmap& tabBarBackgroundImage() { return m_tabBarBackgroundImage; }
|
||||
const QPixmap& tabBarLeftCornerImage() { return m_tabBarLeftCornerImage; }
|
||||
const QPixmap& tabBarRightCornerImage() { return m_tabBarRightCornerImage; }
|
||||
|
||||
const QPoint& tabBarNewTabButtonPosition() { return m_tabBarNewTabButtonPosition; }
|
||||
const QString tabBarNewTabButtonStyleSheet() { return m_tabBarNewTabButtonStyleSheet; }
|
||||
|
||||
const QPoint& tabBarCloseTabButtonPosition() { return m_tabBarCloseTabButtonPosition; }
|
||||
const QString tabBarCloseTabButtonStyleSheet() { return m_tabBarCloseTabButtonStyleSheet; }
|
||||
|
||||
|
||||
signals:
|
||||
void iconChanged();
|
||||
|
||||
|
||||
private slots:
|
||||
void systemIconsChanged(int group);
|
||||
|
||||
|
||||
private:
|
||||
const QString buttonStyleSheet(const QString& up, const QString& over, const QString& down);
|
||||
|
||||
void updateTabBarPreventClosingImageCache();
|
||||
|
||||
QColor m_borderColor;
|
||||
int m_borderWidth;
|
||||
|
||||
|
||||
QPixmap m_titleBarBackgroundImage;
|
||||
QPixmap m_titleBarLeftCornerImage;
|
||||
QPixmap m_titleBarRightCornerImage;
|
||||
|
||||
QPoint m_titleBarFocusButtonPosition;
|
||||
QString m_titleBarFocusButtonStyleSheet;
|
||||
|
||||
QPoint m_titleBarMenuButtonPosition;
|
||||
QString m_titleBarMenuButtonStyleSheet;
|
||||
|
||||
QPoint m_titleBarQuitButtonPosition;
|
||||
QString m_titleBarQuitButtonStyleSheet;
|
||||
|
||||
QString m_titleBarText;
|
||||
QPoint m_titleBarTextPosition;
|
||||
QColor m_titleBarTextColor;
|
||||
bool m_titleBarTextBold;
|
||||
|
||||
QPoint m_tabBarPosition;
|
||||
QColor m_tabBarTextColor;
|
||||
|
||||
QPixmap m_tabBarSeparatorImage;
|
||||
QPixmap m_tabBarUnselectedBackgroundImage;
|
||||
QPixmap m_tabBarSelectedBackgroundImage;
|
||||
QPixmap m_tabBarSelectedLeftCornerImage;
|
||||
QPixmap m_tabBarSelectedRightCornerImage;
|
||||
|
||||
QPixmap m_tabBarPreventClosingImage;
|
||||
QPixmap m_tabBarPreventClosingImageCached;
|
||||
QPoint m_tabBarPreventClosingImagePosition;
|
||||
|
||||
QPixmap m_tabBarBackgroundImage;
|
||||
QPixmap m_tabBarLeftCornerImage;
|
||||
QPixmap m_tabBarRightCornerImage;
|
||||
|
||||
QPoint m_tabBarNewTabButtonPosition;
|
||||
QString m_tabBarNewTabButtonStyleSheet;
|
||||
|
||||
QPoint m_tabBarCloseTabButtonPosition;
|
||||
QString m_tabBarCloseTabButtonStyleSheet;
|
||||
};
|
||||
|
||||
#endif
|
53
yakuake/app/splitter.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "splitter.h"
|
||||
|
||||
|
||||
Splitter::Splitter(Qt::Orientation orientation, QWidget* parent) : QSplitter(orientation, parent)
|
||||
{
|
||||
setAutoFillBackground(true);
|
||||
setOpaqueResize(false);
|
||||
}
|
||||
|
||||
Splitter::~Splitter()
|
||||
{
|
||||
}
|
||||
|
||||
void Splitter::recursiveCleanup()
|
||||
{
|
||||
if (count() == 0)
|
||||
deleteLater();
|
||||
else
|
||||
{
|
||||
QList<Splitter*> list = findChildren<Splitter*>();
|
||||
|
||||
QListIterator<Splitter*> i(list);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
Splitter* splitter = i.next();
|
||||
|
||||
if (splitter->parent() == this)
|
||||
splitter->recursiveCleanup();
|
||||
}
|
||||
}
|
||||
}
|
39
yakuake/app/splitter.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright (C) 2008 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef SPLITTER_H
|
||||
#define SPLITTER_H
|
||||
|
||||
|
||||
#include <QSplitter>
|
||||
|
||||
|
||||
class Splitter: public QSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Splitter(Qt::Orientation orientation, QWidget* parent = 0);
|
||||
~Splitter();
|
||||
|
||||
void recursiveCleanup();
|
||||
};
|
||||
|
||||
#endif
|
1056
yakuake/app/tabbar.cpp
Normal file
160
yakuake/app/tabbar.h
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TABBAR_H
|
||||
#define TABBAR_H
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class MainWindow;
|
||||
class Skin;
|
||||
|
||||
class KLineEdit;
|
||||
class KMenu;
|
||||
class KPushButton;
|
||||
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
|
||||
|
||||
class TabBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.yakuake")
|
||||
|
||||
public:
|
||||
explicit TabBar(MainWindow* mainWindow);
|
||||
~TabBar();
|
||||
|
||||
void applySkin();
|
||||
|
||||
|
||||
public slots:
|
||||
void addTab(int sessionId, const QString& title = 0);
|
||||
void removeTab(int sessionId = -1);
|
||||
|
||||
void interactiveRename(int sessionId);
|
||||
|
||||
void selectTab(int sessionId);
|
||||
void selectNextTab();
|
||||
void selectPreviousTab();
|
||||
|
||||
void moveTabLeft(int sessionId = -1);
|
||||
void moveTabRight(int sessionId = -1);
|
||||
|
||||
Q_SCRIPTABLE QString tabTitle(int sessionId);
|
||||
Q_SCRIPTABLE void setTabTitle(int sessionId, const QString& newTitle);
|
||||
|
||||
Q_SCRIPTABLE int sessionAtTab(int index);
|
||||
|
||||
|
||||
signals:
|
||||
void newTabRequested();
|
||||
void tabSelected(int sessionId);
|
||||
void tabClosed(int sessionId);
|
||||
|
||||
void requestTerminalHighlight(int terminalId);
|
||||
void requestRemoveTerminalHighlight();
|
||||
void tabContextMenuClosed();
|
||||
void lastTabClosed();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent*);
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
virtual void wheelEvent(QWheelEvent*);
|
||||
virtual void keyPressEvent(QKeyEvent*);
|
||||
virtual void mousePressEvent(QMouseEvent*);
|
||||
virtual void mouseReleaseEvent(QMouseEvent*);
|
||||
virtual void mouseMoveEvent(QMouseEvent*);
|
||||
virtual void dragMoveEvent(QDragMoveEvent*);
|
||||
virtual void dragEnterEvent(QDragEnterEvent*);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent*);
|
||||
virtual void dropEvent(QDropEvent*);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent*);
|
||||
virtual void contextMenuEvent(QContextMenuEvent*);
|
||||
virtual void leaveEvent(QEvent*);
|
||||
|
||||
|
||||
private slots:
|
||||
void readySessionMenu();
|
||||
|
||||
void contextMenuActionHovered(QAction* action);
|
||||
|
||||
void closeTabButtonClicked();
|
||||
|
||||
void interactiveRenameDone();
|
||||
|
||||
|
||||
private:
|
||||
QString standardTabTitle();
|
||||
QString makeTabTitle(int number);
|
||||
int tabAt(int x);
|
||||
|
||||
void readyTabContextMenu();
|
||||
|
||||
void updateMoveActions(int index);
|
||||
void updateToggleActions(int sessionId);
|
||||
void updateToggleKeyboardInputMenu(int sessionId = -1);
|
||||
void updateToggleMonitorSilenceMenu(int sessionId = -1);
|
||||
void updateToggleMonitorActivityMenu(int sessionId = -1);
|
||||
|
||||
int drawButton(int x, int y, int index, QPainter& painter);
|
||||
|
||||
void startDrag(int index);
|
||||
void drawDropIndicator(int index, bool disabled = false);
|
||||
int dropIndex(const QPoint pos);
|
||||
bool isSameTab(const QDropEvent*);
|
||||
|
||||
MainWindow* m_mainWindow;
|
||||
Skin* m_skin;
|
||||
|
||||
QToolButton* m_newTabButton;
|
||||
KPushButton* m_closeTabButton;
|
||||
|
||||
KMenu* m_tabContextMenu;
|
||||
KMenu* m_toggleKeyboardInputMenu;
|
||||
KMenu* m_toggleMonitorActivityMenu;
|
||||
KMenu* m_toggleMonitorSilenceMenu;
|
||||
KMenu* m_sessionMenu;
|
||||
|
||||
KLineEdit* m_lineEdit;
|
||||
int m_renamingSessionId;
|
||||
|
||||
QList<int> m_tabs;
|
||||
QHash<int, QString> m_tabTitles;
|
||||
QList<int> m_tabWidths;
|
||||
|
||||
int m_selectedSessionId;
|
||||
|
||||
int m_mousePressed;
|
||||
int m_mousePressedIndex;
|
||||
|
||||
QPoint m_startPos;
|
||||
QLabel* m_dropIndicator;
|
||||
QRect m_dropRect;
|
||||
};
|
||||
|
||||
#endif
|
300
yakuake/app/terminal.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "terminal.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <KActionCollection>
|
||||
#include <KApplication>
|
||||
#include <KColorScheme>
|
||||
#include <kde_terminal_interface.h>
|
||||
#include <KLocalizedString>
|
||||
#include <KIcon>
|
||||
#include <KPluginFactory>
|
||||
#include <KPluginLoader>
|
||||
#include <KService>
|
||||
#include <KUser>
|
||||
|
||||
#include <QAction>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
|
||||
int Terminal::m_availableTerminalId = 0;
|
||||
|
||||
Terminal::Terminal(QWidget* parent) : QObject(parent)
|
||||
{
|
||||
m_terminalId = m_availableTerminalId;
|
||||
m_availableTerminalId++;
|
||||
|
||||
m_keyboardInputEnabled = true;
|
||||
|
||||
m_monitorActivityEnabled = false;
|
||||
m_monitorSilenceEnabled = false;
|
||||
|
||||
m_part = NULL;
|
||||
m_terminalInterface = NULL;
|
||||
m_partWidget = NULL;
|
||||
m_terminalWidget = NULL;
|
||||
m_parentSplitter = parent;
|
||||
|
||||
KPluginFactory* factory = KPluginLoader("konsolepart").factory();
|
||||
|
||||
m_part = factory ? (factory->create<KParts::Part>(parent)) : 0;
|
||||
|
||||
if (m_part)
|
||||
{
|
||||
connect(m_part, SIGNAL(setWindowCaption(QString)), this, SLOT(setTitle(QString)));
|
||||
connect(m_part, SIGNAL(overrideShortcut(QKeyEvent*,bool&)), this, SLOT(overrideShortcut(QKeyEvent*,bool&)));
|
||||
connect(m_part, SIGNAL(destroyed()), this, SLOT(deleteLater()));
|
||||
|
||||
m_partWidget = m_part->widget();
|
||||
|
||||
m_terminalWidget = m_part->widget()->focusWidget();
|
||||
|
||||
if (m_terminalWidget)
|
||||
{
|
||||
m_terminalWidget->setFocusPolicy(Qt::WheelFocus);
|
||||
m_terminalWidget->installEventFilter(this);
|
||||
}
|
||||
|
||||
disableOffendingPartActions();
|
||||
|
||||
m_terminalInterface = qobject_cast<TerminalInterface*>(m_part);
|
||||
if (m_terminalInterface) m_terminalInterface->showShellInDir(KUser().homeDir());
|
||||
}
|
||||
else
|
||||
displayKPartLoadError();
|
||||
}
|
||||
|
||||
Terminal::~Terminal()
|
||||
{
|
||||
emit destroyed(m_terminalId);
|
||||
}
|
||||
|
||||
void Terminal::deletePart()
|
||||
{
|
||||
if (m_part)
|
||||
m_part->deleteLater();
|
||||
else
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
bool Terminal::eventFilter(QObject* /* watched */, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::FocusIn)
|
||||
{
|
||||
emit activated(m_terminalId);
|
||||
|
||||
QFocusEvent* focusEvent = static_cast<QFocusEvent*>(event);
|
||||
|
||||
if (focusEvent->reason() == Qt::MouseFocusReason || focusEvent->reason() == Qt::OtherFocusReason
|
||||
|| focusEvent->reason() == Qt::BacktabFocusReason)
|
||||
emit manuallyActivated(this);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseMove)
|
||||
{
|
||||
if (Settings::focusFollowsMouse() && m_terminalWidget && !m_terminalWidget->hasFocus())
|
||||
m_terminalWidget->setFocus();
|
||||
}
|
||||
|
||||
if (!m_keyboardInputEnabled)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
|
||||
if (keyEvent->modifiers() == Qt::NoModifier)
|
||||
emit keyboardInputBlocked(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::KeyRelease)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Terminal::displayKPartLoadError()
|
||||
{
|
||||
KColorScheme colorScheme(QPalette::Active);
|
||||
QColor warningColor = colorScheme.background(KColorScheme::NeutralBackground).color();
|
||||
QColor warningColorLight = KColorScheme::shade(warningColor, KColorScheme::LightShade, 0.1);
|
||||
QString gradient = "qlineargradient(x1:0, y1:0, x2:0, y2:1,"
|
||||
"stop: 0 %1, stop: 0.6 %1 ,stop: 1.0 %2)";
|
||||
gradient = gradient.arg(warningColor.name()).arg(warningColorLight.name());
|
||||
QString styleSheet = "QLabel { background: %1; }";
|
||||
|
||||
QWidget* widget = new QWidget(m_parentSplitter);
|
||||
widget->setStyleSheet(styleSheet.arg(gradient));
|
||||
m_partWidget = widget;
|
||||
m_terminalWidget = widget;
|
||||
m_terminalWidget->setFocusPolicy(Qt::WheelFocus);
|
||||
m_terminalWidget->installEventFilter(this);
|
||||
|
||||
QLabel* label = new QLabel(widget);
|
||||
label->setMargin(10);
|
||||
label->setWordWrap(false);
|
||||
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
label->setText(i18nc("@info", "<application>Yakuake</application> was unable to load "
|
||||
"the <application>Konsole</application> component.<nl/> "
|
||||
"A <application>Konsole</application> installation is "
|
||||
"required to use Yakuake."));
|
||||
|
||||
QLabel* icon = new QLabel(widget);
|
||||
icon->setMargin(10);
|
||||
icon->setPixmap(KIcon("dialog-warning").pixmap(QSize(48, 48)));
|
||||
icon->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
||||
QHBoxLayout* layout = new QHBoxLayout(widget);
|
||||
layout->addWidget(icon);
|
||||
layout->addWidget(label);
|
||||
layout->setSpacing(0);
|
||||
layout->setMargin(0);
|
||||
layout->setStretchFactor(icon, 1);
|
||||
layout->setStretchFactor(label,5);
|
||||
}
|
||||
|
||||
void Terminal::disableOffendingPartActions()
|
||||
{
|
||||
// This is an unwelcome stop-gap that will be removed once we can
|
||||
// count on a Konsole version that doesn't pollute a KPart user's
|
||||
// shortcut "namespace".
|
||||
|
||||
if (!m_part) return;
|
||||
|
||||
KActionCollection* actionCollection = m_part->actionCollection();
|
||||
|
||||
if (actionCollection)
|
||||
{
|
||||
QAction* action = 0;
|
||||
|
||||
action = actionCollection->action("next-view");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("previous-view");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("close-active-view");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("split-view-left-right");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("split-view-top-bottom");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("rename-session");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("enlarge-font");
|
||||
if (action) action->setEnabled(false);
|
||||
|
||||
action = actionCollection->action("shrink-font");
|
||||
if (action) action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::setTitle(const QString& title)
|
||||
{
|
||||
m_title = title;
|
||||
|
||||
emit titleChanged(m_terminalId, m_title);
|
||||
}
|
||||
|
||||
void Terminal::runCommand(const QString& command)
|
||||
{
|
||||
m_terminalInterface->sendInput(command + '\n');
|
||||
}
|
||||
|
||||
void Terminal::manageProfiles()
|
||||
{
|
||||
QMetaObject::invokeMethod(m_part, "showManageProfilesDialog",
|
||||
Qt::QueuedConnection, Q_ARG(QWidget*, KApplication::activeWindow()));
|
||||
}
|
||||
|
||||
void Terminal::editProfile()
|
||||
{
|
||||
QMetaObject::invokeMethod(m_part, "showEditCurrentProfileDialog",
|
||||
Qt::QueuedConnection, Q_ARG(QWidget*, KApplication::activeWindow()));
|
||||
}
|
||||
|
||||
void Terminal::overrideShortcut(QKeyEvent* /* event */, bool& override)
|
||||
{
|
||||
override = false;
|
||||
}
|
||||
|
||||
void Terminal::setMonitorActivityEnabled(bool enabled)
|
||||
{
|
||||
m_monitorActivityEnabled = enabled;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
connect(m_part, SIGNAL(activityDetected()), this, SLOT(activityDetected()),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
QMetaObject::invokeMethod(m_part, "setMonitorActivityEnabled",
|
||||
Qt::QueuedConnection, Q_ARG(bool, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(m_part, SIGNAL(activityDetected()), this, SLOT(activityDetected()));
|
||||
|
||||
QMetaObject::invokeMethod(m_part, "setMonitorActivityEnabled",
|
||||
Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::setMonitorSilenceEnabled(bool enabled)
|
||||
{
|
||||
m_monitorSilenceEnabled = enabled;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
connect(m_part, SIGNAL(silenceDetected()), this, SLOT(silenceDetected()),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
QMetaObject::invokeMethod(m_part, "setMonitorSilenceEnabled",
|
||||
Qt::QueuedConnection, Q_ARG(bool, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(m_part, SIGNAL(silenceDetected()), this, SLOT(silenceDetected()));
|
||||
|
||||
QMetaObject::invokeMethod(m_part, "setMonitorSilenceEnabled",
|
||||
Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::activityDetected()
|
||||
{
|
||||
emit activityDetected(this);
|
||||
}
|
||||
|
||||
void Terminal::silenceDetected()
|
||||
{
|
||||
emit silenceDetected(this);
|
||||
}
|
108
yakuake/app/terminal.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TERMINAL_H
|
||||
#define TERMINAL_H
|
||||
|
||||
#include <KParts/Part>
|
||||
|
||||
|
||||
class QKeyEvent;
|
||||
|
||||
class TerminalInterface;
|
||||
|
||||
|
||||
class Terminal : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Terminal(QWidget* parent = 0);
|
||||
~Terminal();
|
||||
|
||||
bool eventFilter(QObject* watched, QEvent* event);
|
||||
|
||||
int id() { return m_terminalId; }
|
||||
const QString title() { return m_title; }
|
||||
|
||||
QWidget* partWidget() { return m_partWidget; }
|
||||
QWidget* terminalWidget() { return m_terminalWidget; }
|
||||
|
||||
QWidget* splitter() { return m_parentSplitter; }
|
||||
void setSplitter(QWidget* splitter) { m_parentSplitter = splitter; }
|
||||
|
||||
void runCommand(const QString& command);
|
||||
|
||||
void manageProfiles();
|
||||
void editProfile();
|
||||
|
||||
bool keyboardInputEnabled() { return m_keyboardInputEnabled; }
|
||||
void setKeyboardInputEnabled(bool enabled) { m_keyboardInputEnabled = enabled; }
|
||||
|
||||
bool monitorActivityEnabled() { return m_monitorActivityEnabled; }
|
||||
void setMonitorActivityEnabled(bool enabled);
|
||||
|
||||
bool monitorSilenceEnabled() { return m_monitorSilenceEnabled; }
|
||||
void setMonitorSilenceEnabled(bool enabled);
|
||||
|
||||
void deletePart();
|
||||
|
||||
|
||||
signals:
|
||||
void titleChanged(int terminalId, const QString& title);
|
||||
void activated(int terminalId);
|
||||
void manuallyActivated(Terminal* terminal);
|
||||
void keyboardInputBlocked(Terminal* terminal);
|
||||
void activityDetected(Terminal* terminal);
|
||||
void silenceDetected(Terminal* terminal);
|
||||
void destroyed(int terminalId);
|
||||
|
||||
|
||||
private slots:
|
||||
void setTitle(const QString& title);
|
||||
void overrideShortcut(QKeyEvent* event, bool& override);
|
||||
void silenceDetected();
|
||||
void activityDetected();
|
||||
|
||||
|
||||
private:
|
||||
void disableOffendingPartActions();
|
||||
|
||||
void displayKPartLoadError();
|
||||
|
||||
static int m_availableTerminalId;
|
||||
int m_terminalId;
|
||||
|
||||
KParts::Part* m_part;
|
||||
TerminalInterface* m_terminalInterface;
|
||||
QWidget* m_partWidget;
|
||||
QPointer<QWidget> m_terminalWidget;
|
||||
QWidget* m_parentSplitter;
|
||||
|
||||
QString m_title;
|
||||
|
||||
bool m_keyboardInputEnabled;
|
||||
|
||||
bool m_monitorActivityEnabled;
|
||||
bool m_monitorSilenceEnabled;
|
||||
};
|
||||
|
||||
#endif
|
161
yakuake/app/titlebar.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "titlebar.h"
|
||||
#include "mainwindow.h"
|
||||
#include "skin.h"
|
||||
|
||||
#include <KMenu>
|
||||
#include <KPushButton>
|
||||
#include <KGlobalSettings>
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
TitleBar::TitleBar(MainWindow* mainWindow) : QWidget(mainWindow)
|
||||
{
|
||||
setWhatsThis(i18nc("@info:whatsthis",
|
||||
"<title>Title Bar</title>"
|
||||
"<para>The title bar displays the session title if available.</para>"));
|
||||
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
m_mainWindow = mainWindow;
|
||||
m_skin = mainWindow->skin();
|
||||
|
||||
m_focusButton = new KPushButton(this);
|
||||
m_focusButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_focusButton->setCheckable(true);
|
||||
m_focusButton->setToolTip(i18nc("@info:tooltip", "Keep window open when it loses focus"));
|
||||
m_focusButton->setWhatsThis(i18nc("@info:whatsthis", "If this is checked, the window will stay open when it loses focus."));
|
||||
connect(m_focusButton, SIGNAL(toggled(bool)), mainWindow, SLOT(setKeepOpen(bool)));
|
||||
|
||||
m_menuButton = new KPushButton(this);
|
||||
m_menuButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_menuButton->setMenu(mainWindow->menu());
|
||||
m_menuButton->setToolTip(i18nc("@info:tooltip", "Open Menu"));
|
||||
m_menuButton->setWhatsThis(i18nc("@info:whatsthis", "Opens the main menu."));
|
||||
|
||||
m_quitButton = new KPushButton(this);
|
||||
m_quitButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_quitButton->setToolTip(i18nc("@info:tooltip Quits the application", "Quit"));
|
||||
m_quitButton->setWhatsThis(i18nc("@info:whatsthis", "Quits the application."));
|
||||
connect(m_quitButton, SIGNAL(clicked()), mainWindow, SLOT(close()));
|
||||
}
|
||||
|
||||
TitleBar::~TitleBar()
|
||||
{
|
||||
}
|
||||
|
||||
void TitleBar::applySkin()
|
||||
{
|
||||
resize(width(), m_skin->titleBarBackgroundImage().height());
|
||||
|
||||
m_focusButton->setStyleSheet(m_skin->titleBarFocusButtonStyleSheet());
|
||||
m_menuButton->setStyleSheet(m_skin->titleBarMenuButtonStyleSheet());
|
||||
m_quitButton->setStyleSheet(m_skin->titleBarQuitButtonStyleSheet());
|
||||
|
||||
m_focusButton->move(width() - m_skin->titleBarFocusButtonPosition().x(), m_skin->titleBarFocusButtonPosition().y());
|
||||
m_menuButton->move(width() - m_skin->titleBarMenuButtonPosition().x(), m_skin->titleBarMenuButtonPosition().y());
|
||||
m_quitButton->move(width() - m_skin->titleBarQuitButtonPosition().x(), m_skin->titleBarQuitButtonPosition().y());
|
||||
|
||||
repaint();
|
||||
|
||||
updateMask();
|
||||
}
|
||||
|
||||
void TitleBar::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
m_focusButton->move(width() - m_skin->titleBarFocusButtonPosition().x(), m_skin->titleBarFocusButtonPosition().y());
|
||||
m_menuButton->move(width() - m_skin->titleBarMenuButtonPosition().x(), m_skin->titleBarMenuButtonPosition().y());
|
||||
m_quitButton->move(width() - m_skin->titleBarQuitButtonPosition().x(), m_skin->titleBarQuitButtonPosition().y());
|
||||
|
||||
updateMask();
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void TitleBar::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setPen(m_skin->titleBarTextColor());
|
||||
|
||||
const QPixmap& backgroundImage = m_skin->titleBarBackgroundImage();
|
||||
const QPixmap& leftCornerImage = m_skin->titleBarLeftCornerImage();
|
||||
const QPixmap& rightCornerImage = m_skin->titleBarRightCornerImage();
|
||||
|
||||
painter.drawTiledPixmap(leftCornerImage.width(), 0,
|
||||
width() - leftCornerImage.width() - rightCornerImage.width(), height(),
|
||||
backgroundImage);
|
||||
|
||||
painter.drawPixmap(0, 0, leftCornerImage);
|
||||
painter.drawPixmap(width() - rightCornerImage.width(), 0, rightCornerImage);
|
||||
|
||||
QFont font = KGlobalSettings::windowTitleFont();
|
||||
font.setBold(m_skin->titleBarTextBold());
|
||||
painter.setFont(font);
|
||||
|
||||
painter.drawText(m_skin->titleBarTextPosition(), title());
|
||||
|
||||
painter.end();
|
||||
}
|
||||
|
||||
void TitleBar::updateMask()
|
||||
{
|
||||
const QPixmap& leftCornerImage = m_skin->titleBarLeftCornerImage();
|
||||
const QPixmap& rightCornerImage = m_skin->titleBarRightCornerImage();
|
||||
|
||||
QRegion leftCornerRegion = leftCornerImage.hasAlpha() ? QRegion(leftCornerImage.mask()) : QRegion(leftCornerImage.rect());
|
||||
QRegion rightCornerRegion = rightCornerImage.hasAlpha() ? QRegion(rightCornerImage.mask()) : QRegion(rightCornerImage.rect());
|
||||
|
||||
QRegion mask = leftCornerRegion;
|
||||
|
||||
mask += QRegion(QRect(0, 0, width() - leftCornerImage.width() - rightCornerImage.width(),
|
||||
height())).translated(leftCornerImage.width(), 0);
|
||||
|
||||
mask += rightCornerRegion.translated(width() - rightCornerImage.width(), 0);
|
||||
|
||||
setMask(mask);
|
||||
}
|
||||
|
||||
void TitleBar::setFocusButtonState(bool checked)
|
||||
{
|
||||
m_focusButton->setChecked(checked);
|
||||
}
|
||||
|
||||
QString TitleBar::title()
|
||||
{
|
||||
if (!m_skin->titleBarText().isEmpty() && !m_title.isEmpty())
|
||||
return m_title + " - " + m_skin->titleBarText();
|
||||
else if (!m_skin->titleBarText().isEmpty() && m_title.isEmpty())
|
||||
return m_skin->titleBarText();
|
||||
else
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void TitleBar::setTitle(const QString& title)
|
||||
{
|
||||
m_title = title;
|
||||
|
||||
repaint();
|
||||
}
|
71
yakuake/app/titlebar.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TITLEBAR_H
|
||||
#define TITLEBAR_H
|
||||
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class MainWindow;
|
||||
class Skin;
|
||||
|
||||
class KPushButton;
|
||||
|
||||
|
||||
class TitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TitleBar(MainWindow* mainWindow);
|
||||
~TitleBar();
|
||||
|
||||
void applySkin();
|
||||
void updateMask();
|
||||
|
||||
QString title();
|
||||
|
||||
void setFocusButtonState(bool checked);
|
||||
|
||||
|
||||
public slots:
|
||||
void setTitle(const QString& title);
|
||||
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent*);
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
|
||||
|
||||
private:
|
||||
MainWindow* m_mainWindow;
|
||||
Skin* m_skin;
|
||||
|
||||
KPushButton* m_focusButton;
|
||||
KPushButton* m_menuButton;
|
||||
KPushButton* m_quitButton;
|
||||
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
#endif
|
261
yakuake/app/visualeventoverlay.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
Copyright (C) 2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
|
||||
#include "visualeventoverlay.h"
|
||||
#include "sessionstack.h"
|
||||
#include "settings.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include <KColorScheme>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
EventRect::EventRect(const QPoint& topLeft, const QPoint& bottomRight, EventType type,
|
||||
EventFlags flags) : QRect(topLeft, bottomRight)
|
||||
{
|
||||
m_eventType = type;
|
||||
|
||||
m_eventFlags = flags;
|
||||
|
||||
m_timeStamp.start();
|
||||
}
|
||||
|
||||
EventRect::~EventRect()
|
||||
{
|
||||
}
|
||||
|
||||
bool EventRect::operator==(const EventRect& eventRect) const
|
||||
{
|
||||
if (m_eventType == eventRect.eventType() && eventRect.testFlag(EventRect::Singleton))
|
||||
return true;
|
||||
|
||||
if (m_eventType != eventRect.eventType())
|
||||
return false;
|
||||
|
||||
return ::operator==(*this, eventRect);
|
||||
}
|
||||
|
||||
bool EventRect::operator<(const EventRect& eventRect) const
|
||||
{
|
||||
if (!testFlag(EventRect::Exclusive) && eventRect.testFlag(EventRect::Exclusive))
|
||||
return false;
|
||||
if (m_eventType < eventRect.eventType())
|
||||
return true;
|
||||
else if (m_timeStamp < eventRect.timeStamp())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VisualEventOverlay::VisualEventOverlay(SessionStack* parent) : QWidget(parent)
|
||||
{
|
||||
m_sessionStack = parent;
|
||||
|
||||
setAutoFillBackground(false);
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
|
||||
m_cleanupTimer = new QTimer(this);
|
||||
m_cleanupTimer->setSingleShot(true);
|
||||
connect(m_cleanupTimer, SIGNAL(timeout()), this, SLOT(cleanupOverlay()));
|
||||
|
||||
m_cleanupTimerCeiling = 0;
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
VisualEventOverlay::~VisualEventOverlay()
|
||||
{
|
||||
}
|
||||
|
||||
void VisualEventOverlay::highlightTerminal(Terminal* terminal, bool persistent)
|
||||
{
|
||||
if (!persistent && Settings::terminalHighlightDuration() == 0)
|
||||
return;
|
||||
|
||||
if (isHidden()) show();
|
||||
|
||||
EventRect::EventFlags flags = EventRect::Singleton | EventRect::Exclusive;
|
||||
if (persistent) flags |= EventRect::Persistent;
|
||||
|
||||
terminalEvent(terminal, EventRect::TerminalHighlight, flags);
|
||||
|
||||
if (!persistent)
|
||||
scheduleCleanup(Settings::terminalHighlightDuration());
|
||||
}
|
||||
|
||||
void VisualEventOverlay::removeTerminalHighlight()
|
||||
{
|
||||
if (!m_eventRects.count()) return;
|
||||
|
||||
QMutableListIterator<EventRect> i(m_eventRects);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
if (i.next().eventType() == EventRect::TerminalHighlight)
|
||||
i.remove();
|
||||
}
|
||||
|
||||
if (m_sessionStack->requiresVisualEventOverlay())
|
||||
update();
|
||||
else
|
||||
hide();
|
||||
}
|
||||
|
||||
void VisualEventOverlay::indicateKeyboardInputBlocked(Terminal* terminal)
|
||||
{
|
||||
if (Settings::keyboardInputBlockIndicatorDuration() == 0)
|
||||
return;
|
||||
|
||||
terminalEvent(terminal, EventRect::KeyboardInputBlocked);
|
||||
|
||||
scheduleCleanup(Settings::keyboardInputBlockIndicatorDuration());
|
||||
}
|
||||
|
||||
void VisualEventOverlay::terminalEvent(Terminal* terminal, EventRect::EventType type, EventRect::EventFlags flags)
|
||||
{
|
||||
QRect partRect(terminal->partWidget()->rect());
|
||||
const QWidget* partWidget = terminal->partWidget();
|
||||
|
||||
QPoint topLeft(partWidget->mapTo(parentWidget(), partRect.topLeft()));
|
||||
QPoint bottomRight(partWidget->mapTo(parentWidget(), partRect.bottomRight()));
|
||||
|
||||
EventRect eventRect(topLeft, bottomRight, type, flags);
|
||||
|
||||
m_eventRects.removeAll(eventRect);
|
||||
m_eventRects.append(eventRect);
|
||||
|
||||
qSort(m_eventRects);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void VisualEventOverlay::paintEvent(QPaintEvent*)
|
||||
{
|
||||
if (!m_eventRects.count()) return;
|
||||
|
||||
QPainter painter(this);
|
||||
|
||||
m_time.start();
|
||||
bool painted = false;
|
||||
|
||||
QListIterator<EventRect> i(m_eventRects);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
const EventRect& eventRect = i.next();
|
||||
|
||||
painted = false;
|
||||
|
||||
if (eventRect.eventType() == EventRect::TerminalHighlight
|
||||
&& (eventRect.timeStamp().msecsTo(m_time) <= Settings::terminalHighlightDuration()
|
||||
|| eventRect.testFlag(EventRect::Persistent)))
|
||||
{
|
||||
KStatefulBrush terminalHighlightBrush(KColorScheme::View, KColorScheme::HoverColor);
|
||||
|
||||
painter.setOpacity(Settings::terminalHighlightOpacity());
|
||||
|
||||
painter.fillRect(eventRect, terminalHighlightBrush.brush(this));
|
||||
|
||||
painted = true;
|
||||
}
|
||||
else if (eventRect.eventType() == EventRect::KeyboardInputBlocked
|
||||
&& eventRect.timeStamp().msecsTo(m_time) <= Settings::keyboardInputBlockIndicatorDuration())
|
||||
{
|
||||
painter.setOpacity(Settings::keyboardInputBlockIndicatorOpacity());
|
||||
|
||||
painter.fillRect(eventRect, Settings::keyboardInputBlockIndicatorColor());
|
||||
|
||||
painted = true;
|
||||
}
|
||||
|
||||
if (painted && i.hasNext() && eventRect.testFlag(EventRect::Exclusive))
|
||||
{
|
||||
if (!painter.hasClipping())
|
||||
painter.setClipRect(rect());
|
||||
|
||||
painter.setClipRegion(painter.clipRegion().subtracted(eventRect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisualEventOverlay::showEvent(QShowEvent*)
|
||||
{
|
||||
resize(parentWidget()->rect().size());
|
||||
|
||||
raise();
|
||||
}
|
||||
|
||||
void VisualEventOverlay::hideEvent(QHideEvent*)
|
||||
{
|
||||
m_cleanupTimer->stop();
|
||||
|
||||
m_eventRects.clear();
|
||||
}
|
||||
|
||||
void VisualEventOverlay::scheduleCleanup(int in)
|
||||
{
|
||||
int left = m_cleanupTimerCeiling - m_cleanupTimerStarted.elapsed();
|
||||
|
||||
if (in > left)
|
||||
{
|
||||
m_cleanupTimerCeiling = in;
|
||||
m_cleanupTimerStarted.start();
|
||||
m_cleanupTimer->start(in);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualEventOverlay::cleanupOverlay()
|
||||
{
|
||||
if (m_eventRects.count())
|
||||
{
|
||||
m_time.start();
|
||||
|
||||
QMutableListIterator<EventRect> i(m_eventRects);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
const EventRect& eventRect = i.next();
|
||||
|
||||
if (eventRect.eventType() == EventRect::TerminalHighlight
|
||||
&& eventRect.timeStamp().msecsTo(m_time) >= Settings::terminalHighlightDuration()
|
||||
&& !eventRect.testFlag(EventRect::Persistent))
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
else if (eventRect.eventType() == EventRect::KeyboardInputBlocked
|
||||
&& eventRect.timeStamp().msecsTo(m_time) >= Settings::keyboardInputBlockIndicatorDuration())
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sessionStack->requiresVisualEventOverlay())
|
||||
update();
|
||||
else
|
||||
hide();
|
||||
}
|
118
yakuake/app/visualeventoverlay.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (C) 2009 by Eike Hein <hein@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License or (at your option) version 3 or any later version
|
||||
accepted by the membership of KDE e.V. (or its successor appro-
|
||||
ved by the membership of KDE e.V.), which shall act as a proxy
|
||||
defined in Section 14 of version 3 of the license.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef VISUALEVENTOVERLAY_H
|
||||
#define VISUALEVENTOVERLAY_H
|
||||
|
||||
|
||||
#include <QRect>
|
||||
#include <QTime>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class SessionStack;
|
||||
class Terminal;
|
||||
|
||||
class QTimer;
|
||||
|
||||
|
||||
class EventRect : public QRect
|
||||
{
|
||||
public:
|
||||
enum EventType { TerminalHighlight, KeyboardInputBlocked };
|
||||
|
||||
enum EventFlag
|
||||
{
|
||||
NoFlags = 0x00000000,
|
||||
Singleton = 0x00000001,
|
||||
Exclusive = 0x00000002,
|
||||
Persistent = 0x00000004
|
||||
};
|
||||
Q_DECLARE_FLAGS(EventFlags, EventFlag)
|
||||
|
||||
EventRect(const QPoint& topLeft, const QPoint& bottomRight, EventType type,
|
||||
EventFlags flags = EventRect::NoFlags);
|
||||
~EventRect();
|
||||
|
||||
EventType eventType() const { return m_eventType; }
|
||||
const QTime& timeStamp() const { return m_timeStamp; }
|
||||
|
||||
EventFlags eventFlags() const { return m_eventFlags; }
|
||||
void setEventFlags(EventFlags flags) { m_eventFlags = flags; }
|
||||
inline bool testFlag(EventFlag flag) const { return m_eventFlags & flag; }
|
||||
|
||||
bool operator==(const EventRect& eventRect) const;
|
||||
bool operator<(const EventRect& eventRect) const;
|
||||
|
||||
|
||||
private:
|
||||
EventType m_eventType;
|
||||
EventFlags m_eventFlags;
|
||||
|
||||
QTime m_timeStamp;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(EventRect::EventFlags)
|
||||
|
||||
|
||||
class VisualEventOverlay : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VisualEventOverlay(SessionStack* parent = 0);
|
||||
~VisualEventOverlay();
|
||||
|
||||
|
||||
public slots:
|
||||
void highlightTerminal(Terminal* terminal, bool persistent = false);
|
||||
void removeTerminalHighlight();
|
||||
|
||||
void indicateKeyboardInputBlocked(Terminal* terminal);
|
||||
|
||||
void terminalEvent(Terminal* terminal, EventRect::EventType type,
|
||||
EventRect::EventFlags flags = EventRect::NoFlags);
|
||||
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent*);
|
||||
virtual void hideEvent(QHideEvent*);
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
|
||||
|
||||
private slots:
|
||||
void cleanupOverlay();
|
||||
|
||||
|
||||
private:
|
||||
void scheduleCleanup(int in);
|
||||
|
||||
QList<EventRect> m_eventRects;
|
||||
|
||||
QTimer* m_cleanupTimer;
|
||||
QTime m_cleanupTimerStarted;
|
||||
int m_cleanupTimerCeiling;
|
||||
|
||||
QTime m_time;
|
||||
|
||||
SessionStack* m_sessionStack;
|
||||
};
|
||||
|
||||
#endif
|
4
yakuake/app/yakuake.knsrc
Normal file
|
@ -0,0 +1,4 @@
|
|||
[KNewStuff3]
|
||||
Categories=Yakuake Skin
|
||||
Uncompress=always
|
||||
TargetDir=yakuake/kns_skins
|
13
yakuake/data/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
add_subdirectory( icons )
|
||||
add_subdirectory( skins )
|
||||
add_subdirectory( updaters )
|
||||
|
||||
install(PROGRAMS yakuake.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
|
||||
|
||||
macro_ensure_version("4.7.1" ${KDE_VERSION} HAVEKDE4_7_1)
|
||||
|
||||
if (HAVEKDE4_7_1)
|
||||
install(FILES yakuake.notifyrc DESTINATION ${DATA_INSTALL_DIR}/yakuake)
|
||||
else (HAVEKDE4_7_1)
|
||||
install(FILES yakuake.notifyrc-pre-4.7.1 DESTINATION ${DATA_INSTALL_DIR}/yakuake RENAME yakuake.notifyrc)
|
||||
endif (HAVEKDE4_7_1)
|
1
yakuake/data/icons/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
|||
kde4_install_icons( ${ICON_INSTALL_DIR} )
|
BIN
yakuake/data/icons/hi128-app-yakuake.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
yakuake/data/icons/hi16-app-yakuake.png
Normal file
After Width: | Height: | Size: 710 B |
BIN
yakuake/data/icons/hi22-app-yakuake.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
yakuake/data/icons/hi256-app-yakuake.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
yakuake/data/icons/hi32-app-yakuake.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
yakuake/data/icons/hi48-app-yakuake.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
yakuake/data/icons/hi64-app-yakuake.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
yakuake/data/icons/hisc-app-yakuake.svgz
Normal file
5
yakuake/data/skins/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
install(FILES README DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins)
|
||||
|
||||
add_subdirectory( default )
|
||||
add_subdirectory( plastik_light )
|
||||
add_subdirectory( plastik_dark )
|
40
yakuake/data/skins/README
Normal file
|
@ -0,0 +1,40 @@
|
|||
** What is a Yakuake skin?
|
||||
|
||||
A Yakuake skin, at present, is a collection of PNG image files and related
|
||||
settings that allows modifying the visual appearance of the Yakuake window
|
||||
frame, the window title bar and the tab bar along with the button controls
|
||||
on them and the default title bar caption.
|
||||
|
||||
|
||||
** How is a Yakuake skin composed?
|
||||
|
||||
A Yakuake skin consists of a main directory, the name of which is used by
|
||||
the application to identify that skin, and the files within. Two required
|
||||
files are title.skin and tabs.skin located immediately in that directory.
|
||||
Both are INI-style text files which contain the paths of the pixmaps that
|
||||
are to be applied to the title bar and tab bar interface elements, res-
|
||||
pectively, as well as the coordinates of the buttons and additional infor-
|
||||
mation about the skin, such as its display name, its author and the email
|
||||
address of the author.
|
||||
|
||||
You should derive new skins from the default skin. Please remember to
|
||||
change the name of the base skin directory (which serves as identifier),
|
||||
the skin display name, and include author information.
|
||||
|
||||
|
||||
** How should I package a Yakuake skin?
|
||||
|
||||
The "Skins" page in the Yakuake configuration dialog features an "Install
|
||||
Skin" facility that can install Yakuake skin directories packaged as a
|
||||
tar archive and optionally compressed using gzip or bzip2. Packages can be
|
||||
installed from a local volume or a URL (using KIO).
|
||||
|
||||
In managing skins, Yakuake uses the name of the base skin directory loca-
|
||||
ted within the tar archive as internal identifier for the skin. It should
|
||||
be unique to your skin, i.e. ideally a simplified version of the proper
|
||||
name of your skin.
|
||||
|
||||
The skin list on the "Skins" config dialog page reads the Name and Author
|
||||
properties from the *.skin files to populate list items with information.
|
||||
Additionally, it will try to load a 32x32px image file given via the Icon
|
||||
property to show as artwork next to the skin name.
|
38
yakuake/data/skins/default/CMakeLists.txt
Normal file
|
@ -0,0 +1,38 @@
|
|||
install(FILES
|
||||
title.skin
|
||||
tabs.skin
|
||||
icon.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/default)
|
||||
|
||||
install(FILES
|
||||
tabs/back_image.png
|
||||
tabs/left_corner.png
|
||||
tabs/minus_down.png
|
||||
tabs/minus_over.png
|
||||
tabs/minus_up.png
|
||||
tabs/plus_down.png
|
||||
tabs/plus_over.png
|
||||
tabs/plus_up.png
|
||||
tabs/right_corner.png
|
||||
tabs/selected_back.png
|
||||
tabs/selected_left.png
|
||||
tabs/selected_right.png
|
||||
tabs/separator.png
|
||||
tabs/unselected_back.png
|
||||
tabs/lock.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/default/tabs)
|
||||
|
||||
install(FILES
|
||||
title/back.png
|
||||
title/config_down.png
|
||||
title/config_over.png
|
||||
title/config_up.png
|
||||
title/focus_down.png
|
||||
title/focus_over.png
|
||||
title/focus_up.png
|
||||
title/left.png
|
||||
title/quit_down.png
|
||||
title/quit_over.png
|
||||
title/quit_up.png
|
||||
title/right.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/default/title)
|
BIN
yakuake/data/skins/default/icon.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
39
yakuake/data/skins/default/tabs.skin
Normal file
|
@ -0,0 +1,39 @@
|
|||
[Description]
|
||||
Skin=Default
|
||||
Author=Francois Chazal
|
||||
Email=neptune3k@free.fr
|
||||
Icon=/icon.png
|
||||
|
||||
[Tabs]
|
||||
x=20
|
||||
y=0
|
||||
red=255
|
||||
green=255
|
||||
blue=255
|
||||
separator_image=/tabs/unselected_back.png
|
||||
selected_background=/tabs/selected_back.png
|
||||
selected_left_corner=/tabs/selected_left.png
|
||||
selected_right_corner=/tabs/selected_right.png
|
||||
unselected_background=/tabs/unselected_back.png
|
||||
prevent_closing_image=/tabs/lock.png
|
||||
prevent_closing_image_x=2
|
||||
prevent_closing_image_y=4
|
||||
|
||||
[Background]
|
||||
back_image=/tabs/back_image.png
|
||||
left_corner=/tabs/left_corner.png
|
||||
right_corner=/tabs/right_corner.png
|
||||
|
||||
[PlusButton]
|
||||
x=2
|
||||
y=2
|
||||
up_image=/tabs/plus_up.png
|
||||
over_image=/tabs/plus_over.png
|
||||
down_image=/tabs/plus_down.png
|
||||
|
||||
[MinusButton]
|
||||
x=18
|
||||
y=2
|
||||
up_image=/tabs/minus_up.png
|
||||
over_image=/tabs/minus_over.png
|
||||
down_image=/tabs/minus_down.png
|
BIN
yakuake/data/skins/default/tabs/back_image.png
Normal file
After Width: | Height: | Size: 181 B |
BIN
yakuake/data/skins/default/tabs/left_corner.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
yakuake/data/skins/default/tabs/lock.png
Normal file
After Width: | Height: | Size: 427 B |
BIN
yakuake/data/skins/default/tabs/minus_down.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
yakuake/data/skins/default/tabs/minus_over.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
yakuake/data/skins/default/tabs/minus_up.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
yakuake/data/skins/default/tabs/plus_down.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
yakuake/data/skins/default/tabs/plus_over.png
Normal file
After Width: | Height: | Size: 200 B |
BIN
yakuake/data/skins/default/tabs/plus_up.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
yakuake/data/skins/default/tabs/right_corner.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
yakuake/data/skins/default/tabs/selected_back.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
yakuake/data/skins/default/tabs/selected_left.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
yakuake/data/skins/default/tabs/selected_right.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
yakuake/data/skins/default/tabs/separator.png
Normal file
After Width: | Height: | Size: 207 B |
BIN
yakuake/data/skins/default/tabs/unselected_back.png
Normal file
After Width: | Height: | Size: 181 B |
46
yakuake/data/skins/default/title.skin
Normal file
|
@ -0,0 +1,46 @@
|
|||
[Description]
|
||||
Skin=Default
|
||||
Author=Francois Chazal
|
||||
Email=neptune3k@free.fr
|
||||
Icon=/icon.png
|
||||
|
||||
[Border]
|
||||
red=181
|
||||
green=203
|
||||
blue=211
|
||||
width=1
|
||||
|
||||
[Text]
|
||||
x=24
|
||||
y=15
|
||||
red=40
|
||||
green=60
|
||||
blue=80
|
||||
text=KDE Terminal Emulator
|
||||
bold=true
|
||||
|
||||
[Background]
|
||||
back_image=/title/back.png
|
||||
left_corner=/title/left.png
|
||||
right_corner=/title/right.png
|
||||
|
||||
[FocusButton]
|
||||
x=56
|
||||
y=4
|
||||
up_image=/title/focus_up.png
|
||||
over_image=/title/focus_over.png
|
||||
down_image=/title/focus_down.png
|
||||
|
||||
[ConfigButton]
|
||||
x=38
|
||||
y=4
|
||||
up_image=/title/config_up.png
|
||||
over_image=/title/config_over.png
|
||||
down_image=/title/config_down.png
|
||||
|
||||
[QuitButton]
|
||||
x=20
|
||||
y=4
|
||||
up_image=/title/quit_up.png
|
||||
over_image=/title/quit_over.png
|
||||
down_image=/title/quit_down.png
|
BIN
yakuake/data/skins/default/title/back.png
Normal file
After Width: | Height: | Size: 255 B |
BIN
yakuake/data/skins/default/title/config_down.png
Normal file
After Width: | Height: | Size: 508 B |
BIN
yakuake/data/skins/default/title/config_over.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
yakuake/data/skins/default/title/config_up.png
Normal file
After Width: | Height: | Size: 510 B |
BIN
yakuake/data/skins/default/title/focus_down.png
Normal file
After Width: | Height: | Size: 684 B |
BIN
yakuake/data/skins/default/title/focus_over.png
Normal file
After Width: | Height: | Size: 690 B |
BIN
yakuake/data/skins/default/title/focus_up.png
Normal file
After Width: | Height: | Size: 700 B |
BIN
yakuake/data/skins/default/title/left.png
Normal file
After Width: | Height: | Size: 771 B |
BIN
yakuake/data/skins/default/title/quit_down.png
Normal file
After Width: | Height: | Size: 560 B |
BIN
yakuake/data/skins/default/title/quit_over.png
Normal file
After Width: | Height: | Size: 533 B |
BIN
yakuake/data/skins/default/title/quit_up.png
Normal file
After Width: | Height: | Size: 569 B |
BIN
yakuake/data/skins/default/title/right.png
Normal file
After Width: | Height: | Size: 317 B |
38
yakuake/data/skins/plastik_dark/CMakeLists.txt
Normal file
|
@ -0,0 +1,38 @@
|
|||
install(FILES
|
||||
title.skin
|
||||
tabs.skin
|
||||
icon.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/plastik_dark)
|
||||
|
||||
install(FILES
|
||||
tabs/back_image.png
|
||||
tabs/left_corner.png
|
||||
tabs/minus_down.png
|
||||
tabs/minus_over.png
|
||||
tabs/minus_up.png
|
||||
tabs/plus_down.png
|
||||
tabs/plus_over.png
|
||||
tabs/plus_up.png
|
||||
tabs/right_corner.png
|
||||
tabs/selected_back.png
|
||||
tabs/selected_left.png
|
||||
tabs/selected_right.png
|
||||
tabs/separator.png
|
||||
tabs/unselected_back.png
|
||||
tabs/lock.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/plastik_dark/tabs)
|
||||
|
||||
install(FILES
|
||||
title/back.png
|
||||
title/config_down.png
|
||||
title/config_over.png
|
||||
title/config_up.png
|
||||
title/focus_down.png
|
||||
title/focus_over.png
|
||||
title/focus_up.png
|
||||
title/left.png
|
||||
title/quit_down.png
|
||||
title/quit_over.png
|
||||
title/quit_up.png
|
||||
title/right.png
|
||||
DESTINATION ${DATA_INSTALL_DIR}/yakuake/skins/plastik_dark/title)
|
BIN
yakuake/data/skins/plastik_dark/icon.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
39
yakuake/data/skins/plastik_dark/tabs.skin
Normal file
|
@ -0,0 +1,39 @@
|
|||
[Description]
|
||||
Skin=Plastik (Dark)
|
||||
Author=suslik
|
||||
Email=dd@accentsolution.com
|
||||
Icon=/icon.png
|
||||
|
||||
[Tabs]
|
||||
x=38
|
||||
y=0
|
||||
red=255
|
||||
green=255
|
||||
blue=255
|
||||
separator_image=/tabs/separator.png
|
||||
selected_background=/tabs/selected_back.png
|
||||
selected_left_corner=/tabs/selected_left.png
|
||||
selected_right_corner=/tabs/selected_right.png
|
||||
unselected_background=/tabs/unselected_back.png
|
||||
prevent_closing_image=/tabs/lock.png
|
||||
prevent_closing_image_x=2
|
||||
prevent_closing_image_y=3
|
||||
|
||||
[Background]
|
||||
back_image=/tabs/back_image.png
|
||||
left_corner=/tabs/left_corner.png
|
||||
right_corner=/tabs/right_corner.png
|
||||
|
||||
[PlusButton]
|
||||
x=4
|
||||
y=5
|
||||
up_image=/tabs/plus_up.png
|
||||
over_image=/tabs/plus_over.png
|
||||
down_image=/tabs/plus_down.png
|
||||
|
||||
[MinusButton]
|
||||
x=49
|
||||
y=0
|
||||
up_image=/tabs/minus_up.png
|
||||
over_image=/tabs/minus_over.png
|
||||
down_image=/tabs/minus_down.png
|
BIN
yakuake/data/skins/plastik_dark/tabs/back_image.png
Normal file
After Width: | Height: | Size: 111 B |
BIN
yakuake/data/skins/plastik_dark/tabs/left_corner.png
Normal file
After Width: | Height: | Size: 115 B |
BIN
yakuake/data/skins/plastik_dark/tabs/lock.png
Normal file
After Width: | Height: | Size: 427 B |
BIN
yakuake/data/skins/plastik_dark/tabs/minus_down.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
yakuake/data/skins/plastik_dark/tabs/minus_over.png
Normal file
After Width: | Height: | Size: 316 B |
BIN
yakuake/data/skins/plastik_dark/tabs/minus_up.png
Normal file
After Width: | Height: | Size: 317 B |