yakuake: import with changes to build and work

This commit is contained in:
Ivailo Monev 2015-04-07 01:46:47 +00:00
parent 329600ae49
commit 61b4b0b5df
238 changed files with 66465 additions and 0 deletions

View file

@ -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
View file

@ -0,0 +1,2 @@
Eike Hein <hein@kde.org>
Francois Chazal (Inactive; KDE 3 version)

12
yakuake/CMakeLists.txt Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,3 @@
Planned for future releases:
- Session management (requires Konsole changes).
- More flexible skin engine.

View 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})

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

View 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;
}

View 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

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

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

View file

@ -0,0 +1,7 @@
File=yakuake.kcfg
ClassName=Settings
Singleton=true
MemberVariables=private
ItemAccessors=true
Mutators=true
GlobalEnums=true

View 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);
}

View 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

View 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);
}

View 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

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

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

View 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();
}

View 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

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

File diff suppressed because it is too large Load diff

192
yakuake/app/mainwindow.h Normal file
View 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
View 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
View 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

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

File diff suppressed because it is too large Load diff

160
yakuake/app/tabbar.h Normal file
View 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
View 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
View 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
View 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
View 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

View 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();
}

View 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

View file

@ -0,0 +1,4 @@
[KNewStuff3]
Categories=Yakuake Skin
Uncompress=always
TargetDir=yakuake/kns_skins

View 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)

View file

@ -0,0 +1 @@
kde4_install_icons( ${ICON_INSTALL_DIR} )

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

View 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
View 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.

View 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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View 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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Some files were not shown because too many files have changed in this diff Show more