Very early KDE 6 release.

This commit is contained in:
wackyideas 2024-08-09 03:20:25 +02:00
parent 7cc4ccabbc
commit 686046d4f7
6272 changed files with 140920 additions and 529657 deletions

View file

@ -0,0 +1,346 @@
NOTE! The GPL below is copyrighted by the Free Software Foundation, but
the instance of code that it refers to (the kde programs) are copyrighted
by the authors who actually wrote it.
---------------------------------------------------------------------------
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) 19yy <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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) 19yy 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.

View file

@ -0,0 +1,231 @@
/***************************************************************************
* Copyright (C) 2013 by Aurélien Gâteau <agateau@kde.org> *
* Copyright (C) 2013-2015 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
.pragma library
function fillActionMenu(i18n, actionMenu, actionList, favoriteModel, favoriteId) {
// Accessing actionList can be a costly operation, so we don't
// access it until we need the menu.
var actions = createFavoriteActions(i18n, favoriteModel, favoriteId);
if (actions) {
if (actionList && actionList.length > 0) {
var separator = { "type": "separator" };
actionList.unshift(separator);
// actionList = actions.concat(actionList); // this crashes Qt O.o
actionList.unshift.apply(actionList, actions);
} else {
actionList = actions;
}
}
actionMenu.actionList = actionList;
}
function createFavoriteActions(i18n, favoriteModel, favoriteId) {
if (favoriteModel === null || !favoriteModel.enabled || favoriteId == null) {
return null;
}
if ("initForClient" in favoriteModel) {
var activities = favoriteModel.activities.runningActivities;
if (activities.length <= 1) {
var action = {};
if (favoriteModel.isFavorite(favoriteId)) {
action.text = i18n("Remove from Favorites");
action.icon = "list-remove";
action.actionId = "_kicker_favorite_remove";
} else if (favoriteModel.maxFavorites == -1 || favoriteModel.count < favoriteModel.maxFavorites) {
action.text = i18n("Add to Favorites");
action.icon = "bookmark-new";
action.actionId = "_kicker_favorite_add";
} else {
return null;
}
action.actionArgument = { favoriteModel: favoriteModel, favoriteId: favoriteId };
return [action];
} else {
var actions = [];
var linkedActivities = favoriteModel.linkedActivitiesFor(favoriteId);
// Adding the item to link/unlink to all activities
var linkedToAllActivities =
!(linkedActivities.indexOf(":global") === -1);
actions.push({
text : i18n("On All Activities"),
checkable : true,
actionId : linkedToAllActivities ?
"_kicker_favorite_remove_from_activity" :
"_kicker_favorite_set_to_activity",
checked : linkedToAllActivities,
actionArgument : {
favoriteModel: favoriteModel,
favoriteId: favoriteId,
favoriteActivity: ""
}
});
// Adding items for each activity separately
var addActivityItem = function(activityId, activityName) {
var linkedToThisActivity =
!(linkedActivities.indexOf(activityId) === -1);
actions.push({
text : activityName,
checkable : true,
checked : linkedToThisActivity && !linkedToAllActivities,
actionId :
// If we are on all activities, and the user clicks just one
// specific activity, unlink from everything else
linkedToAllActivities ? "_kicker_favorite_set_to_activity" :
// If we are linked to the current activity, just unlink from
// that single one
linkedToThisActivity ? "_kicker_favorite_remove_from_activity" :
// Otherwise, link to this activity, but do not unlink from
// other ones
"_kicker_favorite_add_to_activity",
actionArgument : {
favoriteModel : favoriteModel,
favoriteId : favoriteId,
favoriteActivity : activityId
}
});
};
// Adding the item to link/unlink to the current activity
addActivityItem(favoriteModel.activities.currentActivity, i18n("On The Current Activity"));
actions.push({
type: "separator",
actionId: "_kicker_favorite_separator"
});
// Adding the items for each activity
activities.forEach(function(activityId) {
addActivityItem(activityId, favoriteModel.activityNameForId(activityId));
});
return [{
text : i18n("Show In Favorites"),
icon : "favorite",
subActions : actions
}];
}
} else {
var action = {};
if (favoriteModel.isFavorite(favoriteId)) {
action.text = i18n("Remove from Favorites");
action.icon = "list-remove";
action.actionId = "_kicker_favorite_remove";
} else if (favoriteModel.maxFavorites == -1 || favoriteModel.count < favoriteModel.maxFavorites) {
action.text = i18n("Add to Favorites");
action.icon = "bookmark-new";
action.actionId = "_kicker_favorite_add";
} else {
return null;
}
action.actionArgument = { favoriteModel: favoriteModel, favoriteId: favoriteId };
return [action];
}
}
function triggerAction(plasmoid, model, index, actionId, actionArgument) {
function startsWith(txt, needle) {
return txt.substr(0, needle.length) === needle;
}
if (startsWith(actionId, "_kicker_favorite_")) {
handleFavoriteAction(actionId, actionArgument);
return;
}
var closeRequested = model.trigger(index, actionId, actionArgument);
if (closeRequested) {
plasmoid.expanded = false;
return true;
}
return false;
}
function handleFavoriteAction(actionId, actionArgument) {
var favoriteId = actionArgument.favoriteId;
var favoriteModel = actionArgument.favoriteModel;
console.log(actionId);
if (favoriteModel === null || favoriteId == null) {
return null;
}
if ("initForClient" in favoriteModel) {
if (actionId == "_kicker_favorite_remove") {
console.log("Removing from all activities");
favoriteModel.removeFavoriteFrom(favoriteId, ":any");
} else if (actionId == "_kicker_favorite_add") {
console.log("Adding to global activity");
favoriteModel.addFavoriteTo(favoriteId, ":global");
} else if (actionId == "_kicker_favorite_remove_from_activity") {
console.log("Removing from a specific activity");
favoriteModel.removeFavoriteFrom(favoriteId, actionArgument.favoriteActivity);
} else if (actionId == "_kicker_favorite_add_to_activity") {
console.log("Adding to another activity");
favoriteModel.addFavoriteTo(favoriteId, actionArgument.favoriteActivity);
} else if (actionId == "_kicker_favorite_set_to_activity") {
console.log("Removing the item from the favourites, and re-adding it just to be on a specific activity");
favoriteModel.setFavoriteOn(favoriteId, actionArgument.favoriteActivity);
}
} else {
if (actionId == "_kicker_favorite_remove") {
favoriteModel.removeFavorite(favoriteId);
} else if (actionId == "_kicker_favorite_add") {
favoriteModel.addFavorite(favoriteId);
}
}
}

View file

@ -0,0 +1,35 @@
/***************************************************************************
* Copyright (C) 2014 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
import QtQuick 2.0
import org.kde.plasma.configuration 2.0
ConfigModel {
ConfigCategory {
name: i18n("General")
icon: "preferences-desktop-plasma-theme"
source: "ConfigGeneral.qml"
}
ConfigCategory {
name: i18n("Side panel")
icon: "menu_new"
source: "ConfigSidepanel.qml"
}
}

View file

@ -0,0 +1,128 @@
<?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=""/>
<group name="General">
<entry name="icon" type="String">
<default>start-here-kde</default>
</entry>
<entry name="useCustomButtonImage" type="Bool">
<default>true</default>
</entry>
<entry name="stickOutOrb" type="Bool">
<default>false</default>
</entry>
<entry name="customButtonImage" type="Url">
<default></default>
</entry>
<entry name="customButtonImageHover" type="Url">
<default></default>
</entry>
<entry name="customButtonImageActive" type="Url">
<default></default>
</entry>
<entry name="showFilterList" type="Bool">
<default>true</default>
</entry>
<entry name="appNameFormat" type="Int">
<default>0</default>
</entry>
<entry name="limitDepth" type="Bool">
<default>false</default>
</entry>
<entry name="numberColumns" type="Int">
<default>1</default>
</entry>
<entry name="numberRows" type="Int">
<default>12</default>
</entry>
<entry name="favoriteApps" type="StringList">
<default></default>
</entry>
<entry name="favoriteSystemActions" type="StringList">
<default>logout,lock-screen,reboot,shutdown</default>
</entry>
<entry name="hiddenApplications" type="StringList">
<default></default>
</entry>
<entry name="useExtraRunners" type="Bool">
<default>true</default>
</entry>
<entry name="extraRunners" type="StringList">
<label>The plugin id's of additional KRunner plugins to use. Only used if useExtraRunners is true.</label>
<default>shell,bookmarks,baloosearch,locations</default>
</entry>
<entry name="alignResultsToBottom" type="Bool">
<default>true</default>
</entry>
<entry name="switchCategoriesOnHover" type="Bool">
<label>Whether to switch between menu categories by hovering them.</label>
<default>true</default>
</entry>
<entry name="removeApplicationCommand" type="String">
<default>muon-discover --application</default>
</entry>
<entry name="favoritesPortedToKAstats" type="Bool">
<label>Are the favorites ported to use KActivitiesStats to allow per-activity favorites</label>
<default>false</default>
</entry>
<entry name="showRecentsView" type="Bool">
<default>true</default>
</entry>
<entry name="showHomeSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showDocumentsSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showPicturesSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showMusicSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showVideosSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showDownloadsSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showRootSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showGamesSidepanel" type="Bool">
<default>false</default>
</entry>
<entry name="showRecentItemsSidepanel" type="Bool">
<default>false</default>
</entry>
<entry name="showNetworkSidepanel" type="Bool">
<default>false</default>
</entry>
<entry name="showSettingsSidepanel" type="Bool">
<default>true</default>
</entry>
<entry name="showDevicesSidepanel" type="Bool">
<default>false</default>
</entry>
<entry name="showDefaultsSidepanel" type="Bool">
<default>false</default>
</entry>
<entry name="showHelpSidepanel" type="Bool">
<default>false</default>
</entry>
</group>
</kcfg>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 115 KiB

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
viewBox="0 0 32 32"
id="svg7"
sodipodi:docname="system-lock-screen.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview9"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
showgrid="false"
inkscape:zoom="20.125"
inkscape:cx="15.975155"
inkscape:cy="15.975155"
inkscape:window-width="1600"
inkscape:window-height="832"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg7" />
<defs
id="defs3">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
class="ColorScheme-Text"
d="m 16,8 c -2.216,0 -4,1.784 -4,4 v 4 h -2 v 8 H 22 V 16 H 20 V 12 C 20,9.784 18.216,8 16,8 Z m 0,1 c 1.662,0 3,1.561 3,3.5 V 16 H 13 V 12.5 C 13,10.561 14.338,9 16,9 Z"
fill="currentColor"
id="path5"
sodipodi:nodetypes="ssccccccssssccss" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,107 @@
/*
SPDX-FileCopyrightText: 2013 Aurélien Gâteau <agateau@kde.org>
SPDX-FileCopyrightText: 2014-2015 Eike Hein <hein@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.15
import org.kde.plasma.extras 2.0 as PlasmaExtras
Item {
id: root
property variant actionList
property QtObject menu
property bool opened: menu ? (menu.status !== PlasmaExtras.Menu.Closed) : false
property Item visualParent
signal actionClicked(string actionId, variant actionArgument)
signal closed
function fillMenu(menu, items) {
items.forEach(function (actionItem) {
if (actionItem.subActions) {
// This is a menu
var submenuItem = contextSubmenuItemComponent.createObject(menu, {
"actionItem": actionItem
});
fillMenu(submenuItem.submenu, actionItem.subActions);
} else {
var item = contextMenuItemComponent.createObject(menu, {
"actionItem": actionItem
});
}
});
}
function open(x, y) {
if (!actionList) {
return;
}
if (x && y) {
menu.open(x, y);
} else {
menu.open();
}
}
function refreshMenu() {
if (menu) {
menu.destroy();
}
if (!actionList) {
return;
}
menu = contextMenuComponent.createObject(root);
fillMenu(menu, actionList);
}
onActionListChanged: refreshMenu()
onOpenedChanged: {
if (!opened) {
closed();
}
}
Component {
id: contextMenuComponent
PlasmaExtras.Menu {
visualParent: root.visualParent
}
}
Component {
id: contextSubmenuItemComponent
PlasmaExtras.MenuItem {
id: submenuItem
property variant actionItem
property PlasmaExtras.Menu submenu: PlasmaExtras.Menu {
visualParent: submenuItem.action
}
icon: actionItem.icon ? actionItem.icon : null
text: actionItem.text ? actionItem.text : ""
}
}
Component {
id: contextMenuItemComponent
PlasmaExtras.MenuItem {
property variant actionItem
checkable: actionItem.checkable ? actionItem.checkable : false
checked: actionItem.checked ? actionItem.checked : false
enabled: actionItem.type !== "title" && ("enabled" in actionItem ? actionItem.enabled : true)
icon: actionItem.icon ? actionItem.icon : null
section: actionItem.type === "title"
separator: actionItem.type === "separator"
text: actionItem.text ? actionItem.text : ""
onClicked: {
root.actionClicked(actionItem.actionId, actionItem.actionArgument);
}
}
}
}

View file

@ -0,0 +1,350 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Gregor Taetzner <gregor@freenet.de>
Copyright 2014 Sebastian Kügler <sebas@kde.org>
Copyright (C) 2015-2018 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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import org.kde.plasma.plasmoid
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components as PlasmaComponents
import org.kde.kirigami as Kirigami
Item {
id: appViewContainer
objectName: "ApplicationsView"
property ListView listView: applicationsView.listView
property alias currentIndex: applicationsView.currentIndex
property alias count: applicationsView.count
function decrementCurrentIndex() {
var tempIndex = applicationsView.currentIndex-1;
if(tempIndex < (crumbModel.count == 0 ? 1 : 0)) {
//applicationsView.currentIndex = applicationsView.count-1;
return;
}
applicationsView.decrementCurrentIndex();
}
function incrementCurrentIndex() {
var tempIndex = applicationsView.currentIndex+1;
if(tempIndex >= applicationsView.count) {
applicationsView.currentIndex = -1;
root.m_showAllButton.focus = true;
return;
}
applicationsView.incrementCurrentIndex();
}
function activateCurrentIndex(start) {
if (!applicationsView.currentItem.modelChildren) {
if (!start) {
return;
}
}
applicationsView.state = "OutgoingLeft";
}
function openContextMenu() {
applicationsView.currentItem.openActionMenu();
}
function deactivateCurrentIndex() {
if (crumbModel.count > 0) { // this is not the case when switching from the "Applications" to the "Favorites" tab using the "Left" key
breadcrumbsElement.children[crumbModel.count-1].clickCrumb();
applicationsView.state = "OutgoingRight";
return true;
}
return false;
}
onFocusChanged: {
if(focus)
applicationsView.currentIndex = crumbModel.count == 0 ? 1 : 0;
else applicationsView.currentIndex = -1;
}
Keys.onPressed: {
if(event.key == Qt.Key_Up) {
decrementCurrentIndex();
} else if(event.key == Qt.Key_Down) {
incrementCurrentIndex();
} else if(event.key == Qt.Key_Return || event.key == Qt.Key_Right) {
activateCurrentIndex(applicationsView.currentIndex);
} else if(event.key == Qt.Key_Menu) {
openContextMenu();
} else if(event.key == Qt.Key_Left || event.key == Qt.Key_Backspace) {
deactivateCurrentIndex();
}
}
KeyNavigation.tab: root.m_showAllButton
function reset() {
applicationsView.model = rootModel;
applicationsView.clearBreadcrumbs();
//root.resetRecents();
}
function refreshed() {
reset();
updatedLabelTimer.running = true;
}
Connections {
target: kicker
function onExpandedChanged() {
if (!plasmoid.expanded) {
reset();
}
}
}
Item {
id: crumbContainer
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: childrenRect.height
visible: false
opacity: crumbModel.count > 0
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration } }
Flickable {
id: breadcrumbFlickable
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: breadcrumbsElement.height
boundsBehavior: Flickable.StopAtBounds
contentWidth: breadcrumbsElement.width
pixelAligned: true
//contentX: contentWidth - width
// HACK: Align the content to right for RTL locales
leftMargin: LayoutMirroring.enabled ? Math.max(0, width - contentWidth) : 0
ButtonRow {
id: breadcrumbsElement
exclusive: false
Breadcrumb {
id: rootBreadcrumb
root: true
text: i18n("Back")
depth: 0
}
Repeater {
model: ListModel {
id: crumbModel
// Array of the models
property var models: []
}
Breadcrumb {
root: false
text: model.text
visible: false
}
}
onWidthChanged: {
if (LayoutMirroring.enabled) {
breadcrumbFlickable.contentX = -Math.max(0, breadcrumbsElement.width - breadcrumbFlickable.width)
} else {
breadcrumbFlickable.contentX = Math.max(0, breadcrumbsElement.width - breadcrumbFlickable.width)
}
}
}
}
Rectangle {
id: sepLine
anchors {
top: breadcrumbFlickable.bottom
topMargin: -1
left: breadcrumbFlickable.left
leftMargin: Kirigami.Units.smallSpacing*2
right: breadcrumbFlickable.right
rightMargin: Kirigami.Units.smallSpacing*2
}
height: 1
color: "#d6e5f5"
opacity: 1
z: 6
}
} // crumbContainer
KickoffListView {
id: applicationsView
anchors {
top: (crumbContainer.visible && crumbContainer.opacity) ? crumbContainer.bottom : parent.top
topMargin: Kirigami.Units.smallSpacing/ (crumbContainer.visible ? 2 : 1) + 1
bottom: parent.bottom
rightMargin: -Kirigami.Units.gridUnit
leftMargin: -Kirigami.Units.gridUnit
}
width: parent.width
small: true
property Item activatedItem: null
property var newModel: null
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration } }
focus: true
appView: true
model: rootModel
function moveLeft() {
state = "";
// newModelIndex set by clicked breadcrumb
var oldModel = applicationsView.model;
applicationsView.model = applicationsView.newModel;
var oldModelIndex = model.rowForModel(oldModel);
listView.currentIndex = oldModelIndex;
listView.positionViewAtIndex(oldModelIndex, ListView.Center);
crumbContainer.visible = false;
}
function moveRight() {
state = "";
activatedItem.activate();
applicationsView.listView.positionViewAtBeginning();
crumbContainer.visible = true;
//root.visible = false;
}
function clearBreadcrumbs() {
crumbModel.clear();
crumbModel.models = [];
applicationsView.listView.currentIndex = -1;
}
onReset: appViewContainer.reset()
onAddBreadcrumb: {
crumbModel.append({"text": title, "depth": crumbModel.count+1})
crumbModel.models.push(model);
}
states: [
State {
name: "OutgoingLeft"
PropertyChanges {
target: applicationsView
x: -parent.width
opacity: 0.0
}
},
State {
name: "OutgoingRight"
PropertyChanges {
target: applicationsView
x: parent.width
opacity: 0.0
}
}
]
transitions: [
Transition {
to: "OutgoingLeft"
SequentialAnimation {
// We need to cache the currentItem since the selection can move during animation,
// and we want the item that has been clicked on, not the one that is under the
// mouse once the animation is done
ScriptAction { script: applicationsView.activatedItem = applicationsView.currentItem }
NumberAnimation { properties: "opacity"; easing.type: Easing.InQuad; duration: 100 }
ScriptAction { script: { applicationsView.moveRight(); } }
}
},
Transition {
to: "OutgoingRight"
SequentialAnimation {
NumberAnimation { properties: "opacity"; easing.type: Easing.InQuad; duration: 100 }
ScriptAction { script: applicationsView.moveLeft() }
}
}
]
Component.onCompleted: {
applicationsView.listView.currentIndex = -1;
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.BackButton
onClicked: {
deactivateCurrentIndex()
}
}
Timer {
id: updatedLabelTimer
interval: 1500
running: false
repeat: true
onRunningChanged: {
if (running) {
updatedLabel.opacity = 1;
crumbContainer.opacity = 0.3;
applicationsView.scrollArea.opacity = 0.3;
}
}
onTriggered: {
updatedLabel.opacity = 0;
crumbContainer.opacity = 1;
applicationsView.scrollArea.opacity = 1;
running = false;
}
}
PlasmaComponents.Label {
id: updatedLabel
text: i18n("Applications updated.")
opacity: 0
visible: opacity != 0
anchors.centerIn: parent
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
}
Component.onCompleted: {
rootModel.cleared.connect(refreshed);
}
} // appViewContainer

View file

@ -0,0 +1,96 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.ksvg as KSvg
import org.kde.kirigami as Kirigami
//import QtQuick.Controls.Styles.Plasma as Styles
Item {
id: crumbRoot
height: crumb.implicitHeight + Kirigami.Units.smallSpacing * 2
width: crumb.implicitWidth + arrowSvg.width
property string text
property bool root: false
property int depth: model.depth
function clickCrumb() {
heading_ma.clicked(null);
}
PlasmaExtras.Heading {
id: crumb
anchors {
left: arrowSvg.right
top: parent.top
bottom: parent.bottom
topMargin: Kirigami.Units.smallSpacing
leftMargin: Kirigami.Units.smallSpacing
bottomMargin: Kirigami.Units.smallSpacing
}
horizontalAlignment: Text.AlignHCenter
text: crumbRoot.text + ""
color: "#404040"
font.underline: heading_ma.enabled && heading_ma.containsMouse
level: 5
MouseArea {
id: heading_ma
anchors.fill: parent
hoverEnabled: crumbRoot.depth < crumbModel.count
enabled: crumbRoot.depth < crumbModel.count
onClicked: {
// Remove all the breadcrumbs in front of the clicked one
while (crumbModel.count > 0 && crumbRoot.depth < crumbModel.get(crumbModel.count-1).depth) {
crumbModel.remove(crumbModel.count-1)
crumbModel.models.pop()
}
if (crumbRoot.root) {
applicationsView.newModel = rootModel;
} else {
applicationsView.newModel = crumbModel.models[index];
}
applicationsView.state = "OutgoingRight";
}
cursorShape: Qt.PointingHandCursor
z: 99
}
}
KSvg.SvgItem{
id: arrowSvg
anchors.left: parent.left
anchors.leftMargin: Kirigami.Units.smallSpacing*2
anchors.verticalCenter: parent.verticalCenter
height: crumbRoot.height / 2
width: visible ? height : 0
svg: arrowsSvg
elementId: LayoutMirroring.enabled ? "right-arrow" : "left-arrow"
}
} // crumbRoot

View file

@ -0,0 +1,149 @@
/*
SPDX-FileCopyrightText: 2011 Nokia Corporation and /or its subsidiary(-ies) <qt-info@nokia.com>
This file is part of the Qt Components project.
SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 OR GPL-3.0-only OR LicenseRef-Qt-Commercial
*/
var self;
var checkHandlers = [];
var visibleButtons = [];
var nonVisibleButtons = [];
var direction;
function create(that, options) {
self = that;
direction = options.direction || Qt.Horizontal;
self.childrenChanged.connect(rebuild);
self.exclusiveChanged.connect(rebuild);
// self.widthChanged.connect(resizeChildren);
build();
}
function isButton(item) {
if (item && item.hasOwnProperty("__position"))
return true;
return false;
}
function hasChecked(item) {
return (item && item.hasOwnProperty("checked"));
}
function destroy() {
self.childrenChanged.disconnect(rebuild);
// self.widthChanged.disconnect(resizeChildren);
cleanup();
}
function build() {
visibleButtons = [];
nonVisibleButtons = [];
for (var i = 0, item; (item = self.children[i]); i++) {
if (!hasChecked(item))
continue;
item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app
if (!item.visible) {
nonVisibleButtons.push(item);
continue;
}
visibleButtons.push(item);
if (self.exclusive && item.hasOwnProperty("checkable"))
item.checkable = true;
if (self.exclusive) {
checkHandlers.push(checkExclusive(item));
item.checkedChanged.connect(checkHandlers[checkHandlers.length - 1]);
}
if (item.checked) {
checkExclusive(item)()
if (item.checked) self.checkedButton = item
}
}
var nrButtons = visibleButtons.length;
if (nrButtons == 0)
return;
if (self.checkedButton)
self.checkedButton.checked = true;
else if (self.exclusive) {
self.checkedButton = visibleButtons[0];
self.checkedButton.checked = true;
}
if (nrButtons == 1) {
finishButton(visibleButtons[0], "only");
} else {
finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top");
for (var i = 1; i < nrButtons - 1; i++)
finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle");
finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom");
}
}
function finishButton(button, position) {
if (isButton(button)) {
button.__position = position;
if (direction == Qt.Vertical) {
button.anchors.left = self.left //mm How to make this not cause binding loops? see QTBUG-17162
button.anchors.right = self.right
}
}
}
function cleanup() {
visibleButtons.forEach(function(item, i) {
if (checkHandlers[i])
item.checkedChanged.disconnect(checkHandlers[i]);
item.visibleChanged.disconnect(rebuild);
});
checkHandlers = [];
nonVisibleButtons.forEach(function(item, i) {
item.visibleChanged.disconnect(rebuild);
});
}
function rebuild() {
if (self == undefined)
return;
cleanup();
build();
}
function resizeChildren() {
if (direction != Qt.Horizontal)
return;
var extraPixels = self.width % visibleButtons;
var buttonSize = (self.width - extraPixels) / visibleButtons;
visibleButtons.forEach(function(item, i) {
if (!item || !item.visible)
return;
item.width = buttonSize + (extraPixels > 0 ? 1 : 0);
if (extraPixels > 0)
extraPixels--;
});
}
function checkExclusive(item) {
var button = item;
return function() {
for (var i = 0, ref; (ref = visibleButtons[i]); i++) {
if (ref.checked == (button === ref))
continue;
// Disconnect the signal to avoid recursive calls
ref.checkedChanged.disconnect(checkHandlers[i]);
ref.checked = !ref.checked;
ref.checkedChanged.connect(checkHandlers[i]);
}
self.checkedButton = button;
}
}

View file

@ -0,0 +1,57 @@
/*
SPDX-FileCopyrightText: 2011 Nokia Corporation and /or its subsidiary(-ies) <qt-info@nokia.com>
This file is part of the Qt Components project.
SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 OR GPL-3.0-only OR LicenseRef-Qt-Commercial
*/
import QtQuick 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
import "ButtonGroup.js" as Behavior
/**
* A ButtonRow allows you to group Buttons in a row. It provides a
* selection-behavior as well.
*
* Note: This component does not support the enabled property. If you need to
* disable it you should disable all the buttons inside it.
*
* Example code:
*
* @code
* ButtonRow {
* Button { text: "Left" }
* Button { text: "Right" }
* }
* @endcode
*
* @inherit QtQuick.Row
*/
Row {
id: root
/**
* Specifies the grouping behavior. If enabled, the checked property on
* buttons contained in the group will be exclusive.The default value is true.
*
* Note that a button in an exclusive group will always be checkable
*/
property bool exclusive: true
/**
* Returns the last checked button
*/
property Item checkedButton;
spacing: PlasmaCore.Theme.defaultFont.pointSize
Component.onCompleted: {
Behavior.create(root, {direction: Qt.Horizontal});
}
Component.onDestruction: {
Behavior.destroy();
}
}

View file

@ -0,0 +1,284 @@
/***************************************************************************
* Copyright (C) 2013-2014 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kwindowsystem 1.0
import org.kde.kirigami as Kirigami
Item {
id: root
Layout.minimumHeight: floatingOrbPanel.buttonIconSizes.height;
Layout.maximumHeight: floatingOrbPanel.buttonIconSizes.height;
Layout.minimumWidth: floatingOrbPanel.buttonIconSizes.width;
Layout.maximumWidth: floatingOrbPanel.buttonIconSizes.width;
property bool compositing: false
/*
* The following code gets the ContainmentInterface instance which is used for keeping track of edit mode's state.
* This allows us to hide the StartOrb object so the user can actually highlight and select this plasmoid during edit mode.
*/
//property var containmentInterface: null
property QtObject contextMenu: null
property QtObject dashWindow: null
readonly property bool editMode: Plasmoid.containment.corona.editMode //containmentInterface ? containmentInterface.editMode : false
readonly property bool inPanel: (Plasmoid.location == PlasmaCore.Types.TopEdge || Plasmoid.location == PlasmaCore.Types.RightEdge || Plasmoid.location == PlasmaCore.Types.BottomEdge || Plasmoid.location == PlasmaCore.Types.LeftEdge)
property bool menuShown: dashWindow.visible
property QtObject orb: null
property alias orbTimer: orbTimer
readonly property var screenGeometry: Plasmoid.screenGeometry
// Should the orb be rendered in its own dialog window so that it can stick out of the panel?
readonly property bool stickOutOrb: Plasmoid.configuration.stickOutOrb && inPanel && !editMode
readonly property bool useCustomButtonImage: (Plasmoid.configuration.useCustomButtonImage)
readonly property bool vertical: (Plasmoid.formFactor == PlasmaCore.Types.Vertical)
//property int opacityDuration: 350
/*function createContextMenu(pos) {
contextMenu = Qt.createQmlObject("ContextMenu {}", root);
contextMenu.fillActions();
contextMenu.show();
}*/
// If the url is empty (default value), then use the fallback url. Otherwise, return the url path relative to
// the location of the source code.
function getResolvedUrl(url, fallback) {
if (url.toString() === "") {
return Qt.resolvedUrl(fallback);
}
return url;
}
function positionOrb() {
var pos = kicker.mapToGlobal(floatingOrbPanel.x, floatingOrbPanel.y);
pos.y -= 5;
//if(floatingOrbPanel.buttonIcon.implicitHeight === 54) // Using an orb with extra height around it
//var pos = kicker.mapToGlobal(kicker.x, kicker.y); // Gets the global position of this plasmoid, in screen coordinates.
orb.width = floatingOrbPanel.buttonIcon.implicitWidth// + panelSvg.margins.left;
orb.height = floatingOrbPanel.buttonIcon.implicitHeight;
orb.x = pos.x;
orb.y = pos.y;// + panelSvg.margins.bottom;
// Keep the orb positioned exactly on the bottom if it is rendered out of bounds (beyond the screen geometry)
/*if (orb.y + orb.height > kicker.screenGeometry.height) {
orb.y = kicker.screenGeometry.height - orb.height; //orb.y + orb.height - kicker.screenGeometry.height;
}*/
}
function showMenu() {
dashWindow.visible = !dashWindow.visible;
dashWindow.showingAllPrograms = false;
Plasmoid.setActiveWin(dashWindow);
console.log(floatingOrbPanel.buttonIcon.implicitHeight);
dashWindow.m_searchField.focus = true;
orb.raise();
}
function updateSizeHints() {
return;
if (useCustomButtonImage) {
if (vertical) {
var scaledHeight = Math.floor(parent.width * (floatingOrbPanel.buttonIcon.height / floatingOrbPanel.buttonIcon.width));
root.Layout.minimumHeight = scaledHeight;
root.Layout.maximumHeight = scaledHeight;
root.Layout.minimumWidth = Kirigami.Units.iconSizes.small;
root.Layout.maximumWidth = inPanel ? Kirigami.Units.iconSizes.medium : -1;
} else {
var scaledWidth = Math.floor(parent.height * (floatingOrbPanel.buttonIcon.width / floatingOrbPanel.buttonIcon.height));
root.Layout.minimumWidth = scaledWidth;
root.Layout.maximumWidth = scaledWidth;
root.Layout.minimumHeight = Kirigami.Units.iconSizes.small;
root.Layout.maximumHeight = inPanel ? Kirigami.Units.iconSizes.medium : -1;
}
} else {
root.Layout.minimumWidth = Kirigami.Units.iconSizes.small;
root.Layout.maximumWidth = inPanel ? Kirigami.Units.iconSizes.medium : -1;
root.Layout.minimumHeight = Kirigami.Units.iconSizes.small;
root.Layout.maximumHeight = inPanel ? Kirigami.Units.iconSizes.medium : -1;
}
if (stickOutOrb && orb) {
root.Layout.minimumWidth = orb.width + panelSvg.margins.right * (compositing ? 0 : 1);
root.Layout.maximumWidth = orb.width + panelSvg.margins.right * (compositing ? 0 : 1);
root.Layout.minimumHeight = orb.height;
root.Layout.maximumHeight = orb.height;
}
// This has to be done, or else the orb won't be positioned correctly. ??????????
/*orb.y += 5;
orb.y -= 5; // ??????????????????????????????????????*/
}
//kicker.status: PlasmaCore.Types.PassiveStatus
Plasmoid.status: dashWindow && dashWindow.visible ? PlasmaCore.Types.RequiresAttentionStatus : PlasmaCore.Types.PassiveStatus
//clip: true
Component.onCompleted: {
dashWindow = Qt.createQmlObject("MenuRepresentation {}", kicker);
orb = Qt.createQmlObject("StartOrb {}", kicker);
//Plasmoid.fullRepresentation = dashWindow
Plasmoid.activated.connect(function () {
showMenu();
});
}
onCompositingChanged: {
updateSizeHints();
positionOrb();
/*if (compositing) {
orb.x += panelSvg.margins.left;
}*/
compositingFix.start();
}
onHeightChanged: updateSizeHints()
onParentChanged: {
/*if (parent) {
for (var obj = root, depth = 0; !!obj; obj = obj.parent, depth++) {
if (obj.toString().startsWith('ContainmentInterface')) {
// desktop containment / plasmoidviewer
// Note: This doesn't always work. FolderViewDropArea may not yet have
// ContainmentInterface as a parent when this loop runs.
if (typeof obj['editMode'] === 'boolean') {
root.containmentInterface = obj;
break;
}
} else if (obj.toString().startsWith('DeclarativeDropArea')) {
// panel containment
if (typeof obj['Plasmoid'] !== 'undefined' && obj['Plasmoid'].toString().startsWith('ContainmentInterface')) {
if (typeof obj['Plasmoid']['editMode'] === 'boolean') {
root.containmentInterface = obj.Plasmoid;
break;
}
}
}
}
}*/
}
onStickOutOrbChanged: {
updateSizeHints();
positionOrb();
}
onWidthChanged: updateSizeHints()
/*Connections {
target: Kirigami.Units.iconSizeHints
function onPanelChanged() { updateSizeHints(); }
}*/
Connections {
target: Plasmoid.configuration
function onCustomButtonImageChanged() {
positionOrb();
console.log("AAAA")
}
}
Connections {
function onScreenChanged() {
positionOrb();
}
function onScreenGeometryChanged() {
positionOrb();
}
target: kicker
}
/*
* Three IconItems are used in order to achieve the same look and feel as Windows 7's
* orbs. When the menu is closed, hovering over the orb results in the hovered icon
* gradually appearing into view, and clicking on the orb causes an instant change in
* visibility, where the normal and hovered icons are invisible, and the pressed icon
* is visible.
*
* When they're bounded by the panel, these icons will by default try to fill up as
* much space as they can in the compact representation while preserving their aspect
* ratio.
*/
FloatingOrb {
id: floatingOrbPanel
anchors.left: parent.left
//anchors.leftMargin: -Kirigami.Units.mediumSpacing
anchors.verticalCenter: parent.verticalCenter
//anchors.verticalCenterOffset: Kirigami.Units.smallSpacing-1
//anchors.fill: parent
objectName: "innerorb"
opacity: (!stickOutOrb)
}
// Handles all mouse events for the popup orb
MouseArea {
id: mouseAreaCompositingOff
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
//visible: !stickOutOrb
propagateComposedEvents: true
onPressed: mouse => {
if(mouse.button === Qt.LeftButton)
showMenu();
else
mouse.accepted = false;
}
}
// I hate this
// So the only way I could reasonably think of to make this work is running the function
// with a delay.
Timer {
id: compositingFix
interval: 150
onTriggered: {
if (!compositing) {
Plasmoid.setTransparentWindow();
}
}
}
// Even worse, this just makes things even more unsophisticated. If someone has a better
// way of solving this, I would love to know.
Timer {
id: orbTimer
interval: 15
onTriggered: {
Plasmoid.setOrb(orb);
// Currently hardcoded, will make it configurable soon, when it's been properly tested and hopefully slightly refactored.
Plasmoid.setMask(Qt.resolvedUrl("./orbs/mask.png"), false);
Plasmoid.setWinState(orb);
Plasmoid.setWinType(orb);
Plasmoid.setDashWindow(dashWindow);
updateSizeHints();
positionOrb();
}
}
}

View file

@ -0,0 +1,180 @@
/***************************************************************************
* Copyright (C) 2014 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Dialogs
import QtQuick.Layouts
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.kcmutils as KCM
import org.kde.draganddrop 2.0 as DragDrop
import org.kde.kirigami 2.3 as Kirigami
import org.kde.plasma.plasmoid 2.0
import org.kde.iconthemes as KIconThemes
import org.kde.plasma.private.kicker 0.1 as Kicker
KCM.SimpleKCM {
id: configGeneral
width: childrenRect.width
height: childrenRect.height
property string cfg_icon: Plasmoid.configuration.icon
property bool cfg_useCustomButtonImage: Plasmoid.configuration.useCustomButtonImage
property string cfg_customButtonImage: Plasmoid.configuration.customButtonImage
property string cfg_customButtonImageHover: Plasmoid.configuration.customButtonImageHover
property string cfg_customButtonImageActive: Plasmoid.configuration.customButtonImageActive
property alias cfg_showRecentsView: showRecentsView.checked
property alias cfg_appNameFormat: appNameFormat.currentIndex
property alias cfg_switchCategoriesOnHover: switchCategoriesOnHover.checked
property alias cfg_stickOutOrb: stickOutOrb.checked
property alias cfg_useExtraRunners: useExtraRunners.checked
property alias cfg_numberRows: numberRows.value
component CustomGroupBox: GroupBox {
id: gbox
label: Label {
id: lbl
x: gbox.leftPadding + 2
y: lbl.implicitHeight/2-gbox.bottomPadding-1
width: lbl.implicitWidth
text: gbox.title
elide: Text.ElideRight
Rectangle {
anchors.fill: parent
anchors.leftMargin: -2
anchors.rightMargin: -2
color: Kirigami.Theme.backgroundColor
z: -1
}
}
background: Rectangle {
y: gbox.topPadding - gbox.bottomPadding*2
width: parent.width
height: parent.height - gbox.topPadding + gbox.bottomPadding*2
color: "transparent"
border.color: "#d5dfe5"
radius: 3
}
}
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Kirigami.Units.gridUnit*4
anchors.rightMargin: Kirigami.Units.gridUnit*4
CustomGroupBox {
id: orbGroup
title: i18n("Orb texture")
Layout.fillWidth: true
IconPicker {
id: iconPickerNormal
currentIcon: cfg_customButtonImage
defaultIcon: ""
onIconChanged: iconName => { cfg_customButtonImage = iconName; }
anchors.right: parent.right
anchors.left: parent.left
}
}
CustomGroupBox {
Layout.fillWidth: true
title: i18n("Behavior")
//flat: false
ColumnLayout {
RowLayout {
visible: false
Label {
text: i18n("Show applications as:")
}
ComboBox {
id: appNameFormat
Layout.fillWidth: true
model: [i18n("Name only"), i18n("Description only"), i18n("Name (Description)"), i18n("Description (Name)")]
}
}
CheckBox {
id: switchCategoriesOnHover
visible: false
text: i18n("Switch categories on hover")
}
CheckBox {
id: useExtraRunners
visible: false
text: i18n("Expand search to bookmarks, files and emails")
}
CheckBox {
id: stickOutOrb
text: i18n("Force constant orb size")
}
CheckBox {
id: showRecentsView
text: i18n("Show recent programs")
}
RowLayout{
Layout.fillWidth: true
Label {
Layout.leftMargin: Kirigami.Units.smallSpacing
text: i18n("Number of rows:")
}
SpinBox{
id: numberRows
from: 10
to: 15
}
}
}
}
}
Component.onCompleted: {
if(Plasmoid.configuration.stickOutOrb) Plasmoid.setTransparentWindow();
}
Component.onDestruction: {
if(Plasmoid.configuration.stickOutOrb) Plasmoid.setTransparentWindow();
}
}

View file

@ -0,0 +1,141 @@
/***************************************************************************
* Copyright (C) 2014 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts
import org.kde.kcmutils as KCM
import org.kde.plasma.plasmoid 2.0
import org.kde.kirigami 2.3 as Kirigami
KCM.SimpleKCM {
id: configSidepanel
width: childrenRect.width
height: childrenRect.height
property alias cfg_showHomeSidepanel: showHomeSidepanel.checked
property alias cfg_showDocumentsSidepanel: showDocumentsSidepanel.checked
property alias cfg_showPicturesSidepanel: showPicturesSidepanel.checked
property alias cfg_showMusicSidepanel: showMusicSidepanel.checked
property alias cfg_showVideosSidepanel: showVideosSidepanel.checked
property alias cfg_showDownloadsSidepanel: showDownloadsSidepanel.checked
property alias cfg_showGamesSidepanel: showGamesSidepanel.checked
property alias cfg_showRecentItemsSidepanel: showRecentItemsSidepanel.checked
property alias cfg_showRootSidepanel: showRootSidepanel.checked
property alias cfg_showNetworkSidepanel: showNetworkSidepanel.checked
property alias cfg_showSettingsSidepanel: showSettingsSidepanel.checked
property alias cfg_showDevicesSidepanel: showDevicesSidepanel.checked
property alias cfg_showDefaultsSidepanel: showDefaultsSidepanel.checked
property alias cfg_showHelpSidepanel: showHelpSidepanel.checked
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Kirigami.Units.gridUnit*4
anchors.rightMargin: Kirigami.Units.gridUnit*4
GroupBox {
id: gbox
Layout.fillWidth: true
background: Rectangle {
color: "white"
border.color: "#bababe"
y: gbox.topPadding - gbox.bottomPadding
height: parent.height - gbox.topPadding + gbox.bottomPadding
}
label: Label {
x: gbox.leftPadding
width: gbox.availableWidth
text: gbox.title
elide: Text.ElideRight
}
title: i18n("Show sidebar items")
ColumnLayout {
CheckBox {
id: showHomeSidepanel
text: i18n("Home directory")
}
CheckBox {
id: showDocumentsSidepanel
text: i18n("Documents")
}
CheckBox {
id: showPicturesSidepanel
text: i18n("Pictures")
}
CheckBox {
id: showMusicSidepanel
text: i18n("Music")
}
CheckBox {
id: showVideosSidepanel
text: i18n("Videos")
}
CheckBox {
id: showDownloadsSidepanel
text: i18n("Downloads")
}
CheckBox {
id: showGamesSidepanel
text: i18n("Games")
}
CheckBox {
id: showRecentItemsSidepanel
text: i18n("Recent Items")
}
CheckBox {
id: showRootSidepanel
text: i18n("Computer")
}
CheckBox {
id: showNetworkSidepanel
text: i18n("Network")
}
CheckBox {
id: showSettingsSidepanel
text: i18n("Control Panel")
}
CheckBox {
id: showDevicesSidepanel
text: i18n("Devices and Printers")
}
CheckBox {
id: showDefaultsSidepanel
text: i18n("Default Programs")
}
CheckBox {
id: showHelpSidepanel
text: i18n("Help and Support")
}
}
}
}
Component.onCompleted: {
if(Plasmoid.configuration.stickOutOrb) Plasmoid.setTransparentWindow();
}
Component.onDestruction: {
if(Plasmoid.configuration.stickOutOrb) Plasmoid.setTransparentWindow();
}
}

View file

@ -0,0 +1,131 @@
/*
MIT License
Copyright (c) 2020 Pierre-Yves Siret
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import QtQuick 2.15
import QtQml 2.15
Behavior {
id: root
property QtObject fadeTarget: targetProperty.object
property string fadeProperty: "opacity"
property var fadeProperties: [fadeProperty]
property var exitValue: 0
property var enterValue: exitValue
property int fadeDuration: 300
property string easingType: "Quad"
property bool delayWhile: false
property bool sequential: false
onDelayWhileChanged: {
if (!delayWhile)
sequentialAnimation.startExitAnimation();
}
readonly property Component shaderEffectSourceWrapperComponent: Item {
property alias shaderEffectSource: shaderEffectSource
property alias sourceItem: shaderEffectSource.sourceItem
parent: sourceItem.parent
x: sourceItem.x
y: sourceItem.y
ShaderEffectSource {
id: shaderEffectSource
transformOrigin: sourceItem.transformOrigin
hideSource: true
live: false
width: sourceItem.width
height: sourceItem.height
}
}
readonly property Component defaultExitAnimation: NumberAnimation {
properties: root.fadeProperties.join(',')
duration: root.fadeDuration
to: root.exitValue
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["In"+root.easingType]
}
property Component exitAnimation: defaultExitAnimation
// bind SES properties tu function provided by user: {rotation: (t) => () => t.progress * 180, opacity: (p) => 1 - p)}
readonly property Component defaultEnterAnimation: NumberAnimation {
properties: root.fadeProperties.join(',')
duration: root.fadeDuration
from: root.enterValue
to: root.fadeTarget[root.fadeProperties[0]]
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["Out"+root.easingType]
}
property Component enterAnimation: defaultEnterAnimation
SequentialAnimation {
id: sequentialAnimation
signal startEnterAnimation()
signal startExitAnimation()
ScriptAction {
script: {
const exitItem = shaderEffectSourceWrapperComponent.createObject(null, { sourceItem: root.fadeTarget });
const exitShaderEffectSource = exitItem.shaderEffectSource;
if (exitAnimation === root.defaultExitAnimation)
root.fadeProperties.forEach(p => exitShaderEffectSource[p] = root.fadeTarget[p]);
exitShaderEffectSource.width = root.fadeTarget.width;
exitShaderEffectSource.height = root.fadeTarget.height;
const exitAnimationInstance = exitAnimation.createObject(root, { target: exitItem.shaderEffectSource });
sequentialAnimation.startExitAnimation.connect(exitAnimationInstance.start);
if (root.sequential)
exitAnimationInstance.finished.connect(sequentialAnimation.startEnterAnimation);
else
exitAnimationInstance.started.connect(sequentialAnimation.startEnterAnimation);
exitAnimationInstance.finished.connect(() => {
exitItem.destroy();
exitAnimationInstance.destroy();
});
}
}
PauseAnimation {
duration: 5 // figure out how to wait on a signal in an animation (for ShaderEffectSource update or Image loading when Behaviour on source)
}
PropertyAction {}
ScriptAction {
script: {
const enterItem = shaderEffectSourceWrapperComponent.createObject(null, { sourceItem: root.fadeTarget });
const enterShaderEffectSource = enterItem.shaderEffectSource;
if (enterAnimation === root.defaultEnterAnimation)
root.fadeProperties.forEach(p => enterShaderEffectSource[p] = root.enterValue);
enterShaderEffectSource.live = true;
const enterAnimationInstance = enterAnimation.createObject(root, { target: enterItem.shaderEffectSource });
sequentialAnimation.startEnterAnimation.connect(enterAnimationInstance.start);
enterAnimationInstance.finished.connect(() => {
enterItem.destroy();
enterAnimationInstance.destroy();
});
if (!root.delayWhile)
sequentialAnimation.startExitAnimation();
}
}
}
}

View file

@ -0,0 +1,187 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Marco Martin <mart@kde.org>
Copyright 2014 Sebastian Kügler <sebas@kde.org>
Copyright (C) 2015-2018 Eike Hein <hein@kde.org>
Copyright (C) 2016 Jonathan Liu <net147@gmail.com>
Copyright (C) 2016 Kai Uwe Broulik <kde@privat.broulik.de>
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
import org.kde.plasma.plasmoid
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components as PlasmaComponents
import org.kde.draganddrop 2.0
import org.kde.plasma.private.kicker 0.1 as Kicker
Item {
property ListView listView: favoritesView.listView
function activateCurrentIndex() {
favoritesView.currentItem.activate();
}
function decrementCurrentIndex() {
if (favoritesView.currentIndex == 0)
return;
favoritesView.decrementCurrentIndex();
}
function getFavoritesCount() {
return favoritesView.count;
}
function incrementCurrentIndex() {
var tempIndex = favoritesView.currentIndex + 1;
if (tempIndex >= favoritesView.count) {
favoritesView.currentIndex = -1;
if (Plasmoid.configuration.showRecentsView) {
root.m_recents.focus = true;
root.m_recents.currentIndex = 0;
} else {
root.m_showAllButton.focus = true;
}
return;
}
favoritesView.incrementCurrentIndex();
}
// QQuickItem::isAncestorOf is not invokable...
function isChildOf(item, parent) {
if (!item || !parent) {
return false;
}
if (item.parent === parent) {
return true;
}
return isChildOf(item, item.parent);
}
function openContextMenu() {
favoritesView.currentItem.openActionMenu();
}
function resetCurrentIndex() {
favoritesView.currentIndex = -1;
}
function setCurrentIndex() {
favoritesView.currentIndex = 0;
}
KeyNavigation.tab: Plasmoid.configuration.showRecentsView ? root.m_recents : root.m_showAllButton
//anchors.fill: parent
anchors.topMargin: Kirigami.Units.smallSpacing
objectName: "FavoritesView"
Keys.onPressed: event => {
if (event.key == Qt.Key_Up) {
decrementCurrentIndex();
} else if (event.key == Qt.Key_Down) {
incrementCurrentIndex();
} else if (event.key == Qt.Key_Return) {
activateCurrentIndex();
} else if (event.key == Qt.Key_Menu) {
openContextMenu();
}
}
onFocusChanged: {
if (focus)
setCurrentIndex();
else
resetCurrentIndex();
}
DropArea {
property int startRow: -1
function syncTarget(event) {
if (favoritesView.animating) {
return;
}
var pos = mapToItem(listView.contentItem, event.x, event.y);
var above = listView.itemAt(pos.x, pos.y);
var source = kickoff.dragSource;
if (above && above !== source && isChildOf(source, favoritesView)) {
favoritesView.model.moveRow(source.itemIndex, above.itemIndex);
// itemIndex changes directly after moving,
// we can just set the currentIndex to it then.
favoritesView.currentIndex = source.itemIndex;
}
}
anchors.fill: parent
enabled: plasmoid.immutability !== PlasmaCore.Types.SystemImmutable
onDragEnter: {
syncTarget(event);
startRow = favoritesView.currentIndex;
}
onDragMove: syncTarget(event)
}
Transition {
id: moveTransition
SequentialAnimation {
PropertyAction {
property: "animating"
target: favoritesView
value: true
}
NumberAnimation {
duration: favoritesView.animationDuration
easing.type: Easing.OutQuad
properties: "x, y"
}
PropertyAction {
property: "animating"
target: favoritesView
value: false
}
}
}
Connections {
function onExpandedChanged() {
if (!plasmoid.expanded) {
favoritesView.currentIndex = -1;
}
}
target: kicker
}
KickoffListView {
id: favoritesView
property bool animating: false
property int animationDuration: resetAnimationDurationTimer.interval
anchors.fill: parent
interactive: contentHeight > height
model: globalFavorites
move: moveTransition
moveDisplaced: moveTransition
onCountChanged: {
animationDuration = 0;
resetAnimationDurationTimer.start();
}
}
Timer {
id: resetAnimationDurationTimer
interval: 150
onTriggered: favoritesView.animationDuration = interval - 20
}
}

View file

@ -0,0 +1,104 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Window
import org.kde.plasma.plasmoid
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.plasma.extras as PlasmaExtras
import org.kde.plasma.private.kicker as Kicker
import org.kde.coreaddons as KCoreAddons // kuser
import org.kde.plasma.private.shell 2.0
import org.kde.kwindowsystem 1.0
import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.quicklaunch 1.0
import org.kde.kirigami 2.13 as Kirigami
import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons
import org.kde.kcmutils as KCM
import org.kde.kwindowsystem 1.0
Item {
id: iconContainer
//The frame displayed on top of the user icon
height: Kirigami.Units.iconSizes.huge
//Kirigami.Units.iconSizes.huge
width: height
anchors.horizontalCenter: parent.horizontalCenter
property alias iconSource: imgAuthorIcon.source
Image {
source: "../pics/user.png"
smooth: true
z: 1
opacity: imgAuthorIcon.source === ""
Behavior on opacity {
NumberAnimation { duration: 350 }
}
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
top: parent.top
}
}
Kirigami.Icon {
id: imgAuthorIcon
source: ""
height: parent.height
width: height
smooth: true
visible: true
//usesPlasmaTheme: false
z: 99
CrossFadeBehavior on source {
fadeDuration: 350
}
}
Image {
id: imgAuthor
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.bottom
topMargin: Kirigami.Units.smallSpacing*2
leftMargin: Kirigami.Units.smallSpacing*2
rightMargin: Kirigami.Units.smallSpacing*2
bottomMargin: Kirigami.Units.smallSpacing*2
}
opacity: imgAuthorIcon.source === ""
Behavior on opacity {
NumberAnimation { duration: 350 }
}
source: kuser.faceIconUrl.toString()
smooth: true
mipmap: true
visible: true
}
/*OpacityMask {
anchors.fill: imgAuthor
source: (kuser.faceIconUrl.toString() === "") ? imgAuthorIcon : imgAuthor;
maskSource: Rectangle {
width: imgAuthorIcon.source === "" ? imgAuthor.width : 0
height: imgAuthor.height
visible: false
}
}*/
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onPressed: {
root.visible = false;
KCM.KCMLauncher.openSystemSettings("kcm_users")
}
cursorShape: Qt.PointingHandCursor
}
}

View file

@ -0,0 +1,90 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Window
import org.kde.plasma.plasmoid
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.plasma.extras as PlasmaExtras
import org.kde.plasma.private.kicker as Kicker
import org.kde.coreaddons as KCoreAddons // kuser
import org.kde.plasma.private.shell 2.0
import org.kde.kwindowsystem 1.0
import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.quicklaunch 1.0
import org.kde.kirigami 2.13 as Kirigami
import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons
import org.kde.kwindowsystem 1.0
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
import org.kde.kirigami as Kirigami
Item {
id: floatingOrb
width: buttonIconSizes.width
height: buttonIconSizes.height / 3
property alias buttonIconSizes: buttonIconSizes
property alias buttonIcon: buttonIcon
property alias buttonIconPressed: buttonIconPressed
property alias buttonIconHovered: buttonIconHovered
property alias mouseArea: mouseArea
property string orbTexture: getResolvedUrl(Plasmoid.configuration.customButtonImage, "orbs/orb.png")
property int opacityDuration: 300
Image {
id: buttonIconSizes
smooth: true
source: orbTexture
opacity: 0;
}
clip: false
Image {
id: buttonIcon
smooth: true
source: orbTexture
sourceClipRect: Qt.rect(0, 0, buttonIconSizes.width, buttonIconSizes.height / 3);
}
Image {
id: buttonIconPressed
visible: dashWindow.visible
smooth: true
source: orbTexture
verticalAlignment: Image.AlignBottom
sourceClipRect: Qt.rect(0, 2*buttonIconSizes.height / 3, buttonIconSizes.width, buttonIconSizes.height / 3);
}
Image {
id: buttonIconHovered
source: orbTexture
opacity: mouseArea.containsMouse || mouseAreaCompositingOff.containsMouse
visible: !dashWindow.visible
Behavior on opacity {
NumberAnimation { properties: "opacity"; easing.type: Easing.Linear; duration: opacityDuration }
}
verticalAlignment: Image.AlignVCenter
sourceClipRect: Qt.rect(0, buttonIconSizes.height / 3, buttonIconSizes.width, buttonIconSizes.height / 3);
}
MouseArea
{
id: mouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
propagateComposedEvents: true
onPressed: mouse => {
if(mouse.button === Qt.LeftButton)
root.showMenu();
else
mouse.accepted = false;
}
}
}

View file

@ -0,0 +1,199 @@
/*****************************************************************************
* Copyright (C) 2022 by Friedrich Schriewer <friedrich.schriewer@gmx.net> *
* *
* 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
****************************************************************************/
import QtQuick 2.12
import QtQuick.Layouts 1.12
import Qt5Compat.GraphicalEffects
import QtQuick.Window 2.2
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.coreaddons 1.0 as KCoreAddons
import org.kde.kirigami 2.13 as Kirigami
import QtQuick.Controls 2.15
import "../code/tools.js" as Tools
Item {
id: allItem
width: scrollView.availableWidth - Kirigami.Units.mediumSpacing
height: Kirigami.Units.iconSizes.smallMedium
property var itemSection: model.group
property bool highlighted: false
property bool isDraging: false
property bool canDrag: true
property bool canNavigate: false
signal highlightChanged
signal aboutToShowActionMenu(variant actionMenu)
property bool hasActionList: ((model.favoriteId !== null)
|| (("hasActionList" in model) && (model.hasActionList !== null)))
property var triggerModel
onAboutToShowActionMenu: actionMenu => {
var actionList = allItem.hasActionList ? model.actionList : [];
Tools.fillActionMenu(i18n, actionMenu, actionList, globalFavorites, model.favoriteId);
}
function openActionMenu(x, y) {
aboutToShowActionMenu(actionMenu);
if(actionMenu.actionList.length === 0) return;
actionMenu.visualParent = allItem;
actionMenu.open(x, y);
}
function actionTriggered(actionId, actionArgument) {
var close = (Tools.triggerAction(triggerModel, index, actionId, actionArgument) === true);
if (close) {
//root.toggle();
root.visible = false;
}
}
function trigger() {
triggerModel.trigger(index, "", null);
root.visible = false;
}
function updateHighlight() {
if (navGrid.currentIndex == index){
highlighted = true
} else {
highlighted = false
}
}
function deselect(){
highlighted = false
listView.currentIndex = -1
}
Kirigami.Icon {
id: appicon
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Kirigami.Units.smallSpacing*2 + Kirigami.Units.iconSizes.small
width: Kirigami.Units.iconSizes.small
height: width
source: model.decoration
}
PlasmaComponents.Label {
id: appname
anchors.left: appicon.right
anchors.right: parent.right
anchors.rightMargin: Kirigami.Units.smallSpacing
anchors.leftMargin: Kirigami.Units.smallSpacing
anchors.verticalCenter: appicon.verticalCenter
text: ("name" in model ? model.name : model.display)
font.underline: ma.containsMouse
elide: Text.ElideRight
}
KickoffHighlight {
id: rectFill
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.iconSizes.small
opacity: (listView.currentIndex === index) * 0.7 + ma.containsMouse * 0.3
}
Timer {
id: toolTipTimer
interval: Kirigami.Units.longDuration*4
onTriggered: {
toolTip.showToolTip();
}
}
PlasmaCore.ToolTipArea {
id: toolTip
anchors {
fill: parent
}
active: appname.truncated
interactive: false
/*location: (((Plasmoid.location === PlasmaCore.Types.RightEdge)
* || (Qt.application.layoutDirection === Qt.RightToLeft))
* ? PlasmaCore.Types.RightEdge : PlasmaCore.Types.LeftEdge)*/
mainText: appname.text
}
MouseArea {
id: ma
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.iconSizes.small
z: parent.z + 1
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: mouse => {
if (mouse.button == Qt.RightButton) {
if (allItem.hasActionList) {
var mapped = mapToItem(allItem, mouse.x, mouse.y);
allItem.openActionMenu(mapped.x, mapped.y);
}
} else {
trigger()
}
}
onReleased: {
isDraging: false
}
// to prevent crashing
onEntered: {
if(parent.parent) {
listView.currentIndex = index;
}
toolTipTimer.start();
}
onExited: {
if(parent.parent) {
listView.currentIndex = -1;
toolTipTimer.stop();
toolTip.hideToolTip();
}
}
onPositionChanged: {
isDraging = pressed
if (pressed && canDrag){
if ("pluginName" in model) {
dragHelper.startDrag(kicker, model.url, model.decoration,
"text/x-plasmoidservicename", model.pluginName);
} else {
dragHelper.startDrag(kicker, model.url, model.decoration);
}
}
listView.currentIndex = containsMouse ? index : -1
/*if (containsMouse) {
if (canNavigate) {
listView.currentIndex = index
//listView.focus = true
}
}*/
}
}
ActionMenu {
id: actionMenu
onActionClicked: {
visualParent.actionTriggered(actionId, actionArgument);
//root.toggle()
}
}
}

View file

@ -0,0 +1,94 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.iconthemes as KIconThemes
import org.kde.ksvg as KSvg
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.extras as PlasmaExtras
import org.kde.kirigami 2.3 as Kirigami
// basically taken from kickoff
RowLayout {
id: iconButton
property string currentIcon
property string defaultIcon
signal iconChanged(string iconName)
//Layout.minimumWidth: previewFrame.width + Kirigami.Units.smallSpacing * 2
//Layout.maximumWidth: Layout.minimumWidth
//Layout.minimumHeight: previewFrame.height + Kirigami.Units.smallSpacing * 2
//Layout.maximumHeight: Layout.minimumWidth
KIconThemes.IconDialog {
id: iconDialog
onIconNameChanged: iconName => {
iconPreview.source = iconName
iconChanged(iconName)
}
}
Layout.fillWidth: true
ColumnLayout {
Text {
Layout.fillWidth: true
Layout.fillHeight: true
wrapMode: Text.WordWrap
text: "Customize the way the menu orb looks like using ClassicShell/OpenShell-compatible PNG resources.\nOnly orb textures with three frames are supported."
}
RowLayout {
Button {
text: i18nc("@item:inmenu Open icon chooser dialog", "Choose...")
onClicked: iconDialog.open()
}
Button {
text: i18nc("@item:inmenu Reset icon to default", "Reset")
onClicked: setDefaultIcon()
}
}
}
KSvg.FrameSvgItem {
id: previewFrame
//anchors.centerIn: parent
imagePath: Plasmoid.location === PlasmaCore.Types.Vertical || Plasmoid.location === PlasmaCore.Types.Horizontal
? "widgets/panel-background" : "widgets/background"
Layout.preferredWidth: Kirigami.Units.iconSizes.large + fixedMargins.left + fixedMargins.right
Layout.preferredHeight: Kirigami.Units.iconSizes.large + fixedMargins.top + fixedMargins.bottom
Layout.bottomMargin: Kirigami.Units.smallSpacing
Kirigami.Icon {
id: iconPreview
anchors.centerIn: parent
width: Kirigami.Units.iconSizes.large
height: width
source: currentIcon
}
}
function setDefaultIcon() {
iconPreview.source = defaultIcon
iconChanged(defaultIcon)
}
// QQC Menu can only be opened at cursor position, not a random one
/*PlasmaExtras.Menu {
id: iconMenu
PlasmaExtras.MenuItem {
text: i18nc("@item:inmenu Open icon chooser dialog", "Choose...")
icon: "document-open-folder"
onClicked: iconDialog.open()
}
PlasmaExtras.MenuItem {
text: i18nc("@item:inmenu Reset icon to default", "Clear Icon")
icon: "edit-clear"
onClicked: setDefaultIcon()
}
}*/
}

View file

@ -0,0 +1,67 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
PlasmaComponents.TabButton {
id: button
objectName: "KickoffButton"
property string iconSource
property alias text: labelElement.text
implicitHeight: iconElement.height + labelElement.implicitHeight + iconElement.anchors.topMargin + labelElement.anchors.topMargin + labelElement.anchors.bottomMargin
Item {
anchors {
margins: Kirigami.Units.smallSpacing
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
height: childrenRect.height
PlasmaCore.IconItem {
id: iconElement
anchors.horizontalCenter: parent.horizontalCenter
width: Kirigami.Units.iconSizes.medium
height: width
source: iconSource
}
PlasmaComponents.Label {
id: labelElement
anchors {
top: iconElement.bottom
left: parent.left
right: parent.right
}
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
wrapMode: Text.WordWrap
font: theme.smallestFont
}
}
} // button

View file

@ -0,0 +1,88 @@
/*
* Copyright 2014 Sebastian Kügler <sebas@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) 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.ksvg as KSvg
import org.kde.kirigami as Kirigami
Item {
id: highlight
/** true if the user is hovering over the component */
//in the case we are the highlight of a listview, it follows the mouse, so hover = true
property bool hover: ListView ? true : false
/** true if the mouse button is pressed over the component. */
property bool pressed: false
width: ListView.view ? ListView.view.width : undefined
property alias marginHints: background.margins;
Connections {
target: highlight.ListView.view
function onCurrentIndexChanged() {
if (highlight.ListView.view.currentIndex >= 0) {
background.opacity = 1
} else {
background.opacity = 0
}
}
}
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.OutQuad
}
}
KSvg.FrameSvgItem {
id: background
imagePath: Qt.resolvedUrl("svgs/menuitem.svg")
prefix: {
if (pressed)
return hover ? "selected+hover" : "selected";
if (hover)
return "hover";
return "normal";
}
Behavior on opacity {
NumberAnimation {
duration: Kirigami.Units.veryShortDuration
easing.type: Easing.OutQuad
}
}
anchors {
fill: parent
leftMargin: Kirigami.Units.smallSpacing
rightMargin: Kirigami.Units.smallSpacing
//FIXME: breaks listviews and highlight item
// topMargin: -background.margins.top
// leftMargin: -background.margins.left
// bottomMargin: -background.margins.bottom
// rightMargin: -background.margins.right
}
}
}

View file

@ -0,0 +1,210 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Gregor Taetzner <gregor@freenet.de>
Copyright 2014 Sebastian Kügler <sebas@kde.org>
Copyright (C) 2015-2018 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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//This is the generic item delegate used by FavoritesView, RecentlyUsedView and SearchView.
import QtQuick 2.0
import org.kde.plasma.plasmoid
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.draganddrop 2.0
import org.kde.kirigami as Kirigami
import org.kde.ksvg as KSvg
import "code/tools.js" as Tools
Item {
id: listItem
enabled: !model.disabled && !(model.display === "" || model.display === "Recent Applications")
visible: !(model.display === "" || model.display === "Recent Applications")
width: ListView.view.width
height: model.display === "" || model.display === "Recent Applications" ? 0 : (Kirigami.Units.smallSpacing / (small ? 2 : 1)) + Math.max(elementIcon.height, titleElement.implicitHeight /*+ subTitleElement.implicitHeight*/)
signal reset
signal actionTriggered(string actionId, variant actionArgument)
signal aboutToShowActionMenu(variant actionMenu)
signal addBreadcrumb(var model, string title)
property alias toolTip: toolTip
property bool smallIcon: false
readonly property int itemIndex: model.index
readonly property string url: model.url || ""
readonly property var decoration: model.decoration || ""
property bool dropEnabled: false
property bool appView: false
property bool modelChildren: model.hasChildren || false
property bool isCurrent: listItem.ListView.view.currentIndex === index;
property bool showAppsByName: Plasmoid.configuration.showAppsByName
property bool hasActionList: ((model.favoriteId !== null)
|| (("hasActionList" in model) && (model.hasActionList === true)))
property Item menu: actionMenu
//property alias usePlasmaIcon: elementIcon.usesPlasmaTheme
onAboutToShowActionMenu: (actionMenu) => {
var actionList = hasActionList ? model.actionList : [];
Tools.fillActionMenu(i18n, actionMenu, actionList, ListView.view.model.favoritesModel, model.favoriteId);
}
onActionTriggered: (actionId, actionArgument) => {
kicker.expanded = false;
if (Tools.triggerAction(ListView.view.model, model.index, actionId, actionArgument) === true) {
kicker.expanded = false;
}
/*if (actionId.indexOf("_kicker_favorite_") === 0) {
switchToInitial();
}*/
}
function activate() {
var view = listItem.ListView.view;
if (model.hasChildren) {
var childModel = view.model.modelForRow(index);
listItem.addBreadcrumb(childModel, model.display);
view.model = childModel;
} else {
view.model.trigger(model.index, "", null);
kicker.expanded = false;
listItem.reset();
}
}
function openActionMenu(x, y) {
aboutToShowActionMenu(actionMenu);
actionMenu.visualParent = listItem;
actionMenu.open(x, y);
}
ActionMenu {
id: actionMenu
onActionClicked: (actionId, actionArgument) => {
actionTriggered(actionId, actionArgument);
}
}
Kirigami.Icon {
id: elementIcon
anchors {
left: parent.left
leftMargin: Kirigami.Units.smallSpacing*2-1
verticalCenter: parent.verticalCenter
}
width: smallIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.medium
height: width
animated: false
//usesPlasmaTheme: false
source: model.decoration
}
PlasmaComponents.Label {
id: titleElement
y: Math.round((parent.height - titleElement.height - ( (subTitleElement.text != "") ? subTitleElement.implicitHeight : 0) ) / 2)
anchors {
left: elementIcon.right
right: arrow.left
leftMargin: Kirigami.Units.smallSpacing * 2 - 2
rightMargin: Kirigami.Units.smallSpacing * 2
}
height: implicitHeight //undo PC2 height override, remove when porting to PC3
// TODO: games should always show the by name!
text: model.display
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
color: "#000000"
}
PlasmaComponents.Label {
id: subTitleElement
anchors {
left: titleElement.left
right: arrow.right
top: titleElement.bottom
}
height: implicitHeight
color: "#000000"
text: ""//model.description || ""
opacity: isCurrent ? 0.8 : 0.6
font: Kirigami.Theme.smallFont
elide: Text.ElideMiddle
horizontalAlignment: Text.AlignLeft
}
KSvg.SvgItem {
id: arrow
anchors {
right: parent.right
rightMargin: Kirigami.Units.smallSpacing
verticalCenter: parent.verticalCenter
}
width: visible ? Kirigami.Units.iconSizes.small : 0
height: width
visible: (model.hasChildren === true)
opacity: (listItem.ListView.view.currentIndex === index) ? 1.0 : 0.8
svg: arrowsSvg
elementId: (Qt.application.layoutDirection == Qt.RightToLeft) ? "left-arrow-black" : "right-arrow-black"
}
Keys.onPressed: {
if (event.key === Qt.Key_Menu && hasActionList) {
event.accepted = true;
openActionMenu();
} else if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return) && !modelChildren) {
if (!modelChildren) {
event.accepted = true;
listItem.activate();
}
}
}
PlasmaCore.ToolTipArea {
id: toolTip
anchors {
fill: parent
}
active: titleElement.truncated
interactive: false
/*location: (((Plasmoid.location === PlasmaCore.Types.RightEdge)
|| (Qt.application.layoutDirection === Qt.RightToLeft))
? PlasmaCore.Types.RightEdge : PlasmaCore.Types.LeftEdge)*/
mainText: model.display
}
}

View file

@ -0,0 +1,218 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Gregor Taetzner <gregor@freenet.de>
Copyright (C) 2015-2018 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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components as PlasmaComponents
import org.kde.kirigami as Kirigami
FocusScope {
id: view
property bool appView: false
property alias contentHeight: listView.contentHeight
property alias count: listView.count
property alias currentIndex: listView.currentIndex
property alias currentItem: listView.currentItem
property alias delegate: listView.delegate
property alias interactive: listView.interactive
readonly property Item listView: listView
property alias model: listView.model
property alias move: listView.move
property alias moveDisplaced: listView.moveDisplaced
readonly property Item scrollView: scrollView
property bool showAppsByName: true
property bool small: false
signal addBreadcrumb(var model, string title)
signal reset
function decrementCurrentIndex() {
listView.decrementCurrentIndex();
}
function incrementCurrentIndex() {
listView.incrementCurrentIndex();
}
Connections {
function onExpandedChanged() {
if (!kicker.expanded) {
listView.positionViewAtBeginning();
}
}
target: kicker
}
Timer {
id: toolTipTimer
interval: Kirigami.Units.longDuration*4
onTriggered: {
if(listView.currentItem) listView.currentItem.toolTip.showToolTip();
}
}
PlasmaComponents.ScrollView {
id: scrollView
//frameVisible: false
anchors.fill: parent
ListView {
id: listView
boundsBehavior: Flickable.StopAtBounds
focus: true
highlightMoveDuration: 0
highlightResizeDuration: 0
keyNavigationWraps: true
spacing: small ? 0 : Kirigami.Units.smallSpacing / 2
delegate: KickoffItem {
id: delegateItem
required property var model
required property int index
appView: view.appView
showAppsByName: view.showAppsByName
smallIcon: small
onAddBreadcrumb: view.addBreadcrumb(model, title)
onReset: view.reset()
}
highlight: KickoffHighlight {
}
section.property: "group"
/*section {
criteria: ViewSection.FullString
property: "group"
delegate: SectionDelegate {
}
}*/
MouseArea {
id: mouseArea
// property Item pressed: null
property int pressX: -1
property int pressY: -1
property bool tapAndHold: false
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.left: parent.left
height: parent.height
hoverEnabled: true
width: scrollView.width
onContainsMouseChanged: {
if (!containsMouse) {
//pressed = null;
toolTipTimer.stop();
if(listView.currentItem) listView.currentItem.toolTip.hideToolTip();
pressX = -1;
pressY = -1;
tapAndHold = false;
listView.currentIndex = -1;
}
}
onPositionChanged: function(mouse) {
var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y);
var item = listView.itemAt(mapped.x, mapped.y);
if (item) {
toolTipTimer.stop();
if(listView.currentItem) listView.currentItem.toolTip.hideToolTip();
listView.currentIndex = item.itemIndex;
toolTipTimer.start();
//item.toolTip.showToolTip();
} else {
listView.currentIndex = -1;
}
if (mouse.source != Qt.MouseEventSynthesizedByQt || tapAndHold) {
if (pressed && pressX != -1 && pressed.url && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) {
kickoff.dragSource = item;
if (mouse.source == Qt.MouseEventSynthesizedByQt) {
dragHelper.dragIconSize = Kirigami.Units.iconSizes.huge;
dragHelper.startDrag(kickoff, pressed.url, pressed.decoration);
} else {
dragHelper.dragIconSize = Kirigami.Units.iconSizes.medium;
dragHelper.startDrag(kickoff, pressed.url, pressed.decoration);
}
//pressed = null;
pressX = -1;
pressY = -1;
tapAndHold = false;
}
}
}
onPressAndHold: function(mouse) {
if (mouse.source == Qt.MouseEventSynthesizedByQt) {
tapAndHold = true;
positionChanged(mouse);
}
}
onPressed: function(mouse) {
var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y);
var item = listView.itemAt(mapped.x, mapped.y);
if (!item) {
return;
}
if (mouse.buttons & Qt.RightButton) {
if (item.hasActionList) {
mapped = listView.contentItem.mapToItem(item, mapped.x, mapped.y);
listView.currentItem.openActionMenu(mapped.x, mapped.y);
}
} else {
//pressed = item;
//item.activate();
pressX = mouse.x;
pressY = mouse.y;
}
}
onReleased: function(mouse) {
var mapped = listView.mapToItem(listView.contentItem, mouse.x, mouse.y);
var item = listView.itemAt(mapped.x, mapped.y);
if (item && /*pressed === item && */!tapAndHold) {
if (item.appView) {
if (mouse.source == Qt.MouseEventSynthesizedByQt) {
positionChanged(mouse);
}
view.state = "OutgoingLeft";
} else {
item.activate();
root.visible = false;
}
listView.currentIndex = -1;
}
if (tapAndHold && mouse.source == Qt.MouseEventSynthesizedByQt) {
if (item.hasActionList) {
mapped = listView.contentItem.mapToItem(item, mapped.x, mapped.y);
listView.currentItem.openActionMenu(mapped.x, mapped.y);
}
}
//pressed = null;
pressX = -1;
pressY = -1;
tapAndHold = false;
}
}
}
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright 2015 Kai Uwe Broulik <kde@privat.broulik.de>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.2
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.kirigami as Kirigami
Item {
id: item
signal clicked
signal iconClicked
property alias text: label.text
// property alias subText: sublabel.text
property alias icon: icon.source
// "enabled" also affects all children
property bool interactive: true
property bool interactiveIcon: false
property bool showIcon: false
//property alias usesPlasmaTheme: icon.usesPlasmaTheme
property alias containsMouse: area.containsMouse
property alias size: icon.height
property Item highlight
Layout.fillWidth: true
height: size + 2 * Kirigami.Units.smallSpacing
width: height
MouseArea {
id: area
anchors.fill: parent
enabled: item.interactive
hoverEnabled: true
onClicked: item.clicked()
onContainsMouseChanged: {
if (!highlight) {
return
}
if (containsMouse) {
highlight.parent = item
highlight.width = item.width
highlight.height = item.height
}
highlight.visible = containsMouse
}
}
Kirigami.Icon {
id: icon
width: icon.height
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Kirigami.Units.smallSpacing * 2
//usesPlasmaTheme: true
visible: showIcon
MouseArea {
anchors.fill: parent
visible: item.interactiveIcon
cursorShape: Qt.PointingHandCursor
onClicked: item.iconClicked()
}
}
PlasmaComponents.Label {
id: label
wrapMode: Text.NoWrap
elide: Text.ElideRight
anchors.left: showIcon ? icon.right : parent.left
anchors.leftMargin: Kirigami.Units.smallSpacing * 2
anchors.verticalCenter: icon.verticalCenter
style: Text.Sunken
styleColor: "transparent"
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,138 @@
/*****************************************************************************
* Copyright (C) 2022 by Friedrich Schriewer <friedrich.schriewer@gmx.net> *
* *
* 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
****************************************************************************/
import QtQuick 2.12
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.kquickcontrolsaddons 2.0
import QtQuick.Controls 2.15
import org.kde.draganddrop 2.0
FocusScope {
id: navGrid
signal keyNavUp
signal keyNavDown
property alias triggerModel: listView.model
property alias count: listView.count
property alias currentIndex: listView.currentIndex
property alias currentItem: listView.currentItem
property alias contentItem: listView.contentItem
property Item flickableItem: listView
onFocusChanged: {
if (!focus) {
currentIndex = -1;
}
}
function tryActivate() {
if(currentIndex === -1 && listView.count > 0) {
listView.itemAtIndex(0).trigger();
return;
}
if (currentItem){
currentItem.trigger()
}
}
function setFocus() {
currentIndex = 0
focus = true
}
function setFocusLast() {
if (count > 0) {
currentIndex = count - 1
focus = true
} else {
setFocus()
}
}
Text {
id: noResults
opacity: 0.6
text: "No items match your search."
anchors.fill: parent
anchors.topMargin: 13
horizontalAlignment: Text.AlignHCenter
visible: listView.count === 0 && searching
}
ScrollView {
id: scrollView
anchors.fill: parent
anchors.rightMargin: 4
ListView {
anchors.fill: parent
id: listView
currentIndex: -1
focus: true
property alias scrollBar: scrollView
highlightMoveDuration: 0
highlightResizeDuration: 0
snapMode: ListView.SnapToItem
interactive: false
boundsBehavior: Flickable.StopAtBounds
section {
criteria: ViewSection.FullString
property: "group"
delegate: SectionDelegate {
sectionCount: {
var x = 0;
if(!listView) return 0;
for(var i = 0; i < listView.count; i++) {
//console.log(listView.itemAtIndex(i));
if(listView.itemAtIndex(i)) {
if(listView.itemAtIndex(i).itemSection === section) x++;
}
}
return x;
}
}
}
delegate: GenericItem {
canNavigate: true
canDrag: true
triggerModel: listView.model
//Layout.leftMargin: Kirigami.Units.iconSizes.small
//x: Kirigami.Units.iconSizes.small
}
onCurrentIndexChanged: {
if (currentIndex != -1) {
focus = true;
}
}
onModelChanged: {
currentIndex = -1;
}
onFocusChanged: {
if (!focus) {
currentIndex = -1
}
}
}
}
}

View file

@ -0,0 +1,172 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Marco Martin <mart@kde.org>
Copyright (C) 2015 Eike Hein <hein@kde.org>
Copyright (C) 2017 Ivan Cukic <ivan.cukic@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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.components as PlasmaComponents
import org.kde.kitemmodels as KItemModels
import org.kde.plasma.plasmoid
import org.kde.plasma.private.kicker 0.1 as Kicker
/*
* Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
* Copyright (C) 2012 Marco Martin <mart@kde.org>
* Copyright (C) 2015-2018 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) 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.draganddrop 2.0
Item {
property alias model: baseView.model
property alias delegate: baseView.delegate
property alias currentIndex: baseView.currentIndex;
property alias count: baseView.count;
objectName: "OftenUsedView"
property ListView listView: baseView.listView
function decrementCurrentIndex() {
var tempIndex = baseView.currentIndex-1;
if(tempIndex < 0) {
baseView.currentIndex = -1;
root.m_faves.focus = true;
root.m_faves.listView.currentIndex = root.m_faves.listView.count-1;
return;
}
baseView.decrementCurrentIndex();
}
KeyNavigation.tab: root.m_showAllButton
function incrementCurrentIndex() {
var tempIndex = baseView.currentIndex+1;
if(tempIndex >= baseView.count) {
baseView.currentIndex = -1;
root.m_showAllButton.focus = true;
return;
}
baseView.incrementCurrentIndex();
}
function activateCurrentIndex() {
baseView.currentItem.activate();
}
function openContextMenu() {
baseView.currentItem.openActionMenu();
}
function setCurrentIndex() {
baseView.currentIndex = 0;
}
function resetCurrentIndex() {
baseView.currentIndex = -1;
}
Connections {
target: kicker
function onExpandedChanged() {
if (!kicker.expanded) {
baseView.currentIndex = -1;
}
}
}
KickoffListView {
id: baseView
anchors.fill: parent
currentIndex: -1
interactive: contentHeight > height
model: KItemModels.KSortFilterProxyModel {
sourceModel: rootModel.modelForRow(0)
property var favoritesModel: globalFavorites
property int favoritesCount: sourceModel.favoritesModel.count
onFavoritesCountChanged: {
sourceModel.refresh();
}
function trigger(index, str, ptr) {
sourceModel.trigger(index, str, ptr);
}
filterRowCallback: function(source_row, source_parent) {
//return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) == "...";
return source_row < Plasmoid.configuration.numberRows - sourceModel.favoritesModel.count;
};
}
}
onFocusChanged: {
if(focus) setCurrentIndex();
else resetCurrentIndex();
}
Keys.onPressed: event => {
if(event.key == Qt.Key_Up) {
decrementCurrentIndex();
} else if(event.key == Qt.Key_Down) {
incrementCurrentIndex();
} else if(event.key == Qt.Key_Return) {
activateCurrentIndex();
} else if(event.key == Qt.Key_Menu) {
openContextMenu();
}
}
}
/*
BaseView {
id: recentsModel
objectName: "OftenUsedView"
KeyNavigation.tab: root.m_showAllButton
model: KItemModels.KSortFilterProxyModel {
sourceModel: rootModel.modelForRow(0)
property var favoritesModel: globalFavorites
function trigger(index, str, ptr) {
sourceModel.trigger(index, str, ptr);
}
filterRowCallback: function(source_row, source_parent) {
//return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) == "...";
return source_row < Plasmoid.configuration.numberRows - sourceModel.favoritesModel.count ;
};
}
}
*/

View file

@ -0,0 +1,104 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Gregor Taetzner <gregor@freenet.de>
Copyright (C) 2015-2018 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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.private.kicker as Kicker
import org.kde.kirigami as Kirigami
Item {
id: searchViewContainer
property Item itemGrid: runnerGrid
property bool queryFinished: false
property int repeaterModelIndex: 0
function activateCurrentIndex() {
runnerGrid.tryActivate();
}
function decrementCurrentIndex() {
var listView = runnerGrid.flickableItem;
if(listView.currentIndex-1 < 0) {
listView.currentIndex = listView.count - 1;
} else {
listView.currentIndex--;
}
}
function incrementCurrentIndex() {
var listView = runnerGrid.flickableItem;
if(listView.currentIndex+1 >= listView.count) {
listView.currentIndex = 0;
} else {
listView.currentIndex++;
}
}
function onQueryChanged() {
queryFinished = false;
runnerModel.query = searchField.text;
if (!searchField.text) {
if (runnerModel.model)
runnerModel.model = null;
}
}
function openContextMenu() {
runnerModel.currentItem.openActionMenu();
}
function resetCurrentIndex() {
runnerModel.currentIndex = -1;
}
/*function setCurrentIndex() {
runnerGrid.modelIndex = 0;
}*/
objectName: "SearchView"
Connections {
function onCountChanged() {
if (runnerModel.count && !runnerGrid.model) {
runnerGrid.model = runnerModel.modelForRow(0);
}
}
function onQueryFinished() {
if (runnerModel.count) {
runnerGrid.model = null;
runnerGrid.model = runnerModel.modelForRow(0);
queryFinished = true;
var listView = runnerGrid.flickableItem;
if(listView.count > 0) listView.currentIndex = 0;
//console.log(runnerModel.modelForRow(0).modelForRow(0))
}
}
target: runnerModel
}
NavGrid {
id: runnerGrid
anchors.fill: parent
property alias model: runnerGrid.triggerModel
triggerModel: kicker.runnerModel.count ? kicker.runnerModel.modelForRow(0) : null
}
}

View file

@ -0,0 +1,61 @@
/*
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
Copyright (C) 2012 Marco Martin <mart@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) 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import QtQuick.Controls 2.15
import org.kde.kirigami as Kirigami
Item {
id: sectionDelegate
width: parent.width
height: Kirigami.Units.iconSizes.medium-1 //childrenRect.height
objectName: "SectionDelegate"
function getName() {
return sectionHeading.text;
}
property int sectionCount: 0
PlasmaExtras.Heading {
id: sectionHeading
anchors {
left: parent.left
leftMargin: Kirigami.Units.smallSpacing*2
verticalCenter: parent.verticalCenter
//verticalCenterOffset: Kirigami.Units.smallSpacing/2
}
color: "#1d3287"
//y: Math.round(Kirigami.Units.gridUnit / 4)
level: 3
text: section + (sectionCount > 0 ? " (" + sectionCount + ")" : "")
}
Rectangle {
id: line
anchors.left: sectionHeading.right
anchors.leftMargin: Kirigami.Units.largeSpacing-1
anchors.rightMargin: Kirigami.Units.largeSpacing+1 + (scrollView.ScrollBar.vertical.visible ? scrollView.ScrollBar.vertical.width : 0)
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 1
height: 1
color: "#e5e5e5"
}
} // sectionDelegate

View file

@ -0,0 +1,136 @@
import QtQuick 2.4
import QtQuick.Controls
import QtQuick.Layouts 1.1
import QtQuick.Dialogs
import QtQuick.Window 2.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.ksvg as KSvg
import org.kde.kirigami as Kirigami
Item {
id: sidePanelDelegate
objectName: "SidePanelItemDelegate"
property int iconSizeSide: Kirigami.Units.iconSizes.smallMedium
property string itemText: ""
property string itemIcon: ""
property string executableString: ""
property bool executeProgram: false
property alias textLabel: label
//text: itemText
//icon: itemIcon
width: label.implicitWidth + Kirigami.Units.largeSpacing*2
//Layout.preferredWidth: label.implicitWidth
height: 33
KeyNavigation.backtab: findPrevious();
KeyNavigation.tab: findNext();
function findItem() {
for(var i = 1; i < parent.visibleChildren.length-1; i++) {
if(sidePanelDelegate == parent.visibleChildren[i])
return i;
}
return -1;
}
function findPrevious() {
var i = findItem()-1;
if(i < 1) {
return root.m_searchField;
}
if(parent.visibleChildren[i].objectName == "SidePanelItemSeparator") {
i--;
}
return parent.visibleChildren[i];
}
function findNext() {
var i = findItem()+1;
if(i >= parent.visibleChildren.length-1) {
return root.m_shutDownButton;
}
if(parent.visibleChildren[i].objectName == "SidePanelItemSeparator") {
i++;
}
return parent.visibleChildren[i];
}
Keys.onPressed: event => {
if(event.key == Qt.Key_Return) {
sidePanelMouseArea.clicked(null);
} else if(event.key == Qt.Key_Up) {
//console.log(findPrevious());
findPrevious().focus = true;
} else if(event.key == Qt.Key_Down) {
//console.log(findNext());
findNext().focus = true;
} else if(event.key == Qt.Key_Left) {
var pos = parent.mapToItem(mainFocusScope, sidePanelDelegate.x, sidePanelDelegate.y);
var obj = mainFocusScope.childAt(Kirigami.Units.smallSpacing*10, pos.y);
if(obj.objectName == "") {
obj = root.m_recents;
}
obj.focus = true;
}
}
//For some reason this is the only thing that prevents a width reduction bug, despite it being UB in QML
/*anchors.left: parent.left;
anchors.right: parent.right;*/
KSvg.FrameSvgItem {
id: itemFrame
z: -1
opacity: sidePanelMouseArea.containsMouse || parent.focus
anchors.fill: parent
imagePath: Qt.resolvedUrl("svgs/sidebaritem.svg")
prefix: "menuitem"
}
PlasmaComponents.Label {
id: label
wrapMode: Text.NoWrap
//elide: Text.ElideRight
anchors.left: parent.left
anchors.leftMargin: Kirigami.Units.smallSpacing * 2
anchors.verticalCenter: sidePanelDelegate.verticalCenter
anchors.verticalCenterOffset: -1
style: Text.Sunken
styleColor: "transparent"
text: itemText
}
onFocusChanged: {
/*if(focus) {
root.m_sidebarIcon.source = itemIcon;
} else {
root.m_sidebarIcon.source = "";
}*/
if(root.m_delayTimer.running) root.m_delayTimer.restart();
else root.m_delayTimer.start();
}
MouseArea {
id: sidePanelMouseArea
enabled: !root.hoverDisabled
acceptedButtons: Qt.LeftButton
onEntered: {
sidePanelDelegate.focus = true;
}
onExited: {
sidePanelDelegate.focus = false;
}
onClicked: {
root.visible = false;
if(executeProgram)
executable.exec(executableString);
else {
Qt.openUrlExternally(executableString);
}
}
hoverEnabled: true
anchors.fill: parent
}
}

View file

@ -0,0 +1,55 @@
import QtQuick 2.4
import QtQuick.Controls
import QtQuick.Layouts 1.1
import QtQuick.Dialogs
import QtQuick.Window 2.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.ksvg as KSvg
import org.kde.kirigami as Kirigami
Item {
id: sidePanelDelegate
objectName: "SidePanelItemSeparator"
//icon: itemIcon
function findItem() {
for(var i = 0; i < parent.visibleChildren.length; i++) {
if(sidePanelDelegate == parent.visibleChildren[i])
return i;
}
return -1;
}
function updateVisibility() {
if(!visible) visible = true;
var i = findItem();
var pred = i-1;
var succ = i+1;
if(pred <= 0 || succ >= parent.visibleChildren.length) {
sidePanelDelegate.visible = false;
return;
}
if(parent.visibleChildren[pred].objectName !== "SidePanelItemDelegate" || parent.visibleChildren[succ].objectName !== "SidePanelItemDelegate") {
sidePanelDelegate.visible = false;
return;
}
sidePanelDelegate.visible = true;
}
//For some reason this is the only thing that prevents a width reduction bug, despite it being UB in QML
/*anchors.left: parent.left;
anchors.right: parent.right;*/
height: 2;
KSvg.SvgItem {
id: itemFrame
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.smallSpacing*2;
anchors.rightMargin: Kirigami.Units.smallSpacing*2;
svg: separatorSvg
elementId: "separator-line"
}
}

View file

@ -0,0 +1,75 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts 1.1
import QtQuick.Dialogs
import QtQuick.Window 2.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.private.kicker 0.1 as Kicker
import org.kde.coreaddons as KCoreAddons // kuser
import org.kde.plasma.private.shell 2.0
import org.kde.kwindowsystem 1.0
import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.quicklaunch 1.0
import org.kde.kirigami 2.13 as Kirigami
import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons
import org.kde.kwindowsystem 1.0
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
/*
* This is the Dialog that displays the Start menu orb when it sticks out
* of the panel. In principle, it works in almost the same way as the
* Start menu user icon, in fact most of the code is directly copied from
* there.
*
* Compared to the popup avatar, this dialog window should NOT have any
* visualParent set, as it causes inexplicable behavior where the orb
* moves away during certain interactions. I have no idea why it does that.
*
* This has been developed only for the bottom/south oriented panel, and
* other orientations should receive support when I begin giving pretty
* much *everything* else support for other orientations.
*
*/
PlasmaCore.Dialog {
id: iconUser
flags: Qt.WindowStaysOnTopHint | Qt.Popup | Qt.WindowTransparentForInput
location: "Floating"
//outputOnly: true // Simplifies things, prevents accidental misclicks when clicking close to the orb.
// Positions are defined later when the plasmoid has been fully loaded, to prevent undefined behavior.
x: 0
y: 0
// Input masks won't be applied correctly when compositing is disabled unless I do this. WHY?
onYChanged: {
Plasmoid.setTransparentWindow();
}
onXChanged: {
Plasmoid.setTransparentWindow();
}
onVisibleChanged: {
if(visible) {
orbTimer.start(); // Delayed initialization, again, for what reason?
}
}
backgroundHints: PlasmaCore.Types.NoBackground // Prevents a dialog SVG background from being drawn.
visible: root.visible && stickOutOrb
opacity: iconUser.visible // To prevent even more NP-hard unpredictable behavior and visual glitches.
// The actual orb button, this dialog window is just a container for it.
mainItem: FloatingOrb {
id: floatingOrbIcon
}
}

View file

@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: 2013 Aurélien Gâteau <agateau@kde.org>
* SPDX-FileCopyrightText: 2013-2015 Eike Hein <hein@kde.org>
* SPDX-FileCopyrightText: 2017 Ivan Cukic <ivan.cukic@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.pragma library
function fillActionMenu(i18n, actionMenu, actionList, favoriteModel, favoriteId) {
// Accessing actionList can be a costly operation, so we don't
// access it until we need the menu.
var actions = createFavoriteActions(i18n, favoriteModel, favoriteId);
if (actions) {
if (actionList && actionList.length > 0) {
var actionListCopy = Array.from(actionList);
var separator = { "type": "separator" };
actionListCopy.push(separator);
// actionList = actions.concat(actionList); // this crashes Qt O.o
actionListCopy.push.apply(actionListCopy, actions);
actionList = actionListCopy;
} else {
actionList = actions;
}
}
actionMenu.actionList = actionList;
}
function createFavoriteActions(i18n, favoriteModel, favoriteId) {
if (!favoriteModel || !favoriteModel.enabled || !favoriteId) {
return null;
}
if (favoriteModel.activities === undefined ||
favoriteModel.activities.runningActivities.length <= 1) {
var action = {};
if (favoriteModel.isFavorite(favoriteId)) {
action.text = i18n("Unpin from Start Menu");
//action.icon = "pin";
action.actionId = "_kicker_favorite_remove";
} else if (favoriteModel.maxFavorites === -1 || favoriteModel.count < favoriteModel.maxFavorites) {
action.text = i18n("Pin to Start Menu");
//action.icon = "bookmark-new";
action.actionId = "_kicker_favorite_add";
} else {
return null;
}
action.actionArgument = { favoriteModel: favoriteModel, favoriteId: favoriteId };
return [action];
} else {
var actions = [];
var linkedActivities = favoriteModel.linkedActivitiesFor(favoriteId);
var activities = favoriteModel.activities.runningActivities;
// Adding the item to link/unlink to all activities
var linkedToAllActivities =
!(linkedActivities.indexOf(":global") === -1);
actions.push({
text : i18n("On All Activities"),
checkable : true,
actionId : linkedToAllActivities ?
"_kicker_favorite_remove_from_activity" :
"_kicker_favorite_set_to_activity",
checked : linkedToAllActivities,
actionArgument : {
favoriteModel: favoriteModel,
favoriteId: favoriteId,
favoriteActivity: ""
}
});
// Adding items for each activity separately
var addActivityItem = function(activityId, activityName) {
var linkedToThisActivity =
!(linkedActivities.indexOf(activityId) === -1);
actions.push({
text : activityName,
checkable : true,
checked : linkedToThisActivity && !linkedToAllActivities,
actionId :
// If we are on all activities, and the user clicks just one
// specific activity, unlink from everything else
linkedToAllActivities ? "_kicker_favorite_set_to_activity" :
// If we are linked to the current activity, just unlink from
// that single one
linkedToThisActivity ? "_kicker_favorite_remove_from_activity" :
// Otherwise, link to this activity, but do not unlink from
// other ones
"_kicker_favorite_add_to_activity",
actionArgument : {
favoriteModel : favoriteModel,
favoriteId : favoriteId,
favoriteActivity : activityId
}
});
};
// Adding the item to link/unlink to the current activity
addActivityItem(favoriteModel.activities.currentActivity, i18n("On the Current Activity"));
actions.push({
type: "separator",
actionId: "_kicker_favorite_separator"
});
// Adding the items for each activity
activities.forEach(function(activityId) {
addActivityItem(activityId, favoriteModel.activityNameForId(activityId));
});
return [{
text : i18n("Show in Favorites"),
icon : "favorite",
subActions : actions
}];
}
}
function triggerAction(model, index, actionId, actionArgument) {
function startsWith(txt, needle) {
return txt.substr(0, needle.length) === needle;
}
if (startsWith(actionId, "_kicker_favorite_")) {
handleFavoriteAction(actionId, actionArgument);
return;
}
var closeRequested = model.trigger(index, actionId, actionArgument);
if (closeRequested) {
return true;
}
return false;
}
function handleFavoriteAction(actionId, actionArgument) {
var favoriteId = actionArgument.favoriteId;
var favoriteModel = actionArgument.favoriteModel;
if (favoriteModel === null || favoriteId === null) {
return null;
}
if (actionId === "_kicker_favorite_remove") {
favoriteModel.removeFavorite(favoriteId);
} else if (actionId === "_kicker_favorite_add") {
favoriteModel.addFavorite(favoriteId);
} else if (actionId === "_kicker_favorite_remove_from_activity") {
favoriteModel.removeFavoriteFrom(favoriteId, actionArgument.favoriteActivity);
} else if (actionId === "_kicker_favorite_add_to_activity") {
favoriteModel.addFavoriteTo(favoriteId, actionArgument.favoriteActivity);
} else if (actionId === "_kicker_favorite_set_to_activity") {
favoriteModel.setFavoriteOn(favoriteId, actionArgument.favoriteActivity);
}
}

View file

@ -0,0 +1,291 @@
/***************************************************************************
* Copyright (C) 2014-2015 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) 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.plasma.private.kicker 0.1 as Kicker
import org.kde.kquickcontrolsaddons as KQuickControlsAddons
import org.kde.kwindowsystem
import org.kde.ksvg as KSvg
import org.kde.kirigami as Kirigami
import org.kde.plasma.plasma5support as Plasma5Support
PlasmoidItem {
id: kicker
signal reset
anchors.fill: parent
property bool isDash: false
property Item dragSource: null
switchWidth: isDash || !fullRepresentationItem ? 0 :fullRepresentationItem.Layout.minimumWidth
switchHeight: isDash || !fullRepresentationItem ? 0 :fullRepresentationItem.Layout.minimumHeight
property QtObject globalFavorites: rootModel.favoritesModel
property QtObject systemFavorites: rootModel.systemFavoritesModel
// I see what you did here
//property bool compositingEnabled: kwindowsystem.compositingActive
property bool compositingEnabled: KWindowSystem.isPlatformX11 ? KX11Extras.compositingActive : true
preferredRepresentation: isDash ? menuRepresentation : null
compactRepresentation: isDash ? null : compactRepresentation
fullRepresentation: isDash ? compactRepresentation : menuRepresentation
Plasmoid.constraintHints: Plasmoid.CanFillArea
// Runs KMenuEdit.
function action_menuedit() {
processRunner.runMenuEditor();
}
function action_taskman() {
menu_executable.exec("ksysguard");
}
Component {
id: compactRepresentation
CompactRepresentation {}
}
Component {
id: menuRepresentation
MenuRepresentation { }
}
// Used to run separate programs through this plasmoid.
Plasma5Support.DataSource {
id: menu_executable
engine: "executable"
connectedSources: []
onNewData: {
var exitCode = data["exit code"]
var exitStatus = data["exit status"]
var stdout = data["stdout"]
var stderr = data["stderr"]
exited(sourceName, exitCode, exitStatus, stdout, stderr)
disconnectSource(sourceName)
}
function exec(cmd) {
if (cmd) {
connectSource(cmd)
}
}
signal exited(string cmd, int exitCode, int exitStatus, string stdout, string stderr)
}
Kicker.WindowSystem {
id: windowSystem
}
Kicker.RecentUsageModel {
id: recentUsageModel
favoritesModel: globalFavorites
ordering: 0
shownItems: Kicker.RecentUsageModel.OnlyApps
}
Kicker.RunnerModel {
id: runnerModel
appletInterface: kicker
//query: kickoff.searchField ? kickoff.searchField.text : ""
//deleteWhenEmpty: false
favoritesModel: rootModel.favoritesModel
//runners: ["Dictionary","services","calculator","shell","org.kde.windowedwidgets","org.kde.datetime","baloosearch","locations","unitconverter","bookmarks", "krunner_services", "krunner_systemsettings", "krunner_sessions", "krunner_powerdevil"]
/*runners: {
const results = ["Dictionary","services","calculator","shell","org.kde.windowedwidgets","org.kde.datetime","baloosearch","locations","unitconverter","bookmarks", "krunner_services", "krunner_systemsettings", "krunner_sessions", "krunner_powerdevil"];
if (Plasmoid.configuration.useExtraRunners) {
results.push(...Plasmoid.configuration.extraRunners);
}
return results;
}*/
mergeResults: true
}
//KWindowSystem { id: kwindowsystem } // Used for detecting compositing changes.
Kicker.RootModel {
id: rootModel
autoPopulate: false
appNameFormat: Plasmoid.configuration.appNameFormat
flat: true
sorted: true
showSeparators: false
appletInterface: kicker
paginate: false
pageSize: Plasmoid.configuration.numberColumns * Plasmoid.configuration.numberRows
showAllApps: false
showAllAppsCategorized: false
showRecentApps: true
showRecentDocs: false
//showRecentContacts: false
showPowerSession: false
onFavoritesModelChanged: {
if ("initForClient" in favoritesModel) {
favoritesModel.initForClient("org.kde.plasma.kicker.favorites.instance-" + plasmoid.id)
if (!Plasmoid.configuration.favoritesPortedToKAstats) {
favoritesModel.portOldFavorites(Plasmoid.configuration.favoriteApps);
Plasmoid.configuration.favoritesPortedToKAstats = true;
}
} else {
favoritesModel.favorites = Plasmoid.configuration.favoriteApps;
}
favoritesModel.maxFavorites = pageSize;
}
onSystemFavoritesModelChanged: {
systemFavoritesModel.enabled = false;
systemFavoritesModel.favorites = Plasmoid.configuration.favoriteSystemActions;
systemFavoritesModel.maxFavorites = 8;
}
Component.onCompleted: {
if ("initForClient" in favoritesModel) {
favoritesModel.initForClient("org.kde.plasma.kicker.favorites.instance-" + plasmoid.id)
if (!Plasmoid.configuration.favoritesPortedToKAstats) {
favoritesModel.portOldFavorites(Plasmoid.configuration.favoriteApps);
Plasmoid.configuration.favoritesPortedToKAstats = true;
}
} else {
favoritesModel.favorites = Plasmoid.configuration.favoriteApps;
}
favoritesModel.maxFavorites = pageSize;
rootModel.refresh();
}
}
Connections {
target: globalFavorites
function onFavoritesChanged() {
Plasmoid.configuration.favoriteApps = target.favorites;
}
}
Connections {
target: systemFavorites
function onFavoritesChanged() {
Plasmoid.configuration.favoriteSystemActions = target.favorites;
}
}
Connections {
target: Plasmoid.configuration
function onFavoriteAppsChanged() {
globalFavorites.favorites = Plasmoid.configuration.favoriteApps;
}
function onFavoriteSystemActionsChanged() {
systemFavorites.favorites = Plasmoid.configuration.favoriteSystemActions;
}
}
Kicker.DragHelper {
id: dragHelper
}
Kicker.ProcessRunner {
id: processRunner
}
// SVGs
KSvg.FrameSvgItem {
id : highlightItemSvg
visible: false
imagePath: Qt.resolvedUrl("svgs/menuitem.svg")
prefix: "hover"
}
KSvg.FrameSvgItem {
id : panelSvg
visible: false
imagePath: "widgets/panel-background"
}
KSvg.Svg {
id: arrowsSvg
imagePath: Qt.resolvedUrl("svgs/arrows.svgz")
size: "16x16"
}
KSvg.Svg {
id: separatorSvg
imagePath: Qt.resolvedUrl("svgs/sidebarseparator.svg")
}
KSvg.Svg {
id: lockScreenSvg
imagePath: Qt.resolvedUrl("svgs/system-lock-screen.svg")
}
PlasmaComponents.Label {
id: toolTipDelegate
width: contentWidth
height: contentHeight
property Item toolTip
text: (toolTip != null) ? toolTip.text : ""
}
function resetDragSource() {
dragSource = null;
}
function enableHideOnWindowDeactivate() {
kicker.hideOnWindowDeactivate = true;
}
Plasmoid.contextualActions: [
PlasmaCore.Action {
text: i18n("Edit Applications...")
icon.name: "application-menu"
onTriggered: menu_executable.exec("kmenuedit");
},
PlasmaCore.Action {
text: i18n("Task Manager")
icon.name: "ksysguardd"
onTriggered: menu_executable.exec("ksysguard");
}
]
Component.onCompleted: {
if (Plasmoid.hasOwnProperty("activationTogglesExpanded")) {
Plasmoid.activationTogglesExpanded = !kicker.isDash
}
windowSystem.focusIn.connect(enableHideOnWindowDeactivate);
kicker.hideOnWindowDeactivate = true;
rootModel.refreshed.connect(reset);
dragHelper.dropped.connect(resetDragSource);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 141 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 115 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 115 KiB

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
viewBox="0 0 32 32"
id="svg7"
sodipodi:docname="system-lock-screen.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview9"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
showgrid="false"
inkscape:zoom="10.0625"
inkscape:cx="9.689441"
inkscape:cy="15.204969"
inkscape:window-width="1440"
inkscape:window-height="874"
inkscape:window-x="1600"
inkscape:window-y="150"
inkscape:window-maximized="1"
inkscape:current-layer="svg7"
inkscape:showpageshadow="2"
inkscape:deskcolor="#505050" />
<defs
id="defs3">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
class="ColorScheme-Text"
d="m 16,8 c -2.216,0 -4,1.784 -4,4 v 4 h -2 v 8 H 22 V 16 H 20 V 12 C 20,9.784 18.216,8 16,8 Z m 0,1 c 1.662,0 3,1.561 3,3.5 V 16 H 13 V 12.5 C 13,10.561 14.338,9 16,9 Z"
fill="currentColor"
id="light-lock"
sodipodi:nodetypes="ssccccccssssccss" />
<path
d="m 16,8 c -2.216,0 -4,1.784 -4,4 v 4 h -2 v 8 H 22 V 16 H 20 V 12 C 20,9.784 18.216,8 16,8 Z m 0,1 c 1.662,0 3,1.561 3,3.5 V 16 H 13 V 12.5 C 13,10.561 14.338,9 16,9 Z"
fill="currentColor"
id="dark-lock"
sodipodi:nodetypes="ssccccccssssccss"
style="fill:#202020;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,27 @@
{
"KPlugin": {
"Authors": [
{
"Email": "wackyideas[at]disroot.org",
"Name": "WackyIdeas"
}
],
"Category": "Application Launchers",
"Dependencies": [
],
"Description": "Open application menu",
"EnabledByDefault": true,
"Icon": "start-here-kde",
"Id": "io.gitgud.wackyideas.SevenStart",
"License": "GPL v2+",
"Name": "Seven Start",
"Version": "1.0"
},
"X-Plasma-API-Minimum-Version": "6.0",
"KPackageStructure": "Plasma/Applet",
"X-Plasma-API": "declarativeappletscript",
"X-Plasma-MainScript": "ui/main.qml",
"X-Plasma-Provides": [
"org.kde.plasma.launchermenu"
]
}

View file

@ -0,0 +1,25 @@
{
"KPlugin": {
"Authors": [
{
"Email": "wackyideas[at]disroot.org",
"Name": "WackyIdeas"
}
],
"Category": "Application Launchers",
"Dependencies": [
],
"Description": "Open application menu",
"EnabledByDefault": true,
"Icon": "start-here-kde",
"Id": "io.gitgud.wackyideas.SevenStart",
"License": "GPL v2+",
"Name": "Seven Start",
"Version": "1.0"
},
"X-Plasma-API-Minimum-Version": "6.0",
"KPackageStructure": "Plasma/Applet",
"X-Plasma-Provides": [
"org.kde.plasma.launchermenu"
]
}