Compare commits
513 Commits
Author | SHA1 | Date | |
---|---|---|---|
16bdff4f48 | |||
565cdf502c | |||
2dc8d9b462 | |||
ce6dd21cd3 | |||
e7066d12cf | |||
09df6a3818 | |||
17d1e06c7c | |||
e6b80927ad | |||
f9c5202dd1 | |||
a21ba292eb | |||
5429104f04 | |||
bb0a977edc | |||
77ed621c74 | |||
fc39919856 | |||
d8800c095a | |||
e5ba414f2d | |||
b8a9eec14f | |||
059504ca70 | |||
b2db95380b | |||
b6bb26e9ae | |||
126d02ae90 | |||
8d76e362a0 | |||
004cf3da5c | |||
fb9fd6925a | |||
ec725cc6d4 | |||
79fe60e6fb | |||
c793d7d0a4 | |||
1b7c3580e6 | |||
3c3e0b6f20 | |||
fd6863dda4 | |||
690be611ee | |||
18c5405b79 | |||
cfd63c7d4c | |||
49a9335f68 | |||
5b1d52c5e7 | |||
9f43ed3f95 | |||
0770fd5be5 | |||
3c8ba348c2 | |||
b84a7042f1 | |||
8ef75524ea | |||
cec62a7ca5 | |||
77fe0db623 | |||
e86c821878 | |||
02f67af464 | |||
fd310bc7b9 | |||
94d3e27c53 | |||
6aa02c5edc | |||
97e19d7d4a | |||
94f32030e6 | |||
721e1ea863 | |||
5331d3e360 | |||
f52744cfbc | |||
4749393ab5 | |||
975603d608 | |||
99346522e9 | |||
090335ad8b | |||
d8af8f7305 | |||
2a2b597e09 | |||
da1d43fc61 | |||
03a750176b | |||
1d2bb5c51c | |||
60046aaa4f | |||
a6df234528 | |||
5ead0de7ca | |||
229cfd9f80 | |||
01c267b095 | |||
33a6c41810 | |||
7040e9a63b | |||
901eabb82d | |||
b11aa5f676 | |||
ccaa11bb6b | |||
dd0fba4270 | |||
3f6759061d | |||
abc7b1ff02 | |||
75a677701d | |||
11656ebd89 | |||
d62b4cf130 | |||
c4b3d18e26 | |||
38b7904f92 | |||
c89ee2f8f2 | |||
c21e692652 | |||
071efd826c | |||
d27f19a561 | |||
7642040fc0 | |||
67e70df0c9 | |||
fc0acc9e37 | |||
3a7dc32659 | |||
36e761b7a5 | |||
9a1cb9c3db | |||
32e2ff7573 | |||
ea4b1c6c29 | |||
2d574047e4 | |||
8ded91e975 | |||
0b2eeccd4b | |||
fa5b0efdb4 | |||
7555915441 | |||
3e1b1d5789 | |||
8e759d7f32 | |||
caaa543385 | |||
dce4b2f325 | |||
fb7ed1ee28 | |||
a74cef9d2f | |||
c88d21d487 | |||
6f83b39ee4 | |||
f5c4e23c9c | |||
f1fb0d32c6 | |||
ed129b40a3 | |||
fd1ce40ee7 | |||
2b15f38730 | |||
86515f3943 | |||
9afb09128b | |||
e40063fc34 | |||
d20d815b45 | |||
ed36517615 | |||
fa60165764 | |||
3c9d0fbca6 | |||
8d31c2f4dc | |||
eaa1f9a0f4 | |||
3e19f41cba | |||
e6902a1f1c | |||
b1007ed811 | |||
54d385a0a9 | |||
df48e9d1c0 | |||
e3be74a31a | |||
a8aa0c085f | |||
cd78f1158c | |||
d9668bd425 | |||
dc3ff10c6f | |||
31f9da7b8f | |||
05e3a747d0 | |||
8db212db99 | |||
2494cc1637 | |||
ee75355e71 | |||
863f9f285b | |||
d7e0051bc6 | |||
2aa305b51d | |||
4006d7d57f | |||
0a566f70b6 | |||
be2801d1fa | |||
648126e598 | |||
8184b2c57b | |||
337eab614e | |||
20abc4cb99 | |||
5aca0b7704 | |||
74446ce3e0 | |||
7bb14bd8da | |||
ed75f0da63 | |||
d9008054cf | |||
b10d9c9ad7 | |||
5f855045a2 | |||
88737b2083 | |||
a50d64e8e9 | |||
4deef2a9ef | |||
dd9a29633a | |||
4407f0bd65 | |||
73fd896f3c | |||
f8acd0f6f6 | |||
ccc6a23f68 | |||
c236c501e7 | |||
2a0e0ae66f | |||
11276a3505 | |||
c90371d9d5 | |||
038a32330f | |||
fa1fe4fdd1 | |||
59d6029f47 | |||
33b3d05039 | |||
7486c09fbb | |||
3f750a5637 | |||
e54fe59723 | |||
38b20ca0a4 | |||
8c178378ae | |||
341b9a80c5 | |||
45e89bf34a | |||
c17e1249d5 | |||
262f92e0be | |||
da797dff35 | |||
7043215f5e | |||
5202dd5157 | |||
7c4765d053 | |||
69c8aef6c2 | |||
71786e50cf | |||
e5647c4f83 | |||
98a8dd682d | |||
af3b965e00 | |||
2dfe113a42 | |||
a2cae50e0e | |||
9423cc7fae | |||
767fe0ebc2 | |||
edce0e8feb | |||
554549338a | |||
350e958383 | |||
0e5c83bd2a | |||
6e1a791273 | |||
2435c603ec | |||
44cc42484f | |||
44712c274e | |||
1c4c3afb27 | |||
e326202477 | |||
45f4292259 | |||
288eae91e2 | |||
f4c05deb2d | |||
1cd9a15ac0 | |||
d1edefdc39 | |||
2cb4dfb4a4 | |||
c0ff0066e6 | |||
55fbb9d0af | |||
c4a49b4de2 | |||
aa9d3515a1 | |||
4394bc3e40 | |||
6b1c3d323b | |||
b7646d18ae | |||
f5f92b2e79 | |||
14df7cd62c | |||
c2fe9e57b1 | |||
5a3c3efbeb | |||
a8d18ac18a | |||
949f67469c | |||
a442dfea14 | |||
42757a0c87 | |||
81b7c0170d | |||
d624db18c5 | |||
b03fa1ebf7 | |||
478dba8502 | |||
20294f2c92 | |||
34003a1f6b | |||
a4405be71c | |||
b6cc9c7ff6 | |||
368d484dee | |||
7b0526dc5c | |||
236a9b184f | |||
6b816fa7dc | |||
e2ac769fd1 | |||
dd8f05c81d | |||
f0e3b87330 | |||
1d2dc09ede | |||
73cd9513bd | |||
907fc2f067 | |||
2f1ca7bf28 | |||
93f3412f70 | |||
f815844eb4 | |||
b0cb8fb85a | |||
e9787c0f1e | |||
efc291ac5b | |||
1cc78fdf60 | |||
8c59bc71b0 | |||
7b9f5b7643 | |||
0bc578230f | |||
bb366f8fbe | |||
8ac97fe1a0 | |||
2c914374e0 | |||
1526500079 | |||
9ba5ca0193 | |||
3529b8c915 | |||
4e8206d60e | |||
a5edc78fac | |||
cdd508e12d | |||
931cbc6ae3 | |||
ab809faaf0 | |||
8334b063f1 | |||
21f15246a6 | |||
050e710770 | |||
bb63d513fd | |||
985d707788 | |||
9ddebf0480 | |||
8c05003acf | |||
7c796b2d2a | |||
48f8e4943d | |||
fec2ea5e9c | |||
4014313910 | |||
06cf6c51f3 | |||
426d7bc515 | |||
bf68f9f0cf | |||
ce90dda76f | |||
66cab3b8ed | |||
bc255a525f | |||
d51384fb86 | |||
1626e8c09a | |||
263d738ef6 | |||
8040ad61c6 | |||
057f0effed | |||
bf7b166237 | |||
ae744bf206 | |||
af35dea019 | |||
1b75ae0184 | |||
07a8d5ed2d | |||
2f27f61a1f | |||
585bfe5b5a | |||
5ee72d807d | |||
fcac7ac0b3 | |||
dcd7762253 | |||
869e744670 | |||
626f679947 | |||
4f456b9689 | |||
e2e513ff08 | |||
37a948e4eb | |||
b8d9319c32 | |||
f549269934 | |||
dc232d4631 | |||
930a0b52f3 | |||
f14d7f891b | |||
01138d55ca | |||
2103a4da24 | |||
627f86a9dc | |||
baf823c466 | |||
94bd6f1718 | |||
c8b1afbad6 | |||
395f45c570 | |||
3ebb0f149d | |||
6d9aadfa4d | |||
22e26bea8f | |||
d9ff1f2ec1 | |||
10991d363d | |||
0c37a5bd6f | |||
369e0c2c6f | |||
17c8173640 | |||
8fd00ac6cc | |||
4f4e54cbf7 | |||
16cb878f4e | |||
d5adfa6445 | |||
8e9549c6f1 | |||
7239eb2f90 | |||
5b769138b6 | |||
81d579aca0 | |||
7548f2d71e | |||
bda7d3994b | |||
a336ed79ae | |||
416fbc775e | |||
e941e8088b | |||
77cf9ae077 | |||
358175e998 | |||
7f5c600133 | |||
56bcdd41fd | |||
cd33dc7f22 | |||
2eef17bcdc | |||
79a614240b | |||
7c954898a2 | |||
497c74f4d8 | |||
51c41aed90 | |||
d705c1bb52 | |||
d9df7c1b1e | |||
49eb687713 | |||
7bec02dcb1 | |||
38c06ca837 | |||
6623ca1287 | |||
d1bdd6f11d | |||
39edf54aa9 | |||
aa9c585562 | |||
8b813060f0 | |||
ca263dade5 | |||
b8ef9cdf4b | |||
aa92c6fdf5 | |||
3af8130fff | |||
ab0460ad59 | |||
a27c29f4fc | |||
212d5c1954 | |||
8929f43ad9 | |||
a26b0b60d1 | |||
60dbb19c2d | |||
3703a86354 | |||
992b43f914 | |||
ff39edd1ee | |||
a81a16801d | |||
4c6f770dea | |||
c0b01c0210 | |||
400326e549 | |||
d7af6d40e3 | |||
90ebcd32e3 | |||
53d0581377 | |||
439daf828f | |||
d120d03de9 | |||
53fbabe2ca | |||
4bdd40911f | |||
ff4ac0d02e | |||
45dd342cc0 | |||
e5efecd2bd | |||
3bf88b8988 | |||
4ddc1118bb | |||
fd1e7b2a0f | |||
aed1e67add | |||
dc99e8ffcd | |||
6a8b50cb00 | |||
edb50d5dc7 | |||
2f6c951997 | |||
64cd51667d | |||
caa08f27fa | |||
26015ef16d | |||
4798ad5107 | |||
9b05304c2d | |||
795feca393 | |||
31663dcd83 | |||
2f2df61093 | |||
3b8d53060d | |||
c5ce405859 | |||
b3a5fc72fb | |||
8a2cc11cc0 | |||
cbb3a3aec8 | |||
e382da9708 | |||
ab1fbbde92 | |||
5f5266ca60 | |||
68e8b14b8b | |||
abdd8b330c | |||
eb8176deeb | |||
956f89f377 | |||
1c69380923 | |||
d2bc7b200e | |||
afb3b1e718 | |||
061a2cfbfb | |||
243824ab80 | |||
90ddad7ba1 | |||
20b29ff48f | |||
96f4d318c5 | |||
6f7da264ba | |||
640e45c12a | |||
04e28cd7c4 | |||
2cc41c6726 | |||
03a45b665c | |||
5a42179a96 | |||
af3ec56ca1 | |||
289b19aa31 | |||
91eb613d69 | |||
1c7c53d19f | |||
d4304495c6 | |||
b77b205d37 | |||
a15205e6c4 | |||
28dbf7a06e | |||
1ec8e9eb6b | |||
fa09f7a6da | |||
d67e54d3ee | |||
d263c12e2e | |||
4d55ccff39 | |||
2a0adc0fc8 | |||
076e902b2c | |||
8c72623da3 | |||
1fd25573e5 | |||
6527dbc8b7 | |||
3c646ec516 | |||
a9fd350396 | |||
e91e8e993d | |||
276d9a9302 | |||
6b95864076 | |||
d4c577a299 | |||
b90fc1e194 | |||
55497899dd | |||
e37790fdf9 | |||
83402957bb | |||
58325fca76 | |||
8b6962f3bf | |||
c1f91def74 | |||
529f74c0e5 | |||
459a3b18f2 | |||
ac2be7f0d1 | |||
f6b80d5ed4 | |||
d291e568fd | |||
2b78d5bd5d | |||
c9d9846759 | |||
6baafaa530 | |||
c2af05f753 | |||
97df305a6d | |||
fee385ba35 | |||
373fa3c325 | |||
84a6a6faf0 | |||
9432ddb12e | |||
d4a2f9e604 | |||
7f468b36e7 | |||
349e5b39af | |||
cad774aca1 | |||
b25bbf4c0a | |||
72dd458c80 | |||
79d5d3dba0 | |||
c14a4deddf | |||
4bab511fa5 | |||
36b11ee8c7 | |||
3ffc510be7 | |||
ec92bfba14 | |||
f5f22b3935 | |||
159081dcfc | |||
1da4837d98 | |||
0f63ae1869 | |||
32ef951fe0 | |||
3564d78d30 | |||
4bff2675ae | |||
2020d15a1a | |||
64d8d7a91c | |||
eb025901c8 | |||
9fee99bc7a | |||
67bfbc9b4b | |||
11d884d724 | |||
24d42adc04 | |||
110ef17e2d | |||
0143512e00 | |||
4876474be3 | |||
0e4a86f2e6 | |||
18dbc5462f | |||
8f660f563c | |||
fa316ddd3d | |||
7703bee284 | |||
90e6769638 | |||
0b6d09bbe2 | |||
3734479cbd | |||
6cae94edcc | |||
0918bdd612 | |||
a75b1abc93 | |||
e6a08cc9fd | |||
09c9defbf0 | |||
3ba6ff4ca9 | |||
19fa0b5d5b | |||
79db50500d | |||
f26c9ab245 | |||
293adb9bcc | |||
e79b15c645 | |||
08603c1524 | |||
cee7106cb1 | |||
2c0661d377 |
7
.gitignore
vendored
@ -22,8 +22,10 @@ intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
libtool
|
||||
m4/
|
||||
omf.make
|
||||
po/*.gmo
|
||||
po/gnome-shell.pot
|
||||
po/Makefile.in.in
|
||||
po/POTFILES
|
||||
po/stamp-it
|
||||
@ -38,5 +40,10 @@ src/gnomeshell-taskpanel
|
||||
src/gnome-shell
|
||||
src/test-recorder
|
||||
src/test-recorder.ogg
|
||||
src/test-theme
|
||||
src/st.h
|
||||
stamp-h1
|
||||
tests/run-test.sh
|
||||
xmldocs.make
|
||||
*~
|
||||
*.patch
|
||||
|
29
Makefile.am
@ -1,18 +1,21 @@
|
||||
SUBDIRS = data js src po
|
||||
# Point to our macro directory and pick up user flags from the environment
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
SUBDIRS = data js src tests po man
|
||||
|
||||
EXTRA_DIST = \
|
||||
.project \
|
||||
.settings
|
||||
.settings \
|
||||
autogen.sh \
|
||||
tools/check-for-missing.py
|
||||
|
||||
# These are files checked into Git that we don't want to distribute
|
||||
DIST_EXCLUDE = \
|
||||
.gitignore \
|
||||
gnome-shell.doap \
|
||||
MAINTAINERS \
|
||||
tools/build/*
|
||||
|
||||
distcheck-hook:
|
||||
@echo "Checking disted javascript against files in git"
|
||||
@failed=false; \
|
||||
for f in `cd $(srcdir) && git ls-files js` ; do \
|
||||
if ! test -e $(distdir)/$$f ; then \
|
||||
echo File missing from distribution: $$f ; \
|
||||
failed=true ; \
|
||||
fi \
|
||||
done ; \
|
||||
if $$failed ; then \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@echo "Checking disted files against files in git"
|
||||
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
||||
|
@ -5,7 +5,6 @@ srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="gnome-shell"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
@ -15,7 +14,7 @@ REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "You need to install gnome-common from GNOME Git (or from"
|
||||
echo "your OS vendor's package manager)."
|
||||
exit 1
|
||||
}
|
||||
|
42
configure.ac
@ -1,30 +1,33 @@
|
||||
AC_INIT(gnome-shell, 2.27.3)
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[2.29.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([config])
|
||||
|
||||
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip foreign])
|
||||
AM_INIT_AUTOMAKE([1.10 dist-bzip2 no-dist-gzip foreign])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
AC_DISABLE_STATIC
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
# Needed for per-target cflags, like in gnomeshell-taskpanel
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
# Initialize libtool
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT([disable-static])
|
||||
|
||||
GETTEXT_PACKAGE=gnome-shell
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
||||
[The prefix for our gettext translation domains.])
|
||||
|
||||
PKG_PROG_PKG_CONFIG(0.16)
|
||||
|
||||
IT_PROG_INTLTOOL(0.26)
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
AC_DEFINE([GETTEXT_PACKAGE], [PACKAGE_TARNAME], [The prefix for our gettext translation domain])
|
||||
|
||||
PKG_PROG_PKG_CONFIG([0.22])
|
||||
|
||||
# GConf stuff
|
||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||
AM_GCONF_SOURCE_2
|
||||
|
||||
@ -51,12 +54,13 @@ fi
|
||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
|
||||
# Collect more than 20 libraries for a prize!
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugins
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugins >= 2.29.0
|
||||
gjs-gi-1.0 libgnome-menu $recorder_modules gconf-2.0
|
||||
gdk-x11-2.0 clutter-x11-1.0 clutter-glx-1.0
|
||||
gnome-desktop-2.0 >= 2.26 libstartup-notification-1.0
|
||||
gobject-introspection-1.0 >= 0.6.5)
|
||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6)
|
||||
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
|
||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-2.0)
|
||||
PKG_CHECK_MODULES(TRAY, gtk+-2.0)
|
||||
@ -93,8 +97,7 @@ AC_SUBST(TYPELIBDIR)
|
||||
# Stay command-line compatible with the gnome-common configure option. Here
|
||||
# minimum/yes/maximum are the same, however.
|
||||
AC_ARG_ENABLE(compile_warnings,
|
||||
AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
|
||||
[Turn on compiler warnings]),,
|
||||
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
||||
enable_compile_warnings=error)
|
||||
|
||||
changequote(,)dnl
|
||||
@ -121,12 +124,15 @@ changequote([,])dnl
|
||||
AC_PATH_PROG(mutter, [mutter])
|
||||
AC_SUBST(mutter)
|
||||
|
||||
AC_OUTPUT([
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
js/Makefile
|
||||
js/misc/Makefile
|
||||
js/ui/Makefile
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
po/Makefile.in
|
||||
man/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
@ -12,17 +12,35 @@ gnome-shell.desktop.in: gnome-shell.desktop.in.in
|
||||
gnome-shell.desktop: gnome-shell.desktop.in
|
||||
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
||||
|
||||
imagedir = $(pkgdatadir)/images
|
||||
imagesdir = $(pkgdatadir)/images
|
||||
dist_images_DATA = \
|
||||
close-black.svg \
|
||||
magnifier.svg
|
||||
|
||||
themedir = $(pkgdatadir)/theme
|
||||
dist_theme_DATA = \
|
||||
theme/add-workspace.svg \
|
||||
theme/close-window.svg \
|
||||
theme/close.svg \
|
||||
theme/corner-ripple.png \
|
||||
theme/gnome-shell.css \
|
||||
theme/mosaic-view-active.svg \
|
||||
theme/mosaic-view.svg \
|
||||
theme/remove-workspace.svg \
|
||||
theme/scroll-button-down-hover.png \
|
||||
theme/scroll-button-down.png \
|
||||
theme/scroll-button-up-hover.png \
|
||||
theme/scroll-button-up.png \
|
||||
theme/scroll-hhandle.svg \
|
||||
theme/scroll-vhandle.svg \
|
||||
theme/section-back.svg \
|
||||
theme/section-more.svg \
|
||||
theme/section-more-open.svg \
|
||||
theme/single-view-active.svg \
|
||||
theme/single-view.svg \
|
||||
theme/ws-switch-arrow-left.svg \
|
||||
theme/ws-switch-arrow-right.svg
|
||||
|
||||
dist_image_DATA = \
|
||||
add-workspace.svg \
|
||||
app-well-glow.png \
|
||||
back.svg \
|
||||
close.svg \
|
||||
close-black.svg \
|
||||
info.svg \
|
||||
magnifier.svg \
|
||||
remove-workspace.svg
|
||||
|
||||
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||
schema_DATA = gnome-shell.schemas
|
||||
|
@ -1,70 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="59.995201"
|
||||
height="59.995102"
|
||||
id="svg3113"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
version="1.0"
|
||||
sodipodi:docname="add-workspace.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3115">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3121" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="375"
|
||||
inkscape:cy="520"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="641"
|
||||
inkscape:window-height="683"
|
||||
inkscape:window-x="4"
|
||||
inkscape:window-y="54" />
|
||||
<metadata
|
||||
id="metadata3118">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-498.57383,-439.50749)">
|
||||
<path
|
||||
id="path3269"
|
||||
d="M 528.57143,439.91129 C 512.23433,439.91129 498.97763,453.16795 498.97763,469.50504 C 498.97763,485.84214 512.23433,499.09881 528.57143,499.09879 C 544.90853,499.09879 558.16513,485.84215 558.16523,469.50504 C 558.16523,453.16794 544.90853,439.9113 528.57143,439.91129 z M 525.29023,451.16129 L 531.88393,451.16129 C 533.75363,451.16129 535.25893,452.66659 535.25893,454.53629 L 535.25893,462.84879 L 543.54023,462.84879 C 545.40973,462.84879 546.91523,464.35409 546.91523,466.22379 L 546.91523,472.81754 C 546.91523,474.68728 545.40993,476.19255 543.54023,476.19254 L 535.25893,476.19254 L 535.25893,484.47379 C 535.25893,486.34353 533.75363,487.8488 531.88393,487.84879 L 525.29023,487.84879 C 523.42053,487.84881 521.91523,486.34351 521.91523,484.47379 L 521.91523,476.19254 L 513.60263,476.19254 C 511.73313,476.19257 510.22773,474.68726 510.22763,472.81754 L 510.22763,466.22379 C 510.22763,464.35407 511.73303,462.8488 513.60263,462.84879 L 521.91523,462.84879 L 521.91523,454.53629 C 521.91523,452.66657 523.42043,451.1613 525.29023,451.16129 z"
|
||||
style="opacity:0.30701785;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.807603px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
@ -73,6 +73,20 @@
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/autohide</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/autohide</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<locale name="C">
|
||||
<short>Whether the sidebar should automatically hide itself in compact mode</short>
|
||||
<long>
|
||||
Controls the autohide state of the sidebar.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/widgets</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/widgets</applyto>
|
||||
@ -88,6 +102,83 @@
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/disabled_extensions</key>
|
||||
<applyto>/desktop/gnome/shell/disabled_extensions</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>list</type>
|
||||
<list_type>string</list_type>
|
||||
<default>[]</default>
|
||||
<locale name="C">
|
||||
<short>Uuids of extensions to disable</short>
|
||||
<long>
|
||||
GNOME Shell extensions have a uuid property; this key lists extensions which should not be loaded.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/recorder/framerate</key>
|
||||
<applyto>/desktop/gnome/shell/recorder/framerate</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>15</default>
|
||||
<locale name="C">
|
||||
<short>Framerate used for recording screencasts.</short>
|
||||
<long>
|
||||
The framerate of the resulting screencast recordered by GNOME Shell's screencast recorder in frames-per-second.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/recorder/pipeline</key>
|
||||
<applyto>/desktop/gnome/shell/recorder/pipeline</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
<locale name="C">
|
||||
<short>The gstreamer pipeline used to encode the screencast</short>
|
||||
<long>
|
||||
Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch.
|
||||
The pipeline should have an unconnected sink pad where the recorded video is recorded. It will
|
||||
normally have a unconnected source pad; output from that pad will be written into the output file.
|
||||
However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar.
|
||||
When unset or set to an empty value, the default pipeline will be used. This is currently 'videorate ! theoraenc ! oggmux' and records to Ogg Theora.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/recorder/file_extension</key>
|
||||
<applyto>/desktop/gnome/shell/recorder/file_extension</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default>ogg</default>
|
||||
<locale name="C">
|
||||
<short>File extension used for storing the screencast</short>
|
||||
<long>
|
||||
The filename for recorded screencasts will be a unique filename based on the current date, and use this extension.
|
||||
It should be changed when recording to a different container format.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/overview/workspaces_view</key>
|
||||
<applyto>/desktop/gnome/shell/overview/workspaces_view</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default>single</default>
|
||||
<locale name="C">
|
||||
<short>Overview workspace view mode</short>
|
||||
<long>
|
||||
The selected workspace view mode in the overview.
|
||||
Supported values are "single" and "grid".
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
|
||||
</gconfschemafile>
|
||||
|
@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="info_16.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata2389"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs2387"><linearGradient
|
||||
id="linearGradient3710"><stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3712" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3714" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16 : 8 : 1"
|
||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||
id="perspective2391" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3710"
|
||||
id="linearGradient3716"
|
||||
x1="7.9066148"
|
||||
y1="15.937743"
|
||||
x2="7.9377432"
|
||||
y2="0.031128405"
|
||||
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
|
||||
inkscape:window-height="713"
|
||||
inkscape:window-width="722"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="32.125"
|
||||
inkscape:cx="8"
|
||||
inkscape:cy="8.154146"
|
||||
inkscape:window-x="20"
|
||||
inkscape:window-y="20"
|
||||
inkscape:current-layer="Foreground" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M7,3h2v2H7V3z M5.5,12H7V8H5.5V7H9v5h1.5v1h-5V12z M0,8c0-4.418,3.582-8,8-8 s8,3.582,8,8s-3.582,8-8,8S0,12.418,0,8z"
|
||||
id="path2384"
|
||||
style="fill-opacity:1;fill:url(#linearGradient3716)" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.5 KiB |
@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="59.995201"
|
||||
height="59.995102"
|
||||
id="svg3113"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
version="1.0"
|
||||
sodipodi:docname="remove-workspace.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3115">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3121" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.5"
|
||||
inkscape:cx="-8.1974244"
|
||||
inkscape:cy="38.948933"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1400"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="454"
|
||||
inkscape:window-y="105" />
|
||||
<metadata
|
||||
id="metadata3118">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-498.57383,-439.50749)">
|
||||
<path
|
||||
style="opacity:0.30701785;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.807603px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="M 30 0.40625 C 13.662899 0.40624999 0.40625 13.66291 0.40625 30 C 0.40624999 46.337101 13.6629 59.59377 30 59.59375 C 46.337099 59.593749 59.59365 46.33711 59.59375 30 C 59.59375 13.662901 46.3371 0.40626 30 0.40625 z M 15.03125 23.34375 L 44.96875 23.34375 C 46.83825 23.343751 48.34375 24.84905 48.34375 26.71875 L 48.34375 33.3125 C 48.34375 35.182239 46.83845 36.68751 44.96875 36.6875 L 15.03125 36.6875 C 13.16175 36.687529 11.65635 35.18222 11.65625 33.3125 L 11.65625 26.71875 C 11.65625 24.849031 13.16165 23.34376 15.03125 23.34375 z "
|
||||
transform="translate(498.57383,439.50749)"
|
||||
id="path2382" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.8 KiB |
98
data/theme/add-workspace.svg
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="23"
|
||||
height="15"
|
||||
id="svg6375"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="New document 13">
|
||||
<defs
|
||||
id="defs6377">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective6383" />
|
||||
<inkscape:perspective
|
||||
id="perspective6366"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6380">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-17)">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g6243"
|
||||
transform="translate(-986.28859,-658.2796)">
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="rect5318"
|
||||
width="22"
|
||||
height="14"
|
||||
x="986.89801"
|
||||
y="675.86743"
|
||||
rx="0.49999979"
|
||||
ry="0.5" />
|
||||
<g
|
||||
id="g5320"
|
||||
transform="translate(402.77304,-12.882544)">
|
||||
<path
|
||||
id="path5322"
|
||||
d="m 595.125,692.53048 0,6.43903"
|
||||
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
id="path5324"
|
||||
d="m 598.34451,695.75 -6.43902,0"
|
||||
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
76
data/theme/close-window.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.0"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="close-window.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata2399"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs2397"><linearGradient
|
||||
id="linearGradient3173"><stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3175" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3177" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16 : 8 : 1"
|
||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||
id="perspective2401" /></defs><sodipodi:namedview
|
||||
inkscape:window-height="999"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="1"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#000000"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="25.648691"
|
||||
inkscape:cx="8.8097603"
|
||||
inkscape:cy="9.0472789"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:current-layer="Foreground"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true" />
|
||||
|
||||
<g
|
||||
id="g3175"><path
|
||||
sodipodi:nodetypes="csssc"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.59217799;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2394"
|
||||
d="M 0.83987936,8.0425327 C 0.83987936,4.0805265 4.0712155,0.86823453 8.0567103,0.86823453 C 12.042205,0.86823453 15.273542,4.0805265 15.273542,8.0425327 C 15.273542,12.004539 12.042205,15.216831 8.0567103,15.216831 C 4.0712155,15.216831 0.83987936,12.004539 0.83987936,8.0425327 z"
|
||||
clip-rule="evenodd" /><g
|
||||
id="g3172"><path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 5.4242673,5.3313047 L 10.515414,10.421272 L 10.714004,10.646491"
|
||||
id="path3152" /></g></g><path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 5.4402527,10.650392 L 10.688082,5.3573033"
|
||||
id="path3154"
|
||||
sodipodi:nodetypes="cc" /></svg>
|
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
data/theme/corner-ripple.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
750
data/theme/gnome-shell.css
Normal file
@ -0,0 +1,750 @@
|
||||
/* Copyright 2009, Red Hat, Inc.
|
||||
*
|
||||
* Portions adapted from Mx's data/style/default.css
|
||||
* Copyright 2009 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU Lesser General Public License,
|
||||
* version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
.shell-link {
|
||||
color: #0000ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.shell-link:hover {
|
||||
color: #0000e0;
|
||||
}
|
||||
|
||||
.label-shadow {
|
||||
color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
StScrollBar
|
||||
{
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
StScrollView
|
||||
{
|
||||
scrollbar-width: 16px;
|
||||
scrollbar-height: 16px;
|
||||
}
|
||||
|
||||
StScrollView > .top-shadow
|
||||
{
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 0, 255);
|
||||
background-gradient-end: rgba(0, 0, 0, 0);
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
StScrollView > .bottom-shadow
|
||||
{
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 0, 0);
|
||||
background-gradient-end: rgba(0, 0, 0, 255);
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
StScrollBar {
|
||||
background-color: #080808;
|
||||
border: 1px solid #2d2d2d;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
StScrollBar StButton#vhandle
|
||||
{
|
||||
background-image: url("scroll-vhandle.svg");
|
||||
background-color: #252525;
|
||||
border: 1px solid #080808;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
StScrollBar StButton#hhandle
|
||||
{
|
||||
background-image: url("scroll-hhandle.svg");
|
||||
background-color: #252525;
|
||||
border: 1px solid #080808;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
StScrollBar StButton#hhandle:hover,
|
||||
StScrollBar StButton#vhandle:hover
|
||||
{
|
||||
background-color: #292929;
|
||||
}
|
||||
|
||||
StTooltip {
|
||||
border: 1px solid rgba(79,111,173,0.9);
|
||||
border-radius: 5px;
|
||||
padding: 4px;
|
||||
background-color: rgba(79,111,173,0.9);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Panel */
|
||||
|
||||
#panel {
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: #161616;
|
||||
background-gradient-end: #000000;
|
||||
border-bottom: 1px solid #1f1f1f;
|
||||
}
|
||||
|
||||
#panelLeft, #panelCenter, #panelRight {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#panelLeft {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
#panelRight {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
#appMenu {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.app-menu-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.panel-button {
|
||||
padding: 4px 12px 3px;
|
||||
border-radius: 5px;
|
||||
border-radius-bottomleft: 0px;
|
||||
border-radius-bottomright: 0px;
|
||||
font: 16px sans-serif;
|
||||
}
|
||||
|
||||
.panel-button:active, .panel-button:checked, .panel-button:pressed {
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: #3c3c3c;
|
||||
background-gradient-end: #131313;
|
||||
}
|
||||
|
||||
#panelActivities {
|
||||
border-radius-topleft: 0px;
|
||||
}
|
||||
|
||||
#panelStatus {
|
||||
border-radius-topright: 0px;
|
||||
}
|
||||
|
||||
#statusMenu {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
/* Overview */
|
||||
|
||||
.overview {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.info-bar {
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
spacing: 20px;
|
||||
}
|
||||
|
||||
.info-bar-link-button {
|
||||
background-color: #2d2d2d;
|
||||
padding: 2px 14px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #181818;
|
||||
}
|
||||
|
||||
.info-bar-link-button:hover {
|
||||
border: 1px solid #666666;
|
||||
}
|
||||
|
||||
.workspaces {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.workspaces.single {
|
||||
spacing: 25px;
|
||||
}
|
||||
|
||||
.workspaces.mosaic {
|
||||
spacing: 15px;
|
||||
}
|
||||
|
||||
.workspaces-bar {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.workspaces-bar, .workspaces-bar * {
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
.workspace-indicator {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
background: rgba(155,155,155,0.8);
|
||||
border-spacing: 16px;
|
||||
}
|
||||
|
||||
.workspace-indicator.active {
|
||||
background: rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
.window-caption {
|
||||
background: rgba(0,0,0,0.8);
|
||||
border: 1px solid rgba(128,128,128,0.40);
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
-shell-caption-spacing: 4px;
|
||||
}
|
||||
|
||||
.window-close {
|
||||
background-image: url("close-window.svg");
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
-st-shadow: -2px 2px 6px rgba(0,0,0,0.5);
|
||||
-shell-close-overlap: 16px;
|
||||
}
|
||||
|
||||
.single-view-controls {
|
||||
padding: 0px 15px;
|
||||
}
|
||||
|
||||
.workspace-controls {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.workspace-controls.add {
|
||||
background-image: url("add-workspace.svg");
|
||||
}
|
||||
|
||||
.workspace-controls.remove {
|
||||
background-image: url("remove-workspace.svg");
|
||||
}
|
||||
|
||||
.workspace-controls.switch-single {
|
||||
background-image: url("single-view.svg");
|
||||
}
|
||||
|
||||
.workspace-controls.switch-mosaic {
|
||||
background-image: url("mosaic-view.svg");
|
||||
}
|
||||
|
||||
.workspace-controls.switch-single:checked {
|
||||
background-image: url("single-view-active.svg");
|
||||
}
|
||||
|
||||
.workspace-controls.switch-mosaic:checked {
|
||||
background-image: url("mosaic-view-active.svg");
|
||||
}
|
||||
|
||||
#SwitchScroll {
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
#SwitchScroll #hhandle {
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
/* Dash */
|
||||
|
||||
#dash {
|
||||
color: #5f5f5f;
|
||||
font-size: 12px;
|
||||
padding: 0px 14px;
|
||||
}
|
||||
|
||||
#dashSections {
|
||||
spacing: 12px;
|
||||
}
|
||||
|
||||
#searchEntry {
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid #262626;
|
||||
}
|
||||
|
||||
#searchEntry:active {
|
||||
background-color: #c4c4c4;
|
||||
}
|
||||
|
||||
.dash-section {
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
}
|
||||
|
||||
.section-header-inner {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.section-text-content {
|
||||
padding: 4px 0px;
|
||||
}
|
||||
|
||||
.section-header-back {
|
||||
padding: 0px 4px 0px 0px;
|
||||
border-right: 1px solid #262626;
|
||||
}
|
||||
|
||||
.section-header-back-image {
|
||||
background-image: url("section-back.svg");
|
||||
width: 12px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.section-count {
|
||||
}
|
||||
|
||||
.dash-section-content {
|
||||
color: #ffffff;
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
.more-link {
|
||||
}
|
||||
|
||||
.more-link-expander {
|
||||
background-image: url("section-more.svg");
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.more-link-expander.open {
|
||||
background-image: url("section-more-open.svg");
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.dash-pane {
|
||||
background-color: rgba(0,0,0,0.95);
|
||||
border: 1px solid #262626;
|
||||
padding: 4px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.dash-pane-close {
|
||||
background-image: url("close.svg");
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.dash-search-section-header {
|
||||
padding: 6px 0px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.dash-search-section-results {
|
||||
color: #ffffff;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.dash-search-section-list-results {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.dash-search-result-content {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.dash-search-result-content:selected {
|
||||
padding: 2px;
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 2px;
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
/* GenericDisplay */
|
||||
|
||||
.generic-display-container {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.generic-display-item {
|
||||
height: 50px;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.generic-display-item:selected {
|
||||
background-color: rgba(79,111,173,0.66);
|
||||
}
|
||||
|
||||
.generic-display-item-text {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.generic-display-item-description {
|
||||
font-size: 12px;
|
||||
color: #bababa;
|
||||
}
|
||||
|
||||
.generic-display-details {
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.generic-display-details-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Apps */
|
||||
|
||||
.overview-pane {
|
||||
width: 440px;
|
||||
}
|
||||
|
||||
#dashAppWell {
|
||||
spacing: 6px;
|
||||
-shell-grid-item-size: 70px;
|
||||
}
|
||||
|
||||
.all-app {
|
||||
border-radius: 10px;
|
||||
background-color: rgba(0,0,0,0.95);
|
||||
border: 1px solid #262626;
|
||||
color: #ffffff;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.all-app-controls-panel {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.all-app-scroll-view {
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.app-well-app {
|
||||
border: 1px solid #181818;
|
||||
border-radius: 4px;
|
||||
padding: 2px;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.app-well-app.running {
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: #3d3d3d;
|
||||
background-gradient-end: #181818;
|
||||
}
|
||||
|
||||
.app-well-app:hover {
|
||||
border: 1px solid #666666;
|
||||
}
|
||||
|
||||
.app-well-app:active {
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #5f5f5f;
|
||||
}
|
||||
|
||||
.app-well-menu {
|
||||
border: 1px solid #5f5f5f;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
color: #ffffff;
|
||||
-shell-arrow-width: 12px;
|
||||
-shell-menu-spacing: 4px;
|
||||
}
|
||||
|
||||
.app-well-menu-item:hover {
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
.app-well-menu-separator {
|
||||
padding-top: 1px;
|
||||
border-bottom: 1px solid #5f5f5f;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
/* Places */
|
||||
|
||||
.places-actions {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#placesDevices {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
/* LookingGlass */
|
||||
|
||||
#LookingGlassDialog
|
||||
{
|
||||
background-color: rgba(0,0,0,0.85);
|
||||
spacing: 4px;
|
||||
padding: 4px;
|
||||
border: 1px solid rgba(0,0,172,0.85);
|
||||
border-radius: 4px;
|
||||
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
#LookingGlassDialog > #Toolbar
|
||||
{
|
||||
border: 1px solid grey;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog .labels {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog .notebook-tab {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog .notebook-tab:selected {
|
||||
border: 1px solid #88ff66;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StLabel
|
||||
{
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StEntry
|
||||
{
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StBoxLayout#EvalBox
|
||||
{
|
||||
padding: 4px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#lookingGlassExtensions {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.lg-extension-list {
|
||||
padding: 4px;
|
||||
spacing: 6px;
|
||||
}
|
||||
|
||||
.lg-extension {
|
||||
border: 1px solid #6f6f6f;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.lg-extension-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lg-extension-actions {
|
||||
spacing: 6px;
|
||||
}
|
||||
|
||||
/* Calendar popup */
|
||||
|
||||
#calendarPopup {
|
||||
border-radius: 5px;
|
||||
background: rgba(0,0,0,0.9);
|
||||
border: 1px solid rgba(128,128,128,0.45);
|
||||
color: white;
|
||||
}
|
||||
|
||||
#calendarPopup .calendar {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.calendar {
|
||||
spacing-rows: 5px;
|
||||
spacing-columns: 3px;
|
||||
}
|
||||
|
||||
.calendar-change-month {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.calendar-change-month:hover {
|
||||
background: #314a6c;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.calendar-change-month:active {
|
||||
background: #213050;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.calendar-day {
|
||||
padding: 1px 2px;
|
||||
}
|
||||
|
||||
.calendar-today {
|
||||
font-weight: bold;
|
||||
background: #ffffff;
|
||||
color: black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.calendar-other-month-day {
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
/* Message Tray */
|
||||
#message-tray {
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0,0,0,0.01);
|
||||
background-gradient-end: rgba(0,0,0,0.95);
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
#notification {
|
||||
font-size: 16px;
|
||||
border-radius: 5px;
|
||||
background: rgba(0,0,0,0.9);
|
||||
color: white;
|
||||
padding: 2px 10px 10px 10px;
|
||||
spacing-rows: 5px;
|
||||
spacing-columns: 10px;
|
||||
max-width: 40em;
|
||||
}
|
||||
|
||||
#notification-actions {
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
.notification-button {
|
||||
border: 2px rgba(0,0,0,0.0);
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
background: #c0c0c0;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notification-button:hover {
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
.notification-button:active {
|
||||
border: 2px solid white;
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
#summary-mode {
|
||||
spacing: 10px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
/* App Switcher */
|
||||
.switcher-list {
|
||||
background: rgba(0,0,0,0.8);
|
||||
border: 1px solid rgba(128,128,128,0.40);
|
||||
border-radius: 8px;
|
||||
padding: 18px;
|
||||
|
||||
font: 12px sans-serif;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.switcher-list .item-box {
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.switcher-list .thumbnail-box {
|
||||
padding: 2px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.switcher-list .thumbnail {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
}
|
||||
|
||||
.switcher-list .outlined-item-box {
|
||||
padding: 6px;
|
||||
border: 2px solid rgba(85,85,85,1.0);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.switcher-list .selected-item-box {
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background: rgba(255,255,255,0.33);
|
||||
}
|
||||
|
||||
.switcher-list .separator {
|
||||
width: 1px;
|
||||
background: rgba(255,255,255,0.33);
|
||||
}
|
||||
|
||||
.ripple-box {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
background-image: url("corner-ripple.png");
|
||||
}
|
||||
|
||||
/* Workspace Switcher */
|
||||
.workspace-switcher-container {
|
||||
background: rgba(0,0,0,0.8);
|
||||
border: 1px solid rgba(128,128,128,0.40);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.workspace-switcher {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.ws-switcher-active-left {
|
||||
height: 98px;
|
||||
border: 0px;
|
||||
background: rgba(255,255,255,0.5);
|
||||
background-image: url("ws-switch-arrow-left.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ws-switcher-active-right {
|
||||
height: 98px;
|
||||
border: 0px;
|
||||
background: rgba(255,255,255,0.5);
|
||||
background-image: url("ws-switch-arrow-right.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ws-switcher-spacer {
|
||||
width: 0.5px;
|
||||
height: 96px;
|
||||
border: 0px;
|
||||
background: transparent;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.ws-switcher-box {
|
||||
height: 96px;
|
||||
border: 2px solid rgba(85,85,85,0.5);
|
||||
background: transparent;
|
||||
border-radius: 4px;
|
||||
}
|
113
data/theme/mosaic-view-active.svg
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="16"
|
||||
id="svg6503"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="mosaic-view-active.svg">
|
||||
<defs
|
||||
id="defs6505">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective6511" />
|
||||
<inkscape:perspective
|
||||
id="perspective6494"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="-15.97056"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6508">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-16)">
|
||||
<g
|
||||
style="display:inline;fill:#cbcbcb;fill-opacity:1"
|
||||
transform="translate(-449.85476,-685.85869)"
|
||||
id="g5306">
|
||||
<rect
|
||||
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none"
|
||||
id="rect5308"
|
||||
width="11"
|
||||
height="7"
|
||||
x="450.5"
|
||||
y="710.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||
id="rect5310"
|
||||
width="11"
|
||||
height="7"
|
||||
x="462.5"
|
||||
y="702.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999976000000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||
id="rect5312"
|
||||
width="11"
|
||||
height="7"
|
||||
x="450.5"
|
||||
y="702.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||
id="rect5314"
|
||||
width="11"
|
||||
height="7"
|
||||
x="462.5"
|
||||
y="710.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
113
data/theme/mosaic-view.svg
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="16"
|
||||
id="svg6503"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="New document 19">
|
||||
<defs
|
||||
id="defs6505">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective6511" />
|
||||
<inkscape:perspective
|
||||
id="perspective6494"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6508">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-16)">
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="translate(-449.85476,-685.85869)"
|
||||
id="g5306">
|
||||
<rect
|
||||
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none"
|
||||
id="rect5308"
|
||||
width="11"
|
||||
height="7"
|
||||
x="450.5"
|
||||
y="710.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||
id="rect5310"
|
||||
width="11"
|
||||
height="7"
|
||||
x="462.5"
|
||||
y="702.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||
id="rect5312"
|
||||
width="11"
|
||||
height="7"
|
||||
x="450.5"
|
||||
y="702.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
<rect
|
||||
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||
id="rect5314"
|
||||
width="11"
|
||||
height="7"
|
||||
x="462.5"
|
||||
y="710.5"
|
||||
rx="0.99999958"
|
||||
ry="1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
92
data/theme/remove-workspace.svg
Normal file
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="23"
|
||||
height="15"
|
||||
id="svg5501"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="add-workspace.svg">
|
||||
<defs
|
||||
id="defs5503">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective5509" />
|
||||
<inkscape:perspective
|
||||
id="perspective5314"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="-0.074583208"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-bbox="true" />
|
||||
<metadata
|
||||
id="metadata5506">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-17)">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g6239"
|
||||
transform="translate(-953.97989,-657.32287)">
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="rect5318-6"
|
||||
width="22"
|
||||
height="14"
|
||||
x="954.5"
|
||||
y="675"
|
||||
rx="0.49999979"
|
||||
ry="0.5" />
|
||||
<path
|
||||
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
d="m 968.71951,682 -6.43902,0"
|
||||
id="path5324-5" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
BIN
data/theme/scroll-button-down-hover.png
Normal file
After Width: | Height: | Size: 225 B |
BIN
data/theme/scroll-button-down.png
Normal file
After Width: | Height: | Size: 225 B |
BIN
data/theme/scroll-button-up-hover.png
Normal file
After Width: | Height: | Size: 211 B |
BIN
data/theme/scroll-button-up.png
Normal file
After Width: | Height: | Size: 211 B |
64
data/theme/scroll-hhandle.svg
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="10"
|
||||
height="4"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="scroll-hhandle.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="rect3592"
|
||||
width="2"
|
||||
height="4"
|
||||
x="0"
|
||||
y="0"
|
||||
rx="0"
|
||||
ry="0" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#rect3592"
|
||||
id="use2825"
|
||||
transform="translate(8,0)"
|
||||
width="10"
|
||||
height="4" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#use2825"
|
||||
id="use2827"
|
||||
transform="translate(-4,0)"
|
||||
width="10"
|
||||
height="4" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
62
data/theme/scroll-vhandle.svg
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="4"
|
||||
height="10"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="scroll-hhandle.svg">
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="rect3592"
|
||||
width="2"
|
||||
height="4"
|
||||
x="0"
|
||||
y="-4"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(0,1,-1,0,0,0)" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#rect3592"
|
||||
id="use3705"
|
||||
transform="translate(0,4)"
|
||||
width="4"
|
||||
height="10" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#use3705"
|
||||
id="use3707"
|
||||
transform="translate(0,4)"
|
||||
width="4"
|
||||
height="10" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
87
data/theme/section-more-open.svg
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="5.8600588"
|
||||
height="9"
|
||||
id="svg3647"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="section-more.svg">
|
||||
<defs
|
||||
id="defs3649">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3655" />
|
||||
<inkscape:perspective
|
||||
id="perspective3603"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="82.777778"
|
||||
inkscape:cx="2.9300294"
|
||||
inkscape:cy="5.466443"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3652">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-262.78425,-490.71933)">
|
||||
<path
|
||||
transform="matrix(0,-0.98149546,0.71467449,0,25.404986,578.15569)"
|
||||
d="M 88.830127,340 80.169873,340 84.5,332.5 88.830127,340 z"
|
||||
inkscape:randomized="0"
|
||||
inkscape:rounded="0"
|
||||
inkscape:flatsided="true"
|
||||
sodipodi:arg2="1.5707963"
|
||||
sodipodi:arg1="0.52359878"
|
||||
sodipodi:r2="2.5"
|
||||
sodipodi:r1="5"
|
||||
sodipodi:cy="337.5"
|
||||
sodipodi:cx="84.5"
|
||||
sodipodi:sides="3"
|
||||
id="path5497-5"
|
||||
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.59699643;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
sodipodi:type="star" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
87
data/theme/section-more.svg
Executable file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="5.8600588"
|
||||
height="9"
|
||||
id="svg3647"
|
||||
version="1.1"
|
||||
inkscape:version="0.46+devel"
|
||||
sodipodi:docname="New document 6">
|
||||
<defs
|
||||
id="defs3649">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3655" />
|
||||
<inkscape:perspective
|
||||
id="perspective3603"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="112.21575"
|
||||
inkscape:cy="-32.642856"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="609"
|
||||
inkscape:window-height="501"
|
||||
inkscape:window-x="164"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3652">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-262.78425,-490.71933)">
|
||||
<path
|
||||
transform="matrix(0,0.98149546,-0.71467449,0,506.02358,412.28296)"
|
||||
d="M 88.830127,340 80.169873,340 84.5,332.5 88.830127,340 z"
|
||||
inkscape:randomized="0"
|
||||
inkscape:rounded="0"
|
||||
inkscape:flatsided="true"
|
||||
sodipodi:arg2="1.5707963"
|
||||
sodipodi:arg1="0.52359878"
|
||||
sodipodi:r2="2.5"
|
||||
sodipodi:r1="5"
|
||||
sodipodi:cy="337.5"
|
||||
sodipodi:cx="84.5"
|
||||
sodipodi:sides="3"
|
||||
id="path5497-5"
|
||||
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.59699643;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
sodipodi:type="star" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
81
data/theme/single-view-active.svg
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="16"
|
||||
id="svg6446"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="single-view-active.svg">
|
||||
<defs
|
||||
id="defs6448">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective6454" />
|
||||
<inkscape:perspective
|
||||
id="perspective6441"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="0.014720032"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6451">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-17)">
|
||||
<rect
|
||||
ry="0.5"
|
||||
rx="0.49999979"
|
||||
y="17.483809"
|
||||
x="0.53483802"
|
||||
height="15"
|
||||
width="23"
|
||||
id="rect5304"
|
||||
style="fill:#cccccc;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
81
data/theme/single-view.svg
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="16"
|
||||
id="svg6446"
|
||||
version="1.1"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="single-view.svg">
|
||||
<defs
|
||||
id="defs6448">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective6454" />
|
||||
<inkscape:perspective
|
||||
id="perspective6441"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="0.014720032"
|
||||
inkscape:cy="16"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6451">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-17)">
|
||||
<rect
|
||||
ry="0.5"
|
||||
rx="0.49999979"
|
||||
y="17.483809"
|
||||
x="0.53483802"
|
||||
height="15"
|
||||
width="23"
|
||||
id="rect5304"
|
||||
style="fill:#626262;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
96
data/theme/ws-switch-arrow-left.svg
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="96" height="96" id="svg25070" version="1.1" inkscape:version="0.47 r22583" sodipodi:docname="dark-arrow-larger.svg">
|
||||
<defs id="defs25072">
|
||||
<inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 24 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="48 : 24 : 1" inkscape:persp3d-origin="24 : 16 : 1" id="perspective25078"/>
|
||||
<inkscape:perspective id="perspective24985" inkscape:persp3d-origin="0.5 : 0.33333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d"/>
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4034-0-4" id="linearGradient24957" gradientUnits="userSpaceOnUse" gradientTransform="translate(6)" x1="-86.552246" y1="185.439" x2="-83.37072" y2="197.31261"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4034-0-4">
|
||||
<stop style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" offset="0" id="stop4036-5-7"/>
|
||||
<stop style="stop-color: rgb(186, 189, 182); stop-opacity: 1;" offset="1" id="stop4038-9-6"/>
|
||||
</linearGradient>
|
||||
<filter id="filter24765" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix24767" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix24769" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4632-1-3-9-3-2" id="linearGradient24955" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5)" x1="-74.520325" y1="169.06032" x2="-74.520325" y2="205.94189"/>
|
||||
<linearGradient id="linearGradient4632-1-3-9-3-2">
|
||||
<stop style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" offset="0" id="stop4634-1-8-3-9-0"/>
|
||||
<stop id="stop4636-1-9-9-8-8" offset="0.0274937" style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"/>
|
||||
<stop id="stop4638-8-3-9-6-6" offset="0.274937" style="stop-color: rgb(242, 242, 242); stop-opacity: 1;"/>
|
||||
<stop id="stop4640-8-5-7-8-9" offset="0.38707438" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||
<stop id="stop4642-5-41-9-6-9" offset="0.66528589" style="stop-color: rgb(217, 218, 216); stop-opacity: 1;"/>
|
||||
<stop id="stop4644-5-2-7-9-2" offset="0.76745707" style="stop-color: rgb(223, 224, 221); stop-opacity: 1;"/>
|
||||
<stop style="stop-color: rgb(240, 240, 240); stop-opacity: 1;" offset="1" id="stop4646-3-2-3-7-3"/>
|
||||
</linearGradient>
|
||||
<radialGradient inkscape:collect="always" xlink:href="#linearGradient4869-4-1" id="radialGradient24959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)" cx="-33.412369" cy="185.74171" fx="-33.412369" fy="185.74171" r="2.3554697"/>
|
||||
<linearGradient id="linearGradient4869-4-1">
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4871-6-2"/>
|
||||
<stop id="stop4879-7-4" offset="0.31807542" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||
<stop id="stop4877-6-1" offset="0.74691135" style="stop-color: rgb(200, 201, 198); stop-opacity: 1;"/>
|
||||
<stop style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" offset="1" id="stop4873-1-0"/>
|
||||
</linearGradient>
|
||||
<filter id="filter25011" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25013" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25015" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<radialGradient inkscape:collect="always" xlink:href="#linearGradient4869-4-0" id="radialGradient24961" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)" cx="-33.412369" cy="185.74171" fx="-33.412369" fy="185.74171" r="2.3554697"/>
|
||||
<linearGradient id="linearGradient4869-4-0">
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4871-6-8"/>
|
||||
<stop id="stop4879-7-5" offset="0.31807542" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||
<stop id="stop4877-6-5" offset="0.74691135" style="stop-color: rgb(200, 201, 198); stop-opacity: 1;"/>
|
||||
<stop style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" offset="1" id="stop4873-1-4"/>
|
||||
</linearGradient>
|
||||
<filter id="filter25023" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25025" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25027" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4941" id="linearGradient24963" gradientUnits="userSpaceOnUse" x1="-39.858727" y1="184.61784" x2="-38.244785" y2="188.84898"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4941">
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4943"/>
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1" id="stop4945"/>
|
||||
</linearGradient>
|
||||
<filter id="filter25033" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25035" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25037" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4941-7" id="linearGradient24965" gradientUnits="userSpaceOnUse" x1="-39.858727" y1="184.61784" x2="-38.244785" y2="188.84898"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4941-7">
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4943-2"/>
|
||||
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1" id="stop4945-5"/>
|
||||
</linearGradient>
|
||||
<filter id="filter25043" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25045" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25047" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<filter id="filter25049" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25051" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25053" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<filter id="filter25055" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||
<feColorMatrix id="feColorMatrix25057" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||
<feColorMatrix id="feColorMatrix25059" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" inkscape:cx="48.631638" inkscape:cy="57.536221" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" inkscape:window-width="1200" inkscape:window-height="851" inkscape:window-x="0" inkscape:window-y="52" inkscape:window-maximized="0"/>
|
||||
<metadata id="metadata25075">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(0, 48)">
|
||||
<g id="g4030-1-8" transform="matrix(2, 0, 0, 2, 193.25, -374.967)" style="stroke: rgb(0, 0, 0); display: inline; stroke-opacity: 1;">
|
||||
<path sodipodi:nodetypes="ccc" id="path3165-7-3" d="m -72.5,173.5 -14,14 14,14" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 7; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;"/>
|
||||
</g>
|
||||
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; stroke: none; stroke-width: 0.523439; visibility: visible; display: inline;" id="path4050-2-7-9-4" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(3.34328, 0, 0, 3.34328, 185.28, -623.176)"/>
|
||||
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; stroke: none; stroke-width: 0.523439; visibility: visible; display: inline;" id="path4050-2-7-9-4-8" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(3.34328, 0, 0, 3.34328, 207.28, -623.176)"/>
|
||||
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 0.697921; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;" id="path4050-2-7-9-4-0" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(2.86565, 0, 0, 2.86565, 166.846, -534.143)"/>
|
||||
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 0.697921; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;" id="path4050-2-7-9-4-0-9" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(2.86565, 0, 0, 2.86565, 188.846, -534.143)"/>
|
||||
<path style="overflow: visible; marker: none; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; text-indent: 0pt; text-align: start; text-decoration: none; line-height: normal; letter-spacing: normal; word-spacing: normal; text-transform: none; direction: ltr; text-anchor: start; opacity: 0.35; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 1; stroke-miterlimit: 4; stroke-dasharray: none; visibility: visible; display: inline; font-family: Bitstream Vera Sans; stroke-opacity: 1;" d="m 317.06251,365.96875 c -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 l -16.125,16.125 16.125,16.125 c 1.11265,1.11265 3.13735,1.11265 4.25,0 1.11265,-1.11264 1.11265,-3.13735 0,-4.25 l -11.875,-11.875 11.875,-11.875 c 0.86584,-0.83655 1.1475,-2.22114 0.6773,-3.32947 -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 z" id="path3165-7-3-1" sodipodi:nodetypes="ccccscccsc" transform="matrix(2, 0, 0, 2, -586, -765.967)"/>
|
||||
<path style="overflow: visible; marker: none; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; text-indent: 0pt; text-align: start; text-decoration: none; line-height: normal; letter-spacing: normal; word-spacing: normal; text-transform: none; direction: ltr; text-anchor: start; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 1; stroke-linecap: round; stroke-miterlimit: 4; stroke-dasharray: none; visibility: visible; display: inline; font-family: Bitstream Vera Sans; stroke-opacity: 1;" d="m 320.08435,397.03059 c 0.007,-0.79449 -0.27079,-1.59203 -0.83434,-2.15559 L 307.37501,383 m 12.5523,-15.20447 c -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 L 298.87501,383" id="path3165-7-3-1-9" sodipodi:nodetypes="ccccccc" transform="matrix(2, 0, 0, 2, -586, -765.967)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
331
data/theme/ws-switch-arrow-right.svg
Normal file
@ -0,0 +1,331 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
width="96"
|
||||
height="96"
|
||||
id="svg25070">
|
||||
<defs
|
||||
id="defs25072">
|
||||
<linearGradient
|
||||
x1="-86.552246"
|
||||
y1="185.439"
|
||||
x2="-83.37072"
|
||||
y2="197.31261"
|
||||
id="linearGradient24957"
|
||||
xlink:href="#linearGradient4034-0-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(6,0)" />
|
||||
<linearGradient
|
||||
id="linearGradient4034-0-4">
|
||||
<stop
|
||||
id="stop4036-5-7"
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4038-9-6"
|
||||
style="stop-color:#babdb6;stop-opacity:1"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter24765">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix24767" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix24769" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="-74.520325"
|
||||
y1="169.06032"
|
||||
x2="-74.520325"
|
||||
y2="205.94189"
|
||||
id="linearGradient24955"
|
||||
xlink:href="#linearGradient4632-1-3-9-3-2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-5,0)" />
|
||||
<linearGradient
|
||||
id="linearGradient4632-1-3-9-3-2">
|
||||
<stop
|
||||
id="stop4634-1-8-3-9-0"
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4636-1-9-9-8-8"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0.0274937" />
|
||||
<stop
|
||||
id="stop4638-8-3-9-6-6"
|
||||
style="stop-color:#f2f2f2;stop-opacity:1"
|
||||
offset="0.274937" />
|
||||
<stop
|
||||
id="stop4640-8-5-7-8-9"
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="0.38707438" />
|
||||
<stop
|
||||
id="stop4642-5-41-9-6-9"
|
||||
style="stop-color:#d9dad8;stop-opacity:1"
|
||||
offset="0.66528589" />
|
||||
<stop
|
||||
id="stop4644-5-2-7-9-2"
|
||||
style="stop-color:#dfe0dd;stop-opacity:1"
|
||||
offset="0.76745707" />
|
||||
<stop
|
||||
id="stop4646-3-2-3-7-3"
|
||||
style="stop-color:#f0f0f0;stop-opacity:1"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="-33.412369"
|
||||
cy="185.74171"
|
||||
r="2.3554697"
|
||||
fx="-33.412369"
|
||||
fy="185.74171"
|
||||
id="radialGradient24959"
|
||||
xlink:href="#linearGradient4869-4-1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
|
||||
<linearGradient
|
||||
id="linearGradient4869-4-1">
|
||||
<stop
|
||||
id="stop4871-6-2"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4879-7-4"
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="0.31807542" />
|
||||
<stop
|
||||
id="stop4877-6-1"
|
||||
style="stop-color:#c8c9c6;stop-opacity:1"
|
||||
offset="0.74691135" />
|
||||
<stop
|
||||
id="stop4873-1-0"
|
||||
style="stop-color:#d3d7cf;stop-opacity:1"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25011">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25013" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25015" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
cx="-33.412369"
|
||||
cy="185.74171"
|
||||
r="2.3554697"
|
||||
fx="-33.412369"
|
||||
fy="185.74171"
|
||||
id="radialGradient24961"
|
||||
xlink:href="#linearGradient4869-4-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
|
||||
<linearGradient
|
||||
id="linearGradient4869-4-0">
|
||||
<stop
|
||||
id="stop4871-6-8"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4879-7-5"
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="0.31807542" />
|
||||
<stop
|
||||
id="stop4877-6-5"
|
||||
style="stop-color:#c8c9c6;stop-opacity:1"
|
||||
offset="0.74691135" />
|
||||
<stop
|
||||
id="stop4873-1-4"
|
||||
style="stop-color:#d3d7cf;stop-opacity:1"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25023">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25025" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25027" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="-39.858727"
|
||||
y1="184.61784"
|
||||
x2="-38.244785"
|
||||
y2="188.84898"
|
||||
id="linearGradient24963"
|
||||
xlink:href="#linearGradient4941"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient4941">
|
||||
<stop
|
||||
id="stop4943"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4945"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25033">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25035" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25037" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="-39.858727"
|
||||
y1="184.61784"
|
||||
x2="-38.244785"
|
||||
y2="188.84898"
|
||||
id="linearGradient24965"
|
||||
xlink:href="#linearGradient4941-7"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient4941-7">
|
||||
<stop
|
||||
id="stop4943-2"
|
||||
style="stop-color:#ffffff;stop-opacity:1"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4945-5"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25043">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25045" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25047" />
|
||||
</filter>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25049">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25051" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25053" />
|
||||
</filter>
|
||||
<filter
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
color-interpolation-filters="sRGB"
|
||||
id="filter25055">
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphic"
|
||||
values="1"
|
||||
type="saturate"
|
||||
id="feColorMatrix25057" />
|
||||
<feColorMatrix
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||
in="fbSourceGraphic"
|
||||
id="feColorMatrix25059" />
|
||||
</filter>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(0,48)"
|
||||
id="layer1">
|
||||
<g
|
||||
transform="matrix(-2,0,0,2,-97.2497,-374.967)"
|
||||
id="g4030-1-8"
|
||||
style="stroke:#000000;stroke-opacity:1;display:inline">
|
||||
<path
|
||||
d="m -72.5,173.5 -14,14 14,14"
|
||||
id="path3165-7-3"
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:7;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||
</g>
|
||||
<path
|
||||
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||
transform="matrix(-3.34328,0,0,3.34328,-89.2797,-623.176)"
|
||||
id="path4050-2-7-9-4"
|
||||
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||
transform="matrix(-3.34328,0,0,3.34328,-111.2797,-623.176)"
|
||||
id="path4050-2-7-9-4-8"
|
||||
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||
transform="matrix(-2.86565,0,0,2.86565,-70.8457,-534.143)"
|
||||
id="path4050-2-7-9-4-0"
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||
transform="matrix(-2.86565,0,0,2.86565,-92.8457,-534.143)"
|
||||
id="path4050-2-7-9-4-0-9"
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
d="m 47.87528,-34.0295 c 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25 -32.25,32.25 c -2.2253,2.2253 -6.2747,2.2253 -8.5,0 -2.2253,-2.22528 -2.2253,-6.2747 0,-8.5 l 23.75,-23.75 -23.75,-23.75 c -1.73168,-1.6731 -2.295,-4.44228 -1.3546,-6.65894 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 z"
|
||||
id="path3165-7-3-1"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;opacity:0.35;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
|
||||
<path
|
||||
d="m 41.8316,28.09418 c -0.014,-1.58898 0.54158,-3.18406 1.66868,-4.31118 l 23.75,-23.75 m -25.1046,-30.40894 c 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25"
|
||||
id="path3165-7-3-1-9"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
@ -1,4 +1,6 @@
|
||||
jsmiscdir = $(pkgdatadir)/js/misc
|
||||
|
||||
dist_jsmisc_DATA = \
|
||||
docInfo.js
|
||||
docInfo.js \
|
||||
format.js \
|
||||
params.js
|
||||
|
@ -7,6 +7,7 @@ const Shell = imports.gi.Shell;
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Search = imports.ui.search;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const THUMBNAIL_ICON_MARGIN = 2;
|
||||
@ -17,69 +18,43 @@ function DocInfo(recentInfo) {
|
||||
|
||||
DocInfo.prototype = {
|
||||
_init : function(recentInfo) {
|
||||
this._recentInfo = recentInfo;
|
||||
this.recentInfo = recentInfo;
|
||||
// We actually used get_modified() instead of get_visited()
|
||||
// here, as GtkRecentInfo doesn't updated get_visited()
|
||||
// correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
|
||||
this.timestamp = recentInfo.get_modified().getTime() / 1000;
|
||||
this.name = recentInfo.get_display_name();
|
||||
this._lowerName = this.name.toLowerCase();
|
||||
this.uri = recentInfo.get_uri();
|
||||
this.mimeType = recentInfo.get_mime_type();
|
||||
},
|
||||
|
||||
createIcon : function(size) {
|
||||
return Shell.TextureCache.get_default().load_recent_thumbnail(size, this._recentInfo);
|
||||
return Shell.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
|
||||
},
|
||||
|
||||
launch : function() {
|
||||
// While using Gio.app_info_launch_default_for_uri() would be
|
||||
// shorter in terms of lines of code, we are not doing so
|
||||
// because that would duplicate the work of retrieving the
|
||||
// mime type.
|
||||
|
||||
let appInfo = Gio.app_info_get_default_for_type(this.mimeType, true);
|
||||
|
||||
if (appInfo != null) {
|
||||
appInfo.launch_uris([this.uri], Main.createAppLaunchContext());
|
||||
} else {
|
||||
log("Failed to get default application info for mime type " + this.mimeType +
|
||||
". Will try to use the last application that registered the document.");
|
||||
let appName = this._recentInfo.last_application();
|
||||
let [success, appExec, count, time] = this._recentInfo.get_application_info(appName);
|
||||
if (success) {
|
||||
log("Will open a document with the following command: " + appExec);
|
||||
// TODO: Change this once better support for creating
|
||||
// GAppInfo is added to GtkRecentInfo, as right now
|
||||
// this relies on the fact that the file uri is
|
||||
// already a part of appExec, so we don't supply any
|
||||
// files to appInfo.launch().
|
||||
|
||||
// The 'command line' passed to
|
||||
// create_from_command_line is allowed to contain
|
||||
// '%<something>' macros that are expanded to file
|
||||
// name / icon name, etc, so we need to escape % as %%
|
||||
appExec = appExec.replace(/%/g, "%%");
|
||||
|
||||
let appInfo = Gio.app_info_create_from_commandline(appExec, null, 0, null);
|
||||
|
||||
// The point of passing an app launch context to
|
||||
// launch() is mostly to get startup notification and
|
||||
// associated benefits like the app appearing on the
|
||||
// right desktop; but it doesn't really work for now
|
||||
// because with the way we create the appInfo we
|
||||
// aren't reading the application's desktop file, and
|
||||
// thus don't find the StartupNotify=true in it. So,
|
||||
// despite passing the app launch context, no startup
|
||||
// notification occurs.
|
||||
appInfo.launch([], Main.createAppLaunchContext());
|
||||
} else {
|
||||
log("Failed to get application info for " + this.uri);
|
||||
}
|
||||
}
|
||||
Shell.DocSystem.get_default().open(this.recentInfo);
|
||||
},
|
||||
|
||||
exists : function() {
|
||||
return this._recentInfo.exists();
|
||||
matchTerms: function(terms) {
|
||||
let mtype = Search.MatchType.NONE;
|
||||
for (let i = 0; i < terms.length; i++) {
|
||||
let term = terms[i];
|
||||
let idx = this._lowerName.indexOf(term);
|
||||
if (idx == 0) {
|
||||
if (mtype != Search.MatchType.NONE)
|
||||
return Search.MatchType.MULTIPLE;
|
||||
mtype = Search.MatchType.PREFIX;
|
||||
} else if (idx > 0) {
|
||||
if (mtype != Search.MatchType.NONE)
|
||||
return Search.MatchType.MULTIPLE;
|
||||
mtype = Search.MatchType.SUBSTRING;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return mtype;
|
||||
}
|
||||
};
|
||||
|
||||
@ -91,50 +66,86 @@ function getDocManager() {
|
||||
return docManagerInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* DocManager wraps the DocSystem, primarily to expose DocInfo objects
|
||||
* which conform to the GenericDisplay item API.
|
||||
*/
|
||||
function DocManager() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DocManager.prototype = {
|
||||
_init: function() {
|
||||
this._recentManager = Gtk.RecentManager.get_default();
|
||||
this._items = {};
|
||||
this._recentManager.connect('changed', Lang.bind(this, function(recentManager) {
|
||||
this._reload();
|
||||
this.emit('changed');
|
||||
}));
|
||||
this._docSystem = Shell.DocSystem.get_default();
|
||||
this._infosByTimestamp = [];
|
||||
this._infosByUri = {};
|
||||
this._docSystem.connect('changed', Lang.bind(this, this._reload));
|
||||
this._reload();
|
||||
},
|
||||
|
||||
_reload: function() {
|
||||
let docs = this._recentManager.get_items();
|
||||
let newItems = {};
|
||||
let docs = this._docSystem.get_all();
|
||||
this._infosByTimestamp = [];
|
||||
this._infosByUri = {};
|
||||
for (let i = 0; i < docs.length; i++) {
|
||||
let recentInfo = docs[i];
|
||||
if (!recentInfo.exists())
|
||||
continue;
|
||||
|
||||
let docInfo = new DocInfo(recentInfo);
|
||||
|
||||
// we use GtkRecentInfo URI as an item Id
|
||||
newItems[docInfo.uri] = docInfo;
|
||||
this._infosByTimestamp.push(docInfo);
|
||||
this._infosByUri[docInfo.uri] = docInfo;
|
||||
}
|
||||
let deleted = {};
|
||||
for (var uri in this._items) {
|
||||
if (!(uri in newItems))
|
||||
deleted[uri] = this._items[uri];
|
||||
}
|
||||
/* If we'd cached any thumbnail references that no longer exist,
|
||||
dump them here */
|
||||
let texCache = Shell.TextureCache.get_default();
|
||||
for (var uri in deleted) {
|
||||
texCache.evict_recent_thumbnail(this._items[uri]);
|
||||
}
|
||||
this._items = newItems;
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
getItems: function() {
|
||||
return this._items;
|
||||
getTimestampOrderedInfos: function() {
|
||||
return this._infosByTimestamp;
|
||||
},
|
||||
|
||||
getInfosByUri: function() {
|
||||
return this._infosByUri;
|
||||
},
|
||||
|
||||
lookupByUri: function(uri) {
|
||||
return this._infosByUri[uri];
|
||||
},
|
||||
|
||||
queueExistenceCheck: function(count) {
|
||||
return this._docSystem.queue_existence_check(count);
|
||||
},
|
||||
|
||||
initialSearch: function(terms) {
|
||||
let multipleMatches = [];
|
||||
let prefixMatches = [];
|
||||
let substringMatches = [];
|
||||
for (let i = 0; i < this._infosByTimestamp.length; i++) {
|
||||
let item = this._infosByTimestamp[i];
|
||||
let mtype = item.matchTerms(terms);
|
||||
if (mtype == Search.MatchType.MULTIPLE)
|
||||
multipleMatches.push(item.uri);
|
||||
else if (mtype == Search.MatchType.PREFIX)
|
||||
prefixMatches.push(item.uri);
|
||||
else if (mtype == Search.MatchType.SUBSTRING)
|
||||
substringMatches.push(item.uri);
|
||||
}
|
||||
return multipleMatches.concat(prefixMatches.concat(substringMatches));
|
||||
},
|
||||
|
||||
subsearch: function(previousResults, terms) {
|
||||
let multipleMatches = [];
|
||||
let prefixMatches = [];
|
||||
let substringMatches = [];
|
||||
for (let i = 0; i < previousResults.length; i++) {
|
||||
let uri = previousResults[i];
|
||||
let item = this._infosByUri[uri];
|
||||
let mtype = item.matchTerms(terms);
|
||||
if (mtype == Search.MatchType.MULTIPLE)
|
||||
multipleMatches.push(uri);
|
||||
else if (mtype == Search.MatchType.PREFIX)
|
||||
prefixMatches.push(uri);
|
||||
else if (mtype == Search.MatchType.SUBSTRING)
|
||||
substringMatches.push(uri);
|
||||
}
|
||||
return multipleMatches.concat(prefixMatches.concat(substringMatches));
|
||||
}
|
||||
}
|
||||
|
||||
|
44
js/misc/format.js
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
* This function is intended to extend the String object and provide
|
||||
* an String.format API for string formatting.
|
||||
* It has to be set up using String.prototype.format = Format.format;
|
||||
* Usage:
|
||||
* "somestring %s %d".format('hello', 5);
|
||||
* It supports %s, %d and %f, for %f it also support precisions like
|
||||
* "%.2f".format(1.526)
|
||||
*/
|
||||
|
||||
function format() {
|
||||
let str = this;
|
||||
let i = 0;
|
||||
let args = arguments;
|
||||
|
||||
return str.replace(/%(?:\.([0-9]+))?(.)/g, function (str, precisionGroup, genericGroup) {
|
||||
|
||||
if (precisionGroup != '' && genericGroup != 'f')
|
||||
throw new Error("Precision can only be specified for 'f'");
|
||||
|
||||
switch (genericGroup) {
|
||||
case '%':
|
||||
return '%';
|
||||
break;
|
||||
case 's':
|
||||
return args[i++].toString();
|
||||
break;
|
||||
case 'd':
|
||||
return parseInt(args[i++]);
|
||||
break;
|
||||
case 'f':
|
||||
if (precisionGroup == '')
|
||||
return parseFloat(args[i++]);
|
||||
else
|
||||
return parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported conversion character %' + genericGroup);
|
||||
}
|
||||
return ""; // Suppress warning
|
||||
});
|
||||
}
|
33
js/misc/params.js
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
// parse:
|
||||
// @params: caller-provided parameter object, or %null
|
||||
// @default: function-provided defaults object
|
||||
// @allowExtras: whether or not to allow properties not in @default
|
||||
//
|
||||
// Examines @params and fills in default values from @defaults for
|
||||
// any properties in @defaults that don't appear in @params. If
|
||||
// @allowExtras is not %true, it will throw an error if @params
|
||||
// contains any properties that aren't in @defaults.
|
||||
//
|
||||
// If @params is %null, this returns @defaults.
|
||||
//
|
||||
// Return value: the updated params
|
||||
function parse(params, defaults, allowExtras) {
|
||||
if (!params)
|
||||
return defaults;
|
||||
|
||||
if (!allowExtras) {
|
||||
for (let prop in params) {
|
||||
if (!(prop in defaults))
|
||||
throw new Error('Unrecognized parameter "' + prop + '"');
|
||||
}
|
||||
}
|
||||
|
||||
for (let prop in defaults) {
|
||||
if (!(prop in params))
|
||||
params[prop] = defaults[prop];
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
@ -3,23 +3,34 @@ jsuidir = $(pkgdatadir)/js/ui
|
||||
dist_jsui_DATA = \
|
||||
altTab.js \
|
||||
appDisplay.js \
|
||||
appIcon.js \
|
||||
button.js \
|
||||
appFavorites.js \
|
||||
calendar.js \
|
||||
chrome.js \
|
||||
dash.js \
|
||||
dnd.js \
|
||||
docDisplay.js \
|
||||
environment.js \
|
||||
extensionSystem.js \
|
||||
genericDisplay.js \
|
||||
lightbox.js \
|
||||
link.js \
|
||||
lookingGlass.js \
|
||||
main.js \
|
||||
messageTray.js \
|
||||
notificationDaemon.js \
|
||||
overview.js \
|
||||
panel.js \
|
||||
places.js \
|
||||
placeDisplay.js \
|
||||
runDialog.js \
|
||||
search.js \
|
||||
shellDBus.js \
|
||||
sidebar.js \
|
||||
statusMenu.js \
|
||||
tweener.js \
|
||||
widget.js \
|
||||
widgetBox.js \
|
||||
windowAttentionHandler.js \
|
||||
windowManager.js \
|
||||
workspaces.js
|
||||
workspacesView.js \
|
||||
workspaceSwitcherPopup.js \
|
||||
workspace.js
|
||||
|
938
js/ui/altTab.js
@ -2,33 +2,37 @@
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const POPUP_BG_COLOR = new Clutter.Color();
|
||||
POPUP_BG_COLOR.from_pixel(0x00000080);
|
||||
const POPUP_INDICATOR_COLOR = new Clutter.Color();
|
||||
POPUP_INDICATOR_COLOR.from_pixel(0xf0f0f0ff);
|
||||
const POPUP_TRANSPARENT = new Clutter.Color();
|
||||
POPUP_TRANSPARENT.from_pixel(0x00000000);
|
||||
const POPUP_ARROW_COLOR = new Clutter.Color();
|
||||
POPUP_ARROW_COLOR.from_pixel(0xffffffff);
|
||||
const POPUP_UNFOCUSED_ARROW_COLOR = new Clutter.Color();
|
||||
POPUP_UNFOCUSED_ARROW_COLOR.from_pixel(0x808080ff);
|
||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
||||
|
||||
const POPUP_INDICATOR_WIDTH = 4;
|
||||
const POPUP_GRID_SPACING = 8;
|
||||
const POPUP_ICON_SIZE = 48;
|
||||
const POPUP_NUM_COLUMNS = 5;
|
||||
const POPUP_APPICON_SIZE = 96;
|
||||
const POPUP_LIST_SPACING = 8;
|
||||
|
||||
const POPUP_LABEL_MAX_WIDTH = POPUP_NUM_COLUMNS * (POPUP_ICON_SIZE + POPUP_GRID_SPACING);
|
||||
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
||||
|
||||
const OVERLAY_COLOR = new Clutter.Color();
|
||||
OVERLAY_COLOR.from_pixel(0x00000044);
|
||||
const THUMBNAIL_SIZE = 256;
|
||||
const THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
const THUMBNAIL_FADE_TIME = 0.2; // seconds
|
||||
|
||||
const SHOW_TIME = 0.05;
|
||||
const SWITCH_TIME = 0.1;
|
||||
function mod(a, b) {
|
||||
return (a + b) % b;
|
||||
}
|
||||
|
||||
function AltTabPopup() {
|
||||
this._init();
|
||||
@ -36,244 +40,738 @@ function AltTabPopup() {
|
||||
|
||||
AltTabPopup.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new Big.Box({ background_color : POPUP_BG_COLOR,
|
||||
corner_radius: POPUP_GRID_SPACING,
|
||||
padding: POPUP_GRID_SPACING,
|
||||
spacing: POPUP_GRID_SPACING,
|
||||
orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.actor = new Clutter.Group({ reactive: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height });
|
||||
|
||||
// Icon grid. TODO: Investigate Nbtk.Grid once that lands. Currently
|
||||
// just implemented using a chain of Big.Box.
|
||||
this._grid = new Big.Box({ spacing: POPUP_GRID_SPACING,
|
||||
orientation: Big.BoxOrientation.VERTICAL });
|
||||
let gcenterbox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
gcenterbox.append(this._grid, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(gcenterbox, Big.BoxPackFlags.NONE);
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
// Selected-window label
|
||||
this._label = new Clutter.Text({ font_name: "Sans 16px",
|
||||
ellipsize: Pango.EllipsizeMode.END });
|
||||
this._haveModal = false;
|
||||
|
||||
let labelbox = new Big.Box({ background_color: POPUP_INDICATOR_COLOR,
|
||||
corner_radius: POPUP_GRID_SPACING / 2,
|
||||
padding: POPUP_GRID_SPACING / 2 });
|
||||
labelbox.append(this._label, Big.BoxPackFlags.NONE);
|
||||
let lcenterbox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
width: POPUP_LABEL_MAX_WIDTH + POPUP_GRID_SPACING });
|
||||
lcenterbox.append(labelbox, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(lcenterbox, Big.BoxPackFlags.NONE);
|
||||
this._currentApp = 0;
|
||||
this._currentWindow = 0;
|
||||
this._thumbnailTimeoutId = 0;
|
||||
this._motionTimeoutId = 0;
|
||||
|
||||
// Indicator around selected icon
|
||||
this._indicator = new Big.Rectangle({ border_width: POPUP_INDICATOR_WIDTH,
|
||||
corner_radius: POPUP_INDICATOR_WIDTH / 2,
|
||||
border_color: POPUP_INDICATOR_COLOR,
|
||||
color: POPUP_TRANSPARENT });
|
||||
this.actor.append(this._indicator, Big.BoxPackFlags.FIXED);
|
||||
|
||||
this._items = [];
|
||||
this._toplevels = global.window_group.get_children();
|
||||
// Initially disable hover so we ignore the enter-event if
|
||||
// the switcher appears underneath the current pointer location
|
||||
this._disableHover();
|
||||
|
||||
global.stage.add_actor(this.actor);
|
||||
|
||||
// Dark translucent window used to cover all but the
|
||||
// currently-selected window while Alt-Tabbing. Actually
|
||||
// contains four actors which can we rearrange to create
|
||||
// a hole in the overlay.
|
||||
this._overlay = new Clutter.Group({ reactive: true });
|
||||
this._overlay_top = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||
border_width: 0 });
|
||||
this._overlay_bottom = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||
border_width: 0 });
|
||||
this._overlay_left = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||
border_width: 0 });
|
||||
this._overlay_right = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||
border_width: 0 });
|
||||
this._overlay.add_actor(this._overlay_top);
|
||||
this._overlay.add_actor(this._overlay_bottom);
|
||||
this._overlay.add_actor(this._overlay_left);
|
||||
this._overlay.add_actor(this._overlay_right);
|
||||
},
|
||||
|
||||
addWindow : function(win) {
|
||||
let item = { window: win,
|
||||
metaWindow: win.get_meta_window() };
|
||||
show : function(backward) {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let apps = tracker.get_running_apps ("");
|
||||
|
||||
let pixbuf = item.metaWindow.icon;
|
||||
item.icon = new Clutter.Texture({ width: POPUP_ICON_SIZE,
|
||||
height: POPUP_ICON_SIZE,
|
||||
keep_aspect_ratio: true });
|
||||
Shell.clutter_texture_set_from_pixbuf(item.icon, pixbuf);
|
||||
if (!apps.length)
|
||||
return false;
|
||||
|
||||
item.box = new Big.Box({ padding: POPUP_INDICATOR_WIDTH * 2 });
|
||||
item.box.append(item.icon, Big.BoxPackFlags.NONE);
|
||||
if (!Main.pushModal(this.actor))
|
||||
return false;
|
||||
this._haveModal = true;
|
||||
|
||||
item.above = null;
|
||||
for (let i = 1; i < this._toplevels.length; i++) {
|
||||
if (this._toplevels[i] == win) {
|
||||
item.above = this._toplevels[i - 1];
|
||||
break;
|
||||
this._keyPressEventId = global.stage.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||
this._keyReleaseEventId = global.stage.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||
|
||||
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
||||
|
||||
this._appSwitcher = new AppSwitcher(apps);
|
||||
this.actor.add_actor(this._appSwitcher.actor);
|
||||
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
||||
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
||||
|
||||
let focus = global.get_focus_monitor();
|
||||
this._appSwitcher.actor.x = focus.x + Math.floor((focus.width - this._appSwitcher.actor.width) / 2);
|
||||
this._appSwitcher.actor.y = focus.y + Math.floor((focus.height - this._appSwitcher.actor.height) / 2);
|
||||
|
||||
this._appIcons = this._appSwitcher.icons;
|
||||
|
||||
// Make the initial selection
|
||||
if (this._appIcons.length == 1) {
|
||||
if (!backward && this._appIcons[0].cachedWindows.length > 1) {
|
||||
// For compatibility with the multi-app case below
|
||||
this._select(0, 1, true);
|
||||
} else
|
||||
this._select(0);
|
||||
} else if (backward) {
|
||||
this._select(this._appIcons.length - 1);
|
||||
} else {
|
||||
let firstWindows = this._appIcons[0].cachedWindows;
|
||||
if (firstWindows.length > 1) {
|
||||
let curAppNextWindow = firstWindows[1];
|
||||
let nextAppWindow = this._appIcons[1].cachedWindows[0];
|
||||
|
||||
// If the next window of the current app is more-recently-used
|
||||
// than the first window of the next app, then select it.
|
||||
if (curAppNextWindow.get_workspace() == global.screen.get_active_workspace() &&
|
||||
curAppNextWindow.get_user_time() > nextAppWindow.get_user_time())
|
||||
this._select(0, 1, true);
|
||||
else
|
||||
this._select(1);
|
||||
} else
|
||||
this._select(1);
|
||||
}
|
||||
|
||||
// There's a race condition; if the user released Alt before
|
||||
// we got the grab, then we won't be notified. (See
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
|
||||
// details.) So we check now. (Have to do this after updating
|
||||
// selection.)
|
||||
let mods = global.get_modifier_keys();
|
||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
||||
this._finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_nextApp : function() {
|
||||
return mod(this._currentApp + 1, this._appIcons.length);
|
||||
},
|
||||
_previousApp : function() {
|
||||
return mod(this._currentApp - 1, this._appIcons.length);
|
||||
},
|
||||
|
||||
_nextWindow : function() {
|
||||
return mod(this._currentWindow + 1,
|
||||
this._appIcons[this._currentApp].cachedWindows.length);
|
||||
},
|
||||
_previousWindow : function() {
|
||||
return mod(this._currentWindow - 1,
|
||||
this._appIcons[this._currentApp].cachedWindows.length);
|
||||
},
|
||||
|
||||
_keyPressEvent : function(actor, event) {
|
||||
let keysym = event.get_key_symbol();
|
||||
let shift = (Shell.get_event_state(event) & Clutter.ModifierType.SHIFT_MASK);
|
||||
|
||||
this._disableHover();
|
||||
|
||||
// The WASD stuff is for debugging in Xephyr, where the arrow
|
||||
// keys aren't mapped correctly
|
||||
|
||||
if (keysym == Clutter.grave)
|
||||
this._select(this._currentApp, shift ? this._previousWindow() : this._nextWindow());
|
||||
else if (keysym == Clutter.Escape)
|
||||
this.destroy();
|
||||
else if (this._thumbnailsFocused) {
|
||||
if (keysym == Clutter.Tab) {
|
||||
if (shift && this._currentWindow == 0)
|
||||
this._select(this._previousApp());
|
||||
else if (!shift && this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
||||
this._select(this._nextApp());
|
||||
else
|
||||
this._select(this._currentApp, shift ? this._previousWindow() : this._nextWindow());
|
||||
} else if (keysym == Clutter.Left || keysym == Clutter.a)
|
||||
this._select(this._currentApp, this._previousWindow());
|
||||
else if (keysym == Clutter.Right || keysym == Clutter.d)
|
||||
this._select(this._currentApp, this._nextWindow());
|
||||
else if (keysym == Clutter.Up || keysym == Clutter.w)
|
||||
this._select(this._currentApp, null, true);
|
||||
} else {
|
||||
if (keysym == Clutter.Tab)
|
||||
this._select(shift ? this._previousApp() : this._nextApp());
|
||||
else if (keysym == Clutter.Left || keysym == Clutter.a)
|
||||
this._select(this._previousApp());
|
||||
else if (keysym == Clutter.Right || keysym == Clutter.d)
|
||||
this._select(this._nextApp());
|
||||
else if (keysym == Clutter.Down || keysym == Clutter.s)
|
||||
this._select(this._currentApp, this._currentWindow);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_keyReleaseEvent : function(actor, event) {
|
||||
let keysym = event.get_key_symbol();
|
||||
|
||||
if (keysym == Clutter.Alt_L || keysym == Clutter.Alt_R)
|
||||
this._finish();
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_onScroll : function(actor, event) {
|
||||
let direction = event.get_scroll_direction();
|
||||
if (direction == Clutter.ScrollDirection.UP) {
|
||||
if (this._thumbnailsFocused) {
|
||||
if (this._currentWindow == 0)
|
||||
this._select(this._previousApp());
|
||||
else
|
||||
this._select(this._currentApp, this._previousWindow());
|
||||
} else {
|
||||
let nwindows = this._appIcons[this._currentApp].cachedWindows.length;
|
||||
if (nwindows > 1)
|
||||
this._select(this._currentApp, nwindows - 1);
|
||||
else
|
||||
this._select(this._previousApp());
|
||||
}
|
||||
} else if (direction == Clutter.ScrollDirection.DOWN) {
|
||||
if (this._thumbnailsFocused) {
|
||||
if (this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
||||
this._select(this._nextApp());
|
||||
else
|
||||
this._select(this._currentApp, this._nextWindow());
|
||||
} else {
|
||||
let nwindows = this._appIcons[this._currentApp].cachedWindows.length;
|
||||
if (nwindows > 1)
|
||||
this._select(this._currentApp, 0);
|
||||
else
|
||||
this._select(this._nextApp());
|
||||
}
|
||||
}
|
||||
|
||||
item.visible = item.metaWindow.showing_on_its_workspace();
|
||||
|
||||
if (!item.visible) {
|
||||
let rect = new Meta.Rectangle();
|
||||
if (item.metaWindow.get_icon_geometry(rect))
|
||||
item.icon_rect = rect;
|
||||
}
|
||||
|
||||
item.n = this._items.length;
|
||||
this._items.push(item);
|
||||
|
||||
// Add it to the grid
|
||||
if (!this._gridRow || this._gridRow.get_children().length == POPUP_NUM_COLUMNS) {
|
||||
this._gridRow = new Big.Box({ spacing: POPUP_GRID_SPACING,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
this._grid.append(this._gridRow, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
this._gridRow.append(item.box, Big.BoxPackFlags.NONE);
|
||||
},
|
||||
|
||||
show : function(initialSelection) {
|
||||
global.window_group.add_actor(this._overlay);
|
||||
this._overlay.raise_top();
|
||||
this._overlay.show();
|
||||
this.actor.opacity = 0;
|
||||
Tweener.addTween(this.actor, { opacity: 255,
|
||||
time: SHOW_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
_clickedOutside : function(actor, event) {
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
this.actor.show_all();
|
||||
this.actor.x = Math.floor((global.screen_width - this.actor.width) / 2);
|
||||
this.actor.y = Math.floor((global.screen_height - this.actor.height) / 2);
|
||||
_appActivated : function(appSwitcher, n) {
|
||||
// If the user clicks on the selected app, activate the
|
||||
// selected window; otherwise (eg, they click on an app while
|
||||
// !mouseActive) activate the first window of the clicked-on
|
||||
// app.
|
||||
let window = (n == this._currentApp) ? this._currentWindow : 0;
|
||||
Main.activateWindow(this._appIcons[n].cachedWindows[window]);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
this.select(initialSelection);
|
||||
_appEntered : function(appSwitcher, n) {
|
||||
if (!this._mouseActive)
|
||||
return;
|
||||
|
||||
this._select(n);
|
||||
},
|
||||
|
||||
_windowActivated : function(thumbnailList, n) {
|
||||
Main.activateWindow(this._appIcons[this._currentApp].cachedWindows[n]);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_windowEntered : function(thumbnailList, n) {
|
||||
if (!this._mouseActive)
|
||||
return;
|
||||
|
||||
this._select(this._currentApp, n);
|
||||
},
|
||||
|
||||
_disableHover : function() {
|
||||
this._mouseActive = false;
|
||||
|
||||
if (this._motionTimeoutId != 0)
|
||||
Mainloop.source_remove(this._motionTimeoutId);
|
||||
|
||||
this._motionTimeoutId = Mainloop.timeout_add(DISABLE_HOVER_TIMEOUT, Lang.bind(this, this._mouseTimedOut));
|
||||
},
|
||||
|
||||
_mouseTimedOut : function() {
|
||||
this._motionTimeoutId = 0;
|
||||
this._mouseActive = true;
|
||||
},
|
||||
|
||||
_finish : function() {
|
||||
let app = this._appIcons[this._currentApp];
|
||||
let window = app.cachedWindows[this._currentWindow];
|
||||
Main.activateWindow(window);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
destroy : function() {
|
||||
this.actor.destroy();
|
||||
this._overlay.destroy();
|
||||
},
|
||||
|
||||
select : function(n) {
|
||||
if (this._selected) {
|
||||
// Unselect previous
|
||||
_onDestroy : function() {
|
||||
if (this._haveModal)
|
||||
Main.popModal(this.actor);
|
||||
|
||||
if (this._allocationChangedId) {
|
||||
this._selected.box.disconnect(this._allocationChangedId);
|
||||
delete this._allocationChangedId;
|
||||
}
|
||||
if (this._keyPressEventId)
|
||||
global.stage.disconnect(this._keyPressEventId);
|
||||
if (this._keyReleaseEventId)
|
||||
global.stage.disconnect(this._keyReleaseEventId);
|
||||
|
||||
if (this._selected.above)
|
||||
this._selected.window.raise(this._selected.above);
|
||||
if (this._motionTimeoutId != 0)
|
||||
Mainloop.source_remove(this._motionTimeoutId);
|
||||
if (this._thumbnailTimeoutId != 0)
|
||||
Mainloop.source_remove(this._thumbnailTimeoutId);
|
||||
},
|
||||
|
||||
/**
|
||||
* _select:
|
||||
* @app: index of the app to select
|
||||
* @window: (optional) index of which of @app's windows to select
|
||||
* @forceAppFocus: optional flag, see below
|
||||
*
|
||||
* Selects the indicated @app, and optional @window, and sets
|
||||
* this._thumbnailsFocused appropriately to indicate whether the
|
||||
* arrow keys should act on the app list or the thumbnail list.
|
||||
*
|
||||
* If @app is specified and @window is unspecified or %null, then
|
||||
* the app is highlighted (ie, given a light background), and the
|
||||
* current thumbnail list, if any, is destroyed. If @app has
|
||||
* multiple windows, and @forceAppFocus is not %true, then a
|
||||
* timeout is started to open a thumbnail list.
|
||||
*
|
||||
* If @app and @window are specified (and @forceAppFocus is not),
|
||||
* then @app will be outlined, a thumbnail list will be created
|
||||
* and focused (if it hasn't been already), and the @window'th
|
||||
* window in it will be highlighted.
|
||||
*
|
||||
* If @app and @window are specified and @forceAppFocus is %true,
|
||||
* then @app will be highlighted, and @window outlined, and the
|
||||
* app list will have the keyboard focus.
|
||||
*/
|
||||
_select : function(app, window, forceAppFocus) {
|
||||
if (app != this._currentApp || window == null) {
|
||||
if (this._thumbnails)
|
||||
this._destroyThumbnails();
|
||||
}
|
||||
|
||||
if (this._thumbnailTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._thumbnailTimeoutId);
|
||||
this._thumbnailTimeoutId = 0;
|
||||
}
|
||||
|
||||
this._thumbnailsFocused = (window != null) && !forceAppFocus;
|
||||
|
||||
this._currentApp = app;
|
||||
this._currentWindow = window ? window : 0;
|
||||
this._appSwitcher.highlight(app, this._thumbnailsFocused);
|
||||
|
||||
if (window != null) {
|
||||
if (!this._thumbnails)
|
||||
this._createThumbnails();
|
||||
this._currentWindow = window;
|
||||
this._thumbnails.highlight(window, forceAppFocus);
|
||||
} else if (this._appIcons[this._currentApp].cachedWindows.length > 1 &&
|
||||
!forceAppFocus) {
|
||||
this._thumbnailTimeoutId = Mainloop.timeout_add (
|
||||
THUMBNAIL_POPUP_TIME,
|
||||
Lang.bind(this, function () {
|
||||
this._select(this._currentApp, 0, true);
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_destroyThumbnails : function() {
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
{ opacity: 0,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: function() { this.destroy(); }
|
||||
});
|
||||
this._thumbnails = null;
|
||||
},
|
||||
|
||||
_createThumbnails : function() {
|
||||
this._thumbnails = new ThumbnailList (this._appIcons[this._currentApp].cachedWindows);
|
||||
this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated));
|
||||
this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered));
|
||||
|
||||
this.actor.add_actor(this._thumbnails.actor);
|
||||
|
||||
let thumbnailCenter;
|
||||
if (this._thumbnails.actor.width < this._appSwitcher.actor.width) {
|
||||
// Center the thumbnails under the corresponding AppIcon.
|
||||
// If this is being called when the switcher is first
|
||||
// being brought up, then nothing will have been assigned
|
||||
// an allocation yet, and the get_transformed_position()
|
||||
// call will return 0,0.
|
||||
// (http://bugzilla.openedhand.com/show_bug.cgi?id=1115).
|
||||
// Calling clutter_actor_get_allocation_box() would force
|
||||
// it to properly allocate itself, but we can't call that
|
||||
// because it has an out-caller-allocates arg. So we use
|
||||
// clutter_stage_get_actor_at_pos(), which will force a
|
||||
// reallocation as a side effect.
|
||||
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
|
||||
|
||||
let icon = this._appIcons[this._currentApp].actor;
|
||||
let [stageX, stageY] = icon.get_transformed_position();
|
||||
thumbnailCenter = stageX + icon.width / 2;
|
||||
} else {
|
||||
// Center the thumbnails on the monitor
|
||||
let focus = global.get_focus_monitor();
|
||||
thumbnailCenter = focus.x + focus.width / 2;
|
||||
}
|
||||
|
||||
this._thumbnails.actor.x = Math.floor(thumbnailCenter - this._thumbnails.actor.width / 2);
|
||||
this._thumbnails.actor.y = this._appSwitcher.actor.y + this._appSwitcher.actor.height + POPUP_LIST_SPACING;
|
||||
|
||||
this._thumbnails.actor.opacity = 0;
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
{ opacity: 255,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function SwitcherList(squareItems) {
|
||||
this._init(squareItems);
|
||||
}
|
||||
|
||||
SwitcherList.prototype = {
|
||||
_init : function(squareItems) {
|
||||
this.actor = new St.Bin({ style_class: 'switcher-list' });
|
||||
|
||||
// Here we use a GenericContainer so that we can force all the
|
||||
// children except the separator to have the same width.
|
||||
this._list = new Shell.GenericContainer();
|
||||
this._list.spacing = POPUP_LIST_SPACING;
|
||||
|
||||
this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this._list.connect('allocate', Lang.bind(this, this._allocate));
|
||||
|
||||
this.actor.add_actor(this._list);
|
||||
|
||||
this._items = [];
|
||||
this._highlighted = -1;
|
||||
this._separator = null;
|
||||
this._squareItems = squareItems;
|
||||
},
|
||||
|
||||
addItem : function(item) {
|
||||
let bbox = new St.Clickable({ style_class: 'item-box',
|
||||
reactive: true });
|
||||
|
||||
bbox.set_child(item);
|
||||
this._list.add_actor(bbox);
|
||||
|
||||
let n = this._items.length;
|
||||
bbox.connect('clicked', Lang.bind(this, function () {
|
||||
this._itemActivated(n);
|
||||
}));
|
||||
bbox.connect('enter-event', Lang.bind(this, function () {
|
||||
this._itemEntered(n);
|
||||
}));
|
||||
|
||||
this._items.push(bbox);
|
||||
},
|
||||
|
||||
addSeparator: function () {
|
||||
let box = new St.Bin({ style_class: 'separator' })
|
||||
this._separator = box;
|
||||
this._list.add_actor(box);
|
||||
},
|
||||
|
||||
highlight: function(index, justOutline) {
|
||||
if (this._highlighted != -1)
|
||||
this._items[this._highlighted].style_class = 'item-box';
|
||||
|
||||
this._highlighted = index;
|
||||
|
||||
if (this._highlighted != -1) {
|
||||
if (justOutline)
|
||||
this._items[this._highlighted].style_class = 'outlined-item-box';
|
||||
else
|
||||
this._selected.window.lower_bottom();
|
||||
this._items[this._highlighted].style_class = 'selected-item-box';
|
||||
}
|
||||
},
|
||||
|
||||
_itemActivated: function(n) {
|
||||
this.emit('item-activated', n);
|
||||
},
|
||||
|
||||
_itemEntered: function(n) {
|
||||
this.emit('item-entered', n);
|
||||
},
|
||||
|
||||
_maxChildWidth: function (forHeight) {
|
||||
let maxChildMin = 0;
|
||||
let maxChildNat = 0;
|
||||
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
let [childMin, childNat] = this._items[i].get_preferred_width(forHeight);
|
||||
maxChildMin = Math.max(childMin, maxChildMin);
|
||||
maxChildNat = Math.max(childNat, maxChildNat);
|
||||
|
||||
if (this._squareItems) {
|
||||
let [childMin, childNat] = this._items[i].get_preferred_height(-1);
|
||||
maxChildMin = Math.max(childMin, maxChildMin);
|
||||
maxChildNat = Math.max(childNat, maxChildNat);
|
||||
}
|
||||
}
|
||||
|
||||
let item = this._items[n];
|
||||
let changed = this._selected && item != this._selected;
|
||||
this._selected = item;
|
||||
return [maxChildMin, maxChildNat];
|
||||
},
|
||||
|
||||
if (this._selected) {
|
||||
this._label.set_size(-1, -1);
|
||||
this._label.text = this._selected.metaWindow.title;
|
||||
if (this._label.width > POPUP_LABEL_MAX_WIDTH)
|
||||
this._label.width = POPUP_LABEL_MAX_WIDTH;
|
||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(forHeight);
|
||||
|
||||
// Figure out this._selected.box's coordinates in terms of
|
||||
// this.actor
|
||||
let bx = this._selected.box.x, by = this._selected.box.y;
|
||||
let actor = this._selected.box.get_parent();
|
||||
while (actor != this.actor) {
|
||||
bx += actor.x;
|
||||
by += actor.y;
|
||||
actor = actor.get_parent();
|
||||
}
|
||||
let separatorWidth = 0;
|
||||
if (this._separator) {
|
||||
let [sepMin, sepNat] = this._separator.get_preferred_width(forHeight);
|
||||
separatorWidth = sepNat + this._list.spacing;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
Tweener.addTween(this._indicator,
|
||||
{ x: bx,
|
||||
y: by,
|
||||
width: this._selected.box.width,
|
||||
height: this._selected.box.height,
|
||||
time: SWITCH_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||
alloc.min_size = this._items.length * maxChildMin + separatorWidth + totalSpacing;
|
||||
alloc.natural_size = alloc.min_size;
|
||||
},
|
||||
|
||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||
let maxChildMin = 0;
|
||||
let maxChildNat = 0;
|
||||
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
let [childMin, childNat] = this._items[i].get_preferred_height(-1);
|
||||
maxChildMin = Math.max(childMin, maxChildMin);
|
||||
maxChildNat = Math.max(childNat, maxChildNat);
|
||||
}
|
||||
|
||||
if (this._squareItems) {
|
||||
let [childMin, childNat] = this._maxChildWidth(-1);
|
||||
maxChildMin = Math.max(childMin, maxChildMin);
|
||||
maxChildNat = maxChildMin;
|
||||
}
|
||||
|
||||
alloc.min_size = maxChildMin;
|
||||
alloc.natural_size = maxChildNat;
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
let childHeight = box.y2 - box.y1;
|
||||
|
||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(childHeight);
|
||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||
|
||||
let separatorWidth = 0;
|
||||
if (this._separator) {
|
||||
let [sepMin, sepNat] = this._separator.get_preferred_width(childHeight);
|
||||
separatorWidth = sepNat;
|
||||
totalSpacing += this._list.spacing;
|
||||
}
|
||||
|
||||
let childWidth = Math.floor(Math.max(0, box.x2 - box.x1 - totalSpacing - separatorWidth) / this._items.length);
|
||||
|
||||
let x = 0;
|
||||
let children = this._list.get_children();
|
||||
let childBox = new Clutter.ActorBox();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (this._items.indexOf(children[i]) != -1) {
|
||||
let [childMin, childNat] = children[i].get_preferred_height(childWidth);
|
||||
let vSpacing = (childHeight - childNat) / 2;
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = vSpacing;
|
||||
childBox.x2 = x + childWidth;
|
||||
childBox.y2 = childBox.y1 + childNat;
|
||||
children[i].allocate(childBox, flags);
|
||||
|
||||
x += this._list.spacing + childWidth;
|
||||
} else if (children[i] == this._separator) {
|
||||
// We want the separator to be more compact than the rest.
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = 0;
|
||||
childBox.x2 = x + separatorWidth;
|
||||
childBox.y2 = childHeight;
|
||||
children[i].allocate(childBox, flags);
|
||||
x += this._list.spacing + separatorWidth;
|
||||
} else {
|
||||
Tweener.removeTweens(this.indicator);
|
||||
this._indicator.set_position(bx, by);
|
||||
this._indicator.set_size(this._selected.box.width,
|
||||
this._selected.box.height);
|
||||
// Something else, eg, AppSwitcher's arrows;
|
||||
// we don't allocate it.
|
||||
}
|
||||
this._indicator.show();
|
||||
|
||||
if (this._overlay.visible) {
|
||||
if (this._selected.visible)
|
||||
this._selected.window.raise(this._overlay);
|
||||
this._adjust_overlay();
|
||||
}
|
||||
|
||||
this._allocationChangedId =
|
||||
this._selected.box.connect('notify::allocation',
|
||||
Lang.bind(this, this._allocationChanged));
|
||||
} else {
|
||||
this._label.text = "";
|
||||
this._indicator.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_allocationChanged : function() {
|
||||
if (this._selected)
|
||||
this.select(this._selected.n);
|
||||
},
|
||||
|
||||
_adjust_overlay : function() {
|
||||
if (this._selected && this._selected.icon_rect) {
|
||||
// We want to highlight a specific rectangle within the
|
||||
// task bar, so rearrange the pieces of the overlay to
|
||||
// cover the whole screen except that rectangle
|
||||
|
||||
let rect = this._selected.icon_rect;
|
||||
|
||||
this._overlay_top.x = 0;
|
||||
this._overlay_top.y = 0;
|
||||
this._overlay_top.width = global.screen_width;
|
||||
this._overlay_top.height = rect.y;
|
||||
|
||||
this._overlay_left.x = 0;
|
||||
this._overlay_left.y = rect.y;
|
||||
this._overlay_left.width = rect.x;
|
||||
this._overlay_left.height = rect.height;
|
||||
this._overlay_left.show();
|
||||
|
||||
this._overlay_right.x = rect.x + rect.width;
|
||||
this._overlay_right.y = rect.y;
|
||||
this._overlay_right.width = global.screen_width - rect.x - rect.width;
|
||||
this._overlay_right.height = rect.height;
|
||||
this._overlay_right.show();
|
||||
|
||||
this._overlay_bottom.x = 0;
|
||||
this._overlay_bottom.y = rect.y + rect.height;
|
||||
this._overlay_bottom.width = global.screen_width;
|
||||
this._overlay_bottom.height = global.screen_height - rect.y - rect.height;
|
||||
this._overlay_bottom.show();
|
||||
} else {
|
||||
// Either there's no current selection, or the selection
|
||||
// is a visible window. Make the overlay cover the whole
|
||||
// screen. select() will raise the selected window over
|
||||
// the overlay.
|
||||
|
||||
this._overlay_top.x = 0;
|
||||
this._overlay_top.y = 0;
|
||||
this._overlay_top.width = global.screen_width;
|
||||
this._overlay_top.height = global.screen_height;
|
||||
this._overlay_top.show();
|
||||
|
||||
this._overlay_left.hide();
|
||||
this._overlay_right.hide();
|
||||
this._overlay_bottom.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(SwitcherList.prototype);
|
||||
|
||||
function AppIcon(app) {
|
||||
this._init(app);
|
||||
}
|
||||
|
||||
AppIcon.prototype = {
|
||||
_init: function(app) {
|
||||
this.app = app;
|
||||
this.actor = new St.BoxLayout({ style_class: "alt-tab-app",
|
||||
vertical: true });
|
||||
this._icon = this.app.create_icon_texture(POPUP_APPICON_SIZE);
|
||||
let iconBin = new St.Bin({height: POPUP_APPICON_SIZE, width: POPUP_APPICON_SIZE});
|
||||
iconBin.child = this._icon;
|
||||
|
||||
this.actor.add(iconBin, { x_fill: false, y_fill: false } );
|
||||
this._label = new St.Label({ text: this.app.get_name() });
|
||||
this.actor.add(this._label, { x_fill: false });
|
||||
}
|
||||
}
|
||||
|
||||
function AppSwitcher(apps) {
|
||||
this._init(apps);
|
||||
}
|
||||
|
||||
AppSwitcher.prototype = {
|
||||
__proto__ : SwitcherList.prototype,
|
||||
|
||||
_init : function(apps) {
|
||||
SwitcherList.prototype._init.call(this, true);
|
||||
|
||||
// Construct the AppIcons, sort by time, add to the popup
|
||||
let activeWorkspace = global.screen.get_active_workspace();
|
||||
let workspaceIcons = [];
|
||||
let otherIcons = [];
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let appIcon = new AppIcon(apps[i]);
|
||||
// Cache the window list now; we don't handle dynamic changes here,
|
||||
// and we don't want to be continually retrieving it
|
||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||
if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
|
||||
workspaceIcons.push(appIcon);
|
||||
else
|
||||
otherIcons.push(appIcon);
|
||||
}
|
||||
|
||||
workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
|
||||
otherIcons.sort(Lang.bind(this, this._sortAppIcon));
|
||||
|
||||
this.icons = [];
|
||||
this._arrows = [];
|
||||
for (let i = 0; i < workspaceIcons.length; i++)
|
||||
this._addIcon(workspaceIcons[i]);
|
||||
if (workspaceIcons.length > 0 && otherIcons.length > 0)
|
||||
this.addSeparator();
|
||||
for (let i = 0; i < otherIcons.length; i++)
|
||||
this._addIcon(otherIcons[i]);
|
||||
|
||||
this._curApp = -1;
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
// Allocate the main list items
|
||||
SwitcherList.prototype._allocate.call(this, actor, box, flags);
|
||||
|
||||
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
|
||||
let arrowWidth = arrowHeight * 2;
|
||||
|
||||
// Now allocate each arrow underneath its item
|
||||
let childBox = new Clutter.ActorBox();
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
let itemBox = this._items[i].allocation;
|
||||
childBox.x1 = Math.floor(itemBox.x1 + (itemBox.x2 - itemBox.x1 - arrowWidth) / 2);
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y1 = itemBox.y2 + arrowHeight;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._arrows[i].allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
|
||||
// We override SwitcherList's highlight() method to also deal with
|
||||
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
|
||||
// will hide their arrows by default, but show them when their
|
||||
// thumbnails are visible (ie, when the app icon is supposed to be
|
||||
// in justOutline mode). Apps with multiple windows will normally
|
||||
// show a dim arrow, but show a bright arrow when they are
|
||||
// highlighted; their redraw handler will use the right color
|
||||
// based on this._curApp; we just need to do a queue_relayout() to
|
||||
// force it to redraw. (queue_redraw() doesn't work because
|
||||
// ShellDrawingArea only redraws on allocate.)
|
||||
highlight : function(n, justOutline) {
|
||||
if (this._curApp != -1) {
|
||||
if (this.icons[this._curApp].cachedWindows.length == 1)
|
||||
this._arrows[this._curApp].hide();
|
||||
else
|
||||
this._arrows[this._curApp].queue_relayout();
|
||||
}
|
||||
|
||||
SwitcherList.prototype.highlight.call(this, n, justOutline);
|
||||
this._curApp = n;
|
||||
|
||||
if (this._curApp != -1) {
|
||||
if (justOutline && this.icons[this._curApp].cachedWindows.length == 1)
|
||||
this._arrows[this._curApp].show();
|
||||
else
|
||||
this._arrows[this._curApp].queue_relayout();
|
||||
}
|
||||
},
|
||||
|
||||
_addIcon : function(appIcon) {
|
||||
this.icons.push(appIcon);
|
||||
this.addItem(appIcon.actor);
|
||||
|
||||
let n = this._arrows.length;
|
||||
let arrow = new St.DrawingArea();
|
||||
arrow.connect('redraw', Lang.bind(this,
|
||||
function (area, texture) {
|
||||
Shell.draw_box_pointer(texture, Shell.PointerDirection.DOWN,
|
||||
TRANSPARENT_COLOR,
|
||||
this._curApp == n ? POPUP_ARROW_COLOR : POPUP_UNFOCUSED_ARROW_COLOR);
|
||||
}));
|
||||
this._list.add_actor(arrow);
|
||||
this._arrows.push(arrow);
|
||||
|
||||
if (appIcon.cachedWindows.length == 1)
|
||||
arrow.hide();
|
||||
},
|
||||
|
||||
_hasWindowsOnWorkspace: function(appIcon, workspace) {
|
||||
let windows = appIcon.cachedWindows;
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (windows[i].get_workspace() == workspace)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_sortAppIcon : function(appIcon1, appIcon2) {
|
||||
return appIcon1.app.compare(appIcon2.app);
|
||||
}
|
||||
};
|
||||
|
||||
function ThumbnailList(windows) {
|
||||
this._init(windows);
|
||||
}
|
||||
|
||||
ThumbnailList.prototype = {
|
||||
__proto__ : SwitcherList.prototype,
|
||||
|
||||
_init : function(windows) {
|
||||
SwitcherList.prototype._init.call(this);
|
||||
|
||||
let activeWorkspace = global.screen.get_active_workspace();
|
||||
|
||||
// We fake the value of "separatorAdded" when the app has no window
|
||||
// on the current workspace, to avoid displaying a useless separator in
|
||||
// that case.
|
||||
let separatorAdded = windows.length == 0 || windows[0].get_workspace() != activeWorkspace;
|
||||
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (!separatorAdded && windows[i].get_workspace() != activeWorkspace) {
|
||||
this.addSeparator();
|
||||
separatorAdded = true;
|
||||
}
|
||||
|
||||
let mutterWindow = windows[i].get_compositor_private();
|
||||
let windowTexture = mutterWindow.get_texture ();
|
||||
let [width, height] = windowTexture.get_size();
|
||||
let scale = Math.min(1.0, THUMBNAIL_SIZE / width, THUMBNAIL_SIZE / height);
|
||||
|
||||
let box = new St.BoxLayout({ style_class: "thumbnail-box",
|
||||
vertical: true });
|
||||
|
||||
let bin = new St.Bin({ style_class: "thumbnail" });
|
||||
let clone = new Clutter.Clone ({ source: windowTexture,
|
||||
reactive: true,
|
||||
width: width * scale,
|
||||
height: height * scale });
|
||||
|
||||
bin.add_actor(clone);
|
||||
box.add_actor(bin);
|
||||
|
||||
let title = windows[i].get_title();
|
||||
if (title) {
|
||||
let name = new St.Label({ text: title });
|
||||
// St.Label doesn't support text-align so use a Bin
|
||||
let bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||
bin.add_actor(name);
|
||||
box.add_actor(bin);
|
||||
}
|
||||
|
||||
this.addItem(box);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
1624
js/ui/appDisplay.js
120
js/ui/appFavorites.js
Normal file
@ -0,0 +1,120 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
function AppFavorites() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
AppFavorites.prototype = {
|
||||
FAVORITE_APPS_KEY: 'favorite_apps',
|
||||
|
||||
_init: function() {
|
||||
this._favorites = {};
|
||||
this._gconf = Shell.GConf.get_default();
|
||||
this._gconf.connect('changed::' + this.FAVORITE_APPS_KEY, Lang.bind(this, this._onFavsChanged));
|
||||
this._reload();
|
||||
},
|
||||
|
||||
_onFavsChanged: function() {
|
||||
this._reload();
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
_reload: function() {
|
||||
let ids = Shell.GConf.get_default().get_string_list('favorite_apps');
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let apps = ids.map(function (id) {
|
||||
return appSys.get_app(id);
|
||||
}).filter(function (app) {
|
||||
return app != null;
|
||||
});
|
||||
this._favorites = {};
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = apps[i];
|
||||
this._favorites[app.get_id()] = app;
|
||||
}
|
||||
},
|
||||
|
||||
_getIds: function() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(id);
|
||||
return ret;
|
||||
},
|
||||
|
||||
getFavoriteMap: function() {
|
||||
return this._favorites;
|
||||
},
|
||||
|
||||
getFavorites: function() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(this._favorites[id]);
|
||||
return ret;
|
||||
},
|
||||
|
||||
isFavorite: function(appId) {
|
||||
return appId in this._favorites;
|
||||
},
|
||||
|
||||
_addFavorite: function(appId) {
|
||||
if (appId in this._favorites)
|
||||
return false;
|
||||
|
||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||
|
||||
if (!app)
|
||||
return false;
|
||||
|
||||
let ids = this._getIds();
|
||||
ids.push(appId);
|
||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
||||
this._favorites[appId] = app;
|
||||
return true;
|
||||
},
|
||||
|
||||
addFavorite: function(appId) {
|
||||
if (!this._addFavorite(appId))
|
||||
return;
|
||||
|
||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||
|
||||
Main.overview.infoBar.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
|
||||
this._removeFavorite(appId);
|
||||
}));
|
||||
},
|
||||
|
||||
_removeFavorite: function(appId) {
|
||||
if (!appId in this._favorites)
|
||||
return false;
|
||||
|
||||
let ids = this._getIds().filter(function (id) { return id != appId; });
|
||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
||||
return true;
|
||||
},
|
||||
|
||||
removeFavorite: function(appId) {
|
||||
if (!this._removeFavorite(appId))
|
||||
return;
|
||||
|
||||
Main.overview.infoBar.setMessage(_("%s has been removed from your favorites.").format(this._favorites[appId].get_name()),
|
||||
Lang.bind(this, function () {
|
||||
this._addFavorite(appId);
|
||||
}));
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(AppFavorites.prototype);
|
||||
|
||||
var appFavoritesInstance = null;
|
||||
function getAppFavorites() {
|
||||
if (appFavoritesInstance == null)
|
||||
appFavoritesInstance = new AppFavorites();
|
||||
return appFavoritesInstance;
|
||||
}
|
133
js/ui/appIcon.js
@ -1,133 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const GLOW_COLOR = new Clutter.Color();
|
||||
GLOW_COLOR.from_pixel(0x4f6ba4ff);
|
||||
const GLOW_PADDING_HORIZONTAL = 3;
|
||||
const GLOW_PADDING_VERTICAL = 3;
|
||||
|
||||
const APP_ICON_SIZE = 48;
|
||||
|
||||
function AppIcon(appInfo) {
|
||||
this._init(appInfo);
|
||||
}
|
||||
|
||||
AppIcon.prototype = {
|
||||
_init : function(appInfo) {
|
||||
this.appInfo = appInfo;
|
||||
this.windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
||||
for (let i = 0; i < this.windows.length; i++) {
|
||||
this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows));
|
||||
}
|
||||
this._resortWindows();
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
corner_radius: 2,
|
||||
padding: 1,
|
||||
reactive: true });
|
||||
|
||||
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.icon = appInfo.create_icon_texture(APP_ICON_SIZE);
|
||||
iconBox.append(this.icon, Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
||||
|
||||
let nameBox = new Shell.GenericContainer();
|
||||
nameBox.connect('get-preferred-width', Lang.bind(this, this._nameBoxGetPreferredWidth));
|
||||
nameBox.connect('get-preferred-height', Lang.bind(this, this._nameBoxGetPreferredHeight));
|
||||
nameBox.connect('allocate', Lang.bind(this, this._nameBoxAllocate));
|
||||
this._nameBox = nameBox;
|
||||
|
||||
this._name = new Clutter.Text({ color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans 12px",
|
||||
line_alignment: Pango.Alignment.CENTER,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: appInfo.get_name() });
|
||||
nameBox.add_actor(this._name);
|
||||
this._glowBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
let glowPath = GLib.filename_to_uri(global.imagedir + 'app-well-glow.png', '');
|
||||
for (let i = 0; i < this._windows.length && i < 3; i++) {
|
||||
let glow = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
glowPath, -1, -1);
|
||||
glow.keep_aspect_ratio = false;
|
||||
this._glowBox.append(glow, Big.BoxPackFlags.EXPAND);
|
||||
}
|
||||
this._nameBox.add_actor(this._glowBox);
|
||||
this._glowBox.lower(this._name);
|
||||
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
||||
},
|
||||
|
||||
_nameBoxGetPreferredWidth: function (nameBox, forHeight, alloc) {
|
||||
let [min, natural] = this._name.get_preferred_width(forHeight);
|
||||
alloc.min_size = min + GLOW_PADDING_HORIZONTAL * 2;
|
||||
alloc.natural_size = natural + GLOW_PADDING_HORIZONTAL * 2;
|
||||
},
|
||||
|
||||
_nameBoxGetPreferredHeight: function (nameBox, forWidth, alloc) {
|
||||
let [min, natural] = this._name.get_preferred_height(forWidth);
|
||||
alloc.min_size = min + GLOW_PADDING_VERTICAL * 2;
|
||||
alloc.natural_size = natural + GLOW_PADDING_VERTICAL * 2;
|
||||
},
|
||||
|
||||
_nameBoxAllocate: function (nameBox, box, flags) {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let [minWidth, naturalWidth] = this._name.get_preferred_width(-1);
|
||||
let [minHeight, naturalHeight] = this._name.get_preferred_height(-1);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
let targetWidth = availWidth;
|
||||
let xPadding = 0;
|
||||
if (naturalWidth < availWidth) {
|
||||
xPadding = Math.floor((availWidth - naturalWidth) / 2);
|
||||
}
|
||||
childBox.x1 = xPadding;
|
||||
childBox.x2 = availWidth - xPadding;
|
||||
childBox.y1 = GLOW_PADDING_VERTICAL;
|
||||
childBox.y2 = availHeight - GLOW_PADDING_VERTICAL;
|
||||
this._name.allocate(childBox, flags);
|
||||
|
||||
// Now the glow
|
||||
if (this._glowBox != null) {
|
||||
let glowPaddingHoriz = Math.max(0, xPadding - GLOW_PADDING_HORIZONTAL);
|
||||
glowPaddingHoriz = Math.max(GLOW_PADDING_HORIZONTAL, glowPaddingHoriz);
|
||||
childBox.x1 = glowPaddingHoriz;
|
||||
childBox.x2 = availWidth - glowPaddingHoriz;
|
||||
childBox.y1 = 0;
|
||||
childBox.y2 = availHeight;
|
||||
this._glowBox.allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
|
||||
_resortWindows: function() {
|
||||
this.windows.sort(function (a, b) {
|
||||
let timeA = a.get_user_time();
|
||||
let timeB = b.get_user_time();
|
||||
if (timeA == timeB)
|
||||
return 0;
|
||||
else if (timeA > timeB)
|
||||
return -1;
|
||||
return 1;
|
||||
});
|
||||
},
|
||||
|
||||
getDragActor: function() {
|
||||
return this.appInfo.create_icon_texture(APP_ICON_SIZE);
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this.icon;
|
||||
}
|
||||
};
|
173
js/ui/button.js
@ -1,173 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const DEFAULT_BUTTON_COLOR = new Clutter.Color();
|
||||
DEFAULT_BUTTON_COLOR.from_pixel(0xeeddcc66);
|
||||
|
||||
const DEFAULT_PRESSED_BUTTON_COLOR = new Clutter.Color();
|
||||
DEFAULT_PRESSED_BUTTON_COLOR.from_pixel(0xccbbaa66);
|
||||
|
||||
const DEFAULT_TEXT_COLOR = new Clutter.Color();
|
||||
DEFAULT_TEXT_COLOR.from_pixel(0x000000ff);
|
||||
|
||||
const DEFAULT_FONT = 'Sans Bold 16px';
|
||||
|
||||
// Padding on the left and right side of the button.
|
||||
const SIDE_PADDING = 14;
|
||||
|
||||
function Button(widget, buttonColor, pressedButtonColor, textColor, font) {
|
||||
this._init(widget, buttonColor, pressedButtonColor, textColor, font);
|
||||
}
|
||||
|
||||
Button.prototype = {
|
||||
_init : function(widgetOrText, buttonColor, pressedButtonColor, textColor, font) {
|
||||
this._buttonColor = buttonColor
|
||||
if (buttonColor == null)
|
||||
this._buttonColor = DEFAULT_BUTTON_COLOR;
|
||||
|
||||
this._pressedButtonColor = pressedButtonColor
|
||||
if (pressedButtonColor == null)
|
||||
this._pressedButtonColor = DEFAULT_PRESSED_BUTTON_COLOR;
|
||||
|
||||
this._textColor = textColor;
|
||||
if (textColor == null)
|
||||
this._textColor = DEFAULT_TEXT_COLOR;
|
||||
|
||||
this._font = font;
|
||||
if (font == null)
|
||||
this._font = DEFAULT_FONT;
|
||||
|
||||
this._isBetweenPressAndRelease = false;
|
||||
this._mouseIsOverButton = false;
|
||||
|
||||
this.actor = new Shell.ButtonBox({ reactive: true,
|
||||
corner_radius: 5,
|
||||
padding_left: SIDE_PADDING,
|
||||
padding_right: SIDE_PADDING,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER
|
||||
});
|
||||
if (typeof widgetOrText == 'string') {
|
||||
this._widget = new Clutter.Text({ font_name: this._font,
|
||||
color: this._textColor,
|
||||
text: widgetOrText });
|
||||
} else {
|
||||
this._widget = widgetOrText;
|
||||
}
|
||||
|
||||
this.actor.append(this._widget, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this.actor.connect('notify::hover', Lang.bind(this, this._updateColors));
|
||||
this.actor.connect('notify::pressed', Lang.bind(this, this._updateColors));
|
||||
this.actor.connect('notify::active', Lang.bind(this, this._updateColors));
|
||||
},
|
||||
|
||||
_updateColors : function() {
|
||||
if (this.actor.active || this.actor.pressed)
|
||||
this.actor.backgroundColor = this._pressedButtonColor;
|
||||
else if (this.actor.hover)
|
||||
this.actor.backgroundColor = this._buttonColor;
|
||||
else
|
||||
this.actor.backgroundColor = null;
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Button.prototype);
|
||||
|
||||
/* Delay before the icon should appear, in seconds after the pointer has entered the parent */
|
||||
const ANIMATION_TIME = 0.25;
|
||||
|
||||
/* This is an icon button that fades in/out when mouse enters/leaves the parent.
|
||||
* A delay is used before the fading starts. You can force it to be shown if needed.
|
||||
*
|
||||
* parent -- used to show/hide the button depending on mouse entering/leaving it
|
||||
* size -- size in pixels of both the button and the icon it contains
|
||||
* texture -- optional, must be used if the texture for the icon is already created (else, use setIconFromName)
|
||||
*/
|
||||
function iconButton(parent, size, texture) {
|
||||
this._init(parent, size, texture);
|
||||
}
|
||||
|
||||
iconButton.prototype = {
|
||||
_init : function(parent, size, texture) {
|
||||
this._size = size;
|
||||
if (texture)
|
||||
this.actor = texture;
|
||||
else
|
||||
this.actor = new Clutter.Texture({ width: this._size, height: this._size });
|
||||
this.actor.set_reactive(true);
|
||||
this.actor.set_opacity(0);
|
||||
parent.connect("enter-event", Lang.bind(this, function(actor, event) {
|
||||
this._shouldHide = false;
|
||||
// Nothing to do if the cursor has come back from a child of the parent actor
|
||||
if (actor.get_children().indexOf(event.get_related()) != -1)
|
||||
return;
|
||||
|
||||
this._fadeIn();
|
||||
}));
|
||||
parent.connect("leave-event", Lang.bind(this, function(actor, event) {
|
||||
// Nothing to do if the cursor has merely entered a child of the parent actor
|
||||
if (actor.get_children().indexOf(event.get_related()) != -1)
|
||||
return;
|
||||
|
||||
// Remember that we should not be visible to hide the button if forceShow is unset
|
||||
if (this._forceShow) {
|
||||
this._shouldHide = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this._fadeOut();
|
||||
}));
|
||||
},
|
||||
|
||||
/// Private methods ///
|
||||
|
||||
setIconFromName : function(iconName) {
|
||||
let iconTheme = Gtk.IconTheme.get_default();
|
||||
let iconInfo = iconTheme.lookup_icon(iconName, this._size, 0);
|
||||
if (!iconInfo)
|
||||
return;
|
||||
|
||||
let iconPath = iconInfo.get_filename();
|
||||
this.actor.set_from_file(iconPath);
|
||||
},
|
||||
|
||||
// Useful if we want to show the button immediately,
|
||||
// e.g. in case the mouse is already in the parent when the button is created
|
||||
show : function() {
|
||||
this.actor.set_opacity(255);
|
||||
},
|
||||
|
||||
// If show is true, prevents the button from fading out
|
||||
forceShow : function(show) {
|
||||
this._forceShow = show;
|
||||
// Hide the button if it should have been hidden under normal conditions
|
||||
if (!this._forceShow && this._shouldHide) {
|
||||
this._fadeOut();
|
||||
}
|
||||
},
|
||||
|
||||
/// Private methods ///
|
||||
|
||||
_fadeIn : function() {
|
||||
Tweener.removeTweens(this.actor);
|
||||
Tweener.addTween(this.actor, { opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition :"easeInQuad" });
|
||||
},
|
||||
|
||||
_fadeOut : function() {
|
||||
Tweener.removeTweens(this.actor);
|
||||
Tweener.addTween(this.actor, { opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition :"easeOutQuad" });
|
||||
}
|
||||
};
|
||||
|
182
js/ui/calendar.js
Normal file
@ -0,0 +1,182 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
||||
|
||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
function _sameDay(dateA, dateB) {
|
||||
return (dateA.getDate() == dateB.getDate() &&
|
||||
dateA.getMonth() == dateB.getMonth() &&
|
||||
dateA.getYear() == dateB.getYear());
|
||||
}
|
||||
|
||||
function Calendar() {
|
||||
this._init();
|
||||
};
|
||||
|
||||
Calendar.prototype = {
|
||||
_init: function() {
|
||||
// FIXME: This is actually the fallback method for GTK+ for the week start;
|
||||
// GTK+ by preference uses nl_langinfo (NL_TIME_FIRST_WEEKDAY). We probably
|
||||
// should add a C function so we can do the full handling.
|
||||
this._weekStart = NaN;
|
||||
let weekStartString = Gettext_gtk20.gettext("calendar:week_start:0");
|
||||
if (weekStartString.indexOf("calendar:week_start:") == 0) {
|
||||
this._weekStart = parseInt(weekStartString.substring(20));
|
||||
}
|
||||
|
||||
if (isNaN(this._weekStart) || this._weekStart < 0 || this._weekStart > 6) {
|
||||
log("Translation of 'calendar:week_start:0' in GTK+ is not correct");
|
||||
this._weekStart = 0;
|
||||
}
|
||||
|
||||
// Find the ordering for month/year in the calendar heading
|
||||
switch (Gettext_gtk20.gettext("calendar:MY")) {
|
||||
case "calendar:MY":
|
||||
this._headerFormat = "%B %Y";
|
||||
break;
|
||||
case "calendar:YM":
|
||||
this._headerFormat = "%Y %B";
|
||||
break;
|
||||
default:
|
||||
log("Translation of 'calendar:MY' in GTK+ is not correct");
|
||||
this._headerFormat = "%B %Y";
|
||||
break;
|
||||
}
|
||||
|
||||
// Start off with the current date
|
||||
this.date = new Date();
|
||||
|
||||
this.actor = new St.Table({ homogeneous: false,
|
||||
style_class: "calendar",
|
||||
reactive: true });
|
||||
|
||||
this.actor.connect('scroll-event',
|
||||
Lang.bind(this, this._onScroll));
|
||||
|
||||
// Top line of the calendar '<| September 2009 |>'
|
||||
this._topBox = new St.BoxLayout();
|
||||
this.actor.add(this._topBox,
|
||||
{ row: 0, col: 0, col_span: 7 });
|
||||
|
||||
let [backlabel, forwardlabel] = ["<", ">"];
|
||||
if (St.Widget.get_default_direction () == St.TextDirection.RTL) {
|
||||
[backlabel, forwardlabel] = [forwardlabel, backlabel];
|
||||
}
|
||||
|
||||
let back = new St.Button({ label: backlabel, style_class: 'calendar-change-month' });
|
||||
this._topBox.add(back);
|
||||
back.connect("clicked", Lang.bind(this, this._prevMonth));
|
||||
|
||||
this._dateLabel = new St.Label();
|
||||
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||
|
||||
let forward = new St.Button({ label: forwardlabel, style_class: 'calendar-change-month' });
|
||||
this._topBox.add(forward);
|
||||
forward.connect("clicked", Lang.bind(this, this._nextMonth));
|
||||
|
||||
// We need to figure out the abbreviated localized names for the days of the week;
|
||||
// we do this by just getting the next 7 days starting from right now and then putting
|
||||
// them in the right cell in the table. It doesn't matter if we add them in order
|
||||
let iter = new Date(this.date);
|
||||
iter.setSeconds(0); // Leap second protection. Hah!
|
||||
iter.setHours(12);
|
||||
for (let i = 0; i < 7; i++) {
|
||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat("%a") }),
|
||||
{ row: 1,
|
||||
col: (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||
}
|
||||
|
||||
// All the children after this are days, and get removed when we update the calendar
|
||||
this._firstDayIndex = this.actor.get_children().length;
|
||||
|
||||
this._update();
|
||||
},
|
||||
|
||||
// Sets the calendar to show a specific date
|
||||
setDate: function(date) {
|
||||
if (!_sameDay(date, this.date)) {
|
||||
this.date = date;
|
||||
this._update();
|
||||
}
|
||||
},
|
||||
|
||||
_onScroll : function(actor, event) {
|
||||
switch (event.get_scroll_direction()) {
|
||||
case Clutter.ScrollDirection.UP:
|
||||
case Clutter.ScrollDirection.LEFT:
|
||||
this._prevMonth();
|
||||
break;
|
||||
case Clutter.ScrollDirection.DOWN:
|
||||
case Clutter.ScrollDirection.RIGHT:
|
||||
this._nextMonth();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_prevMonth: function() {
|
||||
if (this.date.getMonth() == 0) {
|
||||
this.date.setMonth(11);
|
||||
this.date.setFullYear(this.date.getFullYear() - 1);
|
||||
} else {
|
||||
this.date.setMonth(this.date.getMonth() - 1);
|
||||
}
|
||||
this._update();
|
||||
},
|
||||
|
||||
_nextMonth: function() {
|
||||
if (this.date.getMonth() == 11) {
|
||||
this.date.setMonth(0);
|
||||
this.date.setFullYear(this.date.getFullYear() + 1);
|
||||
} else {
|
||||
this.date.setMonth(this.date.getMonth() + 1);
|
||||
}
|
||||
this._update();
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
this._dateLabel.text = this.date.toLocaleFormat(this._headerFormat);
|
||||
|
||||
// Remove everything but the topBox and the weekday labels
|
||||
let children = this.actor.get_children();
|
||||
for (let i = this._firstDayIndex; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
|
||||
// Start at the beginning of the week before the start of the month
|
||||
let iter = new Date(this.date);
|
||||
iter.setDate(1);
|
||||
iter.setSeconds(0);
|
||||
iter.setHours(12);
|
||||
iter.setTime(iter.getTime() - (iter.getDay() - this._weekStart) * MSECS_IN_DAY);
|
||||
|
||||
let now = new Date();
|
||||
|
||||
let row = 2;
|
||||
while (true) {
|
||||
let label = new St.Label({ text: iter.getDate().toString() });
|
||||
if (_sameDay(now, iter))
|
||||
label.style_class = "calendar-day calendar-today";
|
||||
else if (iter.getMonth() != this.date.getMonth())
|
||||
label.style_class = "calendar-day calendar-other-month-day";
|
||||
else
|
||||
label.style_class = "calendar-day";
|
||||
this.actor.add(label,
|
||||
{ row: row, col: (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
|
||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||
if (iter.getDay() == this._weekStart) {
|
||||
// We stop on the first "first day of the week" after the month we are displaying
|
||||
if (iter.getMonth() > this.date.getMonth() || iter.getYear() > this.date.getYear())
|
||||
break;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
158
js/ui/chrome.js
@ -7,6 +7,7 @@ const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
// This manages the shell "chrome"; the UI that's visible in the
|
||||
// normal mode (ie, outside the Overview), that surrounds the main
|
||||
@ -54,7 +55,7 @@ Chrome.prototype = {
|
||||
|
||||
// addActor:
|
||||
// @actor: an actor to add to the chrome layer
|
||||
// @shapeActor: optional "shape actor".
|
||||
// @params: (optional) additional params
|
||||
//
|
||||
// Adds @actor to the chrome layer and extends the input region
|
||||
// and window manager struts to include it. (Window manager struts
|
||||
@ -64,59 +65,45 @@ Chrome.prototype = {
|
||||
// in its visibility will affect the input region, but NOT the
|
||||
// struts.
|
||||
//
|
||||
// If @shapeActor is provided, it will be used instead of @actor
|
||||
// for the input region/strut shape. (This lets you have things like
|
||||
// drop shadows in @actor that don't affect the struts.) It must
|
||||
// be a child of @actor. Alternatively, you can pass %null for
|
||||
// @shapeActor to indicate that @actor should not affect the input
|
||||
// region or struts at all.
|
||||
addActor: function(actor, shapeActor) {
|
||||
if (shapeActor === undefined)
|
||||
shapeActor = actor;
|
||||
else if (shapeActor && !this._verifyAncestry(shapeActor, actor))
|
||||
throw new Error('shapeActor is not a descendent of actor');
|
||||
// If %visibleInOverview is %true in @params, @actor will remain
|
||||
// visible when the overview is brought up. Otherwise it will
|
||||
// automatically be hidden. If %affectsStruts or %affectsInputRegion
|
||||
// is %false, the actor will not have the indicated effect.
|
||||
addActor: function(actor, params) {
|
||||
params = Params.parse(params, { visibleInOverview: false,
|
||||
affectsStruts: true,
|
||||
affectsInputRegion: true });
|
||||
|
||||
this.nonOverviewActor.add_actor(actor);
|
||||
|
||||
if (shapeActor)
|
||||
this._trackActor(shapeActor, true, true);
|
||||
},
|
||||
|
||||
// setVisibleInOverview:
|
||||
// @actor: an actor in the chrome layer
|
||||
// @visible: Overview visibility
|
||||
//
|
||||
// By default, actors in the chrome layer are automatically hidden
|
||||
// when the Overview is shown. This can be used to override that
|
||||
// behavior
|
||||
setVisibleInOverview: function(actor, visible) {
|
||||
if (!this._verifyAncestry(actor, this.actor))
|
||||
throw new Error('actor is not a descendent of the chrome layer');
|
||||
|
||||
if (visible)
|
||||
actor.reparent(this.actor);
|
||||
if (params.visibleInOverview)
|
||||
this.actor.add_actor(actor);
|
||||
else
|
||||
actor.reparent(this.nonOverviewActor);
|
||||
this.nonOverviewActor.add_actor(actor);
|
||||
|
||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
||||
},
|
||||
|
||||
// addInputRegionActor:
|
||||
// @actor: an actor to add to the stage input region
|
||||
// trackActor:
|
||||
// @actor: a descendant of the chrome to begin tracking
|
||||
// @params: parameters describing how to track @actor
|
||||
//
|
||||
// Adds @actor to the stage input region, as with addActor(), but
|
||||
// for actors that are already descendants of the chrome layer.
|
||||
addInputRegionActor: function(actor) {
|
||||
// Tells the chrome to track @actor, which must be a descendant
|
||||
// of an actor added via addActor(). This can be used to extend the
|
||||
// struts or input region to cover specific children.
|
||||
trackActor: function(actor, params) {
|
||||
if (!this._verifyAncestry(actor, this.actor))
|
||||
throw new Error('actor is not a descendent of the chrome layer');
|
||||
|
||||
this._trackActor(actor, true, false);
|
||||
params = Params.parse(params, { affectsStruts: true,
|
||||
affectsInputRegion: true });
|
||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
||||
},
|
||||
|
||||
// removeInputRegionActor:
|
||||
// @actor: an actor previously added to the stage input region
|
||||
// untrackActor:
|
||||
// @actor: an actor previously tracked via trackActor()
|
||||
//
|
||||
// Undoes the effect of addInputRegionActor()
|
||||
removeInputRegionActor: function(actor) {
|
||||
this._untrackActor(actor, true, false);
|
||||
// Undoes the effect of trackActor()
|
||||
untrackActor: function(actor) {
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
// removeActor:
|
||||
@ -128,7 +115,7 @@ Chrome.prototype = {
|
||||
this.nonOverviewActor.remove_actor(actor);
|
||||
else
|
||||
this.actor.remove_actor(actor);
|
||||
this._untrackActor(actor, true, true);
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
_findActor: function(actor) {
|
||||
@ -142,23 +129,13 @@ Chrome.prototype = {
|
||||
|
||||
_trackActor: function(actor, inputRegion, strut) {
|
||||
let actorData;
|
||||
let i = this._findActor(actor);
|
||||
|
||||
if (i != -1) {
|
||||
actorData = this._trackedActors[i];
|
||||
if (inputRegion)
|
||||
actorData.inputRegion++;
|
||||
if (strut)
|
||||
actorData.strut++;
|
||||
if (!inputRegion && !strut)
|
||||
actorData.children++;
|
||||
return;
|
||||
}
|
||||
if (this._findActor(actor) != -1)
|
||||
throw new Error('trying to re-track existing chrome actor');
|
||||
|
||||
actorData = { actor: actor,
|
||||
inputRegion: inputRegion ? 1 : 0,
|
||||
strut: strut ? 1 : 0,
|
||||
children: 0 };
|
||||
inputRegion: inputRegion,
|
||||
strut: strut };
|
||||
|
||||
actorData.visibleId = actor.connect('notify::visible',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
@ -166,54 +143,31 @@ Chrome.prototype = {
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
actorData.parentSetId = actor.connect('parent-set',
|
||||
Lang.bind(this, this._actorReparented));
|
||||
// Note that destroying actor will unset its parent, so we don't
|
||||
// need to connect to 'destroy' too.
|
||||
|
||||
this._trackedActors.push(actorData);
|
||||
|
||||
actor = actor.get_parent();
|
||||
if (actor != this.actor && actor != this.nonOverviewActor)
|
||||
this._trackActor(actor, false, false);
|
||||
|
||||
if (inputRegion || strut)
|
||||
this._queueUpdateRegions();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_untrackActor: function(actor, inputRegion, strut) {
|
||||
_untrackActor: function(actor) {
|
||||
let i = this._findActor(actor);
|
||||
|
||||
if (i == -1)
|
||||
return;
|
||||
let actorData = this._trackedActors[i];
|
||||
|
||||
if (inputRegion)
|
||||
actorData.inputRegion--;
|
||||
if (strut)
|
||||
actorData.strut--;
|
||||
if (!inputRegion && !strut)
|
||||
actorData.children--;
|
||||
this._trackedActors.splice(i, 1);
|
||||
actor.disconnect(actorData.visibleId);
|
||||
actor.disconnect(actorData.allocationId);
|
||||
actor.disconnect(actorData.parentSetId);
|
||||
|
||||
if (actorData.inputRegion <= 0 && actorData.strut <= 0 && actorData.children <= 0) {
|
||||
this._trackedActors.splice(i, 1);
|
||||
actor.disconnect(actorData.visibleId);
|
||||
actor.disconnect(actorData.allocationId);
|
||||
actor.disconnect(actorData.parentSetId);
|
||||
|
||||
actor = actor.get_parent();
|
||||
if (actor && actor != this.actor && actor != this.nonOverviewActor)
|
||||
this._untrackActor(actor, false, false);
|
||||
}
|
||||
|
||||
if (inputRegion || strut)
|
||||
this._queueUpdateRegions();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_actorReparented: function(actor, oldParent) {
|
||||
if (this._verifyAncestry(actor, this.actor)) {
|
||||
let newParent = actor.get_parent();
|
||||
if (newParent != this.actor && newParent != this.nonOverviewActor)
|
||||
this._trackActor(newParent, false, false);
|
||||
}
|
||||
if (oldParent != this.actor && oldParent != this.nonOverviewActor)
|
||||
this._untrackActor(oldParent, false, false);
|
||||
if (!this._verifyAncestry(actor, this.actor))
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
_overviewShowing: function() {
|
||||
@ -237,6 +191,7 @@ Chrome.prototype = {
|
||||
|
||||
_windowsRestacked: function() {
|
||||
let windows = global.get_windows();
|
||||
let primary = global.get_primary_monitor();
|
||||
|
||||
// The chrome layer should be visible unless there is a window
|
||||
// with layer FULLSCREEN, or a window with layer
|
||||
@ -253,18 +208,21 @@ Chrome.prototype = {
|
||||
this._obscuredByFullscreen = false;
|
||||
for (let i = windows.length - 1; i > -1; i--) {
|
||||
let layer = windows[i].get_meta_window().get_layer();
|
||||
|
||||
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||
if (windows[i].x >= primary.x && windows[i].x <= primary.x + primary.width &&
|
||||
windows[i].y >= primary.y && windows[i].y <= primary.y + primary.height) {
|
||||
this._obscuredByFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT) {
|
||||
if (windows[i].x <= 0 &&
|
||||
windows[i].x + windows[i].width >= global.screen_width &&
|
||||
windows[i].y <= 0 &&
|
||||
windows[i].y + windows[i].height >= global.screen_height) {
|
||||
if (windows[i].x <= primary.x &&
|
||||
windows[i].x + windows[i].width >= primary.x + primary.width &&
|
||||
windows[i].y <= primary.y &&
|
||||
windows[i].y + windows[i].height >= primary.y + primary.height) {
|
||||
this._obscuredByFullscreen = true;
|
||||
break;
|
||||
}
|
||||
} else if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||
this._obscuredByFullscreen = true;
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
894
js/ui/dash.js
213
js/ui/dnd.js
@ -8,6 +8,25 @@ const Tweener = imports.ui.tweener;
|
||||
|
||||
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
||||
|
||||
let eventHandlerActor = null;
|
||||
let currentDraggable = null;
|
||||
|
||||
function _getEventHandlerActor() {
|
||||
if (!eventHandlerActor) {
|
||||
eventHandlerActor = new Clutter.Rectangle();
|
||||
eventHandlerActor.width = 0;
|
||||
eventHandlerActor.height = 0;
|
||||
global.stage.add_actor(eventHandlerActor);
|
||||
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
|
||||
// when you've grabbed the pointer.
|
||||
eventHandlerActor.connect('event',
|
||||
function(actor, event) {
|
||||
return currentDraggable._onEvent(actor, event);
|
||||
});
|
||||
}
|
||||
return eventHandlerActor;
|
||||
}
|
||||
|
||||
function _Draggable(actor, manualMode) {
|
||||
this._init(actor, manualMode);
|
||||
}
|
||||
@ -18,7 +37,11 @@ _Draggable.prototype = {
|
||||
if (!manualMode)
|
||||
this.actor.connect('button-press-event',
|
||||
Lang.bind(this, this._onButtonPress));
|
||||
this._haveSourceGrab = false;
|
||||
this._onEventId = null;
|
||||
|
||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
||||
this._snapBackInProgress = false; // The drag has been cancelled and the item is in the process of snapping back.
|
||||
},
|
||||
|
||||
_onButtonPress : function (actor, event) {
|
||||
@ -27,8 +50,8 @@ _Draggable.prototype = {
|
||||
if (Tweener.getTweenCount(actor))
|
||||
return false;
|
||||
|
||||
this._haveSourceGrab = true;
|
||||
this._grabActor(actor);
|
||||
this._buttonDown = true;
|
||||
this._grabActor();
|
||||
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._dragStartX = stageX;
|
||||
@ -37,41 +60,69 @@ _Draggable.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
_grabActor : function (actor) {
|
||||
Clutter.grab_pointer(actor);
|
||||
|
||||
// We intercept motion and button-release events so that when
|
||||
// you release after dragging, the app doesn't see that and
|
||||
// think you just clicked. We connect to 'event' rather than
|
||||
// 'captured-event' because the capturing phase doesn't happen
|
||||
// when you've grabbed the pointer.
|
||||
this._onEventId = actor.connect('event',
|
||||
Lang.bind(this, this._onEvent));
|
||||
_grabActor: function() {
|
||||
Clutter.grab_pointer(this.actor);
|
||||
this._onEventId = this.actor.connect('event',
|
||||
Lang.bind(this, this._onEvent));
|
||||
},
|
||||
|
||||
_ungrabActor : function (actor) {
|
||||
_ungrabActor: function() {
|
||||
Clutter.ungrab_pointer();
|
||||
actor.disconnect(this._onEventId);
|
||||
this.actor.disconnect(this._onEventId);
|
||||
this._onEventId = null;
|
||||
},
|
||||
|
||||
_onEvent : function (actor, event) {
|
||||
if (this._dragActor) {
|
||||
if (actor != this._dragActor )
|
||||
return false;
|
||||
} else if (actor != this.actor)
|
||||
return false;
|
||||
_grabEvents: function() {
|
||||
Clutter.grab_pointer(_getEventHandlerActor());
|
||||
Clutter.grab_keyboard(_getEventHandlerActor());
|
||||
},
|
||||
|
||||
if (event.type() == Clutter.EventType.BUTTON_RELEASE)
|
||||
return this._onButtonRelease(actor, event);
|
||||
else if (event.type() == Clutter.EventType.MOTION)
|
||||
return this._onMotion(actor, event);
|
||||
else
|
||||
return false;
|
||||
_ungrabEvents: function() {
|
||||
Clutter.ungrab_pointer();
|
||||
Clutter.ungrab_keyboard();
|
||||
},
|
||||
|
||||
_onEvent: function(actor, event) {
|
||||
// We intercept BUTTON_RELEASE event to know that the button was released in case we
|
||||
// didn't start the drag, to drop the draggable in case the drag was in progress, and
|
||||
// to complete the drag and ensure that whatever happens to be under the pointer does
|
||||
// not get triggered if the drag was cancelled with Esc.
|
||||
if (event.type() == Clutter.EventType.BUTTON_RELEASE) {
|
||||
this._buttonDown = false;
|
||||
if (this._dragInProgress) {
|
||||
return this._dragActorDropped(event);
|
||||
} else if (this._dragActor != null && !this._snapBackInProgress) {
|
||||
// Drag must have been cancelled with Esc.
|
||||
this._dragComplete();
|
||||
return true;
|
||||
} else {
|
||||
// Drag has never started.
|
||||
this._ungrabActor();
|
||||
return false;
|
||||
}
|
||||
// We intercept MOTION event to figure out if the drag has started and to draw
|
||||
// this._dragActor under the pointer when dragging is in progress
|
||||
} else if (event.type() == Clutter.EventType.MOTION) {
|
||||
if (this._dragInProgress) {
|
||||
return this._updateDragPosition(event);
|
||||
} else if (this._dragActor == null) {
|
||||
return this._maybeStartDrag(event);
|
||||
}
|
||||
// We intercept KEY_PRESS event so that we can process Esc key press to cancel
|
||||
// dragging and ignore all other key presses.
|
||||
} else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragInProgress) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this._cancelDrag(event.get_time());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* startDrag:
|
||||
* @actor: Origin actor for drag and drop
|
||||
* @stageX: X coordinate of event
|
||||
* @stageY: Y coordinate of event
|
||||
* @time: Event timestamp
|
||||
@ -80,8 +131,14 @@ _Draggable.prototype = {
|
||||
* This function is useful to call if you've specified manualMode
|
||||
* for the draggable.
|
||||
*/
|
||||
startDrag: function (actor, stageX, stageY, time) {
|
||||
startDrag: function (stageX, stageY, time) {
|
||||
currentDraggable = this;
|
||||
this._dragInProgress = true;
|
||||
|
||||
this.emit('drag-begin', time);
|
||||
if (this._onEventId)
|
||||
this._ungrabActor();
|
||||
this._grabEvents();
|
||||
|
||||
this._dragStartX = stageX;
|
||||
this._dragStartY = stageY;
|
||||
@ -112,59 +169,59 @@ _Draggable.prototype = {
|
||||
this._dragActorSource = this.actor;
|
||||
}
|
||||
this._dragOrigParent = undefined;
|
||||
if (this._haveSourceGrab) {
|
||||
this._haveSourceGrab = false;
|
||||
this._ungrabActor(actor);
|
||||
}
|
||||
this._grabActor(this._dragActor);
|
||||
|
||||
this._dragOffsetX = this._dragActor.x - this._dragStartX;
|
||||
this._dragOffsetY = this._dragActor.y - this._dragStartY;
|
||||
} else {
|
||||
this._dragActor = actor;
|
||||
this._dragActor = this.actor;
|
||||
this._dragActorSource = undefined;
|
||||
this._dragOrigParent = actor.get_parent();
|
||||
this._dragOrigParent = this.actor.get_parent();
|
||||
this._dragOrigX = this._dragActor.x;
|
||||
this._dragOrigY = this._dragActor.y;
|
||||
this._dragOrigScale = this._dragActor.scale_x;
|
||||
|
||||
let [actorStageX, actorStageY] = actor.get_transformed_position();
|
||||
let [actorStageX, actorStageY] = this.actor.get_transformed_position();
|
||||
this._dragOffsetX = actorStageX - this._dragStartX;
|
||||
this._dragOffsetY = actorStageY - this._dragStartY;
|
||||
|
||||
// Set the actor's scale such that it will keep the same
|
||||
// transformed size when it's reparented to the stage
|
||||
let [scaledWidth, scaledHeight] = actor.get_transformed_size();
|
||||
actor.set_scale(scaledWidth / actor.width,
|
||||
scaledHeight / actor.height);
|
||||
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
|
||||
this.actor.set_scale(scaledWidth / this.actor.width,
|
||||
scaledHeight / this.actor.height);
|
||||
}
|
||||
|
||||
this._dragActor.reparent(actor.get_stage());
|
||||
this._dragActor.reparent(this.actor.get_stage());
|
||||
this._dragActor.raise_top();
|
||||
},
|
||||
|
||||
_onMotion : function (actor, event) {
|
||||
_maybeStartDrag: function(event) {
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
|
||||
// If we haven't begun a drag, see if the user has moved the
|
||||
// mouse enough to trigger a drag
|
||||
// See if the user has moved the mouse enough to trigger a drag
|
||||
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
|
||||
if (!this._dragActor &&
|
||||
(Math.abs(stageX - this._dragStartX) > threshold ||
|
||||
if ((Math.abs(stageX - this._dragStartX) > threshold ||
|
||||
Math.abs(stageY - this._dragStartY) > threshold)) {
|
||||
this.startDrag(actor, stageX, stageY, event.get_time());
|
||||
this.startDrag(stageX, stageY, event.get_time());
|
||||
this._updateDragPosition(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_updateDragPosition : function (event) {
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
|
||||
// If we are dragging, update the position
|
||||
if (this._dragActor) {
|
||||
this._dragActor.set_position(stageX + this._dragOffsetX,
|
||||
stageY + this._dragOffsetY);
|
||||
// Because we want to find out what other actor is located at the current position of this._dragActor,
|
||||
// we have to temporarily hide this._dragActor.
|
||||
this._dragActor.hide();
|
||||
let target = actor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
stageX + this._dragOffsetX,
|
||||
stageY + this._dragOffsetY);
|
||||
this._dragActor.hide();
|
||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
stageX + this._dragOffsetX,
|
||||
stageY + this._dragOffsetY);
|
||||
this._dragActor.show();
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.handleDragOver) {
|
||||
@ -172,7 +229,7 @@ _Draggable.prototype = {
|
||||
// We currently loop through all parents on drag-over even if one of the children has handled it.
|
||||
// We can check the return value of the function and break the loop if it's true if we don't want
|
||||
// to continue checking the parents.
|
||||
target._delegate.handleDragOver(this.actor._delegate, actor,
|
||||
target._delegate.handleDragOver(this.actor._delegate, this._dragActor,
|
||||
(stageX + this._dragOffsetX - targX) / target.scale_x,
|
||||
(stageY + this._dragOffsetY - targY) / target.scale_y,
|
||||
event.get_time());
|
||||
@ -184,40 +241,42 @@ _Draggable.prototype = {
|
||||
return true;
|
||||
},
|
||||
|
||||
_onButtonRelease : function (actor, event) {
|
||||
this._ungrabActor(actor);
|
||||
|
||||
let dragging = (actor == this._dragActor);
|
||||
this._dragActor = undefined;
|
||||
|
||||
if (!dragging)
|
||||
return false;
|
||||
|
||||
// Find a drop target
|
||||
actor.hide();
|
||||
_dragActorDropped: function(event) {
|
||||
// Find a drop target. Because we want to find out what other actor is located at
|
||||
// the current position of this._dragActor, we have to temporarily hide this._dragActor.
|
||||
this._dragActor.hide();
|
||||
let [dropX, dropY] = event.get_coords();
|
||||
let target = actor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
dropX, dropY);
|
||||
actor.show();
|
||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
dropX, dropY);
|
||||
this._dragActor.show();
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.acceptDrop) {
|
||||
let [targX, targY] = target.get_transformed_position();
|
||||
if (target._delegate.acceptDrop(this.actor._delegate, actor,
|
||||
if (target._delegate.acceptDrop(this.actor._delegate, this._dragActor,
|
||||
(dropX - targX) / target.scale_x,
|
||||
(dropY - targY) / target.scale_y,
|
||||
event.get_time())) {
|
||||
// If it accepted the drop without taking the actor,
|
||||
// destroy it.
|
||||
if (actor.get_parent() == actor.get_stage())
|
||||
actor.destroy();
|
||||
if (this._dragActor.get_parent() == this._dragActor.get_stage())
|
||||
this._dragActor.destroy();
|
||||
|
||||
this._dragInProgress = false;
|
||||
this.emit('drag-end', event.get_time(), true);
|
||||
this._dragComplete();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
target = target.get_parent();
|
||||
}
|
||||
|
||||
this._cancelDrag(event.get_time());
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_cancelDrag: function(eventTime) {
|
||||
this._dragInProgress = false;
|
||||
// Snap back to the actor source if the source is still around, snap back
|
||||
// to the original location if the actor itself was being dragged or the
|
||||
// source is no longer around.
|
||||
@ -227,17 +286,17 @@ _Draggable.prototype = {
|
||||
[snapBackX, snapBackY] = this._dragActorSource.get_transformed_position();
|
||||
}
|
||||
|
||||
this._snapBackInProgress = true;
|
||||
// No target, so snap back
|
||||
Tweener.addTween(actor,
|
||||
Tweener.addTween(this._dragActor,
|
||||
{ x: snapBackX,
|
||||
y: snapBackY,
|
||||
time: SNAP_BACK_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._onSnapBackComplete,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [actor, event.get_time()]
|
||||
onCompleteParams: [this._dragActor, eventTime]
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
||||
_onSnapBackComplete : function (dragActor, eventTime) {
|
||||
@ -249,6 +308,16 @@ _Draggable.prototype = {
|
||||
dragActor.destroy();
|
||||
}
|
||||
this.emit('drag-end', eventTime, false);
|
||||
|
||||
this._snapBackInProgress = false;
|
||||
if (!this._buttonDown)
|
||||
this._dragComplete();
|
||||
},
|
||||
|
||||
_dragComplete: function() {
|
||||
this._dragActor = undefined;
|
||||
currentDraggable = null;
|
||||
this._ungrabEvents();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,13 +8,18 @@ const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
const DND = imports.ui.dnd;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
const Search = imports.ui.search;
|
||||
|
||||
const MAX_DASH_DOCS = 50;
|
||||
const DASH_DOCS_ICON_SIZE = 16;
|
||||
|
||||
const DEFAULT_SPACING = 4;
|
||||
@ -111,19 +116,19 @@ DocDisplayItem.prototype = {
|
||||
/* This class represents a display containing a collection of document items.
|
||||
* The documents are sorted by how recently they were last visited.
|
||||
*/
|
||||
function DocDisplay() {
|
||||
this._init();
|
||||
function DocDisplay(flags) {
|
||||
this._init(flags);
|
||||
}
|
||||
|
||||
DocDisplay.prototype = {
|
||||
__proto__: GenericDisplay.GenericDisplay.prototype,
|
||||
|
||||
_init : function() {
|
||||
GenericDisplay.GenericDisplay.prototype._init.call(this);
|
||||
_init : function(flags) {
|
||||
GenericDisplay.GenericDisplay.prototype._init.call(this, flags);
|
||||
// We keep a single timeout callback for updating last visited times
|
||||
// for all the items in the display. This avoids creating individual
|
||||
// callbacks for each item in the display. So proper time updates
|
||||
// for individual items and item details depend on the item being
|
||||
// for individual items and item details depend on the item being
|
||||
// associated with one of the displays.
|
||||
this._updateTimeoutTargetTime = -1;
|
||||
this._updateTimeoutId = 0;
|
||||
@ -136,7 +141,7 @@ DocDisplay.prototype = {
|
||||
// but redisplaying right away is cool when we use Zephyr.
|
||||
// Also, we might be displaying remote documents, like Google Docs, in the future
|
||||
// which might be edited by someone else.
|
||||
this._redisplay(false);
|
||||
this._redisplay(GenericDisplay.RedisplayFlags.NONE);
|
||||
}));
|
||||
|
||||
this.connect('destroy', Lang.bind(this, function (o) {
|
||||
@ -150,9 +155,11 @@ DocDisplay.prototype = {
|
||||
// Gets the list of recent items from the recent items manager.
|
||||
_refreshCache : function() {
|
||||
if (!this._docsStale)
|
||||
return;
|
||||
this._allItems = this._docManager.getItems();
|
||||
return true;
|
||||
this._allItems = {};
|
||||
Lang.copyProperties(this._docManager.getInfosByUri(), this._allItems);
|
||||
this._docsStale = false;
|
||||
return false;
|
||||
},
|
||||
|
||||
// Sets the list of the displayed items based on how recently they were last visited.
|
||||
@ -171,21 +178,19 @@ DocDisplay.prototype = {
|
||||
// them once when they are returned by this._recentManager.get_items() to avoid having to do
|
||||
// this sorting each time, but the sorting seems to be very fast anyway, so there is no need
|
||||
// to introduce an additional class variable.
|
||||
this._matchedItems = [];
|
||||
this._matchedItems = {};
|
||||
this._matchedItemKeys = [];
|
||||
let docIdsToRemove = [];
|
||||
for (docId in this._allItems) {
|
||||
// this._allItems[docId].exists() checks if the resource still exists
|
||||
if (this._allItems[docId].exists())
|
||||
this._matchedItems.push(docId);
|
||||
else
|
||||
docIdsToRemove.push(docId);
|
||||
this._matchedItems[docId] = 1;
|
||||
this._matchedItemKeys.push(docId);
|
||||
}
|
||||
|
||||
for (docId in docIdsToRemove) {
|
||||
delete this._allItems[docId];
|
||||
}
|
||||
|
||||
this._matchedItems.sort(Lang.bind(this, function (a,b) { return this._compareItems(a,b); }));
|
||||
this._matchedItemKeys.sort(Lang.bind(this, this._compareItems));
|
||||
},
|
||||
|
||||
// Compares items associated with the item ids based on how recently the items
|
||||
@ -270,18 +275,21 @@ DashDocDisplayItem.prototype = {
|
||||
Main.overview.hide();
|
||||
}));
|
||||
|
||||
this.actor._delegate = this;
|
||||
|
||||
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
||||
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
let name = new Clutter.Text({ font_name: "Sans 14px",
|
||||
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: docInfo.name });
|
||||
let name = new St.Label({ style_class: 'dash-recent-docs-item',
|
||||
text: docInfo.name });
|
||||
this.actor.append(name, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
this.actor._delegate = this;
|
||||
},
|
||||
|
||||
getUri: function() {
|
||||
return this._info.uri;
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
@ -298,7 +306,7 @@ DashDocDisplayItem.prototype = {
|
||||
shellWorkspaceLaunch: function () {
|
||||
this._info.launch();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class used to display two column recent documents in the dash
|
||||
@ -313,12 +321,14 @@ DashDocDisplay.prototype = {
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||
this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
|
||||
|
||||
this._actorsByUri = {};
|
||||
|
||||
this._docManager = DocInfo.getDocManager();
|
||||
this._docManager.connect('changed', Lang.bind(this, function(mgr) {
|
||||
this._redisplay();
|
||||
}));
|
||||
this._redisplay();
|
||||
this._docManager.connect('changed', Lang.bind(this, this._onDocsChanged));
|
||||
this._pendingDocsChange = true;
|
||||
this._checkDocExistence = false;
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
@ -347,90 +357,161 @@ DashDocDisplay.prototype = {
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let children = actor.get_children();
|
||||
|
||||
// Two columns, where we go vertically down first. So just take
|
||||
// the height of half of the children as our preferred height.
|
||||
// The width of an item is our allocated width, minus spacing, divided in half.
|
||||
this._itemWidth = Math.floor((forWidth - DEFAULT_SPACING) / 2);
|
||||
|
||||
let firstColumnChildren = children.length / 2;
|
||||
|
||||
alloc.min_size = 0;
|
||||
for (let i = 0; i < firstColumnChildren; i++) {
|
||||
let maxNatural = 0;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let child = children[i];
|
||||
let [minSize, naturalSize] = child.get_preferred_height(forWidth);
|
||||
alloc.natural_size += naturalSize;
|
||||
|
||||
if (i > 0 && i < children.length - 1) {
|
||||
alloc.min_size += DEFAULT_SPACING;
|
||||
alloc.natural_size += DEFAULT_SPACING;
|
||||
}
|
||||
let [minSize, naturalSize] = child.get_preferred_height(this._itemWidth);
|
||||
maxNatural = Math.max(maxNatural, naturalSize);
|
||||
}
|
||||
|
||||
this._itemHeight = maxNatural;
|
||||
|
||||
let firstColumnChildren = Math.ceil(children.length / 2);
|
||||
alloc.natural_size = (firstColumnChildren * maxNatural +
|
||||
(firstColumnChildren - 1) * DEFAULT_SPACING);
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let width = box.x2 - box.x1;
|
||||
let height = box.y2 - box.y1;
|
||||
|
||||
// Make sure this._itemWidth/Height have been computed, even
|
||||
// if the parent actor didn't check our size before allocating.
|
||||
// (Not clear if that is required or not as a Clutter
|
||||
// invariant; this is safe and cheap because of caching.)
|
||||
actor.get_preferred_height(width);
|
||||
|
||||
let children = actor.get_children();
|
||||
|
||||
// The width of an item is our allocated width, minus spacing, divided in half.
|
||||
let itemWidth = Math.floor((width - DEFAULT_SPACING) / 2);
|
||||
let x = box.x1;
|
||||
let y = box.y1;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let columnIndex = 0;
|
||||
let i = 0;
|
||||
// Loop over the children, going vertically down first. When we run
|
||||
// out of vertical space (our y variable is bigger than box.y2), switch
|
||||
// to the second column.
|
||||
for (; i < children.length; i++) {
|
||||
while (i < children.length) {
|
||||
let child = children[i];
|
||||
|
||||
let [minSize, naturalSize] = child.get_preferred_height(-1);
|
||||
|
||||
if (y + naturalSize > box.y2) {
|
||||
// Is this the second column? Ok, break.
|
||||
if (columnIndex == 1) {
|
||||
if (y + this._itemHeight > box.y2) {
|
||||
// Is this the second column, or we're in
|
||||
// the first column and can't even fit one
|
||||
// item? In that case, break.
|
||||
if (columnIndex == 1 || i == 0) {
|
||||
break;
|
||||
}
|
||||
// Set x to the halfway point.
|
||||
columnIndex += 1;
|
||||
x = x + itemWidth + DEFAULT_SPACING;
|
||||
x = x + this._itemWidth + DEFAULT_SPACING;
|
||||
// And y is back to the top.
|
||||
y = box.y1;
|
||||
y = 0;
|
||||
// Retry this same item, now that we're in the second column.
|
||||
// By looping back to the top here, we re-test the size
|
||||
// again for the second column.
|
||||
continue;
|
||||
}
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = y;
|
||||
childBox.x2 = childBox.x1 + itemWidth;
|
||||
childBox.y2 = y + naturalSize;
|
||||
childBox.x2 = childBox.x1 + this._itemWidth;
|
||||
childBox.y2 = y + this._itemHeight;
|
||||
|
||||
y = childBox.y2 + DEFAULT_SPACING;
|
||||
|
||||
child.show();
|
||||
child.allocate(childBox, flags);
|
||||
this.actor.set_skip_paint(child, false);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// Everything else didn't fit, just hide it.
|
||||
for (; i < children.length; i++) {
|
||||
children[i].hide();
|
||||
if (this._checkDocExistence) {
|
||||
// Now we know how many docs we are displaying, queue a check to see if any of them
|
||||
// have been deleted. If they are deleted, then we'll get a 'changed' signal; since
|
||||
// we'll now be displaying items we weren't previously, we'll check again to see
|
||||
// if they were deleted, and so forth and so on.
|
||||
// TODO: We should change this to ask for as many as we can fit in the given space:
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=603522#c23
|
||||
this._docManager.queueExistenceCheck(i);
|
||||
this._checkDocExistence = false;
|
||||
}
|
||||
|
||||
for (; i < children.length; i++)
|
||||
this.actor.set_skip_paint(children[i], true);
|
||||
},
|
||||
|
||||
_onDocsChanged: function() {
|
||||
this._checkDocExistence = true;
|
||||
Main.queueDeferredWork(this._workId);
|
||||
},
|
||||
|
||||
_redisplay: function() {
|
||||
// Should be kept alive by the _actorsByUri
|
||||
this.actor.remove_all();
|
||||
|
||||
let docs = this._docManager.getItems();
|
||||
let docUrls = [];
|
||||
for (let url in docs) {
|
||||
docUrls.push(url);
|
||||
let docs = this._docManager.getTimestampOrderedInfos();
|
||||
for (let i = 0; i < docs.length && i < MAX_DASH_DOCS; i++) {
|
||||
let doc = docs[i];
|
||||
let display = this._actorsByUri[doc.uri];
|
||||
if (display) {
|
||||
this.actor.add_actor(display.actor);
|
||||
} else {
|
||||
let display = new DashDocDisplayItem(doc);
|
||||
this.actor.add_actor(display.actor);
|
||||
this._actorsByUri[doc.uri] = display;
|
||||
}
|
||||
}
|
||||
docUrls.sort(function (urlA, urlB) { return docs[urlB].timestamp - docs[urlA].timestamp; });
|
||||
let textureCache = Shell.TextureCache.get_default();
|
||||
|
||||
for (let i = 0; i < docUrls.length; i++) {
|
||||
let url = docUrls[i];
|
||||
let docInfo = docs[url];
|
||||
let display = new DashDocDisplayItem(docInfo);
|
||||
this.actor.add_actor(display.actor);
|
||||
// Any unparented actors must have been deleted
|
||||
for (let uri in this._actorsByUri) {
|
||||
let display = this._actorsByUri[uri];
|
||||
if (display.actor.get_parent() == null) {
|
||||
display.actor.destroy();
|
||||
delete this._actorsByUri[uri];
|
||||
}
|
||||
}
|
||||
this.emit('changed');
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(DashDocDisplay.prototype);
|
||||
|
||||
function DocSearchProvider() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DocSearchProvider.prototype = {
|
||||
__proto__: Search.SearchProvider.prototype,
|
||||
|
||||
_init: function(name) {
|
||||
Search.SearchProvider.prototype._init.call(this, _("RECENT ITEMS"));
|
||||
this._docManager = DocInfo.getDocManager();
|
||||
},
|
||||
|
||||
getResultMeta: function(resultId) {
|
||||
let docInfo = this._docManager.lookupByUri(resultId);
|
||||
if (!docInfo)
|
||||
return null;
|
||||
return { 'id': resultId,
|
||||
'name': docInfo.name,
|
||||
'icon': docInfo.createIcon(Search.RESULT_ICON_SIZE)};
|
||||
},
|
||||
|
||||
activateResult: function(id) {
|
||||
let docInfo = this._docManager.lookupByUri(id);
|
||||
docInfo.launch();
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms) {
|
||||
return this._docManager.initialSearch(terms);
|
||||
},
|
||||
|
||||
getSubsearchResultSet: function(previousResults, terms) {
|
||||
return this._docManager.subsearch(previousResults, terms);
|
||||
},
|
||||
|
||||
expandSearch: function(terms) {
|
||||
log("TODO expand docs search");
|
||||
}
|
||||
};
|
||||
|
42
js/ui/environment.js
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const St = imports.gi.St;
|
||||
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
||||
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const Format = imports.misc.format;
|
||||
|
||||
// "monkey patch" in some varargs ClutterContainer methods; we need
|
||||
// to do this per-container class since there is no representation
|
||||
// of interfaces in Javascript
|
||||
function _patchContainerClass(containerClass) {
|
||||
// This one is a straightforward mapping of the C method
|
||||
containerClass.prototype.child_set = function(actor, props) {
|
||||
let meta = this.get_child_meta(actor);
|
||||
for (prop in props)
|
||||
meta[prop] = props[prop];
|
||||
};
|
||||
|
||||
// clutter_container_add() actually is a an add-many-actors
|
||||
// method. We conveniently, but somewhat dubiously, take the
|
||||
// this opportunity to make it do something more useful.
|
||||
containerClass.prototype.add = function(actor, props) {
|
||||
this.add_actor(actor);
|
||||
if (props)
|
||||
this.child_set(actor, props);
|
||||
};
|
||||
}
|
||||
|
||||
_patchContainerClass(St.BoxLayout);
|
||||
_patchContainerClass(St.Table);
|
||||
|
||||
function init() {
|
||||
Tweener.init();
|
||||
String.prototype.format = Format.format;
|
||||
|
||||
// Set the default direction for St widgets (this needs to be done before any use of St)
|
||||
if (Gettext_gtk20.gettext("default:LTR") == "default:RTL") {
|
||||
St.Widget.set_default_direction(St.TextDirection.RTL);
|
||||
}
|
||||
}
|
158
js/ui/extensionSystem.js
Normal file
@ -0,0 +1,158 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const ExtensionState = {
|
||||
ENABLED: 1,
|
||||
DISABLED: 2,
|
||||
ERROR: 3,
|
||||
OUT_OF_DATE: 4
|
||||
};
|
||||
|
||||
const ExtensionType = {
|
||||
SYSTEM: 1,
|
||||
PER_USER: 2
|
||||
};
|
||||
|
||||
// Maps uuid -> metadata object
|
||||
const extensionMeta = {};
|
||||
// Maps uuid -> importer object (extension directory tree)
|
||||
const extensions = {};
|
||||
// Array of uuids
|
||||
var disabledExtensions;
|
||||
// GFile for user extensions
|
||||
var userExtensionsDir = null;
|
||||
|
||||
function loadExtension(dir, enabled, type) {
|
||||
let info;
|
||||
let baseErrorString = 'While loading extension from "' + dir.get_parse_name() + '": ';
|
||||
|
||||
let metadataFile = dir.get_child('metadata.json');
|
||||
if (!metadataFile.query_exists(null)) {
|
||||
global.logError(baseErrorString + 'Missing metadata.json');
|
||||
return;
|
||||
}
|
||||
|
||||
let [success, metadataContents, len, etag] = metadataFile.load_contents(null);
|
||||
let meta;
|
||||
try {
|
||||
meta = JSON.parse(metadataContents);
|
||||
} catch (e) {
|
||||
global.logError(baseErrorString + 'Failed to parse metadata.json: ' + e);
|
||||
return;
|
||||
}
|
||||
let requiredProperties = ['uuid', 'name', 'description'];
|
||||
for (let i = 0; i < requiredProperties; i++) {
|
||||
let prop = requiredProperties[i];
|
||||
if (!meta[prop]) {
|
||||
global.logError(baseErrorString + 'missing "' + prop + '" property in metadata.json');
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Encourage people to add this
|
||||
if (!meta['url']) {
|
||||
global.log(baseErrorString + 'Warning: Missing "url" property in metadata.json');
|
||||
}
|
||||
|
||||
let base = dir.get_basename();
|
||||
if (base != meta.uuid) {
|
||||
global.logError(baseErrorString + 'uuid "' + meta.uuid + '" from metadata.json does not match directory name "' + base + '"');
|
||||
return;
|
||||
}
|
||||
|
||||
extensionMeta[meta.uuid] = meta;
|
||||
extensionMeta[meta.uuid].type = type;
|
||||
extensionMeta[meta.uuid].path = dir.get_path();
|
||||
if (!enabled) {
|
||||
extensionMeta[meta.uuid].state = ExtensionState.DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
// Default to error, we set success as the last step
|
||||
extensionMeta[meta.uuid].state = ExtensionState.ERROR;
|
||||
|
||||
let extensionJs = dir.get_child('extension.js');
|
||||
if (!extensionJs.query_exists(null)) {
|
||||
global.logError(baseErrorString + 'Missing extension.js');
|
||||
return;
|
||||
}
|
||||
let stylesheetPath = null;
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
let theme = themeContext.get_theme();
|
||||
let stylesheetFile = dir.get_child('stylesheet.css');
|
||||
if (stylesheetFile.query_exists(null)) {
|
||||
try {
|
||||
theme.load_stylesheet(stylesheetFile.get_path());
|
||||
} catch (e) {
|
||||
global.logError(baseErrorString + 'Stylesheet parse error: ' + e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let extensionModule;
|
||||
try {
|
||||
global.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path());
|
||||
extensionModule = extensions[meta.uuid].extension;
|
||||
} catch (e) {
|
||||
if (stylesheetPath != null)
|
||||
theme.unload_stylesheet(stylesheetPath);
|
||||
global.logError(baseErrorString + e);
|
||||
return;
|
||||
}
|
||||
if (!extensionModule.main) {
|
||||
global.logError(baseErrorString + 'missing \'main\' function');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
extensionModule.main();
|
||||
} catch (e) {
|
||||
if (stylesheetPath != null)
|
||||
theme.unload_stylesheet(stylesheetPath);
|
||||
global.logError(baseErrorString + 'Failed to evaluate main function:' + e);
|
||||
return;
|
||||
}
|
||||
extensionMeta[meta.uuid].state = ExtensionState.ENABLED;
|
||||
global.log('Loaded extension ' + meta.uuid);
|
||||
}
|
||||
|
||||
function init() {
|
||||
let userConfigPath = GLib.get_user_config_dir();
|
||||
let userExtensionsPath = GLib.build_filenamev([userConfigPath, 'gnome-shell', 'extensions']);
|
||||
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
||||
try {
|
||||
userExtensionsDir.make_directory_with_parents(null);
|
||||
} catch (e) {
|
||||
global.logError(""+e);
|
||||
}
|
||||
|
||||
disabledExtensions = Shell.GConf.get_default().get_string_list('disabled_extensions');
|
||||
}
|
||||
|
||||
function _loadExtensionsIn(dir, type) {
|
||||
let fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let file, info;
|
||||
while ((info = fileEnum.next_file(null)) != null) {
|
||||
let fileType = info.get_file_type();
|
||||
if (fileType != Gio.FileType.DIRECTORY)
|
||||
continue;
|
||||
let name = info.get_name();
|
||||
let enabled = disabledExtensions.indexOf(name) < 0;
|
||||
let child = dir.get_child(name);
|
||||
loadExtension(child, enabled, type);
|
||||
}
|
||||
fileEnum.close(null);
|
||||
}
|
||||
|
||||
function loadExtensions() {
|
||||
_loadExtensionsIn(userExtensionsDir, ExtensionType.PER_USER);
|
||||
let systemDataDirs = GLib.get_system_data_dirs();
|
||||
for (let i = 0; i < systemDataDirs.length; i++) {
|
||||
let dirPath = systemDataDirs[i] + '/gnome-shell/extensions';
|
||||
let dir = Gio.file_new_for_path(dirPath);
|
||||
if (dir.query_exists(null))
|
||||
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
|
||||
}
|
||||
}
|
@ -11,20 +11,18 @@ const Meta = imports.gi.Meta;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Signals = imports.signals;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Button = imports.ui.button;
|
||||
const DND = imports.ui.dnd;
|
||||
const Link = imports.ui.link;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ITEM_DISPLAY_NAME_COLOR = new Clutter.Color();
|
||||
ITEM_DISPLAY_NAME_COLOR.from_pixel(0xffffffff);
|
||||
const RedisplayFlags = { NONE: 0,
|
||||
FULL: 1 << 1,
|
||||
SUBSEARCH: 1 << 2,
|
||||
IMMEDIATE: 1 << 3 };
|
||||
|
||||
const ITEM_DISPLAY_DESCRIPTION_COLOR = new Clutter.Color();
|
||||
ITEM_DISPLAY_DESCRIPTION_COLOR.from_pixel(0xffffffbb);
|
||||
const ITEM_DISPLAY_BACKGROUND_COLOR = new Clutter.Color();
|
||||
ITEM_DISPLAY_BACKGROUND_COLOR.from_pixel(0x00000000);
|
||||
const ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR = new Clutter.Color();
|
||||
ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR.from_pixel(0x4f6fadaa);
|
||||
const DISPLAY_CONTROL_SELECTED_COLOR = new Clutter.Color();
|
||||
DISPLAY_CONTROL_SELECTED_COLOR.from_pixel(0x112288ff);
|
||||
const PREVIEW_BOX_BACKGROUND_COLOR = new Clutter.Color();
|
||||
@ -32,10 +30,7 @@ PREVIEW_BOX_BACKGROUND_COLOR.from_pixel(0xADADADf0);
|
||||
|
||||
const DEFAULT_PADDING = 4;
|
||||
|
||||
const ITEM_DISPLAY_HEIGHT = 50;
|
||||
const ITEM_DISPLAY_ICON_SIZE = 48;
|
||||
const ITEM_DISPLAY_PADDING = 1;
|
||||
const ITEM_DISPLAY_PADDING_RIGHT = 2;
|
||||
const DEFAULT_COLUMN_GAP = 6;
|
||||
|
||||
const PREVIEW_ICON_SIZE = 96;
|
||||
@ -46,8 +41,6 @@ const PREVIEW_BOX_CORNER_RADIUS = 10;
|
||||
const PREVIEW_PLACING = 3/4;
|
||||
const PREVIEW_DETAILS_MIN_WIDTH = PREVIEW_ICON_SIZE * 2;
|
||||
|
||||
const INFORMATION_BUTTON_SIZE = 16;
|
||||
|
||||
/* This is a virtual class that represents a single display item containing
|
||||
* a name, a description, and an icon. It allows selecting an item and represents
|
||||
* it by highlighting it with a different background color than the default.
|
||||
@ -58,12 +51,8 @@ function GenericDisplayItem() {
|
||||
|
||||
GenericDisplayItem.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: ITEM_DISPLAY_PADDING,
|
||||
reactive: true,
|
||||
background_color: ITEM_DISPLAY_BACKGROUND_COLOR,
|
||||
corner_radius: 4,
|
||||
height: ITEM_DISPLAY_HEIGHT });
|
||||
this.actor = new St.BoxLayout({ style_class: "generic-display-item",
|
||||
reactive: true });
|
||||
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('button-release-event',
|
||||
@ -75,52 +64,20 @@ GenericDisplayItem.prototype = {
|
||||
}));
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
||||
|
||||
this._infoContent = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_PADDING });
|
||||
this.actor.append(this._infoContent, Big.BoxPackFlags.EXPAND);
|
||||
this._iconBin = new St.Bin();
|
||||
this.actor.add(this._iconBin);
|
||||
|
||||
this._iconBox = new Big.Box();
|
||||
this._infoContent.append(this._iconBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._infoText = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: DEFAULT_PADDING });
|
||||
this._infoContent.append(this._infoText, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let infoIconUri = "file://" + global.imagedir + "info.svg";
|
||||
let infoIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
infoIconUri,
|
||||
INFORMATION_BUTTON_SIZE,
|
||||
INFORMATION_BUTTON_SIZE);
|
||||
this._informationButton = new Button.iconButton(this.actor, INFORMATION_BUTTON_SIZE, infoIcon);
|
||||
let buttonBox = new Big.Box({ width: INFORMATION_BUTTON_SIZE + 2 * DEFAULT_PADDING,
|
||||
height: INFORMATION_BUTTON_SIZE,
|
||||
padding_left: DEFAULT_PADDING, padding_right: DEFAULT_PADDING,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
buttonBox.append(this._informationButton.actor, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(buttonBox, Big.BoxPackFlags.END);
|
||||
|
||||
// Connecting to the button-press-event for the information button ensures that the actor,
|
||||
// which is a draggable actor, does not get the button-press-event and doesn't initiate
|
||||
// the dragging, which then prevents us from getting the button-release-event for the button.
|
||||
this._informationButton.actor.connect('button-press-event',
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
return true;
|
||||
}));
|
||||
this._informationButton.actor.connect('button-release-event',
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
// Selects the item by highlighting it and displaying its details
|
||||
this.emit('show-details');
|
||||
return true;
|
||||
}));
|
||||
this._infoText = new St.BoxLayout({ style_class: 'generic-display-item-text',
|
||||
vertical: true });
|
||||
this.actor.add(this._infoText, { expand: true, y_fill: false });
|
||||
|
||||
this._name = null;
|
||||
this._description = null;
|
||||
this._icon = null;
|
||||
|
||||
this._initialLoadComplete = false;
|
||||
|
||||
// An array of details description actors that we create over time for the item.
|
||||
// It is used for updating the description text inside the details actor when
|
||||
// the description text for the item is updated.
|
||||
@ -145,24 +102,10 @@ GenericDisplayItem.prototype = {
|
||||
|
||||
//// Public methods ////
|
||||
|
||||
// Shows the information button when the item was drawn under the mouse pointer.
|
||||
onDrawnUnderPointer: function() {
|
||||
this._informationButton.show();
|
||||
},
|
||||
|
||||
// Highlights the item by setting a different background color than the default
|
||||
// if isSelected is true, removes the highlighting otherwise.
|
||||
markSelected: function(isSelected) {
|
||||
let color;
|
||||
if (isSelected) {
|
||||
color = ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR;
|
||||
this._informationButton.forceShow(true);
|
||||
}
|
||||
else {
|
||||
color = ITEM_DISPLAY_BACKGROUND_COLOR;
|
||||
this._informationButton.forceShow(false);
|
||||
}
|
||||
this.actor.background_color = color;
|
||||
this.actor.set_style_pseudo_class(isSelected ? "selected" : null);
|
||||
},
|
||||
|
||||
/*
|
||||
@ -178,19 +121,14 @@ GenericDisplayItem.prototype = {
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
|
||||
// Inner box with name and description
|
||||
let textDetails = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
let detailsName = new Clutter.Text({ color: ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans bold 14px",
|
||||
line_wrap: true,
|
||||
text: this._name.text });
|
||||
textDetails.append(detailsName, Big.BoxPackFlags.NONE);
|
||||
let textDetails = new St.BoxLayout({ style_class: 'generic-display-details',
|
||||
vertical: true });
|
||||
let detailsName = new St.Label({ style_class: 'generic-display-details-name',
|
||||
text: this._name.text });
|
||||
textDetails.add(detailsName);
|
||||
|
||||
let detailsDescription = new Clutter.Text({ color: ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans 14px",
|
||||
line_wrap: true,
|
||||
text: this._description.text });
|
||||
textDetails.append(detailsDescription, Big.BoxPackFlags.NONE);
|
||||
let detailsDescription = new St.Label({ text: this._description.text });
|
||||
textDetails.add(detailsDescription);
|
||||
|
||||
this._detailsDescriptions.push(detailsDescription);
|
||||
|
||||
@ -216,7 +154,7 @@ GenericDisplayItem.prototype = {
|
||||
|
||||
// Destroys the item.
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
//// Pure virtual public methods ////
|
||||
@ -253,20 +191,15 @@ GenericDisplayItem.prototype = {
|
||||
}
|
||||
|
||||
this._icon = this._createIcon();
|
||||
this._iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
this._iconBin.set_child(this._icon);
|
||||
|
||||
this._name = new Clutter.Text({ color: ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans 14px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: nameText });
|
||||
this._infoText.append(this._name, Big.BoxPackFlags.EXPAND);
|
||||
this._name = new St.Label({ style_class: "generic-display-item-name",
|
||||
text: nameText });
|
||||
this._infoText.add(this._name);
|
||||
|
||||
this._description = new Clutter.Text({ color: ITEM_DISPLAY_DESCRIPTION_COLOR,
|
||||
font_name: "Sans 12px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: descriptionText ? descriptionText : ""
|
||||
});
|
||||
this._infoText.append(this._description, Big.BoxPackFlags.EXPAND);
|
||||
this._description = new St.Label({ style_class: "generic-display-item-description",
|
||||
text: descriptionText ? descriptionText : "" });
|
||||
this._infoText.add(this._description);
|
||||
},
|
||||
|
||||
// Sets the description text for the item, including the description text
|
||||
@ -298,67 +231,76 @@ GenericDisplayItem.prototype = {
|
||||
// Returns a preview icon for the item.
|
||||
_createPreviewIcon: function() {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
}
|
||||
|
||||
//// Private methods ////
|
||||
|
||||
// Hides the information button once the item starts being dragged.
|
||||
_onDragBegin : function (draggable, time) {
|
||||
// For some reason, we are not getting leave-event signal when we are dragging an item,
|
||||
// so we should remove the link manually.
|
||||
this._informationButton.actor.hide();
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(GenericDisplayItem.prototype);
|
||||
|
||||
const GenericDisplayFlags = {
|
||||
DISABLE_VSCROLLING: 1 << 0
|
||||
}
|
||||
|
||||
/* This is a virtual class that represents a display containing a collection of items
|
||||
* that can be filtered with a search string.
|
||||
*/
|
||||
function GenericDisplay() {
|
||||
this._init();
|
||||
function GenericDisplay(flags) {
|
||||
this._init(flags);
|
||||
}
|
||||
|
||||
GenericDisplay.prototype = {
|
||||
_init : function() {
|
||||
_init : function(flags) {
|
||||
let disableVScrolling = (flags & GenericDisplayFlags.DISABLE_VSCROLLING) != 0;
|
||||
this._search = '';
|
||||
this._expanded = false;
|
||||
|
||||
this._maxItemsPerPage = null;
|
||||
this._list = new Shell.OverflowList({ spacing: 6.0,
|
||||
item_height: ITEM_DISPLAY_HEIGHT });
|
||||
if (disableVScrolling) {
|
||||
this.actor = this._list = new Shell.OverflowList({ spacing: 6,
|
||||
item_height: 50 });
|
||||
} else {
|
||||
this.actor = new St.ScrollView({ x_fill: true, y_fill: true });
|
||||
this.actor.get_hscroll_bar().hide();
|
||||
this._list = new St.BoxLayout({ style_class: 'generic-display-container',
|
||||
vertical: true });
|
||||
this.actor.add_actor(this._list);
|
||||
}
|
||||
|
||||
this._list.connect('notify::n-pages', Lang.bind(this, function () {
|
||||
this._updateDisplayControl(true);
|
||||
}));
|
||||
this._list.connect('notify::page', Lang.bind(this, function () {
|
||||
this._updateDisplayControl(false);
|
||||
}));
|
||||
this._pendingRedisplay = RedisplayFlags.NONE;
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedNotify));
|
||||
|
||||
// map<itemId, Object> where Object represents the item info
|
||||
this._allItems = {};
|
||||
// an array of itemIds of items that match the current request
|
||||
// in the order in which the items should be displayed
|
||||
this._matchedItems = [];
|
||||
// set<itemId>
|
||||
this._matchedItems = {};
|
||||
// sorted array of items matched by search
|
||||
this._matchedItemKeys = [];
|
||||
// map<itemId, GenericDisplayItem>
|
||||
this._displayedItems = {};
|
||||
this._openDetailIndex = -1;
|
||||
this._selectedIndex = -1;
|
||||
// These two are public - .actor is the normal "actor subclass" property,
|
||||
// but we also expose a .displayControl actor which is separate.
|
||||
// See also getNavigationArea.
|
||||
this.actor = this._list;
|
||||
this.displayControl = new Big.Box({ background_color: ITEM_DISPLAY_BACKGROUND_COLOR,
|
||||
spacing: 12,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL});
|
||||
},
|
||||
|
||||
//// Public methods ////
|
||||
|
||||
// Sets the search string and displays the matching items.
|
||||
setSearch: function(text) {
|
||||
this._search = text.toLowerCase();
|
||||
this._redisplay(true);
|
||||
let lowertext = text.toLowerCase();
|
||||
if (lowertext == this._search) {
|
||||
return;
|
||||
}
|
||||
let flags = RedisplayFlags.IMMEDIATE;
|
||||
if (this._search != '') {
|
||||
// Because we combine search terms with OR, we have to be sure that no new term
|
||||
// was introduced before deciding that the new search results will be a subset of
|
||||
// the existing search results.
|
||||
if (lowertext.indexOf(this._search) == 0 &&
|
||||
lowertext.split(/\s+/).length == this._search.split(/\s+/).length) {
|
||||
flags |= RedisplayFlags.SUBSEARCH;
|
||||
}
|
||||
}
|
||||
this._search = lowertext;
|
||||
this._redisplay(flags);
|
||||
},
|
||||
|
||||
// Launches the item that is currently selected, closing the Overview
|
||||
@ -375,7 +317,7 @@ GenericDisplay.prototype = {
|
||||
// to the bottom one. Returns true if the selection actually moved up, false if it wrapped
|
||||
// around to the bottom.
|
||||
selectUp: function() {
|
||||
let count = this._list.displayedCount;
|
||||
let count = this._getVisibleCount();
|
||||
let selectedUp = true;
|
||||
let prev = this._selectedIndex - 1;
|
||||
if (this._selectedIndex <= 0) {
|
||||
@ -390,7 +332,7 @@ GenericDisplay.prototype = {
|
||||
// to the top one. Returns true if the selection actually moved down, false if it wrapped
|
||||
// around to the top.
|
||||
selectDown: function() {
|
||||
let count = this._list.displayedCount;
|
||||
let count = this._getVisibleCount();
|
||||
let selectedDown = true;
|
||||
let next = this._selectedIndex + 1;
|
||||
if (this._selectedIndex == count - 1) {
|
||||
@ -409,7 +351,7 @@ GenericDisplay.prototype = {
|
||||
|
||||
// Selects the last item among the displayed items.
|
||||
selectLastItem: function() {
|
||||
let count = this._list.displayedCount;
|
||||
let count = this._getVisibleCount();
|
||||
if (this.hasItems())
|
||||
this._selectIndex(count - 1);
|
||||
},
|
||||
@ -430,22 +372,24 @@ GenericDisplay.prototype = {
|
||||
// positive number when this._mathedItems.length is 0
|
||||
// This can be triggered if a search string is entered for which there are no matches.
|
||||
// log("this._mathedItems.length: " + this._matchedItems.length + " this._list.displayedCount " + this._list.displayedCount);
|
||||
return this._matchedItems.length > 0;
|
||||
return this._matchedItemKeys.length > 0;
|
||||
},
|
||||
|
||||
getMatchedItemsCount: function() {
|
||||
return this._matchedItems.length;
|
||||
return this._matchedItemKeys.length;
|
||||
},
|
||||
|
||||
// Load the initial state
|
||||
load: function() {
|
||||
this._redisplay(true);
|
||||
this._redisplay(RedisplayFlags.FULL);
|
||||
},
|
||||
|
||||
// Should be called when the display is closed
|
||||
resetState: function() {
|
||||
this._filterReset();
|
||||
this._openDetailIndex = -1;
|
||||
if (!(this.actor instanceof Shell.OverflowList))
|
||||
this.actor.get_vscroll_bar().get_adjustment().value = 0;
|
||||
},
|
||||
|
||||
// Returns an actor which acts as a sidebar; this is used for
|
||||
@ -459,63 +403,18 @@ GenericDisplay.prototype = {
|
||||
return item.createDetailsActor();
|
||||
},
|
||||
|
||||
// Displays the page specified by the pageNumber argument.
|
||||
displayPage: function(pageNumber) {
|
||||
// Cleanup from the previous selection, but don't unset this._selectedIndex
|
||||
if (this.hasSelected()) {
|
||||
this._findDisplayedByIndex(this._selectedIndex).markSelected(false);
|
||||
}
|
||||
this._list.page = pageNumber;
|
||||
},
|
||||
|
||||
//// Protected methods ////
|
||||
|
||||
/*
|
||||
* Displays items that match the current request and should show up on the current page.
|
||||
* Updates the display control to reflect the matched items set and the page selected.
|
||||
*
|
||||
* resetDisplayControl - indicates if the display control should be re-created because
|
||||
* the results or the space allocated for them changed. If it's false,
|
||||
* the existing display control is used and only the page links are
|
||||
* updated to reflect the current page selection.
|
||||
*/
|
||||
_displayMatchedItems: function(resetDisplayControl) {
|
||||
// When generating a new list to display, we first remove all the old
|
||||
// displayed items which will unset the selection. So we need
|
||||
// to keep a flag which indicates if this display had the selection.
|
||||
let hadSelected = this.hasSelected();
|
||||
|
||||
_recreateDisplayItems: function() {
|
||||
this._removeAllDisplayItems();
|
||||
for (let i = 0; i < this._matchedItems.length; i++) {
|
||||
this._addDisplayItem(this._matchedItems[i]);
|
||||
this._setDefaultList();
|
||||
for (let itemId in this._allItems) {
|
||||
this._addDisplayItem(itemId);
|
||||
}
|
||||
|
||||
if (hadSelected) {
|
||||
this._selectedIndex = -1;
|
||||
this.selectFirstItem();
|
||||
}
|
||||
|
||||
// Check if the pointer is over one of the items and display the information button if it is.
|
||||
// We want to do this between finishing our changes to the display and the point where
|
||||
// the display is redrawn.
|
||||
Mainloop.idle_add(Lang.bind(this,
|
||||
function() {
|
||||
let [child, x, y, mask] = Gdk.Screen.get_default().get_root_window().get_pointer();
|
||||
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
|
||||
x, y);
|
||||
if (actor != null) {
|
||||
let item = this._findDisplayedByActor(actor);
|
||||
if (item != null) {
|
||||
item.onDrawnUnderPointer();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
Meta.PRIORITY_BEFORE_REDRAW);
|
||||
},
|
||||
|
||||
// Creates a display item based on the information associated with itemId
|
||||
// and adds it to the displayed items.
|
||||
// Creates a display item based on the information associated with itemId
|
||||
// and adds it to the list of displayed items, but does not yet display it.
|
||||
_addDisplayItem : function(itemId) {
|
||||
if (this._displayedItems.hasOwnProperty(itemId)) {
|
||||
log("Tried adding a display item for " + itemId + ", but an item with this item id is already among displayed items.");
|
||||
@ -529,14 +428,14 @@ GenericDisplay.prototype = {
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
// update the selection
|
||||
this._selectIndex(this._list.get_actor_index(displayItem.actor));
|
||||
this._selectIndex(this._list.get_children().indexOf(displayItem.actor));
|
||||
this.activateSelected();
|
||||
}));
|
||||
|
||||
displayItem.connect('show-details',
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
let index = this._list.get_actor_index(displayItem.actor);
|
||||
let index = this._list.get_children().indexOf(displayItem.actor);
|
||||
/* Close the details pane if already open */
|
||||
if (index == this._openDetailIndex) {
|
||||
this._openDetailIndex = -1;
|
||||
@ -546,15 +445,15 @@ GenericDisplay.prototype = {
|
||||
this.emit('show-details', index);
|
||||
}
|
||||
}));
|
||||
this._list.add_actor(displayItem.actor);
|
||||
this._displayedItems[itemId] = displayItem;
|
||||
},
|
||||
|
||||
// Removes an item identifed by the itemId from the displayed items.
|
||||
_removeDisplayItem: function(itemId) {
|
||||
let count = this._list.displayedCount;
|
||||
let children = this._list.get_children();
|
||||
let count = children.length;
|
||||
let displayItem = this._displayedItems[itemId];
|
||||
let displayItemIndex = this._list.get_actor_index(displayItem.actor);
|
||||
let displayItemIndex = children.indexOf(displayItem.actor);
|
||||
|
||||
if (this.hasSelected() && count == 1) {
|
||||
this.unsetSelected();
|
||||
@ -585,33 +484,120 @@ GenericDisplay.prototype = {
|
||||
this.unsetSelected();
|
||||
},
|
||||
|
||||
_compareSearchMatch: function(a, b) {
|
||||
let countA = this._matchedItems[a];
|
||||
let countB = this._matchedItems[b];
|
||||
if (countA > countB)
|
||||
return -1;
|
||||
else if (countA < countB)
|
||||
return 1;
|
||||
else
|
||||
return this._compareItems(a, b);
|
||||
},
|
||||
|
||||
_setMatches: function(matches) {
|
||||
this._matchedItems = matches;
|
||||
this._matchedItemKeys = [];
|
||||
for (let itemId in this._matchedItems) {
|
||||
this._matchedItemKeys.push(itemId);
|
||||
}
|
||||
this._matchedItemKeys.sort(Lang.bind(this, this._compareSearchMatch));
|
||||
},
|
||||
|
||||
/**
|
||||
* _redisplaySubSearch:
|
||||
* A somewhat more optimized function called when we know
|
||||
* that we're going to be displaying a subset of the items
|
||||
* we already had, in the same order. In that case, we can
|
||||
* just hide the actors that shouldn't be shown.
|
||||
*/
|
||||
_redisplaySubSearch: function() {
|
||||
let matches = this._getSearchMatchedItems(true);
|
||||
|
||||
// Just hide all from the old set,
|
||||
// we'll show the ones we want below
|
||||
for (let itemId in this._displayedItems) {
|
||||
let item = this._displayedItems[itemId];
|
||||
item.actor.hide();
|
||||
}
|
||||
|
||||
this._setMatches(matches);
|
||||
|
||||
for (let itemId in matches) {
|
||||
let item = this._displayedItems[itemId];
|
||||
item.actor.show();
|
||||
}
|
||||
this._list.queue_relayout();
|
||||
},
|
||||
|
||||
_redisplayReordering: function() {
|
||||
if (!this._filterActive()) {
|
||||
this._setDefaultList();
|
||||
} else {
|
||||
this._setMatches(this._getSearchMatchedItems(false));
|
||||
}
|
||||
this._list.remove_all();
|
||||
for (let i = 0; i < this._matchedItemKeys.length; i++) {
|
||||
let itemId = this._matchedItemKeys[i];
|
||||
let item = this._displayedItems[itemId];
|
||||
item.actor.show();
|
||||
this._list.add_actor(item.actor);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Updates the displayed items, applying the search string if one exists.
|
||||
*
|
||||
* resetPage - indicates if the page selection should be reset when displaying the matching results.
|
||||
* We reset the page selection when the change in results was initiated by the user by
|
||||
* entering a different search criteria or by viewing the results list in a different
|
||||
* size mode, but we keep the page selection the same if the results got updated on
|
||||
* their own while the user was browsing through the result pages.
|
||||
* @flags: Flags controlling redisplay behavior as follows:
|
||||
* SUBSEARCH - Indicates that the current _search is a superstring of the previous
|
||||
* one, which implies we only need to re-search through previous results.
|
||||
* FULL - Indicates that we need recreate all displayed items.
|
||||
* IMMEDIATE - Do the full redisplay even if we're not mapped. This is useful
|
||||
* if you want to get the number of matched items and show/hide a section based on
|
||||
* that number.
|
||||
*/
|
||||
_redisplay: function(resetPage) {
|
||||
this._refreshCache();
|
||||
if (!this._filterActive())
|
||||
this._setDefaultList();
|
||||
else
|
||||
this._doSearchFilter();
|
||||
_redisplay: function(flags) {
|
||||
let immediate = (flags & RedisplayFlags.IMMEDIATE) != 0;
|
||||
if (!immediate && !this.actor.mapped) {
|
||||
this._pendingRedisplay |= flags;
|
||||
return;
|
||||
}
|
||||
|
||||
if (resetPage)
|
||||
this._list.page = 0;
|
||||
let isSubSearch = (flags & RedisplayFlags.SUBSEARCH) != 0;
|
||||
let fullReload = (flags & RedisplayFlags.FULL) != 0;
|
||||
|
||||
this._displayMatchedItems(true);
|
||||
let hadSelected = this.hasSelected();
|
||||
this.unsetSelected();
|
||||
|
||||
if (!this._initialLoadComplete)
|
||||
fullReload = true;
|
||||
|
||||
if (!this._refreshCache())
|
||||
fullReload = true;
|
||||
|
||||
if (fullReload) {
|
||||
this._recreateDisplayItems();
|
||||
this._initialLoadComplete = true;
|
||||
}
|
||||
|
||||
if (isSubSearch) {
|
||||
this._redisplaySubSearch();
|
||||
} else {
|
||||
this._redisplayReordering();
|
||||
}
|
||||
|
||||
if (hadSelected) {
|
||||
this._selectedIndex = -1;
|
||||
this.selectFirstItem();
|
||||
}
|
||||
|
||||
this.emit('redisplayed');
|
||||
},
|
||||
|
||||
//// Pure virtual protected methods ////
|
||||
|
||||
|
||||
// Performs the steps needed to have the latest information about the items.
|
||||
// Implementation should return %true if we are up to date, and %false
|
||||
// if a full reload occurred.
|
||||
_refreshCache: function() {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
@ -622,10 +608,10 @@ GenericDisplay.prototype = {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
|
||||
// Compares items associated with the item ids based on the order in which the
|
||||
// items should be displayed.
|
||||
// Intended to be used as a compareFunction for array.sort().
|
||||
// Returns an integer value indicating the result of the comparison.
|
||||
// Compares items associated with the item ids based on the order in which the
|
||||
// items should be displayed.
|
||||
// Intended to be used as a compareFunction for array.sort().
|
||||
// Returns an integer value indicating the result of the comparison.
|
||||
_compareItems: function(itemIdA, itemIdB) {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
@ -643,111 +629,50 @@ GenericDisplay.prototype = {
|
||||
|
||||
//// Private methods ////
|
||||
|
||||
_getSearchMatchedItems: function() {
|
||||
let matchedItemsForSearch = {};
|
||||
_getItemSearchScore: function(itemId, terms) {
|
||||
let item = this._allItems[itemId];
|
||||
let score = 0;
|
||||
for (let i = 0; i < terms.length; i++) {
|
||||
let term = terms[i];
|
||||
if (this._isInfoMatching(item, term)) {
|
||||
score++;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
},
|
||||
|
||||
_getSearchMatchedItems: function(isSubSearch) {
|
||||
// Break the search up into terms, and search for each
|
||||
// individual term. Keep track of the number of terms
|
||||
// each item matched.
|
||||
let terms = this._search.split(/\s+/);
|
||||
for (let i = 0; i < terms.length; i++) {
|
||||
let term = terms[i];
|
||||
for (itemId in this._allItems) {
|
||||
let item = this._allItems[itemId];
|
||||
if (this._isInfoMatching(item, term)) {
|
||||
let count = matchedItemsForSearch[itemId];
|
||||
if (!count)
|
||||
count = 0;
|
||||
count += 1;
|
||||
matchedItemsForSearch[itemId] = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchedItemsForSearch;
|
||||
},
|
||||
let matchScores = {};
|
||||
|
||||
// Applies the search string to the list of items to find matches,
|
||||
// and displays the matching items.
|
||||
_doSearchFilter: function() {
|
||||
let matchedItemsForSearch;
|
||||
|
||||
if (this._filterActive()) {
|
||||
matchedItemsForSearch = this._getSearchMatchedItems();
|
||||
} else {
|
||||
matchedItemsForSearch = {};
|
||||
for (let itemId in this._allItems) {
|
||||
matchedItemsForSearch[itemId] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
this._matchedItems = [];
|
||||
for (itemId in matchedItemsForSearch) {
|
||||
this._matchedItems.push(itemId);
|
||||
}
|
||||
this._matchedItems.sort(Lang.bind(this, function (a, b) {
|
||||
let countA = matchedItemsForSearch[a];
|
||||
let countB = matchedItemsForSearch[b];
|
||||
if (countA > countB)
|
||||
return -1;
|
||||
else if (countA < countB)
|
||||
return 1;
|
||||
else
|
||||
return this._compareItems(a, b);
|
||||
}));
|
||||
},
|
||||
|
||||
/*
|
||||
* Updates the display control to reflect the matched items set and the page selected.
|
||||
*
|
||||
* resetDisplayControl - indicates if the display control should be re-created because
|
||||
* the results or the space allocated for them changed. If it's false,
|
||||
* the existing display control is used and only the page links are
|
||||
* updated to reflect the current page selection.
|
||||
*/
|
||||
_updateDisplayControl: function(resetDisplayControl) {
|
||||
if (resetDisplayControl) {
|
||||
this.displayControl.remove_all();
|
||||
let nPages = this._list.n_pages;
|
||||
// Don't show the page indicator if there is only one page.
|
||||
if (nPages == 1)
|
||||
return;
|
||||
let pageNumber = this._list.page;
|
||||
for (let i = 0; i < nPages; i++) {
|
||||
let pageControl = new Link.Link({ color: (i == pageNumber) ? DISPLAY_CONTROL_SELECTED_COLOR : ITEM_DISPLAY_DESCRIPTION_COLOR,
|
||||
font_name: "Sans Bold 16px",
|
||||
text: (i+1) + "",
|
||||
reactive: (i == pageNumber) ? false : true});
|
||||
this.displayControl.append(pageControl.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
// we use pageNumberLocalScope to get the page number right in the callback function
|
||||
let pageNumberLocalScope = i;
|
||||
pageControl.connect('clicked',
|
||||
Lang.bind(this,
|
||||
function(o, event) {
|
||||
this.displayPage(pageNumberLocalScope);
|
||||
}));
|
||||
if (isSubSearch) {
|
||||
for (let i = 0; i < this._matchedItemKeys.length; i++) {
|
||||
let itemId = this._matchedItemKeys[i];
|
||||
let score = this._getItemSearchScore(itemId, terms);
|
||||
if (score > 0)
|
||||
matchScores[itemId] = score;
|
||||
}
|
||||
} else {
|
||||
let pageControlActors = this.displayControl.get_children();
|
||||
for (let i = 0; i < pageControlActors.length; i++) {
|
||||
let pageControlActor = pageControlActors[i];
|
||||
if (i == this._list.page) {
|
||||
pageControlActor.color = DISPLAY_CONTROL_SELECTED_COLOR;
|
||||
pageControlActor.reactive = false;
|
||||
} else {
|
||||
pageControlActor.color = ITEM_DISPLAY_DESCRIPTION_COLOR;
|
||||
pageControlActor.reactive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.hasSelected()) {
|
||||
this.selectFirstItem();
|
||||
for (let itemId in this._displayedItems) {
|
||||
let score = this._getItemSearchScore(itemId, terms);
|
||||
if (score > 0)
|
||||
matchScores[itemId] = score;
|
||||
}
|
||||
}
|
||||
return matchScores;
|
||||
},
|
||||
|
||||
// Returns a display item based on its index in the ordering of the
|
||||
// display children.
|
||||
_findDisplayedByIndex: function(index) {
|
||||
let actor = this._list.get_displayed_actor(index);
|
||||
let actor;
|
||||
if (this.actor instanceof Shell.OverflowList)
|
||||
actor = this.actor.get_displayed_actor(index);
|
||||
else
|
||||
actor = this._list.get_children()[index];
|
||||
return this._findDisplayedByActor(actor);
|
||||
},
|
||||
|
||||
@ -779,6 +704,20 @@ GenericDisplay.prototype = {
|
||||
let item = this._findDisplayedByIndex(index);
|
||||
item.markSelected(true);
|
||||
this.emit('selected');
|
||||
},
|
||||
|
||||
_getVisibleCount: function() {
|
||||
if (this.actor instanceof Shell.OverflowList)
|
||||
return this._list.displayed_count;
|
||||
return this._list.get_n_children();
|
||||
},
|
||||
|
||||
_onMappedNotify: function () {
|
||||
let mapped = this.actor.mapped;
|
||||
if (mapped && this._pendingRedisplay > RedisplayFlags.NONE)
|
||||
this._redisplay(this._pendingRedisplay);
|
||||
|
||||
this._pendingRedisplay = RedisplayFlags.NONE;
|
||||
}
|
||||
};
|
||||
|
||||
|
158
js/ui/lightbox.js
Normal file
@ -0,0 +1,158 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const SHADE_COLOR = new Clutter.Color();
|
||||
SHADE_COLOR.from_pixel(0x00000044);
|
||||
|
||||
/**
|
||||
* Lightbox:
|
||||
* @container: parent Clutter.Container
|
||||
* @inhibitEvents: whether to inhibit events for @container
|
||||
* @width: (optional) shade actor width
|
||||
* @height: (optional) shade actor height
|
||||
*
|
||||
* Lightbox creates a dark translucent "shade" actor to hide the
|
||||
* contents of @container, and allows you to specify particular actors
|
||||
* in @container to highlight by bringing them above the shade. It
|
||||
* tracks added and removed actors in @container while the lightboxing
|
||||
* is active, and ensures that all actors are returned to their
|
||||
* original stacking order when the lightboxing is removed. (However,
|
||||
* if actors are restacked by outside code while the lightboxing is
|
||||
* active, the lightbox may later revert them back to their original
|
||||
* order.)
|
||||
*
|
||||
* By default, the shade window will have the height and width of
|
||||
* @container and will track any changes in its size. You can override
|
||||
* this by passing an explicit width and height
|
||||
*/
|
||||
function Lightbox(container, inhibitEvents, width, height) {
|
||||
this._init(container, inhibitEvents, width, height);
|
||||
}
|
||||
|
||||
Lightbox.prototype = {
|
||||
_init : function(container, inhibitEvents, width, height) {
|
||||
this._container = container;
|
||||
this._children = container.get_children();
|
||||
this.actor = new Clutter.Rectangle({ color: SHADE_COLOR,
|
||||
x: 0,
|
||||
y: 0,
|
||||
border_width: 0,
|
||||
reactive: inhibitEvents });
|
||||
|
||||
container.add_actor(this.actor);
|
||||
this.actor.raise_top();
|
||||
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
if (width && height) {
|
||||
this.actor.width = width;
|
||||
this.actor.height = height;
|
||||
this._allocationChangedSignalId = 0;
|
||||
} else {
|
||||
this.actor.width = container.width;
|
||||
this.actor.height = container.height;
|
||||
this._allocationChangedSignalId = container.connect('allocation-changed', Lang.bind(this, this._allocationChanged));
|
||||
}
|
||||
|
||||
this._actorAddedSignalId = container.connect('actor-added', Lang.bind(this, this._actorAdded));
|
||||
this._actorRemovedSignalId = container.connect('actor-removed', Lang.bind(this, this._actorRemoved));
|
||||
|
||||
this._highlighted = null;
|
||||
},
|
||||
|
||||
_allocationChanged : function(container, box, flags) {
|
||||
this.actor.width = this._container.width;
|
||||
this.actor.height = this._container.height;
|
||||
},
|
||||
|
||||
_actorAdded : function(container, newChild) {
|
||||
let children = this._container.get_children();
|
||||
let myIndex = children.indexOf(this.actor);
|
||||
let newChildIndex = children.indexOf(newChild);
|
||||
|
||||
if (newChildIndex > myIndex) {
|
||||
// The child was added above the shade (presumably it was
|
||||
// made the new top-most child). Move it below the shade,
|
||||
// and add it to this._children as the new topmost actor.
|
||||
newChild.lower(this.actor);
|
||||
this._children.push(newChild);
|
||||
} else if (newChildIndex == 0) {
|
||||
// Bottom of stack
|
||||
this._children.unshift(newChild);
|
||||
} else {
|
||||
// Somewhere else; insert it into the correct spot
|
||||
let prevChild = this._children.indexOf(children[newChildIndex - 1]);
|
||||
if (prevChild != -1) // paranoia
|
||||
this._children.splice(prevChild + 1, 0, newChild);
|
||||
}
|
||||
},
|
||||
|
||||
_actorRemoved : function(container, child) {
|
||||
let index = this._children.indexOf(child);
|
||||
if (index != -1) // paranoia
|
||||
this._children.splice(index, 1);
|
||||
|
||||
if (child == this._highlighted)
|
||||
this._highlighted = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* highlight:
|
||||
* @window: actor to highlight
|
||||
*
|
||||
* Highlights the indicated actor and unhighlights any other
|
||||
* currently-highlighted actor. With no arguments or a false/null
|
||||
* argument, all actors will be unhighlighted.
|
||||
*/
|
||||
highlight : function(window) {
|
||||
if (this._highlighted == window)
|
||||
return;
|
||||
|
||||
// Walk this._children raising and lowering actors as needed.
|
||||
// Things get a little tricky if the to-be-raised and
|
||||
// to-be-lowered actors were originally adjacent, in which
|
||||
// case we may need to indicate some *other* actor as the new
|
||||
// sibling of the to-be-lowered one.
|
||||
|
||||
let below = this.actor;
|
||||
for (let i = this._children.length - 1; i >= 0; i--) {
|
||||
if (this._children[i] == window)
|
||||
this._children[i].raise_top();
|
||||
else if (this._children[i] == this._highlighted)
|
||||
this._children[i].lower(below);
|
||||
else
|
||||
below = this._children[i];
|
||||
}
|
||||
|
||||
this._highlighted = window;
|
||||
},
|
||||
|
||||
/**
|
||||
* destroy:
|
||||
*
|
||||
* Destroys the lightbox.
|
||||
*/
|
||||
destroy : function() {
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* _onDestroy:
|
||||
*
|
||||
* This is called when the lightbox' actor is destroyed, either
|
||||
* by destroying its container or by explicitly calling this.destroy().
|
||||
*/
|
||||
_onDestroy: function() {
|
||||
if (this._allocationChangedSignalId != 0)
|
||||
this._container.disconnect(this._allocationChangedSignalId);
|
||||
this._container.disconnect(this._actorAddedSignalId);
|
||||
this._container.disconnect(this._actorRemovedSignalId);
|
||||
|
||||
this.highlight(null);
|
||||
}
|
||||
};
|
@ -3,78 +3,21 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
// Link is a clickable link. Right now it just handles properly capturing
|
||||
// press and release events and short-circuiting the button handling in
|
||||
// ClutterText, but more features like different colors for hover/pressed states
|
||||
// or a different mouse cursor could be implemented.
|
||||
//
|
||||
// The properties passed in are forwarded to the Clutter.Text() constructor,
|
||||
// so can include, 'text', 'font_name', etc.
|
||||
function Link(props) {
|
||||
this._init(props);
|
||||
}
|
||||
|
||||
Link.prototype = {
|
||||
_init : function(props) {
|
||||
let realProps = { reactive: true };
|
||||
let realProps = { reactive: true,
|
||||
style_class: 'shell-link' };
|
||||
// The user can pass in reactive: false to override the above and get
|
||||
// a non-reactive link (a link to the current page, perhaps)
|
||||
Lang.copyProperties(props, realProps);
|
||||
Lang.copyProperties(props, realProps);
|
||||
|
||||
this.actor = new Clutter.Text(realProps);
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||
this.actor.connect('enter-event', Lang.bind(this, this._onEnter));
|
||||
this.actor.connect('leave-event', Lang.bind(this, this._onLeave));
|
||||
|
||||
this._buttonDown = false;
|
||||
this._havePointer = false;
|
||||
},
|
||||
|
||||
// Update the text of the link
|
||||
setText : function(text) {
|
||||
this.actor.text = text;
|
||||
},
|
||||
|
||||
// We want to react on buttonDown, but if we override button-release-event for
|
||||
// ClutterText, but not button-press-event, we get a stuck grab. Tracking
|
||||
// buttonDown and doing the grab isn't really necessary, but doing it makes
|
||||
// the behavior perfectly correct if the user clicks on one actor, drags
|
||||
// to another and releases - that should not trigger either actor.
|
||||
_onButtonPress : function(actor, event) {
|
||||
this._buttonDown = true;
|
||||
this._havePointer = true; // Hack to work around poor enter/leave tracking in Clutter
|
||||
Clutter.grab_pointer(actor);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_onButtonRelease : function(actor, event) {
|
||||
if (this._buttonDown) {
|
||||
this._buttonDown = false;
|
||||
Clutter.ungrab_pointer(actor);
|
||||
|
||||
if (this._havePointer)
|
||||
this.emit('clicked');
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_onEnter : function(actor, event) {
|
||||
if (event.get_source() == actor)
|
||||
this._havePointer = true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_onLeave : function(actor, event) {
|
||||
if (event.get_source() == actor)
|
||||
this._havePointer = false;
|
||||
|
||||
return false;
|
||||
this.actor = new St.Button(realProps);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,26 +4,20 @@ const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Pango = imports.gi.Pango;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const ExtensionSystem = imports.ui.extensionSystem;
|
||||
const Link = imports.ui.link;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const LG_BORDER_COLOR = new Clutter.Color();
|
||||
LG_BORDER_COLOR.from_pixel(0x0000aca0);
|
||||
const LG_BACKGROUND_COLOR = new Clutter.Color();
|
||||
LG_BACKGROUND_COLOR.from_pixel(0x000000d5);
|
||||
const GREY = new Clutter.Color();
|
||||
GREY.from_pixel(0xAFAFAFFF);
|
||||
const MATRIX_GREEN = new Clutter.Color();
|
||||
MATRIX_GREEN.from_pixel(0x88ff66ff);
|
||||
// FIXME pull from GConf
|
||||
const MATRIX_FONT = 'Monospace 10';
|
||||
|
||||
/* Imports...feel free to add here as needed */
|
||||
/* Imports...feel free to add here as needed */
|
||||
var commandHeader = "const Clutter = imports.gi.Clutter; " +
|
||||
"const GLib = imports.gi.GLib; " +
|
||||
"const Gtk = imports.gi.Gtk; " +
|
||||
@ -47,32 +41,41 @@ function Notebook() {
|
||||
|
||||
Notebook.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new Big.Box();
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
|
||||
this.tabControls = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4, padding: 2 });
|
||||
this.tabControls = new St.BoxLayout({ style_class: "labels" });
|
||||
|
||||
this._selectedIndex = -1;
|
||||
this._tabs = [];
|
||||
},
|
||||
|
||||
appendPage: function(name, child) {
|
||||
let labelOuterBox = new Big.Box({ padding: 2 });
|
||||
let labelBox = new Big.Box({ padding: 2, border_color: MATRIX_GREEN,
|
||||
reactive: true });
|
||||
labelOuterBox.append(labelBox, Big.BoxPackFlags.NONE);
|
||||
let label = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
text: name });
|
||||
labelBox.connect('button-press-event', Lang.bind(this, function () {
|
||||
let labelBox = new St.BoxLayout({ style_class: "notebook-tab" });
|
||||
let label = new St.Button({ label: name });
|
||||
label.connect('clicked', Lang.bind(this, function () {
|
||||
this.selectChild(child);
|
||||
return true;
|
||||
}));
|
||||
labelBox.append(label, Big.BoxPackFlags.EXPAND);
|
||||
this._tabs.push([child, labelBox]);
|
||||
child.hide();
|
||||
this.actor.append(child, Big.BoxPackFlags.EXPAND);
|
||||
this.tabControls.append(labelOuterBox, Big.BoxPackFlags.NONE);
|
||||
labelBox.add(label, { expand: true });
|
||||
this.tabControls.add(labelBox);
|
||||
|
||||
let scrollview = new St.ScrollView({ x_fill: true, y_fill: true });
|
||||
scrollview.get_hscroll_bar().hide();
|
||||
scrollview.add_actor(child);
|
||||
|
||||
let tabData = { child: child,
|
||||
labelBox: labelBox,
|
||||
label: label,
|
||||
scrollView: scrollview,
|
||||
_scrollToBottom: false };
|
||||
this._tabs.push(tabData);
|
||||
scrollview.hide();
|
||||
this.actor.add(scrollview, { expand: true });
|
||||
|
||||
let vAdjust = scrollview.vscroll.adjustment;
|
||||
vAdjust.connect('changed', Lang.bind(this, function () { this._onAdjustScopeChanged(tabData); }));
|
||||
vAdjust.connect('notify::value', Lang.bind(this, function() { this._onAdjustValueChanged(tabData); }));
|
||||
|
||||
if (this._selectedIndex == -1)
|
||||
this.selectIndex(0);
|
||||
},
|
||||
@ -80,10 +83,9 @@ Notebook.prototype = {
|
||||
_unselect: function() {
|
||||
if (this._selectedIndex < 0)
|
||||
return;
|
||||
let [child, labelBox] = this._tabs[this._selectedIndex];
|
||||
labelBox.padding = 2;
|
||||
labelBox.border = 0;
|
||||
child.hide();
|
||||
let tabData = this._tabs[this._selectedIndex];
|
||||
tabData.labelBox.set_style_pseudo_class(null);
|
||||
tabData.scrollView.hide();
|
||||
this._selectedIndex = -1;
|
||||
},
|
||||
|
||||
@ -95,12 +97,11 @@ Notebook.prototype = {
|
||||
this.emit('selection', null);
|
||||
return;
|
||||
}
|
||||
let [child, labelBox] = this._tabs[index];
|
||||
labelBox.padding = 1;
|
||||
labelBox.border = 1;
|
||||
child.show();
|
||||
let tabData = this._tabs[index];
|
||||
tabData.labelBox.set_style_pseudo_class('selected');
|
||||
tabData.scrollView.show();
|
||||
this._selectedIndex = index;
|
||||
this.emit('selection', child);
|
||||
this.emit('selection', tabData.child);
|
||||
},
|
||||
|
||||
selectChild: function(child) {
|
||||
@ -108,13 +109,32 @@ Notebook.prototype = {
|
||||
this.selectIndex(-1);
|
||||
else {
|
||||
for (let i = 0; i < this._tabs.length; i++) {
|
||||
let [tabChild, labelBox] = this._tabs[i];
|
||||
if (tabChild == child) {
|
||||
let tabData = this._tabs[i];
|
||||
if (tabData.child == child) {
|
||||
this.selectIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scrollToBottom: function(index) {
|
||||
let tabData = this._tabs[index];
|
||||
tabData._scrollToBottom = true;
|
||||
|
||||
},
|
||||
|
||||
_onAdjustValueChanged: function (tabData) {
|
||||
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
||||
if (vAdjust.value < (vAdjust.upper - vAdjust.lower - 0.5))
|
||||
tabData._scrolltoBottom = false;
|
||||
},
|
||||
|
||||
_onAdjustScopeChanged: function (tabData) {
|
||||
if (!tabData._scrollToBottom)
|
||||
return;
|
||||
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
||||
vAdjust.value = vAdjust.upper - vAdjust.page_size;
|
||||
}
|
||||
}
|
||||
Signals.addSignalMethods(Notebook.prototype);
|
||||
@ -130,20 +150,19 @@ Result.prototype = {
|
||||
|
||||
this.actor = new Big.Box();
|
||||
|
||||
let cmdTxt = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: command });
|
||||
let cmdTxt = new St.Label({ text: command });
|
||||
cmdTxt.ellipsize = Pango.EllipsizeMode.END;
|
||||
|
||||
this.actor.append(cmdTxt, Big.BoxPackFlags.NONE);
|
||||
let resultTxt = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: "r(" + index + ") = " + o });
|
||||
let resultTxt = new St.Label({ text: "r(" + index + ") = " + o });
|
||||
resultTxt.ellipsize = Pango.EllipsizeMode.END;
|
||||
|
||||
this.actor.append(resultTxt, Big.BoxPackFlags.NONE);
|
||||
let line = new Big.Box({ border_color: GREY,
|
||||
border_bottom: 1,
|
||||
height: 8 });
|
||||
this.actor.append(line, Big.BoxPackFlags.NONE);
|
||||
let line = new Clutter.Rectangle({ name: "Separator",
|
||||
height: 1 });
|
||||
let padBin = new St.Bin({ name: "Separator", x_fill: true, y_fill: true });
|
||||
padBin.add_actor(line);
|
||||
this.actor.append(padBin, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,17 +177,14 @@ ActorHierarchy.prototype = {
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
this.actor = new Big.Box({ spacing: 4,
|
||||
border: 1,
|
||||
padding: 4,
|
||||
border_color: GREY });
|
||||
this.actor = new St.BoxLayout({ name: "ActorHierarchy", vertical: true });
|
||||
},
|
||||
|
||||
setTarget: function(actor) {
|
||||
this._previousTarget = this._target;
|
||||
this.target = actor;
|
||||
|
||||
this.actor.remove_all();
|
||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
||||
|
||||
if (!(actor instanceof Clutter.Actor))
|
||||
return;
|
||||
@ -181,11 +197,9 @@ ActorHierarchy.prototype = {
|
||||
while ((parent = parent.get_parent()) != null) {
|
||||
this._parentList.push(parent);
|
||||
|
||||
let link = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
reactive: true,
|
||||
text: "" + parent });
|
||||
this.actor.append(link, Big.BoxPackFlags.IF_FITS);
|
||||
let link = new St.Label({ reactive: true,
|
||||
text: "" + parent });
|
||||
this.actor.add_actor(link);
|
||||
let parentTarget = parent;
|
||||
link.connect('button-press-event', Lang.bind(this, function () {
|
||||
this._selectByActor(parentTarget);
|
||||
@ -214,16 +228,13 @@ PropertyInspector.prototype = {
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
this.actor = new Big.Box({ spacing: 4,
|
||||
border: 1,
|
||||
padding: 4,
|
||||
border_color: GREY });
|
||||
this.actor = new St.BoxLayout({ name: "PropertyInspector", vertical: true });
|
||||
},
|
||||
|
||||
setTarget: function(actor) {
|
||||
this.target = actor;
|
||||
|
||||
this.actor.remove_all();
|
||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
||||
|
||||
for (let propName in actor) {
|
||||
let valueStr;
|
||||
@ -233,11 +244,9 @@ PropertyInspector.prototype = {
|
||||
valueStr = '<error>';
|
||||
}
|
||||
let propText = propName + ": " + valueStr;
|
||||
let propDisplay = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
reactive: true,
|
||||
text: propText });
|
||||
this.actor.append(propDisplay, Big.BoxPackFlags.IF_FITS);
|
||||
let propDisplay = new St.Label({ reactive: true,
|
||||
text: propText });
|
||||
this.actor.add_actor(propDisplay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,20 +258,17 @@ function Inspector() {
|
||||
Inspector.prototype = {
|
||||
_init: function() {
|
||||
let width = 150;
|
||||
let eventHandler = new Big.Box({ background_color: LG_BACKGROUND_COLOR,
|
||||
border: 1,
|
||||
border_color: LG_BORDER_COLOR,
|
||||
corner_radius: 4,
|
||||
y: global.stage.height/2,
|
||||
reactive: true
|
||||
});
|
||||
let primary = global.get_primary_monitor();
|
||||
let eventHandler = new St.BoxLayout({ name: "LookingGlassDialog",
|
||||
vertical: false,
|
||||
y: primary.y + Math.floor(primary.height / 2),
|
||||
reactive: true });
|
||||
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
||||
eventHandler.x = Math.floor((global.stage.width)/2 - (eventHandler.width)/2);
|
||||
eventHandler.x = primary.x + Math.floor((primary.width - eventHandler.width) / 2);
|
||||
}));
|
||||
global.stage.add_actor(eventHandler);
|
||||
let displayText = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT, text: '' });
|
||||
eventHandler.append(displayText, Big.BoxPackFlags.EXPAND);
|
||||
let displayText = new St.Label();
|
||||
eventHandler.add(displayText, { expand: true });
|
||||
|
||||
let borderPaintTarget = null;
|
||||
let borderPaintId = null;
|
||||
@ -302,6 +308,135 @@ Inspector.prototype = {
|
||||
|
||||
Signals.addSignalMethods(Inspector.prototype);
|
||||
|
||||
function ErrorLog() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ErrorLog.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout();
|
||||
this.text = new St.Label();
|
||||
this.actor.add(this.text);
|
||||
this.text.clutter_text.line_wrap = true;
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
|
||||
},
|
||||
|
||||
_formatTime: function(d){
|
||||
function pad(n) { return n < 10 ? '0' + n : n };
|
||||
return d.getUTCFullYear()+'-'
|
||||
+ pad(d.getUTCMonth()+1)+'-'
|
||||
+ pad(d.getUTCDate())+'T'
|
||||
+ pad(d.getUTCHours())+':'
|
||||
+ pad(d.getUTCMinutes())+':'
|
||||
+ pad(d.getUTCSeconds())+'Z'
|
||||
},
|
||||
|
||||
_renderText: function() {
|
||||
if (!this.actor.mapped)
|
||||
return;
|
||||
let text = this.text.text;
|
||||
let stack = Main._getAndClearErrorStack();
|
||||
for (let i = 0; i < stack.length; i++) {
|
||||
let logItem = stack[i];
|
||||
text += logItem.category + " t=" + this._formatTime(new Date(logItem.timestamp)) + " " + logItem.message + "\n";
|
||||
}
|
||||
this.text.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
function Extensions() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Extensions.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ vertical: true,
|
||||
name: 'lookingGlassExtensions' });
|
||||
this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
|
||||
text: _("No extensions installed") });
|
||||
this._extensionsList = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'lg-extensions-list' });
|
||||
this.actor.add(this._extensionsList);
|
||||
this._loadExtensionList();
|
||||
},
|
||||
|
||||
_loadExtensionList: function() {
|
||||
let extensions = ExtensionSystem.extensionMeta;
|
||||
let totalExtensions = 0;
|
||||
for (let uuid in extensions) {
|
||||
let extensionDisplay = this._createExtensionDisplay(extensions[uuid]);
|
||||
this._extensionsList.add(extensionDisplay);
|
||||
totalExtensions++;
|
||||
}
|
||||
if (totalExtensions == 0) {
|
||||
this._extensionsList.add(this._noExtensions);
|
||||
}
|
||||
},
|
||||
|
||||
_onViewSource: function (actor) {
|
||||
let meta = actor._extensionMeta;
|
||||
let file = Gio.file_new_for_path(meta.path);
|
||||
let uri = file.get_uri();
|
||||
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context());
|
||||
Main.lookingGlass.close();
|
||||
},
|
||||
|
||||
_onWebPage: function (actor) {
|
||||
let meta = actor._extensionMeta;
|
||||
Gio.app_info_launch_default_for_uri(meta.url, global.create_app_launch_context());
|
||||
Main.lookingGlass.close();
|
||||
},
|
||||
|
||||
_stateToString: function(extensionState) {
|
||||
switch (extensionState) {
|
||||
case ExtensionSystem.ExtensionState.ENABLED:
|
||||
return _("Enabled");
|
||||
case ExtensionSystem.ExtensionState.DISABLED:
|
||||
return _("Disabled");
|
||||
case ExtensionSystem.ExtensionState.ERROR:
|
||||
return _("Error");
|
||||
case ExtensionSystem.ExtensionState.OUT_OF_DATE:
|
||||
return _("Out of date");
|
||||
}
|
||||
return "Unknown"; // Not translated, shouldn't appear
|
||||
},
|
||||
|
||||
_createExtensionDisplay: function(meta) {
|
||||
let box = new St.BoxLayout({ style_class: 'lg-extension', vertical: true });
|
||||
let name = new St.Label({ style_class: 'lg-extension-name',
|
||||
text: meta.name });
|
||||
box.add(name, { expand: true });
|
||||
let description = new St.Label({ style_class: 'lg-extension-description',
|
||||
text: meta.description });
|
||||
box.add(description, { expand: true });
|
||||
|
||||
let metaBox = new St.BoxLayout();
|
||||
box.add(metaBox);
|
||||
let stateString = this._stateToString(meta.state);
|
||||
let state = new St.Label({ style_class: 'lg-extension-state',
|
||||
text: this._stateToString(meta.state) });
|
||||
|
||||
let actionsContainer = new St.Bin({ x_align: St.Align.END });
|
||||
metaBox.add(actionsContainer);
|
||||
let actionsBox = new St.BoxLayout({ style_class: 'lg-extension-actions' });
|
||||
actionsContainer.set_child(actionsBox);
|
||||
|
||||
let viewsource = new Link.Link({ label: _("View Source") });
|
||||
viewsource.actor._extensionMeta = meta;
|
||||
viewsource.actor.connect('clicked', Lang.bind(this, this._onViewSource));
|
||||
actionsBox.add(viewsource.actor);
|
||||
|
||||
if (meta.url) {
|
||||
let webpage = new Link.Link({ label: _("Web Page") });
|
||||
webpage.actor._extensionMeta = meta;
|
||||
webpage.actor.connect('clicked', Lang.bind(this, this._onWebPage));
|
||||
actionsBox.add(webpage.actor);
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
};
|
||||
|
||||
function LookingGlass() {
|
||||
this._init();
|
||||
}
|
||||
@ -314,6 +449,10 @@ LookingGlass.prototype = {
|
||||
this._savedText = null;
|
||||
this._historyNavIndex = -1;
|
||||
this._history = [];
|
||||
this._borderPaintTarget = null;
|
||||
this._borderPaintId = 0;
|
||||
this._borderDestroyId = 0;
|
||||
|
||||
this._readHistory();
|
||||
|
||||
this._open = false;
|
||||
@ -321,29 +460,26 @@ LookingGlass.prototype = {
|
||||
this._offset = 0;
|
||||
this._results = [];
|
||||
|
||||
// TODO replace with scrolling or something better
|
||||
this._maxItems = 10;
|
||||
// Sort of magic, but...eh.
|
||||
this._maxItems = 150;
|
||||
|
||||
this.actor = new St.BoxLayout({ name: "LookingGlassDialog",
|
||||
vertical: true,
|
||||
visible: false });
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
gconf.watch_directory("/desktop/gnome/interface");
|
||||
gconf.connect("changed::/desktop/gnome/interface/monospace_font_name",
|
||||
Lang.bind(this, this._updateFont));
|
||||
this._updateFont();
|
||||
|
||||
this.actor = new Big.Box({ background_color: LG_BACKGROUND_COLOR,
|
||||
border: 1,
|
||||
border_color: LG_BORDER_COLOR,
|
||||
corner_radius: 4,
|
||||
padding_top: 8,
|
||||
padding_left: 4,
|
||||
padding_right: 4,
|
||||
padding_bottom: 4,
|
||||
spacing: 4,
|
||||
visible: false
|
||||
});
|
||||
global.stage.add_actor(this.actor);
|
||||
|
||||
let toolbar = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
border: 1, border_color: GREY,
|
||||
corner_radius: 4 });
|
||||
this.actor.append(toolbar, Big.BoxPackFlags.NONE);
|
||||
let toolbar = new St.BoxLayout({ name: "Toolbar" });
|
||||
this.actor.add_actor(toolbar);
|
||||
let inspectIcon = Shell.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
|
||||
24);
|
||||
toolbar.append(inspectIcon, Big.BoxPackFlags.NONE);
|
||||
toolbar.add_actor(inspectIcon);
|
||||
inspectIcon.reactive = true;
|
||||
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||
let inspector = new Inspector();
|
||||
@ -361,31 +497,27 @@ LookingGlass.prototype = {
|
||||
}));
|
||||
|
||||
let notebook = new Notebook();
|
||||
this.actor.append(notebook.actor, Big.BoxPackFlags.EXPAND);
|
||||
toolbar.append(notebook.tabControls, Big.BoxPackFlags.END);
|
||||
this._notebook = notebook;
|
||||
this.actor.add(notebook.actor, { expand: true });
|
||||
|
||||
this._evalBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: 4 });
|
||||
let emptyBox = new St.Bin();
|
||||
toolbar.add(emptyBox, { expand: true });
|
||||
toolbar.add_actor(notebook.tabControls);
|
||||
|
||||
this._evalBox = new St.BoxLayout({ name: "EvalBox", vertical: true });
|
||||
notebook.appendPage('Evaluator', this._evalBox);
|
||||
|
||||
this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: 4 });
|
||||
this._evalBox.append(this._resultsArea, Big.BoxPackFlags.EXPAND);
|
||||
this._evalBox.add(this._resultsArea, { expand: true });
|
||||
|
||||
let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
this._evalBox.append(entryArea, Big.BoxPackFlags.NONE);
|
||||
this._evalBox.add_actor(entryArea);
|
||||
|
||||
let label = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
text: 'js>>> ' });
|
||||
let label = new St.Label({ text: 'js>>> ' });
|
||||
entryArea.append(label, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._entry = new Clutter.Text({ color: MATRIX_GREEN,
|
||||
font_name: MATRIX_FONT,
|
||||
editable: true,
|
||||
activatable: true,
|
||||
singleLineMode: true,
|
||||
text: ''});
|
||||
this._entry = new St.Entry();
|
||||
/* unmapping the edit box will un-focus it, undo that */
|
||||
notebook.connect('selection', Lang.bind(this, function (nb, child) {
|
||||
if (child == this._evalBox)
|
||||
@ -403,7 +535,13 @@ LookingGlass.prototype = {
|
||||
notebook.selectIndex(0);
|
||||
}));
|
||||
|
||||
this._entry.connect('activate', Lang.bind(this, function (o, e) {
|
||||
this._errorLog = new ErrorLog();
|
||||
notebook.appendPage('Errors', this._errorLog.actor);
|
||||
|
||||
this._extensions = new Extensions();
|
||||
notebook.appendPage('Extensions', this._extensions.actor);
|
||||
|
||||
this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
|
||||
let text = o.get_text();
|
||||
// Ensure we don't get newlines in the command; the history file is
|
||||
// newline-separated.
|
||||
@ -416,12 +554,9 @@ LookingGlass.prototype = {
|
||||
this._historyNavIndex = -1;
|
||||
return true;
|
||||
}));
|
||||
this._entry.connect('key-press-event', Lang.bind(this, function(o, e) {
|
||||
this._entry.clutter_text.connect('key-press-event', Lang.bind(this, function(o, e) {
|
||||
let symbol = e.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this.close();
|
||||
return true;
|
||||
} else if (symbol == Clutter.Up) {
|
||||
if (symbol == Clutter.Up) {
|
||||
if (this._historyNavIndex >= this._history.length - 1)
|
||||
return true;
|
||||
this._historyNavIndex++;
|
||||
@ -446,6 +581,19 @@ LookingGlass.prototype = {
|
||||
}));
|
||||
},
|
||||
|
||||
_updateFont: function() {
|
||||
let gconf = Shell.GConf.get_default();
|
||||
let fontName = gconf.get_string("/desktop/gnome/interface/monospace_font_name");
|
||||
// This is mishandled by the scanner - should by Pango.FontDescription_from_string(fontName);
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=595889
|
||||
let fontDesc = Pango.Font.description_from_string(fontName);
|
||||
// We ignore everything but size and style; you'd be crazy to set your system-wide
|
||||
// monospace font to be bold/oblique/etc. Could easily be added here.
|
||||
this.actor.style =
|
||||
'font-size: ' + fontDesc.get_size() / 1024. + (fontDesc.get_size_is_absolute() ? 'px' : 'pt') + ';'
|
||||
+ 'font-family: "' + fontDesc.get_family() + '";';
|
||||
},
|
||||
|
||||
_readHistory: function () {
|
||||
if (!this._historyFile.query_exists(null))
|
||||
return;
|
||||
@ -475,6 +623,18 @@ LookingGlass.prototype = {
|
||||
this._results.push(result);
|
||||
this._resultsArea.append(result.actor, Big.BoxPackFlags.NONE);
|
||||
this._propInspector.setTarget(obj);
|
||||
if (this._borderPaintTarget != null) {
|
||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
||||
this._borderPaintTarget = null;
|
||||
}
|
||||
if (obj instanceof Clutter.Actor) {
|
||||
this._borderPaintTarget = obj;
|
||||
this._borderPaintId = Shell.add_hook_paint_red_border(obj);
|
||||
this._borderDestroyId = obj.connect('destroy', Lang.bind(this, function () {
|
||||
this._borderDestroyId = 0;
|
||||
this._borderPaintTarget = null;
|
||||
}));
|
||||
}
|
||||
let children = this._resultsArea.get_children();
|
||||
if (children.length > this._maxItems) {
|
||||
this._results.shift();
|
||||
@ -482,6 +642,9 @@ LookingGlass.prototype = {
|
||||
this._offset++;
|
||||
}
|
||||
this._it = obj;
|
||||
|
||||
// Scroll to bottom
|
||||
this._notebook.scrollToBottom(0);
|
||||
},
|
||||
|
||||
_evaluate : function(command) {
|
||||
@ -518,11 +681,11 @@ LookingGlass.prototype = {
|
||||
},
|
||||
|
||||
_resizeTo: function(actor) {
|
||||
let stage = global.stage;
|
||||
let myWidth = stage.width * 0.7;
|
||||
let myHeight = stage.height * 0.7;
|
||||
let primary = global.get_primary_monitor();
|
||||
let myWidth = primary.width * 0.7;
|
||||
let myHeight = primary.height * 0.7;
|
||||
let [srcX, srcY] = actor.get_transformed_position();
|
||||
this.actor.x = srcX + (stage.width-myWidth)/2;
|
||||
this.actor.x = srcX + (primary.width - myWidth) / 2;
|
||||
this._hiddenY = srcY + actor.height - myHeight - 4; // -4 to hide the top corners
|
||||
this._targetY = this._hiddenY + myHeight;
|
||||
this.actor.y = this._hiddenY;
|
||||
@ -538,17 +701,32 @@ LookingGlass.prototype = {
|
||||
this._resizeTo(actor);
|
||||
},
|
||||
|
||||
// Handle key events which are relevant for all tabs of the LookingGlass
|
||||
_globalKeyPressEvent : function(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
open : function() {
|
||||
if (this._open)
|
||||
return;
|
||||
|
||||
if (!Main.pushModal(this.actor))
|
||||
return;
|
||||
|
||||
this._keyPressEventId = global.stage.connect('key-press-event',
|
||||
Lang.bind(this, this._globalKeyPressEvent));
|
||||
|
||||
this.actor.show();
|
||||
this.actor.lower(Main.chrome.actor);
|
||||
this._open = true;
|
||||
|
||||
Tweener.removeTweens(this.actor);
|
||||
|
||||
Main.pushModal(this.actor);
|
||||
global.stage.set_key_focus(this._entry);
|
||||
|
||||
Tweener.addTween(this.actor, { time: 0.5,
|
||||
@ -561,10 +739,19 @@ LookingGlass.prototype = {
|
||||
if (!this._open)
|
||||
return;
|
||||
|
||||
if (this._keyPressEventId)
|
||||
global.stage.disconnect(this._keyPressEventId);
|
||||
|
||||
this._historyNavIndex = -1;
|
||||
this._open = false;
|
||||
Tweener.removeTweens(this.actor);
|
||||
|
||||
if (this._borderPaintTarget != null) {
|
||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
||||
this._borderPaintTarget.disconnect(this._borderDestroyId);
|
||||
this._borderPaintTarget = null;
|
||||
}
|
||||
|
||||
Main.popModal(this.actor);
|
||||
|
||||
Tweener.addTween(this.actor, { time: 0.5,
|
||||
|
312
js/ui/main.js
@ -1,6 +1,7 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const DBus = imports.dbus;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
@ -9,14 +10,21 @@ const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Chrome = imports.ui.chrome;
|
||||
const Environment = imports.ui.environment;
|
||||
const ExtensionSystem = imports.ui.extensionSystem;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Overview = imports.ui.overview;
|
||||
const Panel = imports.ui.panel;
|
||||
const PlaceDisplay = imports.ui.placeDisplay;
|
||||
const RunDialog = imports.ui.runDialog;
|
||||
const LookingGlass = imports.ui.lookingGlass;
|
||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||
const ShellDBus = imports.ui.shellDBus;
|
||||
const Sidebar = imports.ui.sidebar;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
|
||||
@ -25,13 +33,22 @@ DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
||||
let chrome = null;
|
||||
let panel = null;
|
||||
let sidebar = null;
|
||||
let placesManager = null;
|
||||
let overview = null;
|
||||
let runDialog = null;
|
||||
let lookingGlass = null;
|
||||
let wm = null;
|
||||
let notificationDaemon = null;
|
||||
let messageTray = null;
|
||||
let windowAttentionHandler = null;
|
||||
let recorder = null;
|
||||
let shellDBusService = null;
|
||||
let modalCount = 0;
|
||||
let modalActorFocusStack = [];
|
||||
let _errorLogStack = [];
|
||||
let _startDate;
|
||||
|
||||
let background = null;
|
||||
|
||||
function start() {
|
||||
// Add a binding for "global" in the global JS namespace; (gjs
|
||||
@ -39,21 +56,34 @@ function start() {
|
||||
// called "window".)
|
||||
window.global = Shell.Global.get();
|
||||
|
||||
// Now monkey patch utility functions into the global proxy;
|
||||
// This is easier and faster than indirecting down into global
|
||||
// if we want to call back up into JS.
|
||||
global.logError = _logError;
|
||||
global.log = _logDebug;
|
||||
|
||||
Gio.DesktopAppInfo.set_desktop_env("GNOME");
|
||||
|
||||
global.grab_dbus_service();
|
||||
shellDBusService = new ShellDBus.GnomeShell();
|
||||
// Force a connection now; dbus.js will do this internally
|
||||
// if we use its name acquisition stuff but we aren't right
|
||||
// now; to do so we'd need to convert from its async calls
|
||||
// back into sync ones.
|
||||
DBus.session.flush();
|
||||
|
||||
Tweener.init();
|
||||
Environment.init();
|
||||
|
||||
// Ensure ShellAppMonitor is initialized; this will
|
||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||
// also initialize ShellAppSystem first. ShellAppSystem
|
||||
// needs to load all the .desktop files, and ShellAppMonitor
|
||||
// needs to load all the .desktop files, and ShellWindowTracker
|
||||
// will use those to associate with windows. Right now
|
||||
// the Monitor doesn't listen for installed app changes
|
||||
// and recalculate application associations, so to avoid
|
||||
// races for now we initialize it here. It's better to
|
||||
// be predictable anyways.
|
||||
Shell.AppMonitor.get_default();
|
||||
Shell.WindowTracker.get_default();
|
||||
Shell.AppUsage.get_default();
|
||||
|
||||
// The background color really only matters if there is no desktop
|
||||
// window (say, nautilus) running. We set it mostly so things look good
|
||||
@ -66,16 +96,32 @@ function start() {
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
|
||||
global.connect('panel-run-dialog', function(panel) {
|
||||
// Make sure not more than one run dialog is shown.
|
||||
getRunDialog().open();
|
||||
let themeContext = St.ThemeContext.get_for_stage (global.stage);
|
||||
let stylesheetPath = global.datadir + "/theme/gnome-shell.css";
|
||||
let theme = new St.Theme ({ application_stylesheet: stylesheetPath });
|
||||
themeContext.set_theme (theme);
|
||||
|
||||
let shellwm = global.window_manager;
|
||||
shellwm.takeover_keybinding("panel_main_menu");
|
||||
shellwm.connect("keybinding::panel_main_menu", function () {
|
||||
overview.toggle();
|
||||
});
|
||||
shellwm.takeover_keybinding("panel_run_dialog");
|
||||
shellwm.connect("keybinding::panel_run_dialog", function () {
|
||||
getRunDialog().open();
|
||||
});
|
||||
|
||||
placesManager = new PlaceDisplay.PlacesManager();
|
||||
overview = new Overview.Overview();
|
||||
chrome = new Chrome.Chrome();
|
||||
panel = new Panel.Panel();
|
||||
sidebar = new Sidebar.Sidebar();
|
||||
wm = new WindowManager.WindowManager();
|
||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
|
||||
_startDate = new Date();
|
||||
|
||||
global.screen.connect('toggle-recording', function() {
|
||||
if (recorder == null) {
|
||||
@ -85,26 +131,97 @@ function start() {
|
||||
if (recorder.is_recording()) {
|
||||
recorder.pause();
|
||||
} else {
|
||||
//read the parameters from GConf always in case they have changed
|
||||
let gconf = Shell.GConf.get_default();
|
||||
recorder.set_framerate(gconf.get_int("recorder/framerate"));
|
||||
recorder.set_filename("shell-%d%u-%c." + gconf.get_string("recorder/file_extension"));
|
||||
let pipeline = gconf.get_string("recorder/pipeline");
|
||||
if (!pipeline.match(/^\s*$/))
|
||||
recorder.set_pipeline(pipeline);
|
||||
else
|
||||
recorder.set_pipeline(null);
|
||||
|
||||
recorder.record();
|
||||
}
|
||||
});
|
||||
|
||||
_relayout();
|
||||
background = global.create_root_pixmap_actor();
|
||||
global.stage.add_actor(background);
|
||||
background.lower_bottom();
|
||||
|
||||
global.connect('screen-size-changed', _relayout);
|
||||
|
||||
ExtensionSystem.init();
|
||||
ExtensionSystem.loadExtensions();
|
||||
|
||||
panel.startupAnimation();
|
||||
|
||||
let display = global.screen.get_display();
|
||||
display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||
global.connect('panel-main-menu', Lang.bind(overview, overview.toggle));
|
||||
|
||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
||||
|
||||
_log('info', 'loaded at ' + _startDate);
|
||||
log('GNOME Shell started at ' + _startDate);
|
||||
|
||||
Mainloop.idle_add(_removeUnusedWorkspaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* _log:
|
||||
* @category: string message type ('info', 'error')
|
||||
* @msg: A message string
|
||||
* ...: Any further arguments are converted into JSON notation,
|
||||
* and appended to the log message, separated by spaces.
|
||||
*
|
||||
* Log a message into the LookingGlass error
|
||||
* stream. This is primarily intended for use by the
|
||||
* extension system as well as debugging.
|
||||
*/
|
||||
function _log(category, msg) {
|
||||
let text = msg;
|
||||
if (arguments.length > 2) {
|
||||
text += ': ';
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
text += JSON.stringify(arguments[i]);
|
||||
if (i < arguments.length - 1)
|
||||
text += " ";
|
||||
}
|
||||
}
|
||||
_errorLogStack.push({timestamp: new Date().getTime(),
|
||||
category: category,
|
||||
message: text });
|
||||
}
|
||||
|
||||
function _logError(msg) {
|
||||
return _log('error', msg);
|
||||
}
|
||||
|
||||
function _logDebug(msg) {
|
||||
return _log('debug', msg);
|
||||
}
|
||||
|
||||
// Used by the error display in lookingGlass.js
|
||||
function _getAndClearErrorStack() {
|
||||
let errors = _errorLogStack;
|
||||
_errorLogStack = [];
|
||||
return errors;
|
||||
}
|
||||
|
||||
function _relayout() {
|
||||
panel.actor.set_size(global.screen_width, Panel.PANEL_HEIGHT);
|
||||
let primary = global.get_primary_monitor();
|
||||
panel.actor.set_position(primary.x, primary.y);
|
||||
panel.actor.set_size(primary.width, Panel.PANEL_HEIGHT);
|
||||
overview.relayout();
|
||||
|
||||
background.set_size(global.screen_width, global.screen_height);
|
||||
|
||||
// To avoid updating the position and size of the workspaces
|
||||
// in the overview, we just hide the overview. The positions
|
||||
// will be updated when it is next shown. We do the same for
|
||||
// the calendar popdown.
|
||||
overview.hide();
|
||||
panel.hideCalendar();
|
||||
}
|
||||
|
||||
// metacity-clutter currently uses the same prefs as plain metacity,
|
||||
@ -175,7 +292,7 @@ function _globalKeyPressHandler(actor, event) {
|
||||
overview.hide();
|
||||
|
||||
return true;
|
||||
} else if (symbol == Clutter.F2 && (event.get_state() & Clutter.ModifierType.MOD1_MASK)) {
|
||||
} else if (symbol == Clutter.F2 && (Shell.get_event_state(event) & Clutter.ModifierType.MOD1_MASK)) {
|
||||
getRunDialog().open();
|
||||
}
|
||||
}
|
||||
@ -205,9 +322,18 @@ function _findModal(actor) {
|
||||
* Next, record the current Clutter keyboard focus on a stack. If the modal stack
|
||||
* returns to this actor, reset the focus to the actor which was focused
|
||||
* at the time pushModal() was invoked.
|
||||
*
|
||||
* Returns: true iff we successfully acquired a grab or already had one
|
||||
*/
|
||||
function pushModal(actor) {
|
||||
let timestamp = global.screen.get_display().get_current_time();
|
||||
if (modalCount == 0) {
|
||||
if (!global.begin_modal(global.get_current_time())) {
|
||||
log("pushModal: invocation of begin_modal failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||
|
||||
modalCount += 1;
|
||||
actor.connect('destroy', function() {
|
||||
@ -225,14 +351,7 @@ function pushModal(actor) {
|
||||
}
|
||||
modalActorFocusStack.push([actor, curFocus]);
|
||||
|
||||
if (modalCount > 1)
|
||||
return;
|
||||
|
||||
if (!global.begin_modal(timestamp)) {
|
||||
log("pushModal: invocation of begin_modal failed");
|
||||
return;
|
||||
}
|
||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,8 +363,6 @@ function pushModal(actor) {
|
||||
* previous focus at the time when pushModal() was invoked.
|
||||
*/
|
||||
function popModal(actor) {
|
||||
let timestamp = global.screen.get_display().get_current_time();
|
||||
|
||||
modalCount -= 1;
|
||||
let focusIndex = _findModal(actor);
|
||||
if (focusIndex >= 0) {
|
||||
@ -263,7 +380,7 @@ function popModal(actor) {
|
||||
if (modalCount > 0)
|
||||
return;
|
||||
|
||||
global.end_modal(timestamp);
|
||||
global.end_modal(global.get_current_time());
|
||||
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
||||
}
|
||||
|
||||
@ -282,16 +399,145 @@ function getRunDialog() {
|
||||
return runDialog;
|
||||
}
|
||||
|
||||
function createAppLaunchContext() {
|
||||
let screen = global.screen;
|
||||
let display = screen.get_display();
|
||||
/**
|
||||
* activateWindow:
|
||||
* @window: the Meta.Window to activate
|
||||
* @time: (optional) current event time
|
||||
* @workspaceNum: (optional) window's workspace number
|
||||
*
|
||||
* Activates @window, switching to its workspace first if necessary,
|
||||
* and switching out of the overview if it's currently active
|
||||
*/
|
||||
function activateWindow(window, time, workspaceNum) {
|
||||
let activeWorkspaceNum = global.screen.get_active_workspace_index();
|
||||
let windowWorkspaceNum = (workspaceNum !== undefined) ? workspaceNum : window.get_workspace().index();
|
||||
|
||||
let context = new Gdk.AppLaunchContext();
|
||||
context.set_timestamp(display.get_current_time());
|
||||
if (!time)
|
||||
time = global.get_current_time();
|
||||
|
||||
// Make sure that the app is opened on the current workspace even if
|
||||
// the user switches before it starts
|
||||
context.set_desktop(screen.get_active_workspace_index());
|
||||
if (windowWorkspaceNum != activeWorkspaceNum) {
|
||||
let workspace = global.screen.get_workspace_by_index(windowWorkspaceNum);
|
||||
workspace.activate_with_focus(window, time);
|
||||
} else {
|
||||
window.activate(time);
|
||||
}
|
||||
|
||||
return context;
|
||||
overview.hide();
|
||||
}
|
||||
|
||||
// TODO - replace this timeout with some system to guess when the user might
|
||||
// be e.g. just reading the screen and not likely to interact.
|
||||
const DEFERRED_TIMEOUT_SECONDS = 20;
|
||||
var _deferredWorkData = {};
|
||||
// Work scheduled for some point in the future
|
||||
var _deferredWorkQueue = [];
|
||||
// Work we need to process before the next redraw
|
||||
var _beforeRedrawQueue = [];
|
||||
// Counter to assign work ids
|
||||
var _deferredWorkSequence = 0;
|
||||
var _deferredTimeoutId = 0;
|
||||
|
||||
function _runDeferredWork(workId) {
|
||||
if (!_deferredWorkData[workId])
|
||||
return;
|
||||
let index = _deferredWorkQueue.indexOf(workId);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
_deferredWorkQueue.splice(index, 1);
|
||||
_deferredWorkData[workId].callback();
|
||||
if (_deferredWorkQueue.length == 0 && _deferredTimeoutId > 0) {
|
||||
Mainloop.source_remove(_deferredTimeoutId);
|
||||
_deferredTimeoutId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function _runAllDeferredWork() {
|
||||
while (_deferredWorkQueue.length > 0)
|
||||
_runDeferredWork(_deferredWorkQueue[0]);
|
||||
}
|
||||
|
||||
function _runBeforeRedrawQueue() {
|
||||
for (let i = 0; i < _beforeRedrawQueue.length; i++) {
|
||||
let workId = _beforeRedrawQueue[i];
|
||||
_runDeferredWork(workId);
|
||||
}
|
||||
_beforeRedrawQueue = [];
|
||||
}
|
||||
|
||||
function _queueBeforeRedraw(workId) {
|
||||
_beforeRedrawQueue.push(workId);
|
||||
if (_beforeRedrawQueue.length == 1) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function () {
|
||||
_runBeforeRedrawQueue();
|
||||
return false;
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initializeDeferredWork:
|
||||
* @actor: A #ClutterActor
|
||||
* @callback: Function to invoke to perform work
|
||||
*
|
||||
* This function sets up a callback to be invoked when either the
|
||||
* given actor is mapped, or after some period of time when the machine
|
||||
* is idle. This is useful if your actor isn't always visible on the
|
||||
* screen (for example, all actors in the overview), and you don't want
|
||||
* to consume resources updating if the actor isn't actually going to be
|
||||
* displaying to the user.
|
||||
*
|
||||
* Note that queueDeferredWork is called by default immediately on
|
||||
* initialization as well, under the assumption that new actors
|
||||
* will need it.
|
||||
*
|
||||
* Returns: A string work identifer
|
||||
*/
|
||||
function initializeDeferredWork(actor, callback, props) {
|
||||
// Turn into a string so we can use as an object property
|
||||
let workId = "" + (++_deferredWorkSequence);
|
||||
_deferredWorkData[workId] = { 'actor': actor,
|
||||
'callback': callback };
|
||||
actor.connect('notify::mapped', function () {
|
||||
if (!(actor.mapped && _deferredWorkQueue.indexOf(workId) >= 0))
|
||||
return;
|
||||
_queueBeforeRedraw(workId);
|
||||
});
|
||||
actor.connect('destroy', function() {
|
||||
let index = _deferredWorkQueue.indexOf(workId);
|
||||
if (index >= 0)
|
||||
_deferredWorkQueue.splice(index, 1);
|
||||
delete _deferredWorkData[workId];
|
||||
});
|
||||
queueDeferredWork(workId);
|
||||
return workId;
|
||||
}
|
||||
|
||||
/**
|
||||
* queueDeferredWork:
|
||||
* @workId: work identifier
|
||||
*
|
||||
* Ensure that the work identified by @workId will be
|
||||
* run on map or timeout. You should call this function
|
||||
* for example when data being displayed by the actor has
|
||||
* changed.
|
||||
*/
|
||||
function queueDeferredWork(workId) {
|
||||
let data = _deferredWorkData[workId];
|
||||
if (!data) {
|
||||
global.logError("invalid work id ", workId);
|
||||
return;
|
||||
}
|
||||
if (_deferredWorkQueue.indexOf(workId) < 0)
|
||||
_deferredWorkQueue.push(workId);
|
||||
if (data.actor.mapped) {
|
||||
_queueBeforeRedraw(workId);
|
||||
return;
|
||||
} else if (_deferredTimeoutId == 0) {
|
||||
_deferredTimeoutId = Mainloop.timeout_add_seconds(DEFERRED_TIMEOUT_SECONDS, function () {
|
||||
_runAllDeferredWork();
|
||||
_deferredTimeoutId = 0;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
761
js/ui/messageTray.js
Normal file
@ -0,0 +1,761 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ANIMATION_TIME = 0.2;
|
||||
const NOTIFICATION_TIMEOUT = 4;
|
||||
const SUMMARY_TIMEOUT = 1;
|
||||
|
||||
const MESSAGE_TRAY_TIMEOUT = 0.2;
|
||||
|
||||
const ICON_SIZE = 24;
|
||||
|
||||
const State = {
|
||||
HIDDEN: 0,
|
||||
SHOWING: 1,
|
||||
SHOWN: 2,
|
||||
HIDING: 3
|
||||
};
|
||||
|
||||
function _cleanMarkup(text) {
|
||||
// Support &, ", ', < and >, escape all other
|
||||
// occurrences of '&'.
|
||||
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, "&");
|
||||
// Support <b>, <i>, and <u>, escape anything else
|
||||
// so it displays as raw markup.
|
||||
return _text.replace(/<(\/?[^biu]>|[^>\/][^>])/g, "<$1");
|
||||
}
|
||||
|
||||
// Notification:
|
||||
// @id: the notification's id
|
||||
// @source: the notification's Source
|
||||
// @title: the title
|
||||
// @banner: the banner text
|
||||
// @bannerBody: whether or not to promote the banner to the body on overflow
|
||||
//
|
||||
// Creates a notification. In banner mode, it will show
|
||||
// @source's icon, @title (in bold) and @banner, all on a single line
|
||||
// (with @banner ellipsized if necessary).
|
||||
//
|
||||
// Additional notification details can be added via addBody(),
|
||||
// addAction(), and addActor(). If any of these are called, then the
|
||||
// notification will expand to show the additional actors (while
|
||||
// hiding the @banner) if the pointer is moved into it while it is
|
||||
// visible.
|
||||
//
|
||||
// If @bannerBody is %true, then @banner will also be used as the body
|
||||
// of the notification (as with addBody()) when the banner is expanded.
|
||||
// In this case, if @banner is too long to fit in the single-line mode,
|
||||
// the notification will be made expandable automatically.
|
||||
function Notification(id, source, title, banner, bannerBody) {
|
||||
this._init(id, source, title, banner, bannerBody);
|
||||
}
|
||||
|
||||
Notification.prototype = {
|
||||
_init: function(id, source, title, banner, bannerBody) {
|
||||
this.id = id;
|
||||
this.source = source;
|
||||
this._bannerBody = bannerBody;
|
||||
|
||||
source.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
this.emit('dismissed');
|
||||
}));
|
||||
|
||||
this.actor = new St.Table({ name: 'notification' });
|
||||
this.update(title, banner, true);
|
||||
},
|
||||
|
||||
// update:
|
||||
// @title: the new title
|
||||
// @banner: the new banner
|
||||
// @clear: whether or not to clear out extra actors
|
||||
//
|
||||
// Updates the notification by regenerating its icon and updating
|
||||
// the title/banner. If @clear is %true, it will also remove any
|
||||
// additional actors/action buttons previously added.
|
||||
update: function(title, banner, clear) {
|
||||
let children = this.actor.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let meta = this.actor.get_child_meta(children[i]);
|
||||
if (clear || meta.row == 0 || (this._bannerBody && meta.row == 1))
|
||||
children[i].destroy();
|
||||
}
|
||||
if (clear) {
|
||||
this.actions = {};
|
||||
this._actionBox = null;
|
||||
}
|
||||
|
||||
let icon = this.source.createIcon(ICON_SIZE);
|
||||
icon.reactive = true;
|
||||
this.actor.add(icon, { row: 0,
|
||||
col: 0,
|
||||
x_expand: false,
|
||||
y_expand: false,
|
||||
y_fill: false });
|
||||
|
||||
icon.connect('button-release-event', Lang.bind(this,
|
||||
function () {
|
||||
this.source.clicked();
|
||||
}));
|
||||
|
||||
// The first line should have the title, followed by the
|
||||
// banner text, but ellipsized if they won't both fit. We can't
|
||||
// make St.Table or St.BoxLayout do this the way we want (don't
|
||||
// show banner at all if title needs to be ellipsized), so we
|
||||
// use Shell.GenericContainer.
|
||||
this._bannerBox = new Shell.GenericContainer();
|
||||
this._bannerBox.connect('get-preferred-width', Lang.bind(this, this._bannerBoxGetPreferredWidth));
|
||||
this._bannerBox.connect('get-preferred-height', Lang.bind(this, this._bannerBoxGetPreferredHeight));
|
||||
this._bannerBox.connect('allocate', Lang.bind(this, this._bannerBoxAllocate));
|
||||
this.actor.add(this._bannerBox, { row: 0,
|
||||
col: 1,
|
||||
y_expand: false,
|
||||
y_fill: false });
|
||||
|
||||
this._titleLabel = new St.Label();
|
||||
title = title ? _cleanMarkup(title.replace(/\n/g, ' ')) : '';
|
||||
this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
|
||||
this._bannerBox.add_actor(this._titleLabel);
|
||||
|
||||
if (this._bannerBody)
|
||||
this._bannerBodyText = banner;
|
||||
else
|
||||
this._bannerBodyText = null;
|
||||
|
||||
this._bannerLabel = new St.Label();
|
||||
banner = banner ? _cleanMarkup(banner.replace(/\n/g, ' ')) : '';
|
||||
this._bannerLabel.clutter_text.set_markup(banner);
|
||||
this._bannerBox.add_actor(this._bannerLabel);
|
||||
},
|
||||
|
||||
// addActor:
|
||||
// @actor: actor to add to the notification
|
||||
// @props: (optional) child properties
|
||||
//
|
||||
// Adds @actor to the notification's St.Table, using @props.
|
||||
//
|
||||
// If @props does not specify a %row, then @actor will be added
|
||||
// to the bottom of the notification (unless there are action
|
||||
// buttons present, in which case it will be added above them).
|
||||
//
|
||||
// If @props does not specify a %col, it will default to column 1.
|
||||
// (Normally only the icon is in column 0.)
|
||||
//
|
||||
// If @props specifies an already-occupied cell, then the existing
|
||||
// contents of the table will be shifted down to make room for it.
|
||||
addActor: function(actor, props) {
|
||||
if (!props)
|
||||
props = {};
|
||||
|
||||
if (!('col' in props))
|
||||
props.col = 1;
|
||||
|
||||
if ('row' in props) {
|
||||
let children = this.actor.get_children();
|
||||
let i, meta, collision = false;
|
||||
|
||||
for (i = 0; i < children.length; i++) {
|
||||
meta = this.actor.get_child_meta(children[i]);
|
||||
if (meta.row == props.row && meta.col == props.col) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
for (i = 0; i < children.length; i++) {
|
||||
meta = this.actor.get_child_meta(children[i]);
|
||||
if (meta.row >= props.row)
|
||||
meta.row++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this._actionBox) {
|
||||
props.row = this.actor.row_count - 1;
|
||||
this.actor.get_child_meta(this._actionBox).row++;
|
||||
} else {
|
||||
props.row = this.actor.row_count;
|
||||
}
|
||||
}
|
||||
|
||||
this.actor.add(actor, props);
|
||||
},
|
||||
|
||||
// addBody:
|
||||
// @text: the text
|
||||
// @props: (optional) properties for addActor()
|
||||
//
|
||||
// Adds a multi-line label containing @text to the notification.
|
||||
addBody: function(text, props) {
|
||||
let body = new St.Label();
|
||||
body.clutter_text.line_wrap = true;
|
||||
body.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
|
||||
body.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
|
||||
text = text ? _cleanMarkup(text) : '';
|
||||
body.clutter_text.set_markup(text);
|
||||
|
||||
this.addActor(body, props);
|
||||
},
|
||||
|
||||
_addBannerBody: function() {
|
||||
this.addBody(this._bannerBodyText, { row: 1 });
|
||||
this._bannerBodyText = null;
|
||||
},
|
||||
|
||||
// addAction:
|
||||
// @id: the action ID
|
||||
// @label: the label for the action's button
|
||||
//
|
||||
// Adds a button with the given @label to the notification. All
|
||||
// action buttons will appear in a single row at the bottom of
|
||||
// the notification.
|
||||
//
|
||||
// If the button is clicked, the notification will emit the
|
||||
// %action-invoked signal with @id as a parameter
|
||||
addAction: function(id, label) {
|
||||
if (!this._actionBox) {
|
||||
if (this._bannerBodyText)
|
||||
this._addBannerBody();
|
||||
|
||||
let box = new St.BoxLayout({ name: 'notification-actions' });
|
||||
this.addActor(box, { x_expand: false,
|
||||
x_fill: false,
|
||||
x_align: St.Align.END });
|
||||
this._actionBox = box;
|
||||
}
|
||||
|
||||
let button = new St.Button({ style_class: 'notification-button',
|
||||
label: label });
|
||||
this._actionBox.add(button);
|
||||
button.connect('clicked', Lang.bind(this, function() { this.emit('action-invoked', id); }));
|
||||
},
|
||||
|
||||
_bannerBoxGetPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let [titleMin, titleNat] = this._titleLabel.get_preferred_width(forHeight);
|
||||
let [bannerMin, bannerNat] = this._bannerLabel.get_preferred_width(forHeight);
|
||||
let [has_spacing, spacing] = this.actor.get_theme_node().get_length('spacing-columns', false);
|
||||
|
||||
alloc.min_size = titleMin;
|
||||
alloc.natural_size = titleNat + (has_spacing ? spacing : 0) + bannerNat;
|
||||
},
|
||||
|
||||
_bannerBoxGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] =
|
||||
this._titleLabel.get_preferred_height(forWidth);
|
||||
},
|
||||
|
||||
_bannerBoxAllocate: function(actor, box, flags) {
|
||||
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
|
||||
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(-1);
|
||||
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(-1);
|
||||
let [has_spacing, spacing] = this.actor.get_theme_node().get_length('spacing-columns', false);
|
||||
if (!has_spacing)
|
||||
spacing = 0;
|
||||
let availWidth = box.x2 - box.x1;
|
||||
|
||||
let titleBox = new Clutter.ActorBox();
|
||||
titleBox.x1 = titleBox.y1 = 0;
|
||||
titleBox.x2 = Math.min(titleNatW, availWidth);
|
||||
titleBox.y2 = titleNatH;
|
||||
this._titleLabel.allocate(titleBox, flags);
|
||||
|
||||
let overflow = false;
|
||||
if (titleBox.x2 + spacing > availWidth) {
|
||||
this._bannerLabel.hide();
|
||||
overflow = true;
|
||||
} else {
|
||||
let bannerBox = new Clutter.ActorBox();
|
||||
bannerBox.x1 = titleBox.x2 + spacing;
|
||||
bannerBox.y1 = 0;
|
||||
bannerBox.x2 = Math.min(bannerBox.x1 + bannerNatW, availWidth);
|
||||
bannerBox.y2 = titleNatH;
|
||||
this._bannerLabel.show();
|
||||
this._bannerLabel.allocate(bannerBox, flags);
|
||||
|
||||
if (bannerBox.x2 < bannerBox.x1 + bannerNatW)
|
||||
overflow = true;
|
||||
}
|
||||
|
||||
if (this._bannerBodyText &&
|
||||
(overflow || this._bannerBodyText.indexOf('\n') > -1))
|
||||
this._addBannerBody();
|
||||
},
|
||||
|
||||
popOut: function() {
|
||||
if (this.actor.row_count <= 1)
|
||||
return false;
|
||||
|
||||
Tweener.addTween(this._bannerLabel,
|
||||
{ opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
return true;
|
||||
},
|
||||
|
||||
popIn: function() {
|
||||
if (this.actor.row_count <= 1)
|
||||
return false;
|
||||
Tweener.addTween(this._bannerLabel,
|
||||
{ opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
return true;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.emit('destroy');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Notification.prototype);
|
||||
|
||||
function Source(id, createIcon) {
|
||||
this._init(id, createIcon);
|
||||
}
|
||||
|
||||
Source.prototype = {
|
||||
_init: function(id, createIcon) {
|
||||
this.id = id;
|
||||
this.text = null;
|
||||
if (createIcon)
|
||||
this.createIcon = createIcon;
|
||||
this.handleReplacing = true;
|
||||
},
|
||||
|
||||
// This can be overridden by a subclass, or by the createIcon
|
||||
// parameter to _init()
|
||||
createIcon: function(size) {
|
||||
throw new Error('no implementation of createIcon in ' + this);
|
||||
},
|
||||
|
||||
notify: function(notification) {
|
||||
this.emit('notify', notification);
|
||||
},
|
||||
|
||||
clicked: function() {
|
||||
this.emit('clicked');
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.emit('destroy');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Source.prototype);
|
||||
|
||||
function MessageTray() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
MessageTray.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ name: 'message-tray',
|
||||
reactive: true });
|
||||
|
||||
this._notificationBin = new St.Bin({ reactive: true,
|
||||
x_align: St.Align.MIDDLE });
|
||||
this.actor.add(this._notificationBin);
|
||||
this._notificationBin.hide();
|
||||
this._notificationQueue = [];
|
||||
this._notification = null;
|
||||
|
||||
this._summaryBin = new St.BoxLayout();
|
||||
this.actor.add(this._summaryBin);
|
||||
this._summary = new St.BoxLayout({ name: 'summary-mode',
|
||||
reactive: true });
|
||||
this._summaryBin.add(this._summary, { x_align: St.Align.END,
|
||||
x_fill: false,
|
||||
expand: true });
|
||||
this._summary.connect('enter-event',
|
||||
Lang.bind(this, this._onSummaryEntered));
|
||||
this._summary.connect('leave-event',
|
||||
Lang.bind(this, this._onSummaryLeft));
|
||||
this._summaryBin.opacity = 0;
|
||||
|
||||
this.actor.connect('enter-event', Lang.bind(this, this._onTrayEntered));
|
||||
this.actor.connect('leave-event', Lang.bind(this, this._onTrayLeft));
|
||||
|
||||
this._trayState = State.HIDDEN;
|
||||
this._trayLeftTimeoutId = 0;
|
||||
this._pointerInTray = false;
|
||||
this._summaryState = State.HIDDEN;
|
||||
this._summaryTimeoutId = 0;
|
||||
this._pointerInSummary = false;
|
||||
this._notificationState = State.HIDDEN;
|
||||
this._notificationTimeoutId = 0;
|
||||
this._overviewVisible = false;
|
||||
this._notificationRemoved = false;
|
||||
|
||||
this.actor.show();
|
||||
Main.chrome.addActor(this.actor, { affectsStruts: false,
|
||||
visibleInOverview: true });
|
||||
Main.chrome.trackActor(this._notificationBin, { affectsStruts: false });
|
||||
|
||||
global.connect('screen-size-changed',
|
||||
Lang.bind(this, this._setSizePosition));
|
||||
this._setSizePosition();
|
||||
|
||||
Main.overview.connect('showing', Lang.bind(this,
|
||||
function() {
|
||||
this._overviewVisible = true;
|
||||
this._updateState();
|
||||
}));
|
||||
Main.overview.connect('hiding', Lang.bind(this,
|
||||
function() {
|
||||
this._overviewVisible = false;
|
||||
this._updateState();
|
||||
}));
|
||||
|
||||
this._sources = {};
|
||||
this._icons = {};
|
||||
},
|
||||
|
||||
_setSizePosition: function() {
|
||||
let primary = global.get_primary_monitor();
|
||||
this.actor.x = primary.x;
|
||||
this.actor.y = primary.y + primary.height - 1;
|
||||
this.actor.width = primary.width;
|
||||
|
||||
this._notificationBin.x = this._summaryBin.x = 0;
|
||||
this._notificationBin.width = this._summaryBin.width = primary.width;
|
||||
},
|
||||
|
||||
contains: function(source) {
|
||||
return this._sources.hasOwnProperty(source.id);
|
||||
},
|
||||
|
||||
add: function(source) {
|
||||
if (this.contains(source)) {
|
||||
log('Trying to re-add source ' + source.id);
|
||||
return;
|
||||
}
|
||||
|
||||
let iconBox = new St.Bin({ reactive: true });
|
||||
iconBox.child = source.createIcon(ICON_SIZE);
|
||||
this._summary.insert_actor(iconBox, 0);
|
||||
this._summaryNeedsToBeShown = true;
|
||||
this._icons[source.id] = iconBox;
|
||||
this._sources[source.id] = source;
|
||||
|
||||
source.connect('notify', Lang.bind(this, this._onNotify));
|
||||
|
||||
iconBox.connect('button-release-event', Lang.bind(this,
|
||||
function () {
|
||||
source.clicked();
|
||||
}));
|
||||
|
||||
source.connect('destroy', Lang.bind(this,
|
||||
function () {
|
||||
this.removeSource(source);
|
||||
}));
|
||||
},
|
||||
|
||||
removeSource: function(source) {
|
||||
if (!this.contains(source))
|
||||
return;
|
||||
|
||||
// remove all notifications with this source from the queue
|
||||
let newNotificationQueue = [];
|
||||
for (let i = 0; i < this._notificationQueue.length; i++) {
|
||||
if (this._notificationQueue[i].source != source)
|
||||
newNotificationQueue.push(this._notificationQueue[i]);
|
||||
}
|
||||
this._notificationQueue = newNotificationQueue;
|
||||
|
||||
this._summary.remove_actor(this._icons[source.id]);
|
||||
if (this._summary.get_children().length > 0)
|
||||
this._summaryNeedsToBeShown = true;
|
||||
else
|
||||
this._summaryNeedsToBeShown = false;
|
||||
delete this._icons[source.id];
|
||||
delete this._sources[source.id];
|
||||
|
||||
if (this._notification && this._notification.source == source) {
|
||||
if (this._notificationTimeoutId) {
|
||||
Mainloop.source_remove(this._notificationTimeoutId);
|
||||
this._notificationTimeoutId = 0;
|
||||
}
|
||||
this._notificationRemoved = true;
|
||||
this._updateState();
|
||||
}
|
||||
},
|
||||
|
||||
removeNotification: function(notification) {
|
||||
if (this._notification == notification && (this._notificationState == State.SHOWN || this._notificationState == State.SHOWING)) {
|
||||
if (this._notificationTimeoutId) {
|
||||
Mainloop.source_remove(this._notificationTimeoutId);
|
||||
this._notificationTimeoutId = 0;
|
||||
}
|
||||
this._notificationRemoved = true;
|
||||
this._updateState();
|
||||
return;
|
||||
}
|
||||
|
||||
let index = this._notificationQueue.indexOf(notification);
|
||||
if (index != -1)
|
||||
this._notificationQueue.splice(index, 1);
|
||||
},
|
||||
|
||||
getSource: function(id) {
|
||||
return this._sources[id];
|
||||
},
|
||||
|
||||
_getNotification: function(id, source) {
|
||||
if (this._notification && this._notification.id == id)
|
||||
return this._notification;
|
||||
|
||||
for (let i = 0; i < this._notificationQueue.length; i++) {
|
||||
if (this._notificationQueue[i].id == id && this._notificationQueue[i].source == source)
|
||||
return this._notificationQueue[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_onNotify: function(source, notification) {
|
||||
if (!notification.source.handleReplacing || this._getNotification(notification.id, source) == null) {
|
||||
notification.connect('destroy',
|
||||
Lang.bind(this, this.removeNotification));
|
||||
this._notificationQueue.push(notification);
|
||||
}
|
||||
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onSummaryEntered: function() {
|
||||
this._pointerInSummary = true;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onSummaryLeft: function() {
|
||||
this._pointerInSummary = false;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onTrayEntered: function() {
|
||||
if (this._trayLeftTimeoutId) {
|
||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||
this._trayLeftTimeoutId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this._pointerInTray = true;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onTrayLeft: function() {
|
||||
// We wait just a little before hiding the message tray in case the
|
||||
// user quickly moves the mouse back into it.
|
||||
let timeout = MESSAGE_TRAY_TIMEOUT * 1000;
|
||||
this._trayLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onTrayLeftTimeout));
|
||||
},
|
||||
|
||||
_onTrayLeftTimeout: function() {
|
||||
this._trayLeftTimeoutId = 0;
|
||||
this._pointerInTray = false;
|
||||
this._pointerInSummary = false;
|
||||
this._updateState();
|
||||
return false;
|
||||
},
|
||||
|
||||
// All of the logic for what happens when occurs here; the various
|
||||
// event handlers merely update variables such as
|
||||
// "this._pointerInTray", "this._summaryState", etc, and
|
||||
// _updateState() figures out what (if anything) needs to be done
|
||||
// at the present time.
|
||||
_updateState: function() {
|
||||
// Notifications
|
||||
let notificationsPending = this._notificationQueue.length > 0;
|
||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||
let notificationExpanded = this._notificationBin.y < 0;
|
||||
let notificationExpired = (this._notificationTimeoutId == 0 && !this._pointerInTray) || this._notificationRemoved;
|
||||
|
||||
if (this._notificationState == State.HIDDEN) {
|
||||
if (notificationsPending)
|
||||
this._showNotification();
|
||||
} else if (this._notificationState == State.SHOWN) {
|
||||
if (notificationExpired)
|
||||
this._hideNotification();
|
||||
else if (notificationPinned && !notificationExpanded)
|
||||
this._expandNotification();
|
||||
}
|
||||
|
||||
// Summary
|
||||
let summarySummoned = this._pointerInSummary || this._overviewVisible;
|
||||
let summaryPinned = this._summaryTimeoutId != 0 || this._pointerInTray || summarySummoned;
|
||||
|
||||
let notificationsVisible = (this._notificationState == State.SHOWING ||
|
||||
this._notificationState == State.SHOWN);
|
||||
let notificationsDone = !notificationsVisible && !notificationsPending;
|
||||
|
||||
if (this._summaryState == State.HIDDEN) {
|
||||
if (notificationsDone && this._summaryNeedsToBeShown)
|
||||
this._showSummary(true);
|
||||
else if (!notificationsVisible && summarySummoned)
|
||||
this._showSummary(false);
|
||||
} else if (this._summaryState == State.SHOWN) {
|
||||
if (!summaryPinned)
|
||||
this._hideSummary();
|
||||
}
|
||||
|
||||
// Tray itself
|
||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||
this._trayState == State.SHOWN);
|
||||
let trayShouldBeVisible = (!notificationsDone ||
|
||||
this._summaryState == State.SHOWING ||
|
||||
this._summaryState == State.SHOWN);
|
||||
if (!trayIsVisible && trayShouldBeVisible)
|
||||
this._showTray();
|
||||
else if (trayIsVisible && !trayShouldBeVisible)
|
||||
this._hideTray();
|
||||
},
|
||||
|
||||
_tween: function(actor, statevar, value, params) {
|
||||
let onComplete = params.onComplete;
|
||||
let onCompleteScope = params.onCompleteScope;
|
||||
let onCompleteParams = params.onCompleteParams;
|
||||
|
||||
params.onComplete = this._tweenComplete;
|
||||
params.onCompleteScope = this;
|
||||
params.onCompleteParams = [statevar, value, onComplete, onCompleteScope, onCompleteParams];
|
||||
|
||||
Tweener.addTween(actor, params);
|
||||
|
||||
let valuing = (value == State.SHOWN) ? State.SHOWING : State.HIDING;
|
||||
this[statevar] = valuing;
|
||||
},
|
||||
|
||||
_tweenComplete: function(statevar, value, onComplete, onCompleteScope, onCompleteParams) {
|
||||
this[statevar] = value;
|
||||
if (onComplete)
|
||||
onComplete.apply(onCompleteScope, onCompleteParams);
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_showTray: function() {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._tween(this.actor, "_trayState", State.SHOWN,
|
||||
{ y: primary.y + primary.height - this.actor.height,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
},
|
||||
|
||||
_hideTray: function() {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._tween(this.actor, "_trayState", State.HIDDEN,
|
||||
{ y: primary.y + primary.height - 1,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
},
|
||||
|
||||
_showNotification: function() {
|
||||
this._notification = this._notificationQueue.shift();
|
||||
this._notificationBin.child = this._notification.actor;
|
||||
|
||||
this._notificationBin.opacity = 0;
|
||||
this._notificationBin.y = this.actor.height;
|
||||
this._notificationBin.show();
|
||||
|
||||
this._tween(this._notificationBin, "_notificationState", State.SHOWN,
|
||||
{ y: 0,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._showNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
},
|
||||
|
||||
_showNotificationCompleted: function() {
|
||||
this._notificationTimeoutId =
|
||||
Mainloop.timeout_add(NOTIFICATION_TIMEOUT * 1000,
|
||||
Lang.bind(this, this._notificationTimeout));
|
||||
},
|
||||
|
||||
_notificationTimeout: function() {
|
||||
this._notificationTimeoutId = 0;
|
||||
this._updateState();
|
||||
return false;
|
||||
},
|
||||
|
||||
_hideNotification: function() {
|
||||
this._notificationRemoved = false;
|
||||
this._notification.popIn();
|
||||
|
||||
this._tween(this._notificationBin, "_notificationState", State.HIDDEN,
|
||||
{ y: this.actor.height,
|
||||
opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._hideNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
},
|
||||
|
||||
_hideNotificationCompleted: function() {
|
||||
this._notificationBin.hide();
|
||||
this._notificationBin.child = null;
|
||||
this._notification = null;
|
||||
},
|
||||
|
||||
_expandNotification: function() {
|
||||
if (this._notification && this._notification.popOut()) {
|
||||
this._tween(this._notificationBin, "_notificationState", State.SHOWN,
|
||||
{ y: this.actor.height - this._notificationBin.height,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_showSummary: function(withTimeout) {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._summaryBin.opacity = 0;
|
||||
this._summaryBin.y = this.actor.height;
|
||||
this._tween(this._summaryBin, "_summaryState", State.SHOWN,
|
||||
{ y: 0,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._showSummaryCompleted,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [withTimeout]
|
||||
});
|
||||
},
|
||||
|
||||
_showSummaryCompleted: function(withTimeout) {
|
||||
this._summaryNeedsToBeShown = false;
|
||||
|
||||
if (withTimeout) {
|
||||
this._summaryTimeoutId =
|
||||
Mainloop.timeout_add(SUMMARY_TIMEOUT * 1000,
|
||||
Lang.bind(this, this._summaryTimeout));
|
||||
}
|
||||
},
|
||||
|
||||
_summaryTimeout: function() {
|
||||
this._summaryTimeoutId = 0;
|
||||
this._updateState();
|
||||
return false;
|
||||
},
|
||||
|
||||
_hideSummary: function() {
|
||||
this._tween(this._summaryBin, "_summaryState", State.HIDDEN,
|
||||
{ opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
this._summaryNeedsToBeShown = false;
|
||||
}
|
||||
};
|
367
js/ui/notificationDaemon.js
Normal file
@ -0,0 +1,367 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
const EMPATHY = 'Empathy';
|
||||
|
||||
let nextNotificationId = 1;
|
||||
|
||||
// Should really be defined in dbus.js
|
||||
const BusIface = {
|
||||
name: 'org.freedesktop.DBus',
|
||||
methods: [{ name: 'GetConnectionUnixProcessID',
|
||||
inSignature: 's',
|
||||
outSignature: 'i' }]
|
||||
}
|
||||
|
||||
const Bus = function () {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Bus.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.proxifyObject(this, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
||||
}
|
||||
}
|
||||
|
||||
DBus.proxifyPrototype(Bus.prototype, BusIface);
|
||||
|
||||
const NotificationDaemonIface = {
|
||||
name: 'org.freedesktop.Notifications',
|
||||
methods: [{ name: 'Notify',
|
||||
inSignature: 'susssasa{sv}i',
|
||||
outSignature: 'u'
|
||||
},
|
||||
{ name: 'CloseNotification',
|
||||
inSignature: 'u',
|
||||
outSignature: ''
|
||||
},
|
||||
{ name: 'GetCapabilities',
|
||||
inSignature: '',
|
||||
outSignature: 'as'
|
||||
},
|
||||
{ name: 'GetServerInformation',
|
||||
inSignature: '',
|
||||
outSignature: 'ssss'
|
||||
}],
|
||||
signals: [{ name: 'NotificationClosed',
|
||||
inSignature: 'uu' },
|
||||
{ name: 'ActionInvoked',
|
||||
inSignature: 'us' }]
|
||||
};
|
||||
|
||||
const NotificationClosedReason = {
|
||||
EXPIRED: 1,
|
||||
DISMISSED: 2,
|
||||
APP_CLOSED: 3,
|
||||
UNDEFINED: 4
|
||||
};
|
||||
|
||||
const Urgency = {
|
||||
LOW: 0,
|
||||
NORMAL: 1,
|
||||
CRITICAL: 2
|
||||
};
|
||||
|
||||
const rewriteRules = {
|
||||
'XChat': [
|
||||
{ pattern: /^XChat: Private message from: (\S*) \(.*\)$/,
|
||||
replacement: '<$1>' },
|
||||
{ pattern: /^XChat: New public message from: (\S*) \((.*)\)$/,
|
||||
replacement: '$2 <$1>' },
|
||||
{ pattern: /^XChat: Highlighted message from: (\S*) \((.*)\)$/,
|
||||
replacement: '$2 <$1>' }
|
||||
]
|
||||
};
|
||||
function NotificationDaemon() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
NotificationDaemon.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.exportObject('/org/freedesktop/Notifications', this);
|
||||
|
||||
this._everAcquiredName = false;
|
||||
DBus.session.acquire_name('org.freedesktop.Notifications',
|
||||
// We pass MANY_INSTANCES so that if
|
||||
// notification-daemon is running, we'll
|
||||
// get queued behind it and then get the
|
||||
// name after killing it below
|
||||
DBus.MANY_INSTANCES,
|
||||
Lang.bind(this, this._acquiredName),
|
||||
Lang.bind(this, this._lostName));
|
||||
|
||||
this._currentNotifications = {};
|
||||
},
|
||||
|
||||
_acquiredName: function() {
|
||||
this._everAcquiredName = true;
|
||||
},
|
||||
|
||||
_lostName: function() {
|
||||
if (this._everAcquiredName)
|
||||
log('Lost name org.freedesktop.Notifications!');
|
||||
else if (GLib.getenv('GNOME_SHELL_NO_REPLACE'))
|
||||
log('Failed to acquire org.freedesktop.Notifications');
|
||||
else {
|
||||
log('Failed to acquire org.freedesktop.Notifications; trying again');
|
||||
|
||||
// kill the notification-daemon. pkill is more portable
|
||||
// than killall, but on Linux at least it won't match if
|
||||
// you pass more than 15 characters of the process name...
|
||||
// However, if you use the "-f" flag to match the entire
|
||||
// command line, it will work, but we have to be careful
|
||||
// in that case that we don't match "gedit
|
||||
// notification-daemon.c" or whatever...
|
||||
let p = new Shell.Process({ args: ['pkill', '-f',
|
||||
'^([^ ]*/)?(notification-daemon|notify-osd)$']});
|
||||
p.run();
|
||||
}
|
||||
},
|
||||
|
||||
_sourceId: function(id) {
|
||||
return 'source-' + id;
|
||||
},
|
||||
|
||||
Notify: function(appName, replacesId, icon, summary, body,
|
||||
actions, hints, timeout) {
|
||||
let notification, id;
|
||||
// We associate each application with a source and set the source id to be based on
|
||||
// the appName. We support application updates by creating a new Notification object
|
||||
// only if replacesId was not specified or if we no longer have the notification with
|
||||
// the specified replacesId.
|
||||
//
|
||||
// We are planning to add Empathy-specific features in the message tray, but in the
|
||||
// meantime we handle Empathy notifications received through the notification daemon
|
||||
// differently from other notifications.
|
||||
// 1) We display different people sending messages as different sources. So we use
|
||||
// notification id instead of the appName when creating id for the source.
|
||||
// 2) We queue notification with different messages to show them one after another,
|
||||
// rather than replace the notification on the spot. So we create a new Notification
|
||||
// object each time, disregarding the fact that we might already have another
|
||||
// notification with the same replacesId.
|
||||
// Empathy uses replacesId for all the notifications from the same window until the
|
||||
// notification with that id is dismissed. Notifications from different people in
|
||||
// different tabs have the same replacesId. So while being closer to the eventual design,
|
||||
// our special-handling of Empathy notifications is somewhat buggy. The user might end up
|
||||
// with multiple icons for the same person if the user dismisses the window for that person
|
||||
// (which doesn't result in removing the icon) or the user might not get the icon for
|
||||
// the person after a new notification in one of the tabs of the chat window for which
|
||||
// another person's icon is already displayed.
|
||||
|
||||
let isEmpathy = appName == EMPATHY;
|
||||
if (replacesId != 0) {
|
||||
id = replacesId;
|
||||
if (!isEmpathy)
|
||||
notification = this._currentNotifications[id];
|
||||
} else {
|
||||
id = nextNotificationId++;
|
||||
}
|
||||
|
||||
let sourceId = this._sourceId(isEmpathy ? id : appName);
|
||||
let source = Main.messageTray.getSource(sourceId);
|
||||
|
||||
// Source may be null if we have never received a notification from
|
||||
// this app or if all notifications from this app have been acknowledged.
|
||||
if (source == null) {
|
||||
source = new Source(sourceId, icon, hints);
|
||||
Main.messageTray.add(source);
|
||||
|
||||
source.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
source.destroy();
|
||||
}));
|
||||
|
||||
let sender = DBus.getCurrentMessageContext().sender;
|
||||
let busProxy = new Bus();
|
||||
busProxy.GetConnectionUnixProcessIDRemote(sender, function (result, excp) {
|
||||
let app = Shell.WindowTracker.get_default().get_app_from_pid(result);
|
||||
source.setApp(app);
|
||||
});
|
||||
} else {
|
||||
source.update(icon, hints);
|
||||
}
|
||||
|
||||
summary = GLib.markup_escape_text(summary, -1);
|
||||
|
||||
let rewrites = rewriteRules[appName];
|
||||
if (rewrites) {
|
||||
for (let i = 0; i < rewrites.length; i++) {
|
||||
let rule = rewrites[i];
|
||||
if (summary.search(rule.pattern) != -1)
|
||||
summary = summary.replace(rule.pattern, rule.replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (notification == null) {
|
||||
notification = new MessageTray.Notification(id, source, summary, body, true);
|
||||
// This will result in us keeping only the latest Empathy notification with the given
|
||||
// id in this._currentNotifications, which will only affect not being able to close all
|
||||
// the Empathy notifications with a given id in CloseNotification(). Since this not a
|
||||
// a likely scenario and this special-casing of Empathy in the notification daemon is
|
||||
// temporary, it doesn't seem worthwhile to change this._currentNotifications to
|
||||
// {id, [array of notifications]} just for that case.
|
||||
this._currentNotifications[id] = notification;
|
||||
notification.connect('dismissed', Lang.bind(this,
|
||||
function(n) {
|
||||
n.destroy();
|
||||
this._emitNotificationClosed(n.id, NotificationClosedReason.DISMISSED);
|
||||
}));
|
||||
} else {
|
||||
// passing in true as the last parameter will clear out extra actors,
|
||||
// such as actions
|
||||
notification.update(summary, body, true);
|
||||
}
|
||||
|
||||
if (actions.length) {
|
||||
for (let i = 0; i < actions.length - 1; i += 2)
|
||||
notification.addAction(actions[i], actions[i + 1]);
|
||||
notification.connect('action-invoked', Lang.bind(this, this._actionInvoked, source, id));
|
||||
}
|
||||
|
||||
source.notify(notification);
|
||||
return id;
|
||||
},
|
||||
|
||||
CloseNotification: function(id) {
|
||||
let notification = this._currentNotifications[id];
|
||||
if (notification)
|
||||
notification.destroy();
|
||||
this._emitNotificationClosed(id, NotificationClosedReason.APP_CLOSED);
|
||||
},
|
||||
|
||||
GetCapabilities: function() {
|
||||
return [
|
||||
'actions',
|
||||
'body',
|
||||
// 'body-hyperlinks',
|
||||
// 'body-images',
|
||||
'body-markup',
|
||||
// 'icon-multi',
|
||||
'icon-static'
|
||||
// 'sound',
|
||||
];
|
||||
},
|
||||
|
||||
GetServerInformation: function() {
|
||||
return [
|
||||
'GNOME Shell',
|
||||
'GNOME',
|
||||
'0.1', // FIXME, get this from somewhere
|
||||
'1.0'
|
||||
];
|
||||
},
|
||||
|
||||
_actionInvoked: function(notification, action, source, id) {
|
||||
this._emitActionInvoked(id, action);
|
||||
source.destroy();
|
||||
},
|
||||
|
||||
_emitNotificationClosed: function(id, reason) {
|
||||
delete this._currentNotifications[id];
|
||||
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
||||
'org.freedesktop.Notifications',
|
||||
'NotificationClosed', 'uu',
|
||||
[id, reason]);
|
||||
},
|
||||
|
||||
_emitActionInvoked: function(id, action) {
|
||||
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
||||
'org.freedesktop.Notifications',
|
||||
'ActionInvoked', 'us',
|
||||
[id, action]);
|
||||
}
|
||||
};
|
||||
|
||||
DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
|
||||
|
||||
function Source(sourceId, icon, hints) {
|
||||
this._init(sourceId, icon, hints);
|
||||
}
|
||||
|
||||
Source.prototype = {
|
||||
__proto__: MessageTray.Source.prototype,
|
||||
|
||||
_init: function(sourceId, icon, hints) {
|
||||
MessageTray.Source.prototype._init.call(this, sourceId);
|
||||
|
||||
this.update(icon, hints);
|
||||
},
|
||||
|
||||
update: function(icon, hints) {
|
||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||
|
||||
this._icon = icon;
|
||||
this._iconData = hints.icon_data;
|
||||
this._urgency = hints.urgency;
|
||||
|
||||
this.app = null;
|
||||
this._openAppRequested = false;
|
||||
},
|
||||
|
||||
createIcon: function(size) {
|
||||
let textureCache = Shell.TextureCache.get_default();
|
||||
|
||||
if (this._icon) {
|
||||
if (this._icon.substr(0, 7) == 'file://')
|
||||
return textureCache.load_uri_async(this._icon, size, size);
|
||||
else if (this._icon[0] == '/') {
|
||||
let uri = GLib.filename_to_uri(this._icon, null);
|
||||
return textureCache.load_uri_async(uri, size, size);
|
||||
} else
|
||||
return textureCache.load_icon_name(this._icon, size);
|
||||
} else if (this._iconData) {
|
||||
let [width, height, rowStride, hasAlpha,
|
||||
bitsPerSample, nChannels, data] = this._iconData;
|
||||
return textureCache.load_from_raw(data, data.length, hasAlpha,
|
||||
width, height, rowStride, size);
|
||||
} else {
|
||||
let stockIcon;
|
||||
switch (this._urgency) {
|
||||
case Urgency.LOW:
|
||||
case Urgency.NORMAL:
|
||||
stockIcon = 'gtk-dialog-info';
|
||||
break;
|
||||
case Urgency.CRITICAL:
|
||||
stockIcon = 'gtk-dialog-error';
|
||||
break;
|
||||
}
|
||||
return textureCache.load_icon_name(stockIcon, size);
|
||||
}
|
||||
},
|
||||
|
||||
clicked: function() {
|
||||
this.openApp();
|
||||
MessageTray.Source.prototype.clicked.call(this);
|
||||
},
|
||||
|
||||
setApp: function(app) {
|
||||
this.app = app;
|
||||
if (this._openAppRequested)
|
||||
this.openApp();
|
||||
|
||||
if (app.get_name() == EMPATHY)
|
||||
this.handleReplacing = false;
|
||||
},
|
||||
|
||||
openApp: function() {
|
||||
if (this.app == null) {
|
||||
this._openAppRequested = true;
|
||||
return;
|
||||
}
|
||||
let windows = this.app.get_windows();
|
||||
if (windows.length > 0) {
|
||||
let mostRecentWindow = windows[0];
|
||||
Main.activateWindow(mostRecentWindow);
|
||||
}
|
||||
this._openAppRequested = false;
|
||||
}
|
||||
};
|
@ -8,19 +8,18 @@ const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const DocDisplay = imports.ui.docDisplay;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Link = imports.ui.link;
|
||||
const Main = imports.ui.main;
|
||||
const Panel = imports.ui.panel;
|
||||
const Dash = imports.ui.dash;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Workspaces = imports.ui.workspaces;
|
||||
|
||||
const ROOT_OVERVIEW_COLOR = new Clutter.Color();
|
||||
ROOT_OVERVIEW_COLOR.from_pixel(0x000000ff);
|
||||
const WorkspacesView = imports.ui.workspacesView;
|
||||
|
||||
// Time for initial animation going into Overview mode
|
||||
const ANIMATION_TIME = 0.25;
|
||||
@ -39,6 +38,10 @@ const ANIMATION_TIME = 0.25;
|
||||
// will take up the remaining sections of the display.
|
||||
|
||||
const WIDE_SCREEN_CUT_OFF_RATIO = 1.4;
|
||||
// A common netbook resolution is 1024x600, which trips the widescreen
|
||||
// ratio. However that leaves way too few pixels for the dash. So
|
||||
// just treat this as a regular screen.
|
||||
const WIDE_SCREEN_MINIMUM_HEIGHT = 768;
|
||||
|
||||
const COLUMNS_REGULAR_SCREEN = 4;
|
||||
const ROWS_REGULAR_SCREEN = 8;
|
||||
@ -70,10 +73,117 @@ const SHADOW_WIDTH = 6;
|
||||
|
||||
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
||||
|
||||
const INFO_BAR_HIDE_TIMEOUT = 30;
|
||||
|
||||
let wideScreen = false;
|
||||
let displayGridColumnWidth = null;
|
||||
let displayGridRowHeight = null;
|
||||
let addRemoveButtonSize = null;
|
||||
|
||||
function InfoBar() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
InfoBar.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.Bin({ style_class: 'info-bar-panel',
|
||||
x_fill: true,
|
||||
y_fill: false });
|
||||
this._label = new St.Label();
|
||||
this._undo = new St.Button({ label: _("Undo"),
|
||||
style_class: 'info-bar-link-button' });
|
||||
|
||||
let bin = new St.Bin({ x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.actor.set_child(bin);
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'info-bar' });
|
||||
bin.set_child(box);
|
||||
this._timeoutId = 0;
|
||||
|
||||
box.add(this._label, {'y-fill' : false, 'y-align' : St.Align.MIDDLE});
|
||||
box.add(this._undo);
|
||||
|
||||
this.actor.set_opacity(0);
|
||||
|
||||
this._undoCallback = null;
|
||||
this._undo.connect('clicked', Lang.bind(this, this._onUndoClicked));
|
||||
|
||||
this._overviewWasHidden = false;
|
||||
this._hidingOverviewId = 0;
|
||||
},
|
||||
|
||||
_onUndoClicked: function() {
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
|
||||
if (this._undoCallback)
|
||||
this._undoCallback();
|
||||
this.actor.set_opacity(0);
|
||||
this._undoCallback = null;
|
||||
},
|
||||
|
||||
_hideDone: function() {
|
||||
this._undoCallback = null;
|
||||
},
|
||||
|
||||
_hide: function() {
|
||||
this._overviewWasHidden = false;
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 0,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME,
|
||||
onComplete: this._hideDone,
|
||||
onCompleteScope: this
|
||||
});
|
||||
},
|
||||
|
||||
_onTimeout: function() {
|
||||
this._timeoutId = 0;
|
||||
if (this._overviewWasHidden)
|
||||
this._hide();
|
||||
return false;
|
||||
},
|
||||
|
||||
_onOverviewHiding: function() {
|
||||
if (this._timeoutId == 0)
|
||||
this._hide();
|
||||
else
|
||||
this._overviewWasHidden = true;
|
||||
},
|
||||
|
||||
setMessage: function(text, undoCallback) {
|
||||
if (this._timeoutId)
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
|
||||
if (this._hidingOverviewId == 0) {
|
||||
// Set here, because when constructor is called, overview is null.
|
||||
if (!Main.overview)
|
||||
return;
|
||||
// We don't actually use the ID, it's just a way of tracking whether we've hooked up the signal
|
||||
this._hidingOverviewId = Main.overview.connect('hiding', Lang.bind(this, this._onOverviewHiding));
|
||||
}
|
||||
this._timeout = false;
|
||||
this._overviewWasHidden = false;
|
||||
|
||||
this._label.text = text;
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 255,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME
|
||||
});
|
||||
|
||||
this._timeoutId = Mainloop.timeout_add_seconds(INFO_BAR_HIDE_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||
|
||||
this._undoCallback = undoCallback;
|
||||
if (undoCallback)
|
||||
this._undo.show();
|
||||
else
|
||||
this._undo.hide();
|
||||
}
|
||||
};
|
||||
|
||||
function Overview() {
|
||||
this._init();
|
||||
@ -81,9 +191,15 @@ function Overview() {
|
||||
|
||||
Overview.prototype = {
|
||||
_init : function() {
|
||||
this._group = new Clutter.Group();
|
||||
this._group = new St.BoxLayout({ style_class: 'overview' });
|
||||
this._group._delegate = this;
|
||||
|
||||
this.infoBar = new InfoBar();
|
||||
this._group.add_actor(this.infoBar.actor);
|
||||
|
||||
this._workspacesViewSwitch = new WorkspacesView.WorkspacesViewSwitch();
|
||||
this._workspacesViewSwitch.connect('view-changed', Lang.bind(this, this._onViewChanged));
|
||||
|
||||
this.visible = false;
|
||||
this.animationInProgress = false;
|
||||
this._hideInProgress = false;
|
||||
@ -107,7 +223,7 @@ Overview.prototype = {
|
||||
this._group.add_actor(this._transparentBackground);
|
||||
|
||||
// Background color for the Overview
|
||||
this._backOver = new Clutter.Rectangle({ color: ROOT_OVERVIEW_COLOR });
|
||||
this._backOver = new St.Label();
|
||||
this._group.add_actor(this._backOver);
|
||||
|
||||
this._group.hide();
|
||||
@ -118,9 +234,7 @@ Overview.prototype = {
|
||||
this._group.add_actor(this._dash.actor);
|
||||
|
||||
// Container to hold popup pane chrome.
|
||||
this._paneContainer = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 6
|
||||
});
|
||||
this._paneContainer = new St.BoxLayout({ style_class: 'overview-pane' });
|
||||
// Note here we explicitly don't set the paneContainer to be reactive yet; that's done
|
||||
// inside the notify::visible handler on panes.
|
||||
this._paneContainer.connect('button-release-event', Lang.bind(this, function(background) {
|
||||
@ -130,78 +244,127 @@ Overview.prototype = {
|
||||
this._group.add_actor(this._paneContainer);
|
||||
|
||||
this._transparentBackground.lower_bottom();
|
||||
this._paneContainer.lower_bottom();
|
||||
this._paneContainer.hide();
|
||||
|
||||
this._coverPane.lower_bottom();
|
||||
|
||||
this._workspaces = null;
|
||||
},
|
||||
|
||||
_createControlsBar: function() {
|
||||
this._workspacesBar = new St.BoxLayout({ 'pack-start': true,
|
||||
style_class: 'workspaces-bar' });
|
||||
this._workspacesBar.move_by(this._workspacesBarX, this._workspacesBarY);
|
||||
|
||||
let controlsBar = this._workspacesViewSwitch.createControlsBar();
|
||||
let bar = this._workspaces.createControllerBar();
|
||||
this._workspacesBar.add(bar, { expand: true, 'x-fill': true, 'y-fill': true,
|
||||
y_align: St.Align.MIDDLE, x_align: St.Align.START });
|
||||
this._workspacesBar.add(controlsBar, {x_align: St.Align.END});
|
||||
this._workspacesBar.width = this._workspacesBarWidth;
|
||||
|
||||
this._group.add_actor(this._workspacesBar);
|
||||
this._workspacesBar.raise(this._workspaces.actor);
|
||||
},
|
||||
|
||||
_onViewChanged: function() {
|
||||
if (!this.visible)
|
||||
return;
|
||||
//Remove old worspacesView
|
||||
this._group.remove_actor(this._workspacesBar);
|
||||
this._workspaces.hide();
|
||||
this._group.remove_actor(this._workspaces.actor);
|
||||
this._workspaces.destroy();
|
||||
this._workspacesBar.destroy();
|
||||
|
||||
this._workspaces = this._workspacesViewSwitch.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
|
||||
this._workspacesX, this._workspacesY, false);
|
||||
|
||||
//Show new workspacesView
|
||||
this._group.add_actor(this._workspaces.actor);
|
||||
this._dash.actor.raise(this._workspaces.actor);
|
||||
|
||||
this._createControlsBar();
|
||||
|
||||
// Set new position and scale to workspaces.
|
||||
this.emit('showing');
|
||||
},
|
||||
|
||||
_recalculateGridSizes: function () {
|
||||
wideScreen = (global.screen_width/global.screen_height > WIDE_SCREEN_CUT_OFF_RATIO);
|
||||
let primary = global.get_primary_monitor();
|
||||
wideScreen = (primary.width/primary.height > WIDE_SCREEN_CUT_OFF_RATIO) &&
|
||||
(primary.height >= WIDE_SCREEN_MINIMUM_HEIGHT);
|
||||
|
||||
// We divide the screen into an imaginary grid which helps us determine the layout of
|
||||
// different visual components.
|
||||
if (wideScreen) {
|
||||
displayGridColumnWidth = global.screen_width / COLUMNS_WIDE_SCREEN;
|
||||
displayGridRowHeight = global.screen_height / ROWS_WIDE_SCREEN;
|
||||
displayGridColumnWidth = Math.floor(primary.width / COLUMNS_WIDE_SCREEN);
|
||||
displayGridRowHeight = Math.floor(primary.height / ROWS_WIDE_SCREEN);
|
||||
} else {
|
||||
displayGridColumnWidth = global.screen_width / COLUMNS_REGULAR_SCREEN;
|
||||
displayGridRowHeight = global.screen_height / ROWS_REGULAR_SCREEN;
|
||||
displayGridColumnWidth = Math.floor(primary.width / COLUMNS_REGULAR_SCREEN);
|
||||
displayGridRowHeight = Math.floor(primary.height / ROWS_REGULAR_SCREEN);
|
||||
}
|
||||
},
|
||||
|
||||
relayout: function () {
|
||||
let screenHeight = global.screen_height;
|
||||
let screenWidth = global.screen_width;
|
||||
let primary = global.get_primary_monitor();
|
||||
|
||||
this._recalculateGridSizes();
|
||||
|
||||
this._group.set_position(primary.x, primary.y);
|
||||
|
||||
let contentY = Panel.PANEL_HEIGHT;
|
||||
let contentHeight = screenHeight - contentY;
|
||||
let contentHeight = primary.height - contentY;
|
||||
|
||||
this._coverPane.set_position(0, contentY);
|
||||
this._coverPane.set_size(screenWidth, contentHeight);
|
||||
this._coverPane.set_size(primary.width, contentHeight);
|
||||
|
||||
let workspaceColumnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
let workspaceRowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
|
||||
this._workspacesWidth = displayGridColumnWidth * workspaceColumnsUsed
|
||||
- WORKSPACE_GRID_PADDING * 2;
|
||||
// We scale the vertical padding by (screenHeight / screenWidth)
|
||||
// We scale the vertical padding by (primary.height / primary.width)
|
||||
// so that the workspace preserves its aspect ratio.
|
||||
this._workspacesHeight = displayGridRowHeight * workspaceRowsUsed
|
||||
- WORKSPACE_GRID_PADDING * (screenHeight / screenWidth) * 2;
|
||||
this._workspacesHeight = Math.floor(displayGridRowHeight * workspaceRowsUsed
|
||||
- WORKSPACE_GRID_PADDING * (primary.height / primary.width) * 2);
|
||||
|
||||
this._workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
|
||||
this._workspacesY = displayGridRowHeight + WORKSPACE_GRID_PADDING * (screenHeight / screenWidth);
|
||||
this._workspacesY = Math.floor(displayGridRowHeight + WORKSPACE_GRID_PADDING * (primary.height / primary.width));
|
||||
|
||||
this._dash.actor.set_position(0, contentY);
|
||||
this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
|
||||
this._dash.searchArea.height = this._workspacesY - contentY;
|
||||
this._dash.sectionArea.height = this._workspacesHeight;
|
||||
this._dash.searchResults.actor.height = this._workspacesHeight;
|
||||
|
||||
this.infoBar.actor.set_position(displayGridColumnWidth, Panel.PANEL_HEIGHT);
|
||||
this.infoBar.actor.set_size(primary.width - displayGridColumnWidth, this._workspacesY - Panel.PANEL_HEIGHT);
|
||||
this.infoBar.actor.raise_top();
|
||||
|
||||
// place the 'Add Workspace' button in the bottom row of the grid
|
||||
addRemoveButtonSize = Math.floor(displayGridRowHeight * 3/5);
|
||||
this._addButtonX = this._workspacesX + this._workspacesWidth - addRemoveButtonSize;
|
||||
this._addButtonY = screenHeight - Math.floor(displayGridRowHeight * 4/5);
|
||||
this._workspacesBarX = this._workspacesX;
|
||||
this._workspacesBarWidth = primary.width - this._workspacesBarX - WORKSPACE_GRID_PADDING;
|
||||
this._workspacesBarY = primary.height - displayGridRowHeight;
|
||||
|
||||
this._backOver.set_position(0, contentY);
|
||||
this._backOver.set_size(global.screen_width, contentHeight);
|
||||
// The parent (this._group) is positioned at the top left of the primary monitor
|
||||
// while this._backOver occupies the entire screen.
|
||||
this._backOver.set_position(- primary.x, - primary.y);
|
||||
this._backOver.set_size(global.screen_width, global.screen_height);
|
||||
|
||||
this._paneContainer.set_position(this._dash.actor.x + this._dash.actor.width + DEFAULT_PADDING,
|
||||
contentY);
|
||||
this._workspacesY);
|
||||
// Dynamic width
|
||||
this._paneContainer.height = contentHeight;
|
||||
this._paneContainer.height = this._workspacesHeight;
|
||||
|
||||
this._transparentBackground.set_position(this._paneContainer.x, this._paneContainer.y);
|
||||
this._transparentBackground.set_size(global.screen_width - this._paneContainer.x,
|
||||
this._transparentBackground.set_size(primary.width - this._paneContainer.x,
|
||||
this._paneContainer.height);
|
||||
|
||||
if (this._activeDisplayPane != null)
|
||||
this._activeDisplayPane.actor.width = displayGridColumnWidth * 2;
|
||||
},
|
||||
|
||||
addPane: function (pane) {
|
||||
this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE);
|
||||
this._paneContainer.add(pane.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||
// When a pane is displayed, we raise the transparent background to the top
|
||||
// and connect to button-release-event on it, then raise the pane above that.
|
||||
// The idea here is that clicking anywhere outside the pane should close it.
|
||||
@ -209,16 +372,17 @@ Overview.prototype = {
|
||||
let backgroundEventId = null;
|
||||
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
||||
if (isOpen) {
|
||||
pane.actor.width = displayGridColumnWidth * 2;
|
||||
this._activeDisplayPane = pane;
|
||||
this._transparentBackground.raise_top();
|
||||
this._paneContainer.raise_top();
|
||||
this._paneContainer.show();
|
||||
if (backgroundEventId != null)
|
||||
this._transparentBackground.disconnect(backgroundEventId);
|
||||
backgroundEventId = this._transparentBackground.connect('button-release-event', Lang.bind(this, function () {
|
||||
this._activeDisplayPane.close();
|
||||
return true;
|
||||
}));
|
||||
this._workspaces.actor.opacity = 64;
|
||||
} else if (pane == this._activeDisplayPane) {
|
||||
this._activeDisplayPane = null;
|
||||
if (backgroundEventId != null) {
|
||||
@ -226,7 +390,8 @@ Overview.prototype = {
|
||||
backgroundEventId = null;
|
||||
}
|
||||
this._transparentBackground.lower_bottom();
|
||||
this._paneContainer.lower_bottom();
|
||||
this._paneContainer.hide();
|
||||
this._workspaces.actor.opacity = 255;
|
||||
}
|
||||
}));
|
||||
},
|
||||
@ -238,7 +403,7 @@ Overview.prototype = {
|
||||
// This allows the user to place the item on any workspace.
|
||||
handleDragOver : function(source, actor, x, y, time) {
|
||||
if (source instanceof GenericDisplay.GenericDisplayItem
|
||||
|| source instanceof AppDisplay.BaseWellItem) {
|
||||
|| source instanceof AppDisplay.AppIcon) {
|
||||
if (this._activeDisplayPane != null)
|
||||
this._activeDisplayPane.close();
|
||||
return true;
|
||||
@ -277,7 +442,8 @@ Overview.prototype = {
|
||||
show : function() {
|
||||
if (this.visible)
|
||||
return;
|
||||
Main.pushModal(this._dash.actor);
|
||||
if (!Main.pushModal(this._dash.actor))
|
||||
return;
|
||||
|
||||
this.visible = true;
|
||||
this.animationInProgress = true;
|
||||
@ -285,8 +451,8 @@ Overview.prototype = {
|
||||
this._dash.show();
|
||||
|
||||
/* TODO: make this stuff dynamic */
|
||||
this._workspaces = new Workspaces.Workspaces(this._workspacesWidth, this._workspacesHeight,
|
||||
this._workspacesX, this._workspacesY);
|
||||
this._workspaces = this._workspacesViewSwitch.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
|
||||
this._workspacesX, this._workspacesY, true);
|
||||
this._group.add_actor(this._workspaces.actor);
|
||||
|
||||
// The workspaces actor is as big as the screen, so we have to raise the dash above it
|
||||
@ -294,11 +460,7 @@ Overview.prototype = {
|
||||
// be as big as the screen.
|
||||
this._dash.actor.raise(this._workspaces.actor);
|
||||
|
||||
// Create (+) button
|
||||
this._addButton = new AddWorkspaceButton(addRemoveButtonSize, this._addButtonX, this._addButtonY, Lang.bind(this, this._acceptNewWorkspaceDrop));
|
||||
this._addButton.actor.connect('button-release-event', Lang.bind(this, this._addNewWorkspace));
|
||||
this._group.add_actor(this._addButton.actor);
|
||||
this._addButton.actor.raise(this._workspaces.actor);
|
||||
this._createControlsBar();
|
||||
|
||||
// All the the actors in the window group are completely obscured,
|
||||
// hiding the group holding them while the Overview is displayed greatly
|
||||
@ -316,9 +478,10 @@ Overview.prototype = {
|
||||
// The opposite transition is used in hide().
|
||||
this._group.scaleX = this._group.scaleY = this.getZoomedInScale();
|
||||
[this._group.x, this._group.y] = this.getZoomedInPosition();
|
||||
let primary = global.get_primary_monitor();
|
||||
Tweener.addTween(this._group,
|
||||
{ x: 0,
|
||||
y: 0,
|
||||
{ x: primary.x,
|
||||
y: primary.y,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
transition: 'easeOutQuad',
|
||||
@ -349,6 +512,9 @@ Overview.prototype = {
|
||||
this._activeDisplayPane.close();
|
||||
this._workspaces.hide();
|
||||
|
||||
this._workspacesBar.destroy();
|
||||
this._workspacesBar = null;
|
||||
|
||||
// Create a zoom in effect by transforming the Overview group so that
|
||||
// the active workspace fills up the whole screen. The opposite
|
||||
// transition is used in show().
|
||||
@ -395,20 +561,6 @@ Overview.prototype = {
|
||||
return this._workspaces;
|
||||
},
|
||||
|
||||
/**
|
||||
* activateWindow:
|
||||
* @metaWindow: A #MetaWindow
|
||||
* @time: Event timestamp integer
|
||||
*
|
||||
* Make the given MetaWindow be the focus window, switching
|
||||
* to the workspace it's on if necessary. This function
|
||||
* should only be used when the Overview is currently active;
|
||||
* outside of that, use the relevant methods on MetaDisplay.
|
||||
*/
|
||||
activateWindow: function (metaWindow, time) {
|
||||
this._workspaces.activateWindowFromOverview(metaWindow, time);
|
||||
},
|
||||
|
||||
//// Private methods ////
|
||||
|
||||
_showDone: function() {
|
||||
@ -430,7 +582,7 @@ Overview.prototype = {
|
||||
this._dash.hide();
|
||||
this._group.hide();
|
||||
|
||||
this.visible = false;
|
||||
this.visible = false;
|
||||
this.animationInProgress = false;
|
||||
this._hideInProgress = false;
|
||||
|
||||
@ -438,43 +590,6 @@ Overview.prototype = {
|
||||
|
||||
Main.popModal(this._dash.actor);
|
||||
this.emit('hidden');
|
||||
},
|
||||
|
||||
_addNewWorkspace: function() {
|
||||
global.screen.append_new_workspace(false, global.screen.get_display().get_current_time());
|
||||
},
|
||||
|
||||
_acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
|
||||
this._addNewWorkspace();
|
||||
return this._workspaces.acceptNewWorkspaceDrop(source, dropActor, x, y, time);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Overview.prototype);
|
||||
|
||||
function AddWorkspaceButton(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
||||
this._init(buttonSize, buttonX, buttonY, acceptDropCallback);
|
||||
}
|
||||
|
||||
AddWorkspaceButton.prototype = {
|
||||
_init: function(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
||||
this.actor = new Clutter.Group({ x: buttonX,
|
||||
y: buttonY,
|
||||
width: global.screen_width - buttonX,
|
||||
height: global.screen_height - buttonY,
|
||||
reactive: true });
|
||||
this.actor._delegate = this;
|
||||
this._acceptDropCallback = acceptDropCallback;
|
||||
|
||||
let plus = new Clutter.Texture({ x: 0,
|
||||
y: 0,
|
||||
width: buttonSize,
|
||||
height: buttonSize });
|
||||
plus.set_from_file(global.imagedir + 'add-workspace.svg');
|
||||
this.actor.add_actor(plus);
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
acceptDrop: function(source, actor, x, y, time) {
|
||||
return this._acceptDropCallback(source, actor, x, y, time);
|
||||
}
|
||||
};
|
||||
|
517
js/ui/panel.js
@ -7,45 +7,23 @@ const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Button = imports.ui.button;
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Main = imports.ui.main;
|
||||
const StatusMenu = imports.ui.statusMenu;
|
||||
|
||||
const PANEL_HEIGHT = 26;
|
||||
const TRAY_HEIGHT = PANEL_HEIGHT - 1;
|
||||
|
||||
const DEFAULT_PADDING = 4;
|
||||
|
||||
const PANEL_ICON_SIZE = 24;
|
||||
|
||||
const BACKGROUND_TOP = new Clutter.Color();
|
||||
BACKGROUND_TOP.from_pixel(0x161616ff);
|
||||
const BACKGROUND_BOTTOM = new Clutter.Color();
|
||||
BACKGROUND_BOTTOM.from_pixel(0x000000ff);
|
||||
|
||||
const PANEL_FOREGROUND_COLOR = new Clutter.Color();
|
||||
PANEL_FOREGROUND_COLOR.from_pixel(0xffffffff);
|
||||
const SN_BACKGROUND_COLOR = new Clutter.Color();
|
||||
SN_BACKGROUND_COLOR.from_pixel(0xffff00a0);
|
||||
|
||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
||||
|
||||
// Don't make the mouse hover effect visible to the user for a menu feel.
|
||||
const PANEL_BUTTON_COLOR = new Clutter.Color();
|
||||
PANEL_BUTTON_COLOR.from_pixel(0x00000000);
|
||||
|
||||
// Lighten pressed buttons; darkening has no effect on a black background.
|
||||
const PRESSED_BUTTON_BACKGROUND_COLOR = new Clutter.Color();
|
||||
PRESSED_BUTTON_BACKGROUND_COLOR.from_pixel(0x324c6ffa);
|
||||
|
||||
const DEFAULT_FONT = 'Sans 16px';
|
||||
|
||||
const TRAY_PADDING = 0;
|
||||
// See comments around _recomputeTraySize
|
||||
const TRAY_SPACING = 14;
|
||||
const TRAY_SPACING_MIN = 8;
|
||||
@ -53,13 +31,115 @@ const TRAY_SPACING_MIN = 8;
|
||||
// Used for the tray icon container with gtk pre-2.16, which doesn't
|
||||
// fully support tray icon transparency
|
||||
const TRAY_BACKGROUND_COLOR = new Clutter.Color();
|
||||
TRAY_BACKGROUND_COLOR.from_pixel(0xefefefff);
|
||||
TRAY_BACKGROUND_COLOR.from_pixel(0x0b0b0bff);
|
||||
const TRAY_BORDER_COLOR = new Clutter.Color();
|
||||
TRAY_BORDER_COLOR.from_pixel(0x00000033);
|
||||
const TRAY_CORNER_RADIUS = 5;
|
||||
const TRAY_BORDER_WIDTH = 0;
|
||||
|
||||
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
|
||||
|
||||
const STANDARD_TRAY_ICON_ORDER = ['keyboard', 'volume', 'bluetooth', 'network', 'battery']
|
||||
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||
'bluetooth-applet': 'bluetooth',
|
||||
'gnome-volume-control-applet': 'volume',
|
||||
'nm-applet': 'network',
|
||||
'gnome-power-manager': 'battery'
|
||||
};
|
||||
|
||||
function TextShadower() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
TextShadower.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new Shell.GenericContainer();
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||
|
||||
this._label = new St.Label();
|
||||
this.actor.add_actor(this._label);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let actor = new St.Label({ style_class: 'label-shadow' });
|
||||
this.actor.add_actor(actor);
|
||||
}
|
||||
this._label.raise_top();
|
||||
},
|
||||
|
||||
setText: function(text) {
|
||||
let children = this.actor.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].set_text(text);
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let [minWidth, natWidth] = this._label.get_preferred_width(forHeight);
|
||||
alloc.min_size = minWidth;
|
||||
alloc.natural_size = natWidth;
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let [minHeight, natHeight] = this._label.get_preferred_height(forWidth);
|
||||
alloc.min_size = minHeight;
|
||||
alloc.natural_size = natHeight;
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let children = this.actor.get_children();
|
||||
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
|
||||
let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] =
|
||||
this._label.get_preferred_size();
|
||||
|
||||
let childWidth = Math.min(natChildWidth, availWidth);
|
||||
let childHeight = Math.min(natChildHeight, availHeight);
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let child = children[i];
|
||||
let childBox = new Clutter.ActorBox();
|
||||
// The order of the labels here is arbitrary, except
|
||||
// we know the "real" label is at the end because Clutter.Group
|
||||
// sorts by Z order
|
||||
switch (i) {
|
||||
case 0: // top
|
||||
childBox.x1 = 1;
|
||||
childBox.y1 = 0;
|
||||
break;
|
||||
case 1: // right
|
||||
childBox.x1 = 2;
|
||||
childBox.y1 = 1;
|
||||
break;
|
||||
case 2: // bottom
|
||||
childBox.x1 = 1;
|
||||
childBox.y1 = 2;
|
||||
break;
|
||||
case 3: // left
|
||||
childBox.x1 = 0;
|
||||
childBox.y1 = 1;
|
||||
break;
|
||||
case 4: // center
|
||||
childBox.x1 = 1;
|
||||
childBox.y1 = 1;
|
||||
break;
|
||||
}
|
||||
childBox.x2 = childBox.x1 + childWidth;
|
||||
childBox.y2 = childBox.y1 + childHeight;
|
||||
child.allocate(childBox, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AppPanelMenu:
|
||||
*
|
||||
* This class manages the "application menu" component. It tracks the
|
||||
* currently focused application. However, when an app is launched,
|
||||
* this menu also handles startup notification for it. So when we
|
||||
* have an active startup notification, we switch modes to display that.
|
||||
*/
|
||||
function AppPanelMenu() {
|
||||
this._init();
|
||||
}
|
||||
@ -72,24 +152,15 @@ AppPanelMenu.prototype = {
|
||||
this._activeSequence = null;
|
||||
this._startupSequences = {};
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_PADDING,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._iconBox = new Big.Box({ width: PANEL_ICON_SIZE, height: PANEL_ICON_SIZE,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.append(this._iconBox, Big.BoxPackFlags.NONE);
|
||||
let labelBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._label = new Clutter.Text({ font_name: DEFAULT_FONT,
|
||||
color: PANEL_FOREGROUND_COLOR,
|
||||
text: "" });
|
||||
labelBox.append(this._label, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.append(labelBox, Big.BoxPackFlags.NONE);
|
||||
this.actor = new St.BoxLayout({ name: 'appMenu' });
|
||||
this._iconBox = new Shell.Slicer({ name: 'appMenuIcon' });
|
||||
this.actor.add(this._iconBox);
|
||||
this._label = new TextShadower();
|
||||
this.actor.add(this._label.actor, { expand: true, y_fill: true });
|
||||
this.actor.connect('notify::allocation', Lang.bind(this, this._repositionLabel));
|
||||
|
||||
this._startupBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.append(this._startupBox, Big.BoxPackFlags.NONE);
|
||||
this._startupBox = new St.BoxLayout();
|
||||
this.actor.add(this._startupBox);
|
||||
|
||||
Main.overview.connect('hiding', Lang.bind(this, function () {
|
||||
this.actor.opacity = 255;
|
||||
@ -98,34 +169,36 @@ AppPanelMenu.prototype = {
|
||||
this.actor.opacity = 192;
|
||||
}));
|
||||
|
||||
this._metaDisplay.connect('notify::focus-window', Lang.bind(this, this._sync));
|
||||
|
||||
let appMonitor = Shell.AppMonitor.get_default();
|
||||
appMonitor.connect('startup-sequence-changed', Lang.bind(this, this._sync));
|
||||
// For now just resync on application add/remove; this is mainly to handle
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
tracker.connect('notify::focus-app', Lang.bind(this, this._sync));
|
||||
tracker.connect('startup-sequence-changed', Lang.bind(this, this._sync));
|
||||
// For now just resync on all running state changes; this is mainly to handle
|
||||
// cases where the focused window's application changes without the focus
|
||||
// changing. An example case is how we map Firefox based on the window
|
||||
// title which is a dynamic property.
|
||||
appMonitor.connect('app-added', Lang.bind(this, this._sync));
|
||||
appMonitor.connect('app-removed', Lang.bind(this, this._sync));
|
||||
tracker.connect('app-running-changed', Lang.bind(this, this._sync));
|
||||
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
let appMonitor = Shell.AppMonitor.get_default();
|
||||
_repositionLabel: function() {
|
||||
this._label.actor.x = Math.floor(AppDisplay.APPICON_SIZE / 2);
|
||||
let actorAlloc = this.actor.allocation;
|
||||
let actorHeight = actorAlloc.y2 - actorAlloc.y1;
|
||||
let labelAlloc = this._label.actor.allocation;
|
||||
let labelHeight = labelAlloc.y2 - labelAlloc.y1;
|
||||
this._label.actor.y = Math.floor((actorHeight - labelHeight) / 2);
|
||||
this._label.actor.fixed_position_set = true;
|
||||
},
|
||||
|
||||
let focusWindow = this._metaDisplay.get_focus_window();
|
||||
let focusedApp;
|
||||
if (focusWindow == null) {
|
||||
focusedApp = null;
|
||||
} else {
|
||||
focusedApp = appMonitor.get_window_app(focusWindow);
|
||||
}
|
||||
_sync: function() {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
|
||||
let focusedApp = tracker.focus_app;
|
||||
|
||||
let lastSequence = null;
|
||||
if (focusedApp == null) {
|
||||
let sequences = appMonitor.get_startup_sequences();
|
||||
let sequences = tracker.get_startup_sequences();
|
||||
if (sequences.length > 0)
|
||||
lastSequence = sequences[sequences.length - 1];
|
||||
}
|
||||
@ -141,20 +214,27 @@ AppPanelMenu.prototype = {
|
||||
this._focusedApp = focusedApp;
|
||||
this._activeSequence = lastSequence;
|
||||
|
||||
this._iconBox.remove_all();
|
||||
if (this._iconBox.child != null)
|
||||
this._iconBox.child.destroy();
|
||||
this._iconBox.hide();
|
||||
this._label.text = '';
|
||||
this._label.setText('');
|
||||
let icon;
|
||||
if (this._focusedApp != null) {
|
||||
let icon = focusedApp.create_icon_texture(PANEL_ICON_SIZE);
|
||||
this._iconBox.append(icon, Big.BoxPackFlags.NONE);
|
||||
this._iconBox.show();
|
||||
this._label.text = focusedApp.get_name();
|
||||
icon = this._focusedApp.create_icon_texture(AppDisplay.APPICON_SIZE);
|
||||
this._label.setText(this._focusedApp.get_name());
|
||||
} else if (this._activeSequence != null) {
|
||||
let icon = this._activeSequence.create_icon(PANEL_ICON_SIZE);
|
||||
this._iconBox.append(icon, Big.BoxPackFlags.NONE);
|
||||
this._iconBox.show();
|
||||
this._label.text = this._activeSequence.get_name();
|
||||
icon = this._activeSequence.create_icon(AppDisplay.APPICON_SIZE);
|
||||
this._label.setText(this._activeSequence.get_name());
|
||||
} else {
|
||||
icon = null;
|
||||
}
|
||||
|
||||
if (icon != null) {
|
||||
let faded = Shell.fade_app_icon(icon); /* TODO consider caching */
|
||||
this._iconBox.set_child(faded);
|
||||
this._iconBox.show();
|
||||
}
|
||||
this._repositionLabel();
|
||||
|
||||
this.emit('changed');
|
||||
}
|
||||
@ -169,30 +249,17 @@ function Panel() {
|
||||
Panel.prototype = {
|
||||
_init : function() {
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL
|
||||
});
|
||||
let backgroundGradient = Shell.create_vertical_gradient(BACKGROUND_TOP,
|
||||
BACKGROUND_BOTTOM);
|
||||
this.actor.connect('notify::allocation', Lang.bind(this, function () {
|
||||
let [width, height] = this.actor.get_size();
|
||||
backgroundGradient.set_size(width, height);
|
||||
}));
|
||||
this.actor.add_actor(backgroundGradient);
|
||||
this.actor = new St.BoxLayout({ name: 'panel' });
|
||||
this.actor._delegate = this;
|
||||
|
||||
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
spacing: DEFAULT_PADDING,
|
||||
padding_right: DEFAULT_PADDING });
|
||||
this._centerBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
padding_left: DEFAULT_PADDING });
|
||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||
this._centerBox = new St.BoxLayout({ name: 'panelCenter' });
|
||||
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
|
||||
|
||||
/* This box container ensures that the centerBox is positioned in the *absolute*
|
||||
* center, but can be pushed aside if necessary. */
|
||||
this._boxContainer = new Shell.GenericContainer();
|
||||
this.actor.append(this._boxContainer, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.add(this._boxContainer, { expand: true });
|
||||
this._boxContainer.add_actor(this._leftBox);
|
||||
this._boxContainer.add_actor(this._centerBox);
|
||||
this._boxContainer.add_actor(this._rightBox);
|
||||
@ -264,13 +331,16 @@ Panel.prototype = {
|
||||
this._rightBox.allocate(childBox, flags);
|
||||
}));
|
||||
|
||||
/* left side */
|
||||
/* Button on the left side of the panel. */
|
||||
/* Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". */
|
||||
let label = new St.Label({ text: _("Activities") });
|
||||
this.button = new St.Clickable({ name: 'panelActivities',
|
||||
style_class: 'panel-button',
|
||||
reactive: true });
|
||||
this.button.set_child(label);
|
||||
this.button.height = PANEL_HEIGHT;
|
||||
|
||||
this.button = new Button.Button(_("Activities"), PANEL_BUTTON_COLOR, PRESSED_BUTTON_BACKGROUND_COLOR,
|
||||
PANEL_FOREGROUND_COLOR, DEFAULT_FONT);
|
||||
this.button.actor.height = PANEL_HEIGHT;
|
||||
|
||||
this._leftBox.append(this.button.actor, Big.BoxPackFlags.NONE);
|
||||
this._leftBox.add(this.button);
|
||||
|
||||
// We use this flag to mark the case where the user has entered the
|
||||
// hot corner and has not left both the hot corner and a surrounding
|
||||
@ -278,16 +348,22 @@ Panel.prototype = {
|
||||
// multiple times due to an accidental jitter.
|
||||
this._hotCornerEntered = false;
|
||||
|
||||
this._hotCornerEnvirons = new Clutter.Rectangle({ width: 3,
|
||||
this._hotCornerEnvirons = new Clutter.Rectangle({ x: 0,
|
||||
y: 0,
|
||||
width: 3,
|
||||
height: 3,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
|
||||
this._hotCorner = new Clutter.Rectangle({ width: 1,
|
||||
this._hotCorner = new Clutter.Rectangle({ x: 0,
|
||||
y: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
|
||||
this._hotCornerActivationTime = 0;
|
||||
|
||||
this._hotCornerEnvirons.connect('leave-event',
|
||||
Lang.bind(this, this._onHotCornerEnvironsLeft));
|
||||
// Clicking on the hot corner environs should result in the same bahavior
|
||||
@ -305,29 +381,36 @@ Panel.prototype = {
|
||||
this._hotCorner.connect('leave-event',
|
||||
Lang.bind(this, this._onHotCornerLeft));
|
||||
|
||||
this._leftBox.append(this._hotCornerEnvirons, Big.BoxPackFlags.FIXED);
|
||||
this._leftBox.append(this._hotCorner, Big.BoxPackFlags.FIXED);
|
||||
this._leftBox.add(this._hotCornerEnvirons);
|
||||
this._leftBox.add(this._hotCorner);
|
||||
|
||||
let appMenu = new AppPanelMenu();
|
||||
this._leftBox.append(appMenu.actor, Big.BoxPackFlags.NONE);
|
||||
this._leftBox.add(appMenu.actor);
|
||||
|
||||
/* center */
|
||||
|
||||
this._clock = new Clutter.Text({ font_name: DEFAULT_FONT,
|
||||
color: PANEL_FOREGROUND_COLOR,
|
||||
text: "" });
|
||||
this._centerBox.append(this._clock, Big.BoxPackFlags.NONE);
|
||||
let clockButton = new St.Button({ style_class: "panel-button",
|
||||
toggle_mode: true,
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
this._centerBox.add(clockButton, { y_fill: false });
|
||||
clockButton.connect('clicked', Lang.bind(this, this._toggleCalendar));
|
||||
|
||||
this._clock = new St.Label();
|
||||
clockButton.set_child(this._clock);
|
||||
this._clockButton = clockButton;
|
||||
|
||||
this._calendarPopup = null;
|
||||
|
||||
/* right */
|
||||
|
||||
// The tray icons live in trayBox within trayContainer.
|
||||
// The trayBox is hidden when there are no tray icons.
|
||||
let trayContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
y_align: Big.BoxAlignment.START });
|
||||
this._rightBox.append(trayContainer, Big.BoxPackFlags.NONE);
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._rightBox.add(trayContainer);
|
||||
let trayBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
height: TRAY_HEIGHT,
|
||||
padding: TRAY_PADDING,
|
||||
height: PANEL_ICON_SIZE,
|
||||
spacing: TRAY_SPACING });
|
||||
this._trayBox = trayBox;
|
||||
|
||||
@ -345,14 +428,7 @@ Panel.prototype = {
|
||||
trayContainer.append(trayBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._traymanager = new Shell.TrayManager({ bg_color: TRAY_BACKGROUND_COLOR });
|
||||
this._traymanager.connect('tray-icon-added',
|
||||
Lang.bind(this, function(o, icon) {
|
||||
trayBox.append(icon, Big.BoxPackFlags.NONE);
|
||||
|
||||
// Make sure the trayBox is shown.
|
||||
trayBox.show();
|
||||
this._recomputeTraySize();
|
||||
}));
|
||||
this._traymanager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||
this._traymanager.connect('tray-icon-removed',
|
||||
Lang.bind(this, function(o, icon) {
|
||||
trayBox.remove_actor(icon);
|
||||
@ -363,63 +439,60 @@ Panel.prototype = {
|
||||
}));
|
||||
this._traymanager.manage_stage(global.stage);
|
||||
|
||||
let statusbox = new Big.Box();
|
||||
let statusmenu = this._statusmenu = new Shell.StatusMenu();
|
||||
statusmenu.get_icon().hide();
|
||||
statusmenu.get_name().fontName = DEFAULT_FONT;
|
||||
statusmenu.get_name().color = PANEL_FOREGROUND_COLOR;
|
||||
statusbox.append(this._statusmenu, Big.BoxPackFlags.NONE);
|
||||
let statusbutton = new Button.Button(statusbox,
|
||||
PANEL_BUTTON_COLOR,
|
||||
PRESSED_BUTTON_BACKGROUND_COLOR,
|
||||
PANEL_FOREGROUND_COLOR);
|
||||
statusbutton.actor.height = PANEL_HEIGHT;
|
||||
statusbutton.actor.connect('button-press-event', function (b, e) {
|
||||
if (e.get_button() == 1 && e.get_click_count() == 1) {
|
||||
statusmenu.toggle(e);
|
||||
// The statusmenu might not pop up if it couldn't get a pointer grab
|
||||
if (statusmenu.is_active())
|
||||
statusbutton.actor.active = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
let statusmenu = this._statusmenu = new StatusMenu.StatusMenu();
|
||||
let statusbutton = new St.Clickable({ name: 'panelStatus',
|
||||
style_class: 'panel-button',
|
||||
reactive: true });
|
||||
statusbutton.set_child(statusmenu.actor);
|
||||
statusbutton.height = PANEL_HEIGHT;
|
||||
statusbutton.connect('clicked', function (b, event) {
|
||||
statusmenu.toggle(event);
|
||||
// The statusmenu might not pop up if it couldn't get a pointer grab
|
||||
if (statusmenu.isActive())
|
||||
statusbutton.active = true;
|
||||
return true;
|
||||
});
|
||||
this._rightBox.append(statusbutton.actor, Big.BoxPackFlags.NONE);
|
||||
this._rightBox.add(statusbutton);
|
||||
// We get a deactivated event when the popup disappears
|
||||
this._statusmenu.connect('deactivated', function (sm) {
|
||||
statusbutton.actor.active = false;
|
||||
statusbutton.active = false;
|
||||
});
|
||||
|
||||
// TODO: decide what to do with the rest of the panel in the Overview mode (make it fade-out, become non-reactive, etc.)
|
||||
// We get into the Overview mode on button-press-event as opposed to button-release-event because eventually we'll probably
|
||||
// have the Overview act like a menu that allows the user to release the mouse on the activity the user wants
|
||||
// to switch to.
|
||||
this.button.actor.connect('button-press-event', function(b, e) {
|
||||
if (e.get_button() == 1 && e.get_click_count() == 1) {
|
||||
Main.overview.toggle();
|
||||
this.button.connect('clicked', Lang.bind(this, function(b, event) {
|
||||
if (!Main.overview.animationInProgress) {
|
||||
this._maybeToggleOverviewOnClick();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}));
|
||||
// In addition to pressing the button, the Overview can be entered and exited by other means, such as
|
||||
// pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the Overview is entered
|
||||
// and to be released when it is exited regardless of how it was triggered.
|
||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||
this.button.actor.active = true;
|
||||
this.button.active = true;
|
||||
}));
|
||||
Main.overview.connect('hiding', Lang.bind(this, function() {
|
||||
this.button.actor.active = false;
|
||||
this.button.active = false;
|
||||
}));
|
||||
|
||||
Main.chrome.addActor(this.actor);
|
||||
Main.chrome.setVisibleInOverview(this.actor, true);
|
||||
Main.chrome.addActor(this.actor, { visibleInOverview: true });
|
||||
|
||||
// Start the clock
|
||||
this._updateClock();
|
||||
},
|
||||
|
||||
hideCalendar: function() {
|
||||
if (this._calendarPopup != null) {
|
||||
this._clockButton.checked = false;
|
||||
this._calendarPopup.actor.hide();
|
||||
}
|
||||
},
|
||||
|
||||
startupAnimation: function() {
|
||||
this.actor.y = -this.actor.height;
|
||||
Tweener.addTween(this.actor,
|
||||
@ -429,6 +502,38 @@ Panel.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
_onTrayIconAdded: function(o, icon, wmClass) {
|
||||
let role = STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass];
|
||||
if (!role) {
|
||||
// Unknown icons go first in undefined order
|
||||
this._trayBox.prepend(icon, Big.BoxPackFlags.NONE);
|
||||
} else {
|
||||
icon._role = role;
|
||||
// Figure out the index in our well-known order for this icon
|
||||
let position = STANDARD_TRAY_ICON_ORDER.indexOf(role);
|
||||
icon._rolePosition = position;
|
||||
let children = this._trayBox.get_children();
|
||||
let i;
|
||||
// Walk children backwards, until we find one that isn't
|
||||
// well-known, or one where we should follow
|
||||
for (i = children.length - 1; i >= 0; i--) {
|
||||
let rolePosition = children[i]._rolePosition;
|
||||
if (!rolePosition || position > rolePosition) {
|
||||
this._trayBox.insert_after(icon, children[i], Big.BoxPackFlags.NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == -1) {
|
||||
// If we didn't find a position, we must be first
|
||||
this._trayBox.prepend(icon, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the trayBox is shown.
|
||||
this._trayBox.show();
|
||||
this._recomputeTraySize();
|
||||
},
|
||||
|
||||
// By default, tray icons have a spacing of TRAY_SPACING. However this
|
||||
// starts to fail if we have too many as can sadly happen; just jump down
|
||||
// to a spacing of 8 if we're over 6.
|
||||
@ -448,16 +553,70 @@ Panel.prototype = {
|
||||
displayDate.setMinutes(displayDate.getMinutes() + 1);
|
||||
msecRemaining += 60000;
|
||||
}
|
||||
/* Translators: This is a time format. */
|
||||
this._clock.set_text(displayDate.toLocaleFormat(_("%a %l:%M %p")));
|
||||
/* If there is no am or pm, time format is 24h */
|
||||
let isTime24h = displayDate.toLocaleFormat("x%p") == "x";
|
||||
if (isTime24h) {
|
||||
/* Translators: This is the time format used in 24-hour mode. */
|
||||
this._clock.set_text(displayDate.toLocaleFormat(_("%a %R")));
|
||||
} else {
|
||||
/* Translators: This is a time format used for AM/PM. */
|
||||
this._clock.set_text(displayDate.toLocaleFormat(_("%a %l:%M %p")));
|
||||
}
|
||||
Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClock));
|
||||
return false;
|
||||
},
|
||||
|
||||
_toggleCalendar: function(clockButton) {
|
||||
if (clockButton.checked) {
|
||||
if (this._calendarPopup == null)
|
||||
this._calendarPopup = new CalendarPopup();
|
||||
this._calendarPopup.show();
|
||||
} else {
|
||||
this._calendarPopup.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_addRipple : function(delay, time, startScale, startOpacity, finalScale, finalOpacity) {
|
||||
// We draw a ripple by using a source image and animating it scaling
|
||||
// outwards and fading away. We want the ripples to move linearly
|
||||
// or it looks unrealistic, but if the opacity of the ripple goes
|
||||
// linearly to zero it fades away too quickly, so we use Tweener's
|
||||
// 'onUpdate' to give a non-linear curve to the fade-away and make
|
||||
// it more visible in the middle section.
|
||||
|
||||
let [x, y] = this._hotCorner.get_transformed_position();
|
||||
let ripple = new St.BoxLayout({ style_class: 'ripple-box',
|
||||
opacity: 255 * Math.sqrt(startOpacity),
|
||||
scale_x: startScale,
|
||||
scale_y: startScale,
|
||||
x: x,
|
||||
y: y });
|
||||
ripple._opacity = startOpacity;
|
||||
Tweener.addTween(ripple, { _opacity: finalOpacity,
|
||||
scale_x: finalScale,
|
||||
scale_y: finalScale,
|
||||
delay: delay,
|
||||
time: time,
|
||||
transition: 'linear',
|
||||
onUpdate: function() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); },
|
||||
onComplete: function() { ripple.destroy(); } });
|
||||
global.stage.add_actor(ripple);
|
||||
},
|
||||
|
||||
_onHotCornerEntered : function() {
|
||||
if (!this._hotCornerEntered) {
|
||||
this._hotCornerEntered = true;
|
||||
if (!Main.overview.animationInProgress) {
|
||||
this._hotCornerActivationTime = Date.now() / 1000;
|
||||
|
||||
// Show three concentric ripples expanding outwards; the exact
|
||||
// parameters were found by trial and error, so don't look
|
||||
// for them to make perfect sense mathematically
|
||||
|
||||
// delay time scale opacity => scale opacity
|
||||
this._addRipple(0.0, 0.83, 0.25, 1.0, 1.5, 0.0);
|
||||
this._addRipple(0.05, 1.0, 0.0, 0.7, 1.25, 0.0);
|
||||
this._addRipple(0.35, 1.0, 0.0, 0.3, 1, 0.0);
|
||||
Main.overview.toggle();
|
||||
}
|
||||
}
|
||||
@ -466,7 +625,7 @@ Panel.prototype = {
|
||||
|
||||
_onHotCornerClicked : function() {
|
||||
if (!Main.overview.animationInProgress) {
|
||||
Main.overview.toggle();
|
||||
this._maybeToggleOverviewOnClick();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -483,5 +642,61 @@ Panel.prototype = {
|
||||
this._hotCornerEntered = false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Toggles the overview unless this is the first click on the Activities button within the HOT_CORNER_ACTIVATION_TIMEOUT time
|
||||
// of the hot corner being triggered. This check avoids opening and closing the overview if the user both triggered the hot corner
|
||||
// and clicked the Activities button.
|
||||
_maybeToggleOverviewOnClick: function() {
|
||||
if (this._hotCornerActivationTime == 0 || Date.now() / 1000 - this._hotCornerActivationTime > HOT_CORNER_ACTIVATION_TIMEOUT)
|
||||
Main.overview.toggle();
|
||||
this._hotCornerActivationTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
function CalendarPopup() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
CalendarPopup.prototype = {
|
||||
_init: function() {
|
||||
let panelActor = Main.panel.actor;
|
||||
|
||||
this.actor = new St.BoxLayout({ name: 'calendarPopup' });
|
||||
|
||||
this.calendar = new Calendar.Calendar();
|
||||
this.actor.add(this.calendar.actor);
|
||||
|
||||
Main.chrome.addActor(this.actor, { visibleInOverview: true,
|
||||
affectsStruts: false });
|
||||
this.actor.y = (panelActor.y + panelActor.height - this.actor.height);
|
||||
},
|
||||
|
||||
show: function() {
|
||||
let panelActor = Main.panel.actor;
|
||||
|
||||
// Reset the calendar to today's date
|
||||
this.calendar.setDate(new Date());
|
||||
|
||||
this.actor.x = Math.round(panelActor.x + (panelActor.width - this.actor.width) / 2);
|
||||
this.actor.lower(panelActor);
|
||||
this.actor.show();
|
||||
Tweener.addTween(this.actor,
|
||||
{ y: panelActor.y + panelActor.height,
|
||||
time: 0.2,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
let panelActor = Main.panel.actor;
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
{ y: panelActor.y + panelActor.height - this.actor.height,
|
||||
time: 0.2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: function() { this.actor.hide(); },
|
||||
onCompleteScope: this
|
||||
});
|
||||
}
|
||||
};
|
||||
|
584
js/ui/placeDisplay.js
Normal file
@ -0,0 +1,584 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Pango = imports.gi.Pango;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
const Search = imports.ui.search;
|
||||
|
||||
const NAUTILUS_PREFS_DIR = '/apps/nautilus/preferences';
|
||||
const DESKTOP_IS_HOME_KEY = NAUTILUS_PREFS_DIR + '/desktop_is_home_dir';
|
||||
|
||||
const PLACES_ICON_SIZE = 16;
|
||||
|
||||
/**
|
||||
* Represents a place object, which is most normally a bookmark entry,
|
||||
* a mount/volume, or a special place like the Home Folder, Computer, and Network.
|
||||
*
|
||||
* @name: String title
|
||||
* @iconFactory: A JavaScript callback which will create an icon texture given a size parameter
|
||||
* @launch: A JavaScript callback to launch the entry
|
||||
*/
|
||||
function PlaceInfo(id, name, iconFactory, launch) {
|
||||
this._init(id, name, iconFactory, launch);
|
||||
}
|
||||
|
||||
PlaceInfo.prototype = {
|
||||
_init: function(id, name, iconFactory, launch) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this._lowerName = name.toLowerCase();
|
||||
this.iconFactory = iconFactory;
|
||||
this.launch = launch;
|
||||
},
|
||||
|
||||
matchTerms: function(terms) {
|
||||
let mtype = Search.MatchType.NONE;
|
||||
for (let i = 0; i < terms.length; i++) {
|
||||
let term = terms[i];
|
||||
let idx = this._lowerName.indexOf(term);
|
||||
if (idx == 0)
|
||||
return Search.MatchType.PREFIX;
|
||||
else if (idx > 0)
|
||||
mtype = Search.MatchType.SUBSTRING;
|
||||
}
|
||||
return mtype;
|
||||
},
|
||||
|
||||
isRemovable: function() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function PlaceDeviceInfo(mount) {
|
||||
this._init(mount);
|
||||
}
|
||||
|
||||
PlaceDeviceInfo.prototype = {
|
||||
__proto__: PlaceInfo.prototype,
|
||||
|
||||
_init: function(mount) {
|
||||
this._mount = mount;
|
||||
this.name = mount.get_name();
|
||||
this._lowerName = this.name.toLowerCase();
|
||||
this.id = "mount:" + mount.get_root().get_uri();
|
||||
},
|
||||
|
||||
iconFactory: function(size) {
|
||||
let icon = this._mount.get_icon();
|
||||
return Shell.TextureCache.get_default().load_gicon(icon, size);
|
||||
},
|
||||
|
||||
launch: function() {
|
||||
Gio.app_info_launch_default_for_uri(this._mount.get_root().get_uri(),
|
||||
global.create_app_launch_context());
|
||||
},
|
||||
|
||||
isRemovable: function() {
|
||||
return this._mount.can_unmount();
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
if (!this.isRemovable())
|
||||
return;
|
||||
|
||||
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish), null);
|
||||
},
|
||||
|
||||
_removeFinish: function(o, res, data) {
|
||||
this._mount.unmount_finish(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function PlacesManager() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
PlacesManager.prototype = {
|
||||
_init: function() {
|
||||
let gconf = Shell.GConf.get_default();
|
||||
gconf.watch_directory(NAUTILUS_PREFS_DIR);
|
||||
|
||||
this._defaultPlaces = [];
|
||||
this._mounts = [];
|
||||
this._bookmarks = [];
|
||||
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
|
||||
|
||||
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
|
||||
let homeUri = homeFile.get_uri();
|
||||
let homeLabel = Shell.util_get_label_for_uri (homeUri);
|
||||
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
|
||||
this._home = new PlaceInfo('special:home', homeLabel,
|
||||
function(size) {
|
||||
return Shell.TextureCache.get_default().load_gicon(homeIcon, size);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
|
||||
});
|
||||
|
||||
let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
|
||||
let desktopFile = Gio.file_new_for_path (desktopPath);
|
||||
let desktopUri = desktopFile.get_uri();
|
||||
let desktopLabel = Shell.util_get_label_for_uri (desktopUri);
|
||||
let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
|
||||
this._desktopMenu = new PlaceInfo('special:desktop', desktopLabel,
|
||||
function(size) {
|
||||
return Shell.TextureCache.get_default().load_gicon(desktopIcon, size);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
|
||||
});
|
||||
|
||||
this._connect = new PlaceInfo('special:connect', _("Connect to..."),
|
||||
function (size) {
|
||||
return Shell.TextureCache.get_default().load_icon_name("applications-internet", size);
|
||||
},
|
||||
function () {
|
||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||
});
|
||||
|
||||
let networkApp = null;
|
||||
try {
|
||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
|
||||
} catch(e) {
|
||||
try {
|
||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
|
||||
} catch(e) {
|
||||
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
|
||||
}
|
||||
}
|
||||
|
||||
if (networkApp != null) {
|
||||
this._network = new PlaceInfo('special:network', networkApp.get_name(),
|
||||
function(size) {
|
||||
return networkApp.create_icon_texture(size);
|
||||
},
|
||||
function () {
|
||||
networkApp.launch();
|
||||
});
|
||||
}
|
||||
|
||||
this._defaultPlaces.push(this._home);
|
||||
|
||||
this._desktopMenuIndex = this._defaultPlaces.length;
|
||||
if (!this._isDesktopHome)
|
||||
this._defaultPlaces.push(this._desktopMenu);
|
||||
|
||||
if (this._network)
|
||||
this._defaultPlaces.push(this._network);
|
||||
|
||||
this._defaultPlaces.push(this._connect);
|
||||
|
||||
/*
|
||||
* Show devices, code more or less ported from nautilus-places-sidebar.c
|
||||
*/
|
||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||
this._volumeMonitor.connect('volume-added', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('volume-removed',Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('volume-changed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-added', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-changed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||
this._updateDevices();
|
||||
|
||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]);
|
||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||
this._bookmarkTimeoutId = 0;
|
||||
monitor.connect('changed', Lang.bind(this, function () {
|
||||
if (this._bookmarkTimeoutId > 0)
|
||||
return;
|
||||
/* Defensive event compression */
|
||||
this._bookmarkTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () {
|
||||
this._bookmarkTimeoutId = 0;
|
||||
this._reloadBookmarks();
|
||||
return false;
|
||||
}));
|
||||
}));
|
||||
|
||||
this._reloadBookmarks();
|
||||
|
||||
gconf.connect('changed::' + DESKTOP_IS_HOME_KEY, Lang.bind(this, this._updateDesktopMenuVisibility));
|
||||
|
||||
},
|
||||
|
||||
_updateDevices: function() {
|
||||
this._mounts = [];
|
||||
|
||||
/* first go through all connected drives */
|
||||
let drives = this._volumeMonitor.get_connected_drives();
|
||||
for (let i = 0; i < drives.length; i++) {
|
||||
let volumes = drives[i].get_volumes();
|
||||
for(let j = 0; j < volumes.length; j++) {
|
||||
let mount = volumes[j].get_mount();
|
||||
if(mount != null) {
|
||||
this._addMount(mount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add all volumes that is not associated with a drive */
|
||||
let volumes = this._volumeMonitor.get_volumes();
|
||||
for(let i = 0; i < volumes.length; i++) {
|
||||
if(volumes[i].get_drive() != null)
|
||||
continue;
|
||||
|
||||
let mount = volumes[i].get_mount();
|
||||
if(mount != null) {
|
||||
this._addMount(mount);
|
||||
}
|
||||
}
|
||||
|
||||
/* add mounts that have no volume (/etc/mtab mounts, ftp, sftp,...) */
|
||||
let mounts = this._volumeMonitor.get_mounts();
|
||||
for(let i = 0; i < mounts.length; i++) {
|
||||
if(mounts[i].is_shadowed())
|
||||
continue;
|
||||
|
||||
if(mounts[i].get_volume())
|
||||
continue;
|
||||
|
||||
this._addMount(mounts[i]);
|
||||
}
|
||||
|
||||
/* We emit two signals, one for a generic 'all places' update
|
||||
* and the other for one specific to mounts. We do this because
|
||||
* clients like PlaceDisplay may only care about places in general
|
||||
* being updated while clients like DashPlaceDisplay care which
|
||||
* specific type of place got updated.
|
||||
*/
|
||||
this.emit('mounts-updated');
|
||||
this.emit('places-updated');
|
||||
|
||||
},
|
||||
|
||||
_reloadBookmarks: function() {
|
||||
|
||||
this._bookmarks = [];
|
||||
|
||||
if (!GLib.file_test(this._bookmarksPath, GLib.FileTest.EXISTS))
|
||||
return;
|
||||
|
||||
let [success, bookmarksContent, len] = GLib.file_get_contents(this._bookmarksPath);
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
let bookmarks = bookmarksContent.split('\n');
|
||||
|
||||
let bookmarksToLabel = {};
|
||||
let bookmarksOrder = [];
|
||||
for (let i = 0; i < bookmarks.length; i++) {
|
||||
let bookmarkLine = bookmarks[i];
|
||||
let components = bookmarkLine.split(' ');
|
||||
let bookmark = components[0];
|
||||
if (bookmark in bookmarksToLabel)
|
||||
continue;
|
||||
let label = null;
|
||||
if (components.length > 1)
|
||||
label = components.slice(1).join(' ');
|
||||
bookmarksToLabel[bookmark] = label;
|
||||
bookmarksOrder.push(bookmark);
|
||||
}
|
||||
|
||||
for (let i = 0; i < bookmarksOrder.length; i++) {
|
||||
let bookmark = bookmarksOrder[i];
|
||||
let label = bookmarksToLabel[bookmark];
|
||||
let file = Gio.file_new_for_uri(bookmark);
|
||||
if (!file.query_exists(null))
|
||||
continue;
|
||||
if (label == null)
|
||||
label = Shell.util_get_label_for_uri(bookmark);
|
||||
if (label == null)
|
||||
continue;
|
||||
let icon = Shell.util_get_icon_for_uri(bookmark);
|
||||
|
||||
let item = new PlaceInfo('bookmark:' + bookmark, label,
|
||||
function(size) {
|
||||
return Shell.TextureCache.get_default().load_gicon(icon, size);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
|
||||
});
|
||||
this._bookmarks.push(item);
|
||||
}
|
||||
|
||||
/* See comment in _updateDevices for explanation why there are two signals. */
|
||||
this.emit('bookmarks-updated');
|
||||
this.emit('places-updated');
|
||||
},
|
||||
|
||||
_updateDesktopMenuVisibility: function() {
|
||||
let gconf = Shell.GConf.get_default();
|
||||
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
|
||||
|
||||
if (this._isDesktopHome)
|
||||
this._removeById(this._defaultPlaces, "special:desktop");
|
||||
else
|
||||
this._defaultPlaces.splice(this._desktopMenuIndex, 0,
|
||||
this._desktopMenu);
|
||||
|
||||
/* See comment in _updateDevices for explanation why there are two signals. */
|
||||
this.emit('defaults-updated');
|
||||
this.emit('places-updated');
|
||||
},
|
||||
|
||||
_addMount: function(mount) {
|
||||
let devItem = new PlaceDeviceInfo(mount);
|
||||
this._mounts.push(devItem);
|
||||
},
|
||||
|
||||
getAllPlaces: function () {
|
||||
return this.getDefaultPlaces().concat(this.getBookmarks(), this.getMounts());
|
||||
},
|
||||
|
||||
getDefaultPlaces: function () {
|
||||
return this._defaultPlaces;
|
||||
},
|
||||
|
||||
getBookmarks: function () {
|
||||
return this._bookmarks;
|
||||
},
|
||||
|
||||
getMounts: function () {
|
||||
return this._mounts;
|
||||
},
|
||||
|
||||
_lookupIndexById: function(sourceArray, id) {
|
||||
for (let i = 0; i < sourceArray.length; i++) {
|
||||
let place = sourceArray[i];
|
||||
if (place.id == id)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
lookupPlaceById: function(id) {
|
||||
let colonIdx = id.indexOf(':');
|
||||
let type = id.substring(0, colonIdx);
|
||||
let sourceArray = null;
|
||||
if (type == 'special')
|
||||
sourceArray = this._defaultPlaces;
|
||||
else if (type == 'mount')
|
||||
sourceArray = this._mounts;
|
||||
else if (type == 'bookmark')
|
||||
sourceArray = this._bookmarks;
|
||||
return sourceArray[this._lookupIndexById(sourceArray, id)];
|
||||
},
|
||||
|
||||
_removeById: function(sourceArray, id) {
|
||||
sourceArray.splice(this._lookupIndexById(sourceArray, id), 1);
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(PlacesManager.prototype);
|
||||
|
||||
/**
|
||||
* An entry in the places menu.
|
||||
* @info The corresponding PlaceInfo to populate this entry.
|
||||
*/
|
||||
function DashPlaceDisplayItem(info) {
|
||||
this._init(info);
|
||||
}
|
||||
|
||||
DashPlaceDisplayItem.prototype = {
|
||||
_init: function(info) {
|
||||
this.name = info.name;
|
||||
this._info = info;
|
||||
this._icon = info.iconFactory(PLACES_ICON_SIZE);
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4 });
|
||||
let text = new St.Button({ style_class: 'places-item',
|
||||
label: info.name,
|
||||
x_align: St.Align.START });
|
||||
text.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
let iconBox = new St.Bin({ child: this._icon, reactive: true });
|
||||
iconBox.connect('button-release-event',
|
||||
Lang.bind(this, this._onClicked));
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(text, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
if (info.isRemovable()) {
|
||||
let removeIcon = Shell.TextureCache.get_default().load_icon_name ('media-eject', PLACES_ICON_SIZE);
|
||||
let removeIconBox = new St.Button({ child: removeIcon,
|
||||
reactive: true });
|
||||
this.actor.append(removeIconBox, Big.BoxPackFlags.NONE);
|
||||
removeIconBox.connect('clicked',
|
||||
Lang.bind(this, function() {
|
||||
this._info.remove();
|
||||
}));
|
||||
}
|
||||
|
||||
this.actor._delegate = this;
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
},
|
||||
|
||||
_onClicked: function(b) {
|
||||
this._info.launch();
|
||||
Main.overview.hide();
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._icon;
|
||||
},
|
||||
|
||||
getDragActor: function(stageX, stageY) {
|
||||
return this._info.iconFactory(PLACES_ICON_SIZE);
|
||||
},
|
||||
|
||||
//// Drag and drop methods ////
|
||||
|
||||
shellWorkspaceLaunch: function() {
|
||||
this._info.launch();
|
||||
}
|
||||
};
|
||||
|
||||
function DashPlaceDisplay() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DashPlaceDisplay.prototype = {
|
||||
_init: function() {
|
||||
|
||||
// Places is divided semi-arbitrarily into left and right; a grid would
|
||||
// look better in that there would be an even number of items left+right,
|
||||
// but it seems like we want some sort of differentiation between actions
|
||||
// like "Connect to server..." and regular folders
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4 });
|
||||
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.actor.append(this._leftBox, Big.BoxPackFlags.EXPAND);
|
||||
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.actor.append(this._rightBox, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
// Subdivide left into actions and devices
|
||||
this._actionsBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
vertical: true });
|
||||
|
||||
this._devBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
name: 'placesDevices',
|
||||
vertical: true });
|
||||
|
||||
this._dirsBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
vertical: true });
|
||||
|
||||
this._leftBox.append(this._actionsBox, Big.BoxPackFlags.NONE);
|
||||
this._leftBox.append(this._devBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._rightBox.append(this._dirsBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
Main.placesManager.connect('defaults-updated', Lang.bind(this, this._updateDefaults));
|
||||
Main.placesManager.connect('bookmarks-updated', Lang.bind(this, this._updateBookmarks));
|
||||
Main.placesManager.connect('mounts-updated', Lang.bind(this, this._updateMounts));
|
||||
|
||||
this._updateDefaults();
|
||||
this._updateMounts();
|
||||
this._updateBookmarks();
|
||||
},
|
||||
|
||||
_updateDefaults: function() {
|
||||
this._actionsBox.destroy_children();
|
||||
|
||||
let places = Main.placesManager.getDefaultPlaces();
|
||||
for (let i = 0; i < places.length; i++)
|
||||
this._actionsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
},
|
||||
|
||||
_updateMounts: function() {
|
||||
this._devBox.destroy_children();
|
||||
|
||||
let places = Main.placesManager.getMounts();
|
||||
for (let i = 0; i < places.length; i++)
|
||||
this._devBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
},
|
||||
|
||||
_updateBookmarks: function() {
|
||||
this._dirsBox.destroy_children();
|
||||
|
||||
let places = Main.placesManager.getBookmarks();
|
||||
for (let i = 0; i < places.length; i ++)
|
||||
this._dirsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(DashPlaceDisplay.prototype);
|
||||
|
||||
function PlaceSearchProvider() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
PlaceSearchProvider.prototype = {
|
||||
__proto__: Search.SearchProvider.prototype,
|
||||
|
||||
_init: function() {
|
||||
Search.SearchProvider.prototype._init.call(this, _("PLACES & DEVICES"));
|
||||
},
|
||||
|
||||
getResultMeta: function(resultId) {
|
||||
let placeInfo = Main.placesManager.lookupPlaceById(resultId);
|
||||
if (!placeInfo)
|
||||
return null;
|
||||
return { 'id': resultId,
|
||||
'name': placeInfo.name,
|
||||
'icon': placeInfo.iconFactory(Search.RESULT_ICON_SIZE) };
|
||||
},
|
||||
|
||||
activateResult: function(id) {
|
||||
let placeInfo = Main.placesManager.lookupPlaceById(id);
|
||||
placeInfo.launch();
|
||||
},
|
||||
|
||||
_compareResultMeta: function (idA, idB) {
|
||||
let infoA = Main.placesManager.lookupPlaceById(idA);
|
||||
let infoB = Main.placesManager.lookupPlaceById(idB);
|
||||
return infoA.name.localeCompare(infoB.name);
|
||||
},
|
||||
|
||||
_searchPlaces: function(places, terms) {
|
||||
let multipleResults = [];
|
||||
let prefixResults = [];
|
||||
let substringResults = [];
|
||||
|
||||
terms = terms.map(String.toLowerCase);
|
||||
|
||||
for (let i = 0; i < places.length; i++) {
|
||||
let place = places[i];
|
||||
let mtype = place.matchTerms(terms);
|
||||
if (mtype == Search.MatchType.MULTIPLE)
|
||||
multipleResults.push(place.id);
|
||||
else if (mtype == Search.MatchType.PREFIX)
|
||||
prefixResults.push(place.id);
|
||||
else if (mtype == Search.MatchType.SUBSTRING)
|
||||
substringResults.push(place.id);
|
||||
}
|
||||
multipleResults.sort(this._compareResultMeta);
|
||||
prefixResults.sort(this._compareResultMeta);
|
||||
substringResults.sort(this._compareResultMeta);
|
||||
return multipleResults.concat(prefixResults.concat(substringResults));
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms) {
|
||||
let places = Main.placesManager.getAllPlaces();
|
||||
return this._searchPlaces(places, terms);
|
||||
},
|
||||
|
||||
getSubsearchResultSet: function(previousResults, terms) {
|
||||
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
|
||||
return this._searchPlaces(places, terms);
|
||||
}
|
||||
}
|
278
js/ui/places.js
@ -1,278 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Pango = imports.gi.Pango;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
|
||||
const PLACES_VSPACING = 8;
|
||||
const PLACES_ICON_SIZE = 16;
|
||||
|
||||
/**
|
||||
* An entry in the places menu.
|
||||
* @name: String title
|
||||
* @iconFactory: A JavaScript callback which will create an icon texture
|
||||
* @onActivate: A JavaScript callback to launch the entry
|
||||
*/
|
||||
function PlaceDisplay(name, iconFactory, onActivate) {
|
||||
this._init(name, iconFactory, onActivate);
|
||||
}
|
||||
|
||||
PlaceDisplay.prototype = {
|
||||
_init : function(name, iconFactory, onActivate) {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
reactive: true,
|
||||
spacing: 4 });
|
||||
this.actor.connect('button-release-event', Lang.bind(this, function (b, e) {
|
||||
onActivate(this);
|
||||
Main.overview.hide();
|
||||
}));
|
||||
let text = new Clutter.Text({ font_name: "Sans 14px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
text: name });
|
||||
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
||||
this._icon = iconFactory();
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(text, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._iconFactory = iconFactory;
|
||||
this._onActivate = onActivate;
|
||||
|
||||
this.actor._delegate = this;
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._icon;
|
||||
},
|
||||
|
||||
getDragActor: function(stageX, stageY) {
|
||||
return this._iconFactory();
|
||||
},
|
||||
|
||||
//// Drag and drop methods ////
|
||||
|
||||
shellWorkspaceLaunch : function() {
|
||||
this._onActivate();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(PlaceDisplay.prototype);
|
||||
|
||||
function Places() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Places.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4 });
|
||||
this._menuBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PLACES_VSPACING });
|
||||
this.actor.append(this._menuBox, Big.BoxPackFlags.EXPAND);
|
||||
this._devBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PLACES_VSPACING });
|
||||
|
||||
this._dirsBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PLACES_VSPACING });
|
||||
this.actor.append(this._dirsBox, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
|
||||
let homeUri = homeFile.get_uri();
|
||||
let homeLabel = Shell.util_get_label_for_uri (homeUri);
|
||||
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
|
||||
let home = new PlaceDisplay(homeLabel,
|
||||
function() {
|
||||
return Shell.TextureCache.get_default().load_gicon(homeIcon, PLACES_ICON_SIZE);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext());
|
||||
});
|
||||
|
||||
this._menuBox.append(home.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
/*
|
||||
* Show devices, code more or less ported from nautilus-places-sidebar.c
|
||||
*/
|
||||
|
||||
this._menuBox.append(this._devBox, Big.BoxPackFlags.NONE);
|
||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||
this._volumeMonitor.connect('volume-added', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('volume-removed',Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('volume-changed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-added', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('mount-changed', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._updateDevices));
|
||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||
this._updateDevices();
|
||||
|
||||
let networkApp = null;
|
||||
try {
|
||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
|
||||
} catch(e) {
|
||||
try {
|
||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
|
||||
} catch(e) {
|
||||
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
|
||||
}
|
||||
}
|
||||
|
||||
if (networkApp != null) {
|
||||
let network = new PlaceDisplay(networkApp.get_name(),
|
||||
function() {
|
||||
return networkApp.create_icon_texture(PLACES_ICON_SIZE);
|
||||
},
|
||||
function () {
|
||||
networkApp.launch();
|
||||
});
|
||||
this._menuBox.append(network.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
let connect = new PlaceDisplay('Connect to...',
|
||||
function () {
|
||||
return Shell.TextureCache.get_default().load_icon_name("applications-internet", PLACES_ICON_SIZE);
|
||||
},
|
||||
function () {
|
||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||
});
|
||||
this._menuBox.append(connect.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]);
|
||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||
this._bookmarkTimeoutId = 0;
|
||||
monitor.connect('changed', Lang.bind(this, function () {
|
||||
if (this._bookmarkTimeoutId > 0)
|
||||
return;
|
||||
/* Defensive event compression */
|
||||
this._bookmarkTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () {
|
||||
this._bookmarkTimeoutId = 0;
|
||||
this._reloadBookmarks();
|
||||
return false;
|
||||
}));
|
||||
}));
|
||||
|
||||
this._reloadBookmarks();
|
||||
},
|
||||
|
||||
_reloadBookmarks: function() {
|
||||
|
||||
this._dirsBox.remove_all();
|
||||
|
||||
if (!GLib.file_test(this._bookmarksPath, GLib.FileTest.EXISTS))
|
||||
return;
|
||||
|
||||
let [success, bookmarksContent, len] = GLib.file_get_contents(this._bookmarksPath);
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
let bookmarks = bookmarksContent.split('\n');
|
||||
|
||||
let bookmarksToLabel = {};
|
||||
let bookmarksOrder = [];
|
||||
for (let i = 0; i < bookmarks.length; i++) {
|
||||
let bookmarkLine = bookmarks[i];
|
||||
let components = bookmarkLine.split(' ');
|
||||
let bookmark = components[0];
|
||||
if (bookmark in bookmarksToLabel)
|
||||
continue;
|
||||
let label = null;
|
||||
if (components.length > 1)
|
||||
label = components.slice(1).join(' ');
|
||||
bookmarksToLabel[bookmark] = label;
|
||||
bookmarksOrder.push(bookmark);
|
||||
}
|
||||
|
||||
for (let i = 0; i < bookmarksOrder.length; i++) {
|
||||
let bookmark = bookmarksOrder[i];
|
||||
let label = bookmarksToLabel[bookmark];
|
||||
let file = Gio.file_new_for_uri(bookmark);
|
||||
if (!file.query_exists(null))
|
||||
continue;
|
||||
if (label == null)
|
||||
label = Shell.util_get_label_for_uri(bookmark);
|
||||
if (label == null)
|
||||
continue;
|
||||
let icon = Shell.util_get_icon_for_uri(bookmark);
|
||||
|
||||
let item = new PlaceDisplay(label,
|
||||
function() {
|
||||
return Shell.TextureCache.get_default().load_gicon(icon, PLACES_ICON_SIZE);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext());
|
||||
});
|
||||
this._dirsBox.append(item.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
},
|
||||
|
||||
_updateDevices: function() {
|
||||
this._devBox.remove_all();
|
||||
|
||||
/* first go through all connected drives */
|
||||
let drives = this._volumeMonitor.get_connected_drives();
|
||||
for (let i = 0; i < drives.length; i++) {
|
||||
let volumes = drives[i].get_volumes();
|
||||
for(let j = 0; j < volumes.length; j++) {
|
||||
let mount = volumes[j].get_mount();
|
||||
if(mount != null) {
|
||||
this._addMount(mount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add all volumes that is not associated with a drive */
|
||||
let volumes = this._volumeMonitor.get_volumes();
|
||||
for(let i = 0; i < volumes.length; i++) {
|
||||
if(volumes[i].get_drive() != null)
|
||||
continue;
|
||||
|
||||
let mount = volumes[i].get_mount();
|
||||
if(mount != null) {
|
||||
this._addMount(mount);
|
||||
}
|
||||
}
|
||||
|
||||
/* add mounts that have no volume (/etc/mtab mounts, ftp, sftp,...) */
|
||||
let mounts = this._volumeMonitor.get_mounts();
|
||||
for(let i = 0; i < mounts.length; i++) {
|
||||
if(mounts[i].is_shadowed())
|
||||
continue;
|
||||
|
||||
if(mounts[i].get_volume())
|
||||
continue;
|
||||
|
||||
this._addMount(mounts[i]);
|
||||
}
|
||||
},
|
||||
|
||||
_addMount: function(mount) {
|
||||
let mountLabel = mount.get_name();
|
||||
let mountIcon = mount.get_icon();
|
||||
let root = mount.get_root();
|
||||
let mountUri = root.get_uri();
|
||||
let devItem = new PlaceDisplay(mountLabel,
|
||||
function() {
|
||||
return Shell.TextureCache.get_default().load_gicon(mountIcon, PLACES_ICON_SIZE);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(mountUri, Main.createAppLaunchContext());
|
||||
});
|
||||
this._devBox.append(devItem.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
};
|
||||
Signals.addSignalMethods(Places.prototype);
|
@ -2,6 +2,7 @@
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
@ -11,11 +12,9 @@ const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const OVERLAY_COLOR = new Clutter.Color();
|
||||
OVERLAY_COLOR.from_pixel(0x00000044);
|
||||
|
||||
const BOX_BACKGROUND_COLOR = new Clutter.Color();
|
||||
BOX_BACKGROUND_COLOR.from_pixel(0x000000cc);
|
||||
|
||||
@ -26,6 +25,154 @@ const DIALOG_WIDTH = 320;
|
||||
const DIALOG_PADDING = 6;
|
||||
const ICON_SIZE = 24;
|
||||
const ICON_BOX_SIZE = 36;
|
||||
const MAX_FILE_DELETED_BEFORE_INVALID = 10;
|
||||
|
||||
function CommandCompleter() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
CommandCompleter.prototype = {
|
||||
_init : function() {
|
||||
this._changedCount = 0;
|
||||
this._paths = GLib.getenv('PATH').split(':');
|
||||
this._valid = false;
|
||||
this._updateInProgress = false;
|
||||
this._childs = new Array(this._paths.length);
|
||||
this._monitors = new Array(this._paths.length);
|
||||
for (let i = 0; i < this._paths.length; i++) {
|
||||
this._childs[i] = [];
|
||||
let file = Gio.file_new_for_path(this._paths[i]);
|
||||
let info;
|
||||
try {
|
||||
info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
|
||||
} catch (e) {
|
||||
// FIXME catchall
|
||||
this._paths[i] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
|
||||
continue;
|
||||
|
||||
this._paths[i] = file.get_path();
|
||||
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
||||
if (this._monitors[i] != null) {
|
||||
this._monitors[i].connect("changed", Lang.bind(this, this._onChanged));
|
||||
}
|
||||
}
|
||||
this._paths = this._paths.filter(function(a) {
|
||||
return a != null;
|
||||
});
|
||||
this._update(0);
|
||||
},
|
||||
|
||||
_onGetEnumerateComplete : function(obj, res) {
|
||||
this._enumerator = obj.enumerate_children_finish(res);
|
||||
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete), null);
|
||||
},
|
||||
|
||||
_onNextFileComplete : function(obj, res) {
|
||||
let files = obj.next_files_finish(res);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
this._childs[this._i].push(files[i].get_name());
|
||||
}
|
||||
if (files.length) {
|
||||
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete), null);
|
||||
} else {
|
||||
this._enumerator.close(null);
|
||||
this._enumerator = null;
|
||||
this._update(this._i + 1);
|
||||
}
|
||||
},
|
||||
|
||||
update : function() {
|
||||
if (this._valid)
|
||||
return;
|
||||
this._update(0);
|
||||
},
|
||||
|
||||
_update : function(i) {
|
||||
if (i == 0 && this._updateInProgress)
|
||||
return;
|
||||
this._updateInProgress = true;
|
||||
this._changedCount = 0;
|
||||
this._i = i;
|
||||
if (i >= this._paths.length) {
|
||||
this._valid = true;
|
||||
this._updateInProgress = false;
|
||||
return;
|
||||
}
|
||||
let file = Gio.file_new_for_path(this._paths[i]);
|
||||
this._childs[this._i] = [];
|
||||
file.enumerate_children_async(Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onGetEnumerateComplete), null);
|
||||
},
|
||||
|
||||
_onChanged : function(m, f, of, type) {
|
||||
if (!this._valid)
|
||||
return;
|
||||
let path = f.get_parent().get_path();
|
||||
let k = undefined;
|
||||
for (let i = 0; i < this._paths.length; i++) {
|
||||
if (this._paths[i] == path)
|
||||
k = i;
|
||||
}
|
||||
if (k === undefined) {
|
||||
return;
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.CREATED) {
|
||||
this._childs[k].push(f.get_basename());
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.DELETED) {
|
||||
this._changedCount++;
|
||||
if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
|
||||
this._valid = false;
|
||||
}
|
||||
let name = f.get_basename();
|
||||
this._childs[k] = this._childs[k].filter(function(e) {
|
||||
return e != name;
|
||||
});
|
||||
}
|
||||
if (type == Gio.FileMonitorEvent.UNMOUNTED) {
|
||||
this._childs[k] = [];
|
||||
}
|
||||
},
|
||||
|
||||
getCompletion: function(text) {
|
||||
let common = "";
|
||||
let notInit = true;
|
||||
if (!this._valid) {
|
||||
this._update(0);
|
||||
return common;
|
||||
}
|
||||
function _getCommon(s1, s2) {
|
||||
let k = 0;
|
||||
for (; k < s1.length && k < s2.length; k++) {
|
||||
if (s1[k] != s2[k])
|
||||
break;
|
||||
}
|
||||
if (k == 0)
|
||||
return "";
|
||||
return s1.substr(0, k);
|
||||
}
|
||||
function _hasPrefix(s1, prefix) {
|
||||
return s1.indexOf(prefix) == 0;
|
||||
}
|
||||
for (let i = 0; i < this._childs.length; i++) {
|
||||
for (let k = 0; k < this._childs[i].length; k++) {
|
||||
if (!_hasPrefix(this._childs[i][k], text))
|
||||
continue;
|
||||
if (notInit) {
|
||||
common = this._childs[i][k];
|
||||
notInit = false;
|
||||
}
|
||||
common = _getCommon(common, this._childs[i][k]);
|
||||
}
|
||||
}
|
||||
if (common.length)
|
||||
return common.substr(text.length);
|
||||
return common;
|
||||
}
|
||||
};
|
||||
|
||||
function RunDialog() {
|
||||
this._init();
|
||||
@ -36,9 +183,8 @@ RunDialog.prototype = {
|
||||
this._isOpen = false;
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
gconf.connect('changed', Lang.bind(this, function (gconf, key) {
|
||||
if (key == 'development_tools')
|
||||
this._enableInternalCommands = gconf.get_bool('development_tools');
|
||||
gconf.connect('changed::development_tools', Lang.bind(this, function () {
|
||||
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
||||
}));
|
||||
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
||||
|
||||
@ -63,28 +209,26 @@ RunDialog.prototype = {
|
||||
|
||||
// All actors are inside _group. We create it initially
|
||||
// hidden then show it in show()
|
||||
this._group = new Clutter.Group({ visible: false });
|
||||
this._group = new Clutter.Group({ visible: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height });
|
||||
global.stage.add_actor(this._group);
|
||||
|
||||
this._overlay = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height,
|
||||
border_width: 0,
|
||||
reactive: true });
|
||||
this._group.add_actor(this._overlay);
|
||||
let lightbox = new Lightbox.Lightbox(this._group, true);
|
||||
|
||||
let boxH = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height });
|
||||
this._boxH = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
|
||||
this._group.add_actor(boxH);
|
||||
this._group.add_actor(this._boxH);
|
||||
lightbox.highlight(this._boxH);
|
||||
|
||||
let boxV = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
|
||||
boxH.append(boxV, Big.BoxPackFlags.NONE);
|
||||
this._boxH.append(boxV, Big.BoxPackFlags.NONE);
|
||||
|
||||
|
||||
let dialogBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
@ -94,7 +238,7 @@ RunDialog.prototype = {
|
||||
padding: DIALOG_PADDING,
|
||||
width: DIALOG_WIDTH });
|
||||
|
||||
boxH.append(dialogBox, Big.BoxPackFlags.NONE);
|
||||
this._boxH.append(dialogBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
let label = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
||||
font_name: '18px Sans',
|
||||
@ -142,17 +286,57 @@ RunDialog.prototype = {
|
||||
this.close();
|
||||
}));
|
||||
|
||||
this._pathCompleter = new Gio.FilenameCompleter();
|
||||
this._commandCompleter = new CommandCompleter();
|
||||
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
|
||||
this._entry.connect('key-press-event', Lang.bind(this, function(o, e) {
|
||||
let symbol = e.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this.close();
|
||||
return true;
|
||||
}
|
||||
if (symbol == Clutter.slash) {
|
||||
// Need preload data before get completion. GFilenameCompleter load content of parent directory.
|
||||
// Parent directory for /usr/include/ is /usr/. So need to add fake name('a').
|
||||
let text = o.get_text().concat('/a');
|
||||
let prefix;
|
||||
if (text.lastIndexOf(' ') == -1)
|
||||
prefix = text;
|
||||
else
|
||||
prefix = text.substr(text.lastIndexOf(' ') + 1);
|
||||
this._getCompletion(prefix);
|
||||
return false;
|
||||
}
|
||||
if (symbol == Clutter.Tab) {
|
||||
let text = o.get_text();
|
||||
let prefix;
|
||||
if (text.lastIndexOf(' ') == -1)
|
||||
prefix = text;
|
||||
else
|
||||
prefix = text.substr(text.lastIndexOf(' ') + 1);
|
||||
let postfix = this._getCompletion(prefix);
|
||||
if (postfix != null && postfix.length > 0) {
|
||||
o.insert_text(postfix, -1);
|
||||
o.set_cursor_position(text.length + postfix.length);
|
||||
if (postfix[postfix.length - 1] == '/')
|
||||
this._getCompletion(text + postfix + 'a');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
},
|
||||
|
||||
_getCompletion : function(text) {
|
||||
if (text.indexOf('/') != -1) {
|
||||
return this._pathCompleter.get_completion_suffix(text);
|
||||
} else {
|
||||
return this._commandCompleter.getCompletion(text);
|
||||
}
|
||||
},
|
||||
|
||||
_run : function(command) {
|
||||
this._commandError = false;
|
||||
let f;
|
||||
if (this._enableInternalCommands)
|
||||
f = this._internalCommands[command];
|
||||
@ -162,7 +346,6 @@ RunDialog.prototype = {
|
||||
f();
|
||||
} else if (command) {
|
||||
try {
|
||||
this._commandError = false;
|
||||
let [ok, len, args] = GLib.shell_parse_argv(command);
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
@ -175,7 +358,7 @@ RunDialog.prototype = {
|
||||
* We are only interested in the actual error, so parse that out.
|
||||
*/
|
||||
let m = /.+\((.+)\)/.exec(e);
|
||||
let errorStr = "Execution of '" + command + "' failed:\n" + m[1];
|
||||
let errorStr = _("Execution of '%s' failed:").format(command) + "\n" + m[1];
|
||||
this._errorMessage.set_text(errorStr);
|
||||
this._errorBox.show();
|
||||
}
|
||||
@ -186,10 +369,18 @@ RunDialog.prototype = {
|
||||
if (this._isOpen) // Already shown
|
||||
return;
|
||||
|
||||
if (!Main.pushModal(this._group))
|
||||
return;
|
||||
|
||||
// Position the dialog on the current monitor
|
||||
let monitor = global.get_focus_monitor();
|
||||
|
||||
this._boxH.set_position(monitor.x, monitor.y);
|
||||
this._boxH.set_size(monitor.width, monitor.height);
|
||||
|
||||
this._isOpen = true;
|
||||
this._group.show();
|
||||
|
||||
Main.pushModal(this._group);
|
||||
global.stage.set_key_focus(this._entry);
|
||||
},
|
||||
|
||||
@ -203,7 +394,7 @@ RunDialog.prototype = {
|
||||
this._commandError = false;
|
||||
|
||||
this._group.hide();
|
||||
this._entry.text = '';
|
||||
this._entry.set_text('');
|
||||
|
||||
Main.popModal(this._group);
|
||||
}
|
||||
|
272
js/ui/search.js
Normal file
@ -0,0 +1,272 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const RESULT_ICON_SIZE = 24;
|
||||
|
||||
// Not currently referenced by the search API, but
|
||||
// this enumeration can be useful for provider
|
||||
// implementations.
|
||||
const MatchType = {
|
||||
NONE: 0,
|
||||
MULTIPLE: 1,
|
||||
PREFIX: 2,
|
||||
SUBSTRING: 3
|
||||
};
|
||||
|
||||
function SearchResultDisplay(provider) {
|
||||
this._init(provider);
|
||||
}
|
||||
|
||||
SearchResultDisplay.prototype = {
|
||||
_init: function(provider) {
|
||||
this.provider = provider;
|
||||
this.actor = null;
|
||||
this.selectionIndex = -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* renderResults:
|
||||
* @results: List of identifier strings
|
||||
* @terms: List of search term strings
|
||||
*
|
||||
* Display the given search matches which resulted
|
||||
* from the given terms. It's expected that not
|
||||
* all results will fit in the space for the container
|
||||
* actor; in this case, show as many as makes sense
|
||||
* for your result type.
|
||||
*
|
||||
* The terms are useful for search match highlighting.
|
||||
*/
|
||||
renderResults: function(results, terms) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* clear:
|
||||
* Remove all results from this display and reset the selection index.
|
||||
*/
|
||||
clear: function() {
|
||||
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
||||
this.selectionIndex = -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* getSelectionIndex:
|
||||
*
|
||||
* Returns the index of the selected actor, or -1 if none.
|
||||
*/
|
||||
getSelectionIndex: function() {
|
||||
return this.selectionIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* getVisibleResultCount:
|
||||
*
|
||||
* Returns: The number of actors visible.
|
||||
*/
|
||||
getVisibleResultCount: function() {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* selectIndex:
|
||||
* @index: Integer index
|
||||
*
|
||||
* Move selection to the given index.
|
||||
* Return true if successful, false if no more results
|
||||
* available.
|
||||
*/
|
||||
selectIndex: function() {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SearchProvider:
|
||||
*
|
||||
* Subclass this object to add a new result type
|
||||
* to the search system, then call registerProvider()
|
||||
* in SearchSystem with an instance.
|
||||
*/
|
||||
function SearchProvider(title) {
|
||||
this._init(title);
|
||||
}
|
||||
|
||||
SearchProvider.prototype = {
|
||||
_init: function(title) {
|
||||
this.title = title;
|
||||
},
|
||||
|
||||
/**
|
||||
* getInitialResultSet:
|
||||
* @terms: Array of search terms, treated as logical OR
|
||||
*
|
||||
* Called when the user first begins a search (most likely
|
||||
* therefore a single term of length one or two), or when
|
||||
* a new term is added.
|
||||
*
|
||||
* Should return an array of result identifier strings representing
|
||||
* items which match the given search terms. This
|
||||
* is expected to be a substring match on the metadata for a given
|
||||
* item. Ordering of returned results is up to the discretion of the provider,
|
||||
* but you should follow these heruistics:
|
||||
*
|
||||
* * Put items which match multiple search terms before single matches
|
||||
* * Put items which match on a prefix before non-prefix substring matches
|
||||
*
|
||||
* This function should be fast; do not perform unindexed full-text searches
|
||||
* or network queries.
|
||||
*/
|
||||
getInitialResultSet: function(terms) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* getSubsearchResultSet:
|
||||
* @previousResults: Array of item identifiers
|
||||
* @newTerms: Updated search terms
|
||||
*
|
||||
* Called when a search is performed which is a "subsearch" of
|
||||
* the previous search; i.e. when every search term has exactly
|
||||
* one corresponding term in the previous search which is a prefix
|
||||
* of the new term.
|
||||
*
|
||||
* This allows search providers to only search through the previous
|
||||
* result set, rather than possibly performing a full re-query.
|
||||
*/
|
||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* getResultInfo:
|
||||
* @id: Result identifier string
|
||||
*
|
||||
* Return an object with 'id', 'name', (both strings) and 'icon' (Clutter.Texture)
|
||||
* properties which describe the given search result.
|
||||
*/
|
||||
getResultMeta: function(id) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* createResultContainer:
|
||||
*
|
||||
* Search providers may optionally override this to render their
|
||||
* results in a custom fashion. The default implementation
|
||||
* will create a vertical list.
|
||||
*
|
||||
* Returns: An instance of SearchResultDisplay.
|
||||
*/
|
||||
createResultContainerActor: function() {
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* createResultActor:
|
||||
* @resultMeta: Object with result metadata
|
||||
* @terms: Array of search terms, should be used for highlighting
|
||||
*
|
||||
* Search providers may optionally override this to render a
|
||||
* particular serch result in a custom fashion. The default
|
||||
* implementation will show the icon next to the name.
|
||||
*
|
||||
* The actor should be an instance of St.Widget, with the style class
|
||||
* 'dash-search-result-content'.
|
||||
*/
|
||||
createResultActor: function(resultMeta, terms) {
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* activateResult:
|
||||
* @id: Result identifier string
|
||||
*
|
||||
* Called when the user chooses a given result.
|
||||
*/
|
||||
activateResult: function(id) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* expandSearch:
|
||||
*
|
||||
* Called when the user clicks on the header for this
|
||||
* search section. Should typically launch an external program
|
||||
* displaying search results for that item type.
|
||||
*/
|
||||
expandSearch: function(terms) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
}
|
||||
Signals.addSignalMethods(SearchProvider.prototype);
|
||||
|
||||
function SearchSystem() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
SearchSystem.prototype = {
|
||||
_init: function() {
|
||||
this._providers = [];
|
||||
this.reset();
|
||||
},
|
||||
|
||||
registerProvider: function (provider) {
|
||||
this._providers.push(provider);
|
||||
},
|
||||
|
||||
getProviders: function() {
|
||||
return this._providers;
|
||||
},
|
||||
|
||||
getTerms: function() {
|
||||
return this._previousTerms;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._previousTerms = [];
|
||||
this._previousResults = [];
|
||||
},
|
||||
|
||||
updateSearch: function(searchString) {
|
||||
searchString = searchString.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
||||
if (searchString == '')
|
||||
return null;
|
||||
|
||||
let terms = searchString.split(/\s+/);
|
||||
let isSubSearch = terms.length == this._previousTerms.length;
|
||||
if (isSubSearch) {
|
||||
for (let i = 0; i < terms.length; i++) {
|
||||
if (terms[i].indexOf(this._previousTerms[i]) != 0) {
|
||||
isSubSearch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let results = [];
|
||||
if (isSubSearch) {
|
||||
for (let i = 0; i < this._previousResults.length; i++) {
|
||||
let [provider, previousResults] = this._previousResults[i];
|
||||
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
|
||||
if (providerResults.length > 0)
|
||||
results.push([provider, providerResults]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let provider = this._providers[i];
|
||||
let providerResults = provider.getInitialResultSet(terms);
|
||||
if (providerResults.length > 0)
|
||||
results.push([provider, providerResults]);
|
||||
}
|
||||
}
|
||||
|
||||
this._previousTerms = terms;
|
||||
this._previousResults = results;
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
Signals.addSignalMethods(SearchSystem.prototype);
|
75
js/ui/shellDBus.js
Normal file
@ -0,0 +1,75 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const GnomeShellIface = {
|
||||
name: "org.gnome.Shell",
|
||||
methods: [{ name: "Eval",
|
||||
inSignature: "s",
|
||||
outSignature: "bs"
|
||||
}
|
||||
],
|
||||
signals: [],
|
||||
properties: [{ name: "OverviewActive",
|
||||
signature: "b",
|
||||
access: "readwrite" }]
|
||||
};
|
||||
|
||||
function GnomeShell() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
GnomeShell.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.exportObject('/org/gnome/Shell', this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Eval:
|
||||
* @code: A string containing JavaScript code
|
||||
*
|
||||
* This function executes arbitrary code in the main
|
||||
* loop, and returns a boolean success and
|
||||
* JSON representation of the object as a string.
|
||||
*
|
||||
* If evaluation completes without throwing an exception,
|
||||
* then the return value will be [true, JSON.stringify(result)].
|
||||
* If evaluation fails, then the return value will be
|
||||
* [false, JSON.stringify(exception)];
|
||||
*
|
||||
*/
|
||||
Eval: function(code) {
|
||||
let returnValue;
|
||||
let success;
|
||||
try {
|
||||
returnValue = JSON.stringify(eval(code));
|
||||
// A hack; DBus doesn't have null/undefined
|
||||
if (returnValue == undefined)
|
||||
returnValue = "";
|
||||
success = true;
|
||||
} catch (e) {
|
||||
returnValue = JSON.stringify(e);
|
||||
success = false;
|
||||
}
|
||||
return [success, returnValue];
|
||||
},
|
||||
|
||||
get OverviewActive() {
|
||||
return Main.overview.visible;
|
||||
},
|
||||
|
||||
set OverviewActive(visible) {
|
||||
if (visible)
|
||||
Main.overview.show();
|
||||
else
|
||||
Main.overview.hide();
|
||||
}
|
||||
};
|
||||
|
||||
DBus.conformExport(GnomeShell.prototype, GnomeShellIface);
|
||||
|
@ -4,6 +4,7 @@ const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Panel = imports.ui.panel;
|
||||
@ -58,6 +59,8 @@ Sidebar.prototype = {
|
||||
if (this._visible)
|
||||
Main.chrome.addActor(this.actor);
|
||||
|
||||
this._hidden = false;
|
||||
this._hideTimeoutId = 0;
|
||||
this._widgets = [];
|
||||
this.addWidget(new ToggleWidget());
|
||||
|
||||
@ -69,6 +72,14 @@ Sidebar.prototype = {
|
||||
Lang.bind(this, this._expandedChanged));
|
||||
this._gconf.connect('changed::sidebar/visible',
|
||||
Lang.bind(this, this._visibleChanged));
|
||||
this._gconf.connect('changed::sidebar/autohide',
|
||||
Lang.bind(this, this._autohideChanged));
|
||||
|
||||
this.actor.connect('enter-event',Lang.bind(this,this._restoreHidden));
|
||||
this.actor.connect('leave-event',Lang.bind(this,this._startHideTimeout));
|
||||
|
||||
this._adjustPosition();
|
||||
this._autohideChanged();
|
||||
},
|
||||
|
||||
addWidget: function(widget) {
|
||||
@ -82,6 +93,14 @@ Sidebar.prototype = {
|
||||
|
||||
this.box.append(widgetBox.actor, Big.BoxPackFlags.NONE);
|
||||
this._widgets.push(widgetBox);
|
||||
this._adjustPosition();
|
||||
},
|
||||
|
||||
_adjustPosition: function() {
|
||||
let primary=global.get_primary_monitor();
|
||||
|
||||
this.actor.y = Math.floor(Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2));
|
||||
this.actor.x = primary.x;
|
||||
},
|
||||
|
||||
_visibleChanged: function() {
|
||||
@ -108,6 +127,21 @@ Sidebar.prototype = {
|
||||
this._collapse();
|
||||
},
|
||||
|
||||
_autohideChanged: function() {
|
||||
let autohide = this._gconf.get_boolean("sidebar/autohide");
|
||||
if (autohide == this._autohide)
|
||||
return;
|
||||
|
||||
this._autohide = autohide;
|
||||
if (autohide) {
|
||||
this.actor.set_reactive(true);
|
||||
this._hide();
|
||||
} else {
|
||||
this.actor.set_reactive(false);
|
||||
this._restore();
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function() {
|
||||
this._expanded = true;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
@ -125,16 +159,70 @@ Sidebar.prototype = {
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].collapse();
|
||||
|
||||
// Updated the strut/stage area after the animation completes
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
||||
onComplete: function () {
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
} });
|
||||
}) });
|
||||
},
|
||||
|
||||
_hide: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = true;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].hide();
|
||||
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = Math.floor(WidgetBox.WIDGETBOX_PADDING * 2 + SIDEBAR_PADDING);
|
||||
}) });
|
||||
}
|
||||
},
|
||||
|
||||
_restore: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = false;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].restore();
|
||||
|
||||
// Updated the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
} });
|
||||
}
|
||||
},
|
||||
|
||||
_restoreHidden: function(actor, event) {
|
||||
this._cancelHideTimeout();
|
||||
if (this._hidden)
|
||||
this._restore();
|
||||
return false;
|
||||
},
|
||||
|
||||
_startHideTimeout: function(actor, event) {
|
||||
if (!this._expanded) {
|
||||
this._cancelHideTimeout();
|
||||
this._hideTimeoutId = Mainloop.timeout_add_seconds(2, Lang.bind(this,this._hideTimeoutFunc));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_cancelHideTimeout: function() {
|
||||
if (this._hideTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._hideTimeoutId);
|
||||
this._hideTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_hideTimeoutFunc: function() {
|
||||
this._hide();
|
||||
return false;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.hide();
|
||||
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].destroy();
|
||||
this.actor.destroy();
|
||||
|
297
js/ui/statusMenu.js
Normal file
@ -0,0 +1,297 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Gdm = imports.gi.Gdm;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Panel = imports.ui.panel;
|
||||
|
||||
// Adapted from gdm/gui/user-switch-applet/applet.c
|
||||
//
|
||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
||||
// Copyright (C) 2008,2009 Red Hat, Inc.
|
||||
|
||||
const SIDEBAR_VISIBLE_KEY = 'sidebar/visible';
|
||||
|
||||
function StatusMenu() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
StatusMenu.prototype = {
|
||||
_init: function() {
|
||||
this._gdm = Gdm.UserManager.ref_default();
|
||||
this._user = this._gdm.get_user(GLib.get_user_name());
|
||||
this._presence = new GnomeSessionPresence();
|
||||
|
||||
this.actor = new St.BoxLayout({ name: 'statusMenu' });
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._iconBox = new St.Bin();
|
||||
this.actor.add(this._iconBox, { y_align: St.Align.MIDDLE });
|
||||
|
||||
let textureCache = Shell.TextureCache.get_default();
|
||||
// FIXME: these icons are all wrong (likewise in createSubMenu)
|
||||
this._availableIcon = textureCache.load_icon_name('gtk-yes', 16);
|
||||
this._busyIcon = textureCache.load_icon_name('gtk-no', 16);
|
||||
this._invisibleIcon = textureCache.load_icon_name('gtk-close', 16);
|
||||
this._idleIcon = textureCache.load_icon_name('gtk-media-pause', 16);
|
||||
|
||||
this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
|
||||
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
|
||||
|
||||
this._name = new St.Label({ text: this._user.get_real_name() });
|
||||
this.actor.add(this._name, { expand: true, y_align: St.Align.MIDDLE });
|
||||
this._userNameChangedId = this._user.connect('notify::display-name', Lang.bind(this, this._updateUserName));
|
||||
|
||||
this._createSubMenu();
|
||||
this._gdm.connect('users-loaded', Lang.bind(this, this._updateSwitchUser));
|
||||
this._gdm.connect('user-added', Lang.bind(this, this._updateSwitchUser));
|
||||
this._gdm.connect('user-removed', Lang.bind(this, this._updateSwitchUser));
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._user.disconnect(this._userNameChangedId);
|
||||
},
|
||||
|
||||
_updateUserName: function() {
|
||||
this._name.set_text(this._user.get_real_name());
|
||||
},
|
||||
|
||||
_updateSwitchUser: function() {
|
||||
let users = this._gdm.list_users();
|
||||
if (users.length > 1)
|
||||
this._loginScreenItem.show();
|
||||
else
|
||||
this._loginScreenItem.hide();
|
||||
},
|
||||
|
||||
_updatePresenceIcon: function(presence, status) {
|
||||
if (status == GnomeSessionPresenceStatus.AVAILABLE)
|
||||
this._iconBox.child = this._availableIcon;
|
||||
else if (status == GnomeSessionPresenceStatus.BUSY)
|
||||
this._iconBox.child = this._busyIcon;
|
||||
else if (status == GnomeSessionPresenceStatus.INVISIBLE)
|
||||
this._iconBox.child = this._invisibleIcon;
|
||||
else
|
||||
this._iconBox.child = this._idleIcon;
|
||||
},
|
||||
|
||||
// The menu
|
||||
|
||||
_createImageMenuItem: function(label, iconName, forceIcon) {
|
||||
let image = new Gtk.Image();
|
||||
let item = new Gtk.ImageMenuItem({ label: label,
|
||||
image: image,
|
||||
always_show_image: forceIcon == true });
|
||||
item.connect('style-set', Lang.bind(this,
|
||||
function() {
|
||||
image.set_from_icon_name(iconName, Gtk.IconSize.MENU);
|
||||
}));
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
_createSubMenu: function() {
|
||||
this._menu = new Gtk.Menu();
|
||||
this._menu.connect('deactivate', Lang.bind(this, function() { this.emit('deactivated'); }));
|
||||
|
||||
let item;
|
||||
|
||||
item = this._createImageMenuItem(_("Available"), 'gtk-yes', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.AVAILABLE));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Busy"), 'gtk-no', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.BUSY));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Invisible"), 'gtk-close', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.INVISIBLE));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = new Gtk.SeparatorMenuItem();
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Account Information..."), 'user-info');
|
||||
item.connect('activate', Lang.bind(this, this._onAccountInformationActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
item = new Gtk.CheckMenuItem({ label: _("Sidebar"),
|
||||
active: gconf.get_boolean(SIDEBAR_VISIBLE_KEY) });
|
||||
item.connect('activate', Lang.bind(this,
|
||||
function() {
|
||||
gconf.set_boolean(SIDEBAR_VISIBLE_KEY, this._sidebarItem.active);
|
||||
}));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this._sidebarItem = item;
|
||||
|
||||
item = this._createImageMenuItem(_("System Preferences..."), 'preferences-desktop');
|
||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = new Gtk.SeparatorMenuItem();
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Lock Screen"), 'system-lock-screen');
|
||||
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Switch User"), 'system-users');
|
||||
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this._loginScreenItem = item;
|
||||
|
||||
item = this._createImageMenuItem(_("Log Out..."), 'system-log-out');
|
||||
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
item = this._createImageMenuItem(_("Shut Down..."), 'system-shutdown');
|
||||
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
},
|
||||
|
||||
_setPresenceStatus: function(item, status) {
|
||||
this._presence.setStatus(status);
|
||||
},
|
||||
|
||||
_onAccountInformationActivate: function() {
|
||||
this._spawn(['gnome-about-me']);
|
||||
},
|
||||
|
||||
_onPreferencesActivate: function() {
|
||||
this._spawn(['gnome-control-center']);
|
||||
},
|
||||
|
||||
_onLockScreenActivate: function() {
|
||||
this._spawn(['gnome-screensaver-command', '--lock']);
|
||||
},
|
||||
|
||||
_onLoginScreenActivate: function() {
|
||||
this._gdm.goto_login_session();
|
||||
this._onLockScreenActivate();
|
||||
},
|
||||
|
||||
_onQuitSessionActivate: function() {
|
||||
this._spawn(['gnome-session-save', '--logout-dialog']);
|
||||
},
|
||||
|
||||
_onShutDownActivate: function() {
|
||||
this._spawn(['gnome-session-save', '--shutdown-dialog']);
|
||||
},
|
||||
|
||||
_spawn: function(args) {
|
||||
// FIXME: once Shell.Process gets support for signalling
|
||||
// errors we should pop up an error dialog or something here
|
||||
// on failure
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
},
|
||||
|
||||
// shell_status_menu_toggle:
|
||||
// @event: event causing the toggle
|
||||
//
|
||||
// If the menu is not currently up, pops it up. Otherwise, hides it.
|
||||
// Popping up may fail if another grab is already active; check with
|
||||
// isActive().
|
||||
toggle: function(event) {
|
||||
if (this._menu.visible)
|
||||
this._menu.popdown();
|
||||
else {
|
||||
// We don't want to overgrab a Mutter grab with the grab
|
||||
// that GTK+ uses on menus.
|
||||
if (global.display_is_grabbed())
|
||||
return;
|
||||
|
||||
let [menuWidth, menuHeight] = this._menu.get_size_request ();
|
||||
|
||||
let panel;
|
||||
for (panel = this.actor; panel; panel = panel.get_parent()) {
|
||||
if (panel._delegate instanceof Panel.Panel)
|
||||
break;
|
||||
}
|
||||
|
||||
let [panelX, panelY] = panel.get_transformed_position();
|
||||
let [panelWidth, panelHeight] = panel.get_transformed_size();
|
||||
|
||||
let menuX = Math.round(panelX + panelWidth - menuWidth);
|
||||
let menuY = Math.round(panelY + panelHeight);
|
||||
|
||||
Shell.popup_menu(this._menu, event.get_button(), event.get_time(),
|
||||
menuX, menuY);
|
||||
}
|
||||
},
|
||||
|
||||
// isActive:
|
||||
//
|
||||
// Gets whether the menu is currently popped up
|
||||
//
|
||||
// Return value: %true if the menu is currently popped up
|
||||
isActive: function() {
|
||||
return this._menu.visible;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(StatusMenu.prototype);
|
||||
|
||||
|
||||
const GnomeSessionPresenceIface = {
|
||||
name: 'org.gnome.SessionManager.Presence',
|
||||
methods: [{ name: 'SetStatus',
|
||||
inSignature: 'u' }],
|
||||
properties: [{ name: 'status',
|
||||
signature: 'u',
|
||||
access: 'readwrite' }],
|
||||
signals: [{ name: 'StatusChanged',
|
||||
inSignature: 'u' }]
|
||||
};
|
||||
|
||||
const GnomeSessionPresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
INVISIBLE: 1,
|
||||
BUSY: 2,
|
||||
IDLE: 3
|
||||
};
|
||||
|
||||
function GnomeSessionPresence() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
GnomeSessionPresence.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
||||
this.connect('StatusChanged', Lang.bind(this, function (proxy, status) { this.status = status; }));
|
||||
},
|
||||
|
||||
getStatus: function(callback) {
|
||||
this.GetRemote('status', Lang.bind(this,
|
||||
function(status, ex) {
|
||||
if (!ex)
|
||||
callback(this, status);
|
||||
}));
|
||||
},
|
||||
|
||||
setStatus: function(status) {
|
||||
this.SetStatusRemote(status);
|
||||
}
|
||||
};
|
||||
DBus.proxifyPrototype(GnomeSessionPresence.prototype, GnomeSessionPresenceIface);
|
||||
|
@ -178,7 +178,7 @@ function resumeTweens() {
|
||||
function registerSpecialProperty(name, getFunction, setFunction,
|
||||
parameters, preProcessFunction) {
|
||||
Tweener.registerSpecialProperty(name, getFunction, setFunction,
|
||||
parameters, preProcessFunction);
|
||||
parameters, preProcessFunction);
|
||||
}
|
||||
|
||||
function registerSpecialPropertyModifier(name, modifyFunction, getFunction) {
|
||||
|
@ -12,6 +12,7 @@ const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
|
||||
const COLLAPSED_WIDTH = 24;
|
||||
@ -318,12 +319,9 @@ AppsWidget.prototype = {
|
||||
this.collapsedActor = new Big.Box({ spacing: 2});
|
||||
|
||||
let appSystem = Shell.AppSystem.get_default();
|
||||
let apps = appSystem.get_favorites();
|
||||
let apps = AppFavorites.getAppFavorites().getFavorites();
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = appSystem.lookup_cached_app(apps[i]);
|
||||
if (!app)
|
||||
continue;
|
||||
this.addItem(new AppsWidgetInfo(app));
|
||||
this.addItem(new AppsWidgetInfo(apps[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -356,8 +354,7 @@ RecentDocsWidget.prototype = {
|
||||
for (i = 0; i < docs.length; i++) {
|
||||
let docInfo = new DocInfo.DocInfo (docs[i]);
|
||||
|
||||
if (docInfo.exists())
|
||||
items.push(docInfo);
|
||||
items.push(docInfo);
|
||||
}
|
||||
|
||||
items.sort(function (a,b) { return b.timestamp - a.timestamp; });
|
||||
|
@ -27,13 +27,13 @@ WidgetBox.prototype = {
|
||||
_init: function(widget, expanded) {
|
||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
||||
|
||||
if (widget instanceof Widget.Widget) {
|
||||
this._widget = widget;
|
||||
if (widget instanceof Widget.Widget) {
|
||||
this._widget = widget;
|
||||
this._widget.state = this.state;
|
||||
} else {
|
||||
let ctor = this._ctorFromName(widget);
|
||||
} else {
|
||||
let ctor = this._ctorFromName(widget);
|
||||
this._widget = new ctor(this.state);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._widget.actor)
|
||||
throw new Error("widget has no actor");
|
||||
@ -331,7 +331,7 @@ WidgetBox.prototype = {
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_POPPING_OUT;
|
||||
|
||||
Main.chrome.addInputRegionActor(this._hbox);
|
||||
Main.chrome.trackActor(this._hbox, { affectsStruts: false });
|
||||
},
|
||||
|
||||
_popOutComplete: function() {
|
||||
@ -370,7 +370,21 @@ WidgetBox.prototype = {
|
||||
this._egroup.hide();
|
||||
this._ebox.x = 0;
|
||||
|
||||
Main.chrome.removeInputRegionActor(this._hbox);
|
||||
Main.chrome.untrackActor(this._hbox);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
restore: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
|
109
js/ui/windowAttentionHandler.js
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
function WindowAttentionHandler() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
WindowAttentionHandler.prototype = {
|
||||
_init : function() {
|
||||
let display = global.screen.get_display();
|
||||
display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
this._startupIds = {};
|
||||
tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
|
||||
},
|
||||
|
||||
_onStartupSequenceChanged : function(tracker) {
|
||||
let sequences = tracker.get_startup_sequences();
|
||||
this._startupIds = {};
|
||||
for(let i = 0; i < sequences.length; i++) {
|
||||
this._startupIds[sequences[i].get_id()] = true;
|
||||
}
|
||||
},
|
||||
|
||||
_sourceId : function(appId) {
|
||||
return 'attention-' + appId;
|
||||
},
|
||||
|
||||
_getTitle : function(app, window) {
|
||||
if (this._startupIds[window.get_startup_id()])
|
||||
return app.get_name();
|
||||
else
|
||||
return window.title;
|
||||
},
|
||||
|
||||
_getBanner : function(app, window) {
|
||||
if (this._startupIds[window.get_startup_id()])
|
||||
return _("%s has finished starting").format(app.get_name());
|
||||
else
|
||||
return _("'%s' is ready").format(window.title);
|
||||
},
|
||||
|
||||
_onWindowDemandsAttention : function(display, window) {
|
||||
// We don't want to show the notification when the window is already focused,
|
||||
// because this is rather pointless.
|
||||
// Some apps (like GIMP) do things like setting the urgency hint on the
|
||||
// toolbar windows which would result into a notification even though GIMP itself is
|
||||
// focused.
|
||||
// We are just ignoring the hint on skip_taskbar windows for now.
|
||||
// (Which is the same behaviour as with metacity + panel)
|
||||
|
||||
if (!window || window.has_focus() || window.is_skip_taskbar())
|
||||
return;
|
||||
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let app = tracker.get_window_app(window);
|
||||
|
||||
let source = Main.messageTray.getSource(this._sourceId(app.get_id()));
|
||||
if (source == null) {
|
||||
source = new Source(this._sourceId(app.get_id()), app, window);
|
||||
Main.messageTray.add(source);
|
||||
source.connect('clicked', Lang.bind(this, function() { source.destroy(); }));
|
||||
}
|
||||
|
||||
let notification = new MessageTray.Notification(window.get_startup_id(), source, this._getTitle(app, window), this._getBanner(app, window), true);
|
||||
source.notify(notification);
|
||||
|
||||
window.connect('notify::title', Lang.bind(this, function(win) {
|
||||
notification.update(this._getTitle(app, win), this._getBanner(app, win), false);
|
||||
}));
|
||||
window.connect('notify::demands-attention', Lang.bind(this, function() { source.destroy() }));
|
||||
window.connect('focus', Lang.bind(this, function() { source.destroy() }));
|
||||
window.connect('unmanaged', Lang.bind(this, function() { source.destroy() }));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function Source(sourceId, app, window) {
|
||||
this._init(sourceId, app, window);
|
||||
}
|
||||
|
||||
Source.prototype = {
|
||||
__proto__ : MessageTray.Source.prototype,
|
||||
|
||||
_init: function(sourceId, app, window) {
|
||||
MessageTray.Source.prototype._init.call(this, sourceId);
|
||||
this._window = window;
|
||||
this._app = app;
|
||||
},
|
||||
|
||||
createIcon : function(size) {
|
||||
return this._app.create_icon_texture(size);
|
||||
},
|
||||
|
||||
clicked : function() {
|
||||
Main.activateWindow(this._window);
|
||||
MessageTray.Source.prototype.clicked.call(this);
|
||||
}
|
||||
|
||||
}
|
@ -4,8 +4,10 @@ const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const AltTab = imports.ui.altTab;
|
||||
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
@ -39,7 +41,19 @@ WindowManager.prototype = {
|
||||
shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
||||
shellwm.connect('kill-destroy', Lang.bind(this, this._destroyWindowDone));
|
||||
|
||||
shellwm.connect('begin-alt-tab', Lang.bind(this, this._beginAltTab));
|
||||
shellwm.takeover_keybinding('switch_windows');
|
||||
shellwm.connect('keybinding::switch_windows', Lang.bind(this, this._startAppSwitcher));
|
||||
|
||||
this._workspaceSwitcherPopup = null;
|
||||
shellwm.takeover_keybinding('switch_to_workspace_left');
|
||||
shellwm.takeover_keybinding('switch_to_workspace_right');
|
||||
shellwm.takeover_keybinding('switch_to_workspace_up');
|
||||
shellwm.takeover_keybinding('switch_to_workspace_down');
|
||||
shellwm.connect('keybinding::switch_to_workspace_left', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||
shellwm.connect('keybinding::switch_to_workspace_right', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||
shellwm.connect('keybinding::switch_to_workspace_up', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||
shellwm.connect('keybinding::switch_to_workspace_down', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||
|
||||
},
|
||||
|
||||
_shouldAnimate : function(actor) {
|
||||
@ -72,9 +86,14 @@ WindowManager.prototype = {
|
||||
* maybe TODO: get icon geometry passed through and move the window towards it?
|
||||
*/
|
||||
this._minimizing.push(actor);
|
||||
|
||||
let primary = global.get_primary_monitor();
|
||||
|
||||
Tweener.addTween(actor,
|
||||
{ scale_x: 0.0,
|
||||
scale_y: 0.0,
|
||||
x: primary.x,
|
||||
y: 0,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._minimizeWindowDone,
|
||||
@ -161,41 +180,10 @@ WindowManager.prototype = {
|
||||
},
|
||||
|
||||
_destroyWindow : function(shellwm, actor) {
|
||||
if (!this._shouldAnimate(actor)) {
|
||||
shellwm.completed_destroy(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.CENTER);
|
||||
|
||||
/* anachronistic 'tv-like' effect - squash on y axis, leave x alone */
|
||||
this._destroying.push(actor);
|
||||
Tweener.addTween(actor,
|
||||
{ scale_x: 1.0,
|
||||
scale_y: 0.0,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._destroyWindowDone,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [shellwm, actor],
|
||||
onOverwrite: this._destroyWindowOverwrite,
|
||||
onOverwriteScope: this,
|
||||
onOverwriteParams: [shellwm, actor]
|
||||
});
|
||||
shellwm.completed_destroy(actor);
|
||||
},
|
||||
|
||||
_destroyWindowDone : function(shellwm, actor) {
|
||||
if (this._removeEffect(this._destroying, actor)) {
|
||||
shellwm.completed_destroy(actor);
|
||||
Tweener.removeTweens(actor);
|
||||
actor.set_scale(1.0, 1.0);
|
||||
}
|
||||
},
|
||||
|
||||
_destroyWindowOverwrite : function(shellwm, actor) {
|
||||
if (this._removeEffect(this._destroying, actor)) {
|
||||
shellwm.completed_destroy(actor);
|
||||
}
|
||||
},
|
||||
|
||||
_switchWorkspace : function(shellwm, from, to, direction) {
|
||||
@ -300,12 +288,46 @@ WindowManager.prototype = {
|
||||
shellwm.completed_switch_workspace();
|
||||
},
|
||||
|
||||
_beginAltTab : function(shellwm, handler) {
|
||||
let popup = new AltTab.AltTabPopup();
|
||||
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
||||
/* prevent a corner case where both popups show up at once */
|
||||
if (this._workspaceSwitcherPopup != null)
|
||||
this._workspaceSwitcherPopup.actor.hide();
|
||||
|
||||
handler.connect('window-added', function(handler, window) { popup.addWindow(window); });
|
||||
handler.connect('show', function(handler, initialSelection) { popup.show(initialSelection); });
|
||||
handler.connect('destroy', function() { popup.destroy(); });
|
||||
handler.connect('notify::selected', function() { popup.select(handler.selected); });
|
||||
}
|
||||
let tabPopup = new AltTab.AltTabPopup();
|
||||
|
||||
if (!tabPopup.show(backwards))
|
||||
tabPopup.destroy();
|
||||
},
|
||||
|
||||
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
|
||||
/* We don't support this kind of layout */
|
||||
if (binding == "switch_to_workspace_up" || binding == "switch_to_workspace_down")
|
||||
return;
|
||||
|
||||
if (global.screen.n_workspaces == 1)
|
||||
return;
|
||||
|
||||
if (this._workspaceSwitcherPopup == null)
|
||||
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
||||
|
||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
|
||||
if (binding == "switch_to_workspace_left") {
|
||||
if (activeWorkspaceIndex > 0) {
|
||||
global.screen.get_workspace_by_index(activeWorkspaceIndex - 1).activate(global.get_current_time());
|
||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, activeWorkspaceIndex - 1);
|
||||
}
|
||||
else
|
||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, activeWorkspaceIndex);
|
||||
}
|
||||
|
||||
if (binding == "switch_to_workspace_right") {
|
||||
if (activeWorkspaceIndex < global.screen.n_workspaces - 1) {
|
||||
global.screen.get_workspace_by_index(activeWorkspaceIndex + 1).activate(global.get_current_time());
|
||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, activeWorkspaceIndex + 1);
|
||||
}
|
||||
else
|
||||
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, activeWorkspaceIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
104
js/ui/workspaceSwitcherPopup.js
Normal file
@ -0,0 +1,104 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const ANIMATION_TIME = 0.075;
|
||||
const DISPLAY_TIMEOUT = 600;
|
||||
|
||||
const LEFT = -1;
|
||||
const RIGHT = 1;
|
||||
|
||||
function WorkspaceSwitcherPopup() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
WorkspaceSwitcherPopup.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new Clutter.Group({ reactive: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height });
|
||||
global.stage.add_actor(this.actor);
|
||||
|
||||
this._scaleWidth = global.screen_width / global.screen_height;
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: "workspace-switcher-container" });
|
||||
this._list = new St.BoxLayout({ style_class: "workspace-switcher" });
|
||||
|
||||
this._container.add(this._list);
|
||||
|
||||
this.actor.add_actor(this._container);
|
||||
|
||||
this._redraw();
|
||||
|
||||
this._position();
|
||||
|
||||
this.actor.show();
|
||||
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||
},
|
||||
|
||||
_redraw : function(direction, activeWorkspaceIndex) {
|
||||
this._list.destroy_children();
|
||||
|
||||
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
||||
let indicator = null;
|
||||
|
||||
if (i == activeWorkspaceIndex && direction == LEFT)
|
||||
indicator = new St.Bin({ style_class: 'ws-switcher-active-left' });
|
||||
else if(i == activeWorkspaceIndex && direction == RIGHT)
|
||||
indicator = new St.Bin({ style_class: 'ws-switcher-active-right' });
|
||||
else
|
||||
indicator = new St.Bin({ style_class: 'ws-switcher-box' });
|
||||
|
||||
this._list.add(indicator);
|
||||
indicator.set_width(Math.round(indicator.get_height() * this._scaleWidth));
|
||||
|
||||
if (i < global.screen.n_workspaces - 1) {
|
||||
let spacer = new St.Bin({ style_class: 'ws-switcher-spacer' });
|
||||
this._list.add(spacer);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_position: function() {
|
||||
let focus = global.get_focus_monitor();
|
||||
this._container.x = focus.x + Math.floor((focus.width - this._container.width) / 2);
|
||||
this._container.y = focus.y + Math.floor((focus.height - this._container.height) / 2);
|
||||
},
|
||||
|
||||
_show : function() {
|
||||
Tweener.addTween(this._container, { opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
this._position();
|
||||
this.actor.show();
|
||||
},
|
||||
|
||||
display : function(direction, activeWorkspaceIndex) {
|
||||
this._redraw(direction, activeWorkspaceIndex);
|
||||
if (this._timeoutId != 0)
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||
this._show();
|
||||
},
|
||||
|
||||
_onTimeout : function() {
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
Tweener.addTween(this._container, { opacity: 0.0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: function() { this.actor.hide() },
|
||||
onCompleteScope: this
|
||||
});
|
||||
}
|
||||
};
|
1037
js/ui/workspacesView.js
Normal file
1
man/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
dist_man_MANS = gnome-shell.1
|
99
man/gnome-shell.1
Normal file
@ -0,0 +1,99 @@
|
||||
.\" Copyright (c) 2009, Marcelo Jorge Vieira (metal) <metal@alucinados.com>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
.\" Boston, MA 02111-1301 USA.
|
||||
.TH GNOME-SHELL 1
|
||||
.SH NAME
|
||||
gnome-shell \- Graphical shell for the GNOME desktop
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B gnome-shell [options]
|
||||
|
||||
.SH DESCRIPTION
|
||||
GNOME Shell provides core user interface functions for the GNOME 3
|
||||
desktop, like switching to windows and launching applications. GNOME
|
||||
Shell takes advantage of the capabilities of modern graphics hardware
|
||||
and introduces innovative user interface concepts to provide a
|
||||
visually attractive and easy to use experience.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.B \-r, \-\-replace
|
||||
Replace the running metacity/gnome-panel
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-v, \-\-verbose
|
||||
Shows details about the results of running `gnome-shell'.
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-g, \-\-debug
|
||||
Run under a debugger
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-debug\-command
|
||||
Command to use for debugging (defaults to 'gdb \-\-args')
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-sync
|
||||
.br
|
||||
Make X calls synchronously, useful when debugging down X errors
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-xephyr
|
||||
Run a debugging instance inside Xephyr
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-geometry
|
||||
Specify Xephyr screen geometry
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-w, \-\-wide
|
||||
Use widescreen (1280x800) with Xephyr
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-create\-extension
|
||||
Create a new GNOME Shell extension
|
||||
|
||||
.TP
|
||||
.B \-\-eval\-file
|
||||
Evaluate the contents of the given JavaScript file
|
||||
.br
|
||||
|
||||
.SH BUGS
|
||||
The bug tracker can be reached by visiting the website
|
||||
\fIhttps://bugzilla.gnome.org/buglist.cgi?product=gnome-shell\fR
|
||||
|
||||
Before sending a bug report, please verify that you have the latest
|
||||
version of gnome-shell. Many bugs (major and minor) are fixed at each
|
||||
release, and if yours is out of date, the problem may already have
|
||||
been solved.
|
||||
|
||||
.SH ADDITIONAL INFORMATION
|
||||
|
||||
For further information, visit the website \fIhttp://live.gnome.org/GnomeShell\fR
|
11
po/LINGUAS
@ -1,12 +1,17 @@
|
||||
ar
|
||||
bg
|
||||
ca
|
||||
cs
|
||||
da
|
||||
de
|
||||
el
|
||||
en_GB
|
||||
es
|
||||
fi
|
||||
fr
|
||||
ga
|
||||
gl
|
||||
he
|
||||
hu
|
||||
it
|
||||
ko
|
||||
@ -15,6 +20,12 @@ nl
|
||||
pa
|
||||
pl
|
||||
pt_BR
|
||||
ro
|
||||
ru
|
||||
sl
|
||||
sr
|
||||
sr@latin
|
||||
sv
|
||||
tr
|
||||
vi
|
||||
zh_CN
|
||||
|
@ -1,9 +1,15 @@
|
||||
data/gnome-shell.desktop.in.in
|
||||
js/ui/panel.js
|
||||
js/ui/appDisplay.js
|
||||
js/ui/appFavorites.js
|
||||
js/ui/dash.js
|
||||
js/ui/docDisplay.js
|
||||
js/ui/lookingGlass.js
|
||||
js/ui/overview.js
|
||||
js/ui/panel.js
|
||||
js/ui/placeDisplay.js
|
||||
js/ui/runDialog.js
|
||||
js/ui/statusMenu.js
|
||||
js/ui/widget.js
|
||||
src/gdmuser/gdm-user.c
|
||||
src/shell-global.c
|
||||
src/shell-status-menu.c
|
||||
src/shell-uri-util.c
|
||||
|
236
po/ar.po
Normal file
@ -0,0 +1,236 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Khaled Hosny <khaledhosny@eglug.org>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-01-17 11:29+0200\n"
|
||||
"PO-Revision-Date: 2010-01-17 11:29+0300\n"
|
||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ar\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
"X-Generator: Virtaal 0.5.1\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "صدفة جنوم"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "إدارة النوافذ وإطلاق التطبيقات"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "التطبيقات"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "التفضيلات"
|
||||
|
||||
#: ../js/ui/appDisplay.js:644
|
||||
msgid "New Window"
|
||||
msgstr "نافذة جديدة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:648
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "أزِل من المفضّلة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "Add to Favorites"
|
||||
msgstr "أضِف إلى المفضّلة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1001
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "اسحب إلى هنا ليضاف إلى المفضّلة"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "ابحث..."
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
msgid "Searching..."
|
||||
msgstr "يبحث..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "No matching results."
|
||||
msgstr "لا نتائج مطابقة."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "الأماكن والأجهزة"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "العناصر الحديثة"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "الأنشطة"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A %Ol:%OM %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "اتّصل ب..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "من فضلك اكتب أمرا:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "فشل تنفيذ '%s':"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%OH:%OM"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "التطبيقات"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "المستندات الحديثة"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "منذ أقل من دقيقة"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "منذ أقل من دقيقة"
|
||||
msgstr[1] "منذ دقيقة"
|
||||
msgstr[2] "منذ دقيقتين"
|
||||
msgstr[3] "منذ %d دقائق"
|
||||
msgstr[4] "منذ %d دقيقة"
|
||||
msgstr[5] "منذ %d دقيقة"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "منذ أقل من ساعة"
|
||||
msgstr[1] "منذ ساعة"
|
||||
msgstr[2] "منذ ساعتين"
|
||||
msgstr[3] "منذ %d ساعات"
|
||||
msgstr[4] "منذ %d ساعة"
|
||||
msgstr[5] "منذ %d ساعة"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "منذ أقل من يوم"
|
||||
msgstr[1] "منذ يوم"
|
||||
msgstr[2] "منذ يومين"
|
||||
msgstr[3] "منذ %d أيام"
|
||||
msgstr[4] "منذ %d يوما"
|
||||
msgstr[5] "منذ %d يوم"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "منذ أقل من أسبوع"
|
||||
msgstr[1] "منذ أسبوع"
|
||||
msgstr[2] "منذ أسبوعين"
|
||||
msgstr[3] "منذ %d أسابيع"
|
||||
msgstr[4] "منذ %d أسبوعا"
|
||||
msgstr[5] "منذ %d أسبوع"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "مجلد المنزل"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "نظام الملفات"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "ابحث"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "متكرر"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "المزيد"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(انظر الكل)"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "الأماكن"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "نتائج البحث"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "مجهول"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "تعذّر إيصاد الشاشة: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr "تعذّر ضبك حافظة الشاشة مؤقتا لتكون شاشة خالية: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "تعذّر الخروج: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "معلومات الحساب..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "الشريط الجانبي"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "تفضيلات النظام..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "أوصد الشاشة"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "بدّل المستخدم"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "اخرج..."
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "أطفئ..."
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "استعرض"
|
254
po/bg.po
Normal file
@ -0,0 +1,254 @@
|
||||
# Bulgarian translation of gnome-shell po-file.
|
||||
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Ivaylo Valkov <ivaylo@e-valkov.org>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-02-20 14:29+0200\n"
|
||||
"PO-Revision-Date: 2010-02-16 21:13+0200\n"
|
||||
"Last-Translator: Ivaylo Valkov <ivaylo@e-valkov.org>\n"
|
||||
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Обвивка на GNOME"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Управление на прозорци и стартиране на програми"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:177 ../js/ui/dash.js:881
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ПРОГРАМИ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:201
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ПРЕДПОЧИТАНИЯ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:579
|
||||
msgid "New Window"
|
||||
msgstr "Нов прозорец"
|
||||
|
||||
#: ../js/ui/appDisplay.js:583
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Премахване от „Любими“"
|
||||
|
||||
#: ../js/ui/appDisplay.js:584
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Добавяне в „Любими“"
|
||||
|
||||
#: ../js/ui/appDisplay.js:936
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Довлачете до тук обектите за да ги добавите към „Любими“"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "Програмата „%s“ беше добавена в „Любими“"
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Програмата „%s“ беше премахната от „Любими“"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find..."
|
||||
msgstr "Търсене…"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Търсене…"
|
||||
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Няма съвпадения."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "МЕСТА И УСТРОЙСТВА"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "СКОРО ОТВАРЯНИ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
msgid "No extensions installed"
|
||||
msgstr "Няма инсталирани разширения"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Enabled"
|
||||
msgstr "Включено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Disabled"
|
||||
msgstr "Изключено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Error"
|
||||
msgstr "Грешка"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Out of date"
|
||||
msgstr "Остаряло"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
msgid "View Source"
|
||||
msgstr "Преглед на програмния код"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "Web Page"
|
||||
msgstr "Домашна страница"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
msgid "Undo"
|
||||
msgstr "Отмяна"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Дейности"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a, %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Свързване към…"
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Въведете команда:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Неуспешно изпълнение на „%s“:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Налично"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Заето"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Невидимо"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Информация за настройките на потребителя…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Странична лента"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Системни настройки…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Заключване на екрана"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Смяна на потребител"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Изход…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Изключване на компютъра…"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Програми"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Скоро отваряни документи"
|
||||
|
||||
#: ../src/shell-global.c:960
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Преди по-малко от минута"
|
||||
|
||||
#: ../src/shell-global.c:964
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "преди %d минута"
|
||||
msgstr[1] "преди %d минути"
|
||||
|
||||
#: ../src/shell-global.c:969
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "преди %d час"
|
||||
msgstr[1] "преди %d часа"
|
||||
|
||||
#: ../src/shell-global.c:974
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "преди %d ден"
|
||||
msgstr[1] "преди %d дни"
|
||||
|
||||
#: ../src/shell-global.c:979
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "преди %d седмица"
|
||||
msgstr[1] "преди %d седмици"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Домашна папка"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Файлова система"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Търсене"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
105
po/ca.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-30 18:53+0200\n"
|
||||
"PO-Revision-Date: 2009-08-30 18:57+0100\n"
|
||||
"POT-Creation-Date: 2009-10-10 20:19+0200\n"
|
||||
"PO-Revision-Date: 2009-10-10 20:22+0100\n"
|
||||
"Last-Translator: Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,82 +24,126 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestió de finestres i execució d'aplicacions"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Activitats"
|
||||
#: ../js/ui/appDisplay.js:335
|
||||
msgid "Frequent"
|
||||
msgstr "Freqüent"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#: ../js/ui/appIcon.js:462
|
||||
msgid "New Window"
|
||||
msgstr "Finestra nova"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
#: ../js/ui/appIcon.js:475
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Elimina dels preferits"
|
||||
|
||||
#: ../js/ui/appIcon.js:476
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Afegeix als preferits"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Cerca..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Navega"
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Més"
|
||||
|
||||
#: ../js/ui/dash.js:451
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(mostra tot)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:633
|
||||
#: ../js/ui/dash.js:681
|
||||
#: ../js/ui/dash.js:763
|
||||
#: ../js/ui/dash.js:825
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONS"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:653
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "LLOCS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:660
|
||||
#: ../js/ui/dash.js:692
|
||||
#: ../js/ui/dash.js:790
|
||||
#: ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTS RECENTS"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:679
|
||||
#: ../js/ui/dash.js:815
|
||||
#: ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTATS DE LA CERCA"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERÈNCIES"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:272
|
||||
msgid "Activities"
|
||||
msgstr "Activitats"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:464
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "Connecta a..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduïu una ordre:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "No s'ha pogut executar «%s»:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:162
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:316
|
||||
msgid "Applications"
|
||||
msgstr "Aplicacions"
|
||||
|
||||
#: ../js/ui/widget.js:341
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documents recents"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Fa menys d'un minut"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:815
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Fa %d minut"
|
||||
msgstr[1] "Fa %d minuts"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:818
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Fa %d hora"
|
||||
msgstr[1] "Fa %d hores"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:821
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Fa %d dia"
|
||||
msgstr[1] "Fa %d dies"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -180,10 +224,3 @@ msgstr "Cerca"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Cerca aplicacions o documents"
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Gestor"
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "L'objecte gestor d'usuaris que controla a aquest usuari."
|
||||
|
||||
|
228
po/cs.po
@ -1,20 +1,21 @@
|
||||
# Czech translation of gnome-shell.
|
||||
# Copyright (C) 2009 the author(s) of gnome-shell.
|
||||
# Copyright (C) 2009, 2010 the author(s) of gnome-shell.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Andre Klapper <ak-47@gmx.net>, 2009.
|
||||
# Petr Kovar <pknbe@volny.cz>, 2009.
|
||||
# Petr Kovar <pknbe@volny.cz>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-30 17:37+0200\n"
|
||||
"PO-Revision-Date: 2009-08-30 17:33+0200\n"
|
||||
"POT-Creation-Date: 2010-01-12 21:58+0100\n"
|
||||
"PO-Revision-Date: 2010-01-12 21:57+0100\n"
|
||||
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Lokalize 1.0\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
@ -24,59 +25,97 @@ msgstr "Prostředí GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Správa oken a spouštění aplikací"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Činnosti"
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLIKACE"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PŘEDVOLBY"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
#: ../js/ui/appDisplay.js:644
|
||||
msgid "New Window"
|
||||
msgstr "Nové okno"
|
||||
|
||||
#: ../js/ui/appDisplay.js:648
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Odstranit z oblíbených"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Přidat mezi oblíbené"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1001
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Oblíbené přidáte přetažením sem"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Najít..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Procházet"
|
||||
#: ../js/ui/dash.js:493
|
||||
msgid "Searching..."
|
||||
msgstr "Hledá se..."
|
||||
|
||||
#: ../js/ui/dash.js:451
|
||||
msgid "(see all)"
|
||||
msgstr "(zobrazit vše)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:633 ../js/ui/dash.js:681
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLIKACE"
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "No matching results."
|
||||
msgstr "Neodpovídá ani jeden z výsledků."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:653
|
||||
msgid "PLACES"
|
||||
msgstr "MÍSTA"
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "MÍSTA A ZAŘÍZENÍ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:660 ../js/ui/dash.js:692
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "NEDÁVNÉ DOKUMENTY"
|
||||
#: ../js/ui/dash.js:892
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "NEDÁVNÉ POLOŽKY"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:679
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "VÝSLEDKY HLEDÁNÍ"
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Činnosti"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Připojit se k..."
|
||||
|
||||
#: ../js/ui/runDialog.js:235
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Zadejte prosím příkaz:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:351
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Vykonání \"%s\" selhalo:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplikace"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Nedávné dokumenty"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Před méně než minutou"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:893
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -84,7 +123,7 @@ msgstr[0] "Před %d minutou"
|
||||
msgstr[1] "Před %d minutami"
|
||||
msgstr[2] "Před %d minutami"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:896
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -92,7 +131,7 @@ msgstr[0] "Před %d hodinou"
|
||||
msgstr[1] "Před %d hodinami"
|
||||
msgstr[2] "Před %d hodinami"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -100,7 +139,7 @@ msgstr[0] "Před %d dnem"
|
||||
msgstr[1] "Před %d dny"
|
||||
msgstr[2] "Před %d dny"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:902
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -108,67 +147,17 @@ msgstr[0] "Před %d týdnem"
|
||||
msgstr[1] "Před %d týdny"
|
||||
msgstr[2] "Před %d týdny"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Neznámé"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nelze uzamknout obrazovku: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Šetřič obrazovky nelze dočasně nastavit na prázdnou obrazovku: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nelze se odhlásit: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informace o účtu..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Postranní lišta"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Předvolby systému..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Uzamknout obrazovku"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Přepnout uživatele"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Odhlásit..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Vypnout..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Domovská složka"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Systém souborů"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Hledat"
|
||||
|
||||
@ -177,11 +166,62 @@ msgstr "Hledat"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Časté"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Více"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(zobrazit vše)"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "MÍSTA"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "VÝSLEDKY HLEDÁNÍ"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Neznámé"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Nelze uzamknout obrazovku: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr "Šetřič obrazovky nelze dočasně nastavit na prázdnou obrazovku: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Nelze se odhlásit: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Informace o účtu..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Postranní lišta"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Předvolby systému..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Uzamknout obrazovku"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Přepnout uživatele"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Odhlásit..."
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Vypnout..."
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Procházet"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Správce"
|
||||
|
||||
|
96
po/da.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-09-04 01:26+0200\n"
|
||||
"PO-Revision-Date: 2009-09-01 21:48+0200\n"
|
||||
"POT-Creation-Date: 2009-10-21 22:51+0200\n"
|
||||
"PO-Revision-Date: 2009-10-18 17:32+0200\n"
|
||||
"Last-Translator: Kris Thomsen <lakristho@gmail.com>\n"
|
||||
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,80 +24,123 @@ msgstr "Skal til GNOME"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Vinduehåndtering og åbning af programmer"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
#: ../js/ui/appDisplay.js:332
|
||||
msgid "Frequent"
|
||||
msgstr "Ofte"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#: ../js/ui/appIcon.js:410
|
||||
msgid "New Window"
|
||||
msgstr "Nyt vindue"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
#: ../js/ui/appIcon.js:414
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Fjern fra favoritter"
|
||||
|
||||
#: ../js/ui/appIcon.js:415
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Tilføj til favoritter"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Find..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Gennemse"
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Mere"
|
||||
|
||||
#: ../js/ui/dash.js:511
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(se alle)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:705 ../js/ui/dash.js:761 ../js/ui/dash.js:893
|
||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMMER"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:725
|
||||
#: ../js/ui/dash.js:745
|
||||
msgid "PLACES"
|
||||
msgstr "STEDER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:732 ../js/ui/dash.js:773 ../js/ui/dash.js:867
|
||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SENESTE DOKUMENTER"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:751 ../js/ui/dash.js:856 ../js/ui/dash.js:882
|
||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "SØGERESULTATER"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/dash.js:792
|
||||
msgid "PREFERENCES"
|
||||
msgstr "INDSTILLINGER"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "Forbind til..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Indtast en kommando:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Kørsel af \"%s\" mislykkedes:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programmer"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Seneste dokumenter"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre end et minut siden"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:815
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minut siden"
|
||||
msgstr[1] "%d minutter siden"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:818
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d time siden"
|
||||
msgstr[1] "%d timer siden"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:821
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag siden"
|
||||
msgstr[1] "%d dage siden"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -178,6 +221,9 @@ msgstr "Søg"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Gennemse"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Find programmer eller dokumenter"
|
||||
|
||||
|
256
po/de.po
@ -4,18 +4,21 @@
|
||||
#
|
||||
# Hendrik Brandt <heb@gnome-de.org>, 2009.
|
||||
# Hendrik Richter <hendrikr@gnome.org>, 2009.
|
||||
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009.
|
||||
# Mario Blättermann <mariobl@gnome.org>, 2009, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-20 16:47+0200\n"
|
||||
"PO-Revision-Date: 2009-08-20 16:49+0200\n"
|
||||
"Last-Translator: Hendrik Richter <hendrikr@gnome.org>\n"
|
||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-01-07 23:31+0000\n"
|
||||
"PO-Revision-Date: 2010-01-15 16:54+0100\n"
|
||||
"Last-Translator: Mario Blättermann <mariobl@gnome.org>\n"
|
||||
"Language-Team: German <gnome-de@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
@ -26,148 +29,137 @@ msgstr "GNOME-Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Fenster verwalten und Anwendungen starten"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Aktivitäten"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:251
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Anwendungen oder Dokumente suchen"
|
||||
|
||||
#: ../js/ui/dash.js:369
|
||||
msgid "Browse"
|
||||
msgstr "Durchsuchen"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:505 ../js/ui/dash.js:578
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ANWENDUNGEN"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:510 ../js/ui/dash.js:605
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "EINSTELLUNGEN"
|
||||
|
||||
#: ../js/ui/appDisplay.js:707 ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "Neues Fenster"
|
||||
|
||||
#: ../js/ui/appDisplay.js:711 ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Aus Favoriten entfernen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:712 ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Zu Favoriten hinzufügen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1064
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Hier ablegen, um zu Favoriten hinzuzufügen"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Suchen …"
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
#| msgid "Search"
|
||||
msgid "Searching..."
|
||||
msgstr "Suche läuft …"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "No matching results."
|
||||
msgstr "Keine passenden Ergebnisse."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:598
|
||||
msgid "PLACES"
|
||||
msgstr "ORTE"
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ORTE UND GERÄTE"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
#| msgid "RECENT DOCUMENTS"
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Aktivitäten"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Verbinden mit …"
|
||||
|
||||
#: ../js/ui/runDialog.js:235
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Bitte geben Sie einen Befehl ein:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "Manager"
|
||||
msgstr "Verwaltung"
|
||||
#: ../js/ui/runDialog.js:351
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Ausführung von »%s« ist gescheitert:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:244
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "Das Benutzerverwaltungsobjekt welches diesen Benutzer überwacht."
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Anwendungen"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Zuletzt geöffnete Dokumente"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Vor weniger als einer Minute"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#: ../src/shell-global.c:893
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Vor %d Minute"
|
||||
msgstr[1] "Vor %d Minuten"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#: ../src/shell-global.c:896
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Vor %d Stunde"
|
||||
msgstr[1] "Vor %d Stunden"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Vor %d Tag"
|
||||
msgstr[1] "Vor %d Tagen"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#: ../src/shell-global.c:902
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Vor %d Woche"
|
||||
msgstr[1] "Vor %d Wochen"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Bildschirm kann nicht gesperrt werden: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Der Bildschirmschoner kann vorübergehend nicht auf einen leeren Schirm "
|
||||
"gesetzt werden: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Abmelden ist nicht möglich: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Benutzerinformationen …"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Seitenleiste"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systemeinstellungen …"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bildschirm sperren"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Benutzer wechseln"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Abmelden …"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Ausschalten …"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Persönlicher Ordner"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Dateisystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Suchen"
|
||||
|
||||
@ -176,7 +168,69 @@ msgstr "Suchen"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Häufig"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Mehr"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(alle sehen)"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "ORTE"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "SUCHERGEBNISSE"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Unbekannt"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Bildschirm kann nicht gesperrt werden: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Der Bildschirmschoner kann vorübergehend nicht auf einen leeren Schirm "
|
||||
#~ "gesetzt werden: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Abmelden ist nicht möglich: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Benutzerinformationen …"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Seitenleiste"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Systemeinstellungen …"
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Bildschirm sperren"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Benutzer wechseln"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Abmelden …"
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Ausschalten …"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Anwendungen oder Dokumente suchen"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Durchsuchen"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Verwaltung"
|
||||
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "Das Benutzerverwaltungsobjekt welches diesen Benutzer überwacht."
|
||||
|
186
po/el.po
Normal file
@ -0,0 +1,186 @@
|
||||
# translation of gnome-shell.po.master.po to Greek
|
||||
# Greek translation for gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Jennie Petoumenou <epetoumenou@gmail.com>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell.po.master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-10-04 08:03+0000\n"
|
||||
"PO-Revision-Date: 2009-10-04 10:25+0200\n"
|
||||
"Last-Translator: Jennie Petoumenou <epetoumenou@gmail.com>\n"
|
||||
"Language-Team: Greek <<team AT BLOCKSPAM gnome DOT gr>>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Κέλυφος GNOME"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Διαχείριση παραθύρων και εκκίνηση εφαρμογών"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Δραστηριότητες"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:461
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Εύρεση..."
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Περισσότερα"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(εμφάνιση όλων)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ΕΦΑΡΜΟΓΕΣ"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "ΤΟΠΟΘΕΣΙΕΣ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ΠΡΟΣΦΑΤΑ ΕΓΓΡΑΦΑ"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ΑΠΟΤΕΛΕΣΜΑΤΑ ΑΝΑΖΗΤΗΣΗΣ"
|
||||
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ΠΡΟΤΙΜΗΣΕΙΣ"
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Παρακαλώ εισάγετε μία εντολή:"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Λιγότερο από ένα λεπτό πριν"
|
||||
|
||||
#: ../src/shell-global.c:815
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d λεπτό πριν"
|
||||
msgstr[1] "%d λεπτά πριν"
|
||||
|
||||
#: ../src/shell-global.c:818
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ώρα πριν"
|
||||
msgstr[1] "%d ώρες πριν"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ημέρα πριν"
|
||||
msgstr[1] "%d ημέρες πριν"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d εβδομάδα πριν"
|
||||
msgstr[1] "%d εβδομάδες πριν"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Άγνωστο"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Αδύνατο το κλείδωμα της οθόνης: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Δεν είναι δυνατή η προσωρινή ρύθμιση της προστασίας οθόνης σε κενή οθόνη: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Αδύνατη η αποσύνδεση: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Πληροφορίες λογαριασμού..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Πλευρική στήλη"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Προστιμήσεις συστήματος..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Κλείδωμα οθόνης"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Αλλαγή χρήστη"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Αποσύνδεση..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Τερματισμός..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Προσωπικός φάκελος"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Σύστημα αρχείων"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Αναζήτηση"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
301
po/es.po
@ -1,20 +1,19 @@
|
||||
# Spanish translation of gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Jorge González <jorgegonz@svn.gnome.org>, 2009.
|
||||
# Jorge González <jorgegonz@svn.gnome.org>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-09-11 21:48+0000\n"
|
||||
"PO-Revision-Date: 2009-09-12 14:40+0200\n"
|
||||
"POT-Creation-Date: 2010-02-15 13:36+0000\n"
|
||||
"PO-Revision-Date: 2010-02-15 21:45+0100\n"
|
||||
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
|
||||
"Language-Team: Español <gnome-es-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
@ -25,153 +24,223 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestión de ventanas e inicio de aplicaciones"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:269
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONES"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:452
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Ventana nueva"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Quitar de los favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Añadir a los favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arrastrar aquí para añadir a los favoritos"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "Se ha añadido %s a sus favoritos."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
#| msgid "Remove from Favorites"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Se ha quitado %s de sus favoritos."
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Buscar…"
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "Browse"
|
||||
msgstr "Examine"
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Buscando…"
|
||||
|
||||
#: ../js/ui/dash.js:536
|
||||
msgid "(see all)"
|
||||
msgstr "(ver todo)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:736 ../js/ui/dash.js:792
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONES"
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "No se encontró ningún resultado coincidente."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:756
|
||||
msgid "PLACES"
|
||||
msgstr "LUGARES"
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "LUGARES Y DISPOSITIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:802
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECIENTES"
|
||||
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ELEMENTOS RECIENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:782 ../js/ui/dash.js:907
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTADOS DE LA BÚSQUEDA"
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
msgid "No extensions installed"
|
||||
msgstr "No hay extensiones instaladas"
|
||||
|
||||
#: ../js/ui/dash.js:797
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Enabled"
|
||||
msgstr "Activado"
|
||||
|
||||
#: ../js/ui/runDialog.js:90
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Disabled"
|
||||
msgstr "Desactivado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Out of date"
|
||||
msgstr "Caducado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
msgid "View Source"
|
||||
msgstr "Ver fuente"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "Web Page"
|
||||
msgstr "Página web"
|
||||
|
||||
#: ../js/ui/overview.js:95
|
||||
msgid "Undo"
|
||||
msgstr "Deshacer"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar a…"
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduzca un comando:"
|
||||
|
||||
#: ../src/shell-global.c:799
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Falló la ejecución de «%s»:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Ocupado"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Invisible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Información de la cuenta…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencias del sistema…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear la pantalla"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Salir…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar…"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicaciones"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos recientes"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hace menos de un minuto"
|
||||
|
||||
#: ../src/shell-global.c:802
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Hace %d minuto"
|
||||
msgstr[1] "Hace %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:805
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Hace %d hora"
|
||||
msgstr[1] "Hace %d horas"
|
||||
|
||||
#: ../src/shell-global.c:808
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Hace %d día"
|
||||
msgstr[1] "Hace %d días"
|
||||
|
||||
#: ../src/shell-global.c:811
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Hace %d semana"
|
||||
msgstr[1] "Hace %d semanas"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Desconocido"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "No se puede bloquear la pantalla: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"No se puede establecer temporalmente el salvapantallas a oscurecer pantalla: "
|
||||
"%s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "No se puede salir de la sesión: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Información de la cuenta…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencias del sistema…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear la pantalla"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Salir…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar…"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Carpeta personal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Sistema de archivos"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
@ -180,11 +249,43 @@ msgstr "Buscar"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "LUGARES"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Frecuentes"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Más"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(ver todo)"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "RESULTADOS DE LA BÚSQUEDA"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Desconocido"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "No se puede bloquear la pantalla: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "No se puede establecer temporalmente el salvapantallas a oscurecer "
|
||||
#~ "pantalla: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "No se puede salir de la sesión: %s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Examine"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Encuentre aplicaciones o documentos"
|
||||
|
||||
|
226
po/fi.po
Normal file
@ -0,0 +1,226 @@
|
||||
# gnome-shell Finnish translation
|
||||
# Copyright (C) 2009 Timo Jyrinki
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Timo Jyrinki <timo.jyrinki@iki.fi>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-11-04 11:16+0200\n"
|
||||
"PO-Revision-Date: 2009-11-04 11:16+0200\n"
|
||||
"Last-Translator: Timo Jyrinki <timo.jyrinki@iki.fi>\n"
|
||||
"Language-Team: Finnish <gnome-fi-laatu@lists.sourceforge.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Ikkunanhallinta ja sovelluksien käynnistäminen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:332
|
||||
msgid "Frequent"
|
||||
msgstr "Usein käytetyt"
|
||||
|
||||
#: ../js/ui/appDisplay.js:867
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Raahaa tähän lisätäksesi suosikkeihin"
|
||||
|
||||
#: ../js/ui/appIcon.js:426
|
||||
msgid "New Window"
|
||||
msgstr "Uusi ikkuna"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Poista suosikeista"
|
||||
|
||||
#: ../js/ui/appIcon.js:431
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Lisää suosikkeihin"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Etsi..."
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Lisää"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(näytä kaikki)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "SOVELLUKSET"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:745
|
||||
msgid "PLACES"
|
||||
msgstr "SIJAINNIT"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "VIIMEISIMMÄT ASIAKIRJAT"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "HAKUTULOKSET"
|
||||
|
||||
#: ../js/ui/dash.js:792
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ASETUKSET"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "Toiminnot"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %I.%M"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "Yhdistä..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Syötä komento:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%I.%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Sovellukset"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Viimeisimmät asiakirjat"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Alle minuutti sitten"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuutti sitten"
|
||||
msgstr[1] "%d minuuttia sitten"
|
||||
|
||||
#: ../src/shell-global.c:827
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d tunti sitten"
|
||||
msgstr[1] "%d tuntia sitten"
|
||||
|
||||
#: ../src/shell-global.c:830
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d päivä sitten"
|
||||
msgstr[1] "%d päivää sitten"
|
||||
|
||||
#: ../src/shell-global.c:833
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d viikko sitten"
|
||||
msgstr[1] "%d viikkoa sitten"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Tuntematon"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Näyttöä ei voi lukita: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Käyttäjätilin tiedot..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Sivupalkki"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Järjestelmän asetukset"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lukitse näyttö"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Vaihda käyttäjää"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Kirjaudu ulos..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Sammuta..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Kotikansio"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Tiedostojärjestelmä"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Haku"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
102
po/fr.po
@ -6,13 +6,13 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Project-Id-Version: gnome-shell master fr\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-09-09 21:30+0000\n"
|
||||
"PO-Revision-Date: 2009-09-11 21:40+0200\n"
|
||||
"Last-Translator: Mathieu Bridon <bochecha@fedoraproject.org>\n"
|
||||
"Language-Team: GNOME French Team\n"
|
||||
"POT-Creation-Date: 2009-11-13 17:44+0000\n"
|
||||
"PO-Revision-Date: 2009-12-05 16:43+0100\n"
|
||||
"Last-Translator: Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>\n"
|
||||
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@ -26,80 +26,115 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestion des fenêtres et lancement des applications"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:269
|
||||
msgid "Activities"
|
||||
msgstr "Activités"
|
||||
#: ../js/ui/appDisplay.js:696
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Glisser ici pour ajouter aux favoris"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:452
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#: ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "Nouvelle fenêtre"
|
||||
|
||||
#: ../js/ui/dash.js:255
|
||||
#: ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Enlever des favoris"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Ajouter aux favoris"
|
||||
|
||||
#: ../js/ui/dash.js:237
|
||||
msgid "Find..."
|
||||
msgstr "Rechercher..."
|
||||
|
||||
#: ../js/ui/dash.js:372
|
||||
msgid "Browse"
|
||||
msgstr "Parcourir"
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "(see all)"
|
||||
msgstr "(tout afficher)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:700 ../js/ui/dash.js:756 ../js/ui/dash.js:887
|
||||
#: ../js/ui/dash.js:656 ../js/ui/dash.js:718
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APPLICATIONS"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:720
|
||||
#: ../js/ui/dash.js:676 ../js/ui/dash.js:733
|
||||
msgid "PLACES"
|
||||
msgstr "RACCOURCIS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:727 ../js/ui/dash.js:768 ../js/ui/dash.js:861
|
||||
#: ../js/ui/dash.js:683 ../js/ui/dash.js:728
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTS RÉCENTS"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:746 ../js/ui/dash.js:850 ../js/ui/dash.js:876
|
||||
#: ../js/ui/dash.js:708 ../js/ui/dash.js:898
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RÉSULTATS DE LA RECHERCHE"
|
||||
|
||||
#: ../js/ui/runDialog.js:90
|
||||
#: ../js/ui/dash.js:723
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PRÉFÉRENCES"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "Activités"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:84
|
||||
msgid "Connect to..."
|
||||
msgstr "Connexion à..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Veuillez saisir une commande :"
|
||||
|
||||
#: ../src/shell-global.c:799
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Exécution de « %s » impossible :"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Applications"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documents récents"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Il y a moins d'une minute"
|
||||
|
||||
#: ../src/shell-global.c:802
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Il y a %d minute"
|
||||
msgstr[1] "Il y a %d minutes"
|
||||
|
||||
#: ../src/shell-global.c:805
|
||||
#: ../src/shell-global.c:827
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Il y a %d heure"
|
||||
msgstr[1] "Il y a %d heures"
|
||||
|
||||
#: ../src/shell-global.c:808
|
||||
#: ../src/shell-global.c:830
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Il y a %d jour"
|
||||
msgstr[1] "Il y a %d jours"
|
||||
|
||||
#: ../src/shell-global.c:811
|
||||
#: ../src/shell-global.c:833
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -180,3 +215,6 @@ msgstr "Recherche"
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s : %2$s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Parcourir"
|
||||
|
240
po/gl.po
@ -2,19 +2,22 @@
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Fran Diéguez <fran.dieguez@mabishu.com>, 2009.
|
||||
#
|
||||
# Anton Meixome <certima@certima.net>, 2009.
|
||||
# Antón Méixome <meixome@certima.net>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-09-15 23:06+0200\n"
|
||||
"PO-Revision-Date: 2009-09-10 22:32+0100\n"
|
||||
"Last-Translator: Fran Diéguez <fran.dieguez@glug.es>\n"
|
||||
"Language-Team: Galician <gnome@mancomun.org>\n"
|
||||
"POT-Creation-Date: 2009-12-28 17:07+0100\n"
|
||||
"PO-Revision-Date: 2009-12-28 08:11+0100\n"
|
||||
"Last-Translator: Antón Méixome <meixome@certima.net>\n"
|
||||
"Language-Team: Galician Proxecto Trasno <proxecto@trasno.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: gl\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Virtaal 0.4.0\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
@ -22,154 +25,133 @@ msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Xestor de xanelas e lanzado de aplicativos"
|
||||
msgstr "Xestor de xanelas e lanzamento de aplicativos"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:269
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:858
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:452
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
#: ../js/ui/appDisplay.js:707 ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "Xanela nova"
|
||||
|
||||
#: ../js/ui/appDisplay.js:711 ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Eliminar de Favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:712 ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Engadir a Favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1064
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arrastra aquí para engadir favoritos"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Buscar..."
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "Browse"
|
||||
msgstr "Explorar"
|
||||
|
||||
#: ../js/ui/dash.js:536
|
||||
msgid "(see all)"
|
||||
msgstr "(ver todos)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:753 ../js/ui/dash.js:809
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
#: ../js/ui/dash.js:437
|
||||
msgid "Searching..."
|
||||
msgstr "Buscando..."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:773
|
||||
#: ../js/ui/dash.js:878 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES"
|
||||
msgstr "LUGARES"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:780 ../js/ui/dash.js:819
|
||||
#: ../js/ui/dash.js:885
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:799 ../js/ui/dash.js:931
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTADOS DA BÚSQUEDA"
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:227
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#: ../js/ui/dash.js:814
|
||||
msgid "PREFERENCES"
|
||||
msgstr ""
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:440
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar con..."
|
||||
|
||||
#: ../js/ui/runDialog.js:235
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Insira unha orde:"
|
||||
|
||||
#: ../src/shell-global.c:799
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Menos de un minuto"
|
||||
#: ../js/ui/runDialog.js:351
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Fallou a execución de %s"
|
||||
|
||||
#: ../src/shell-global.c:802
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicativos"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos recentes"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hai menos dun minuto"
|
||||
|
||||
#: ../src/shell-global.c:893
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "fai %d minuto"
|
||||
msgstr[1] "fai %d minutos"
|
||||
msgstr[0] "hai %d minuto"
|
||||
msgstr[1] "hai %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:805
|
||||
#: ../src/shell-global.c:896
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "fai %d hora"
|
||||
msgstr[1] "fai %d horas"
|
||||
msgstr[0] "hai %d hora"
|
||||
msgstr[1] "hai %d horas"
|
||||
|
||||
#: ../src/shell-global.c:808
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "fai %d día"
|
||||
msgstr[1] "fai %d días"
|
||||
msgstr[0] "hai %d día"
|
||||
msgstr[1] "hai %d días"
|
||||
|
||||
#: ../src/shell-global.c:811
|
||||
#: ../src/shell-global.c:902
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "fai %d semana"
|
||||
msgstr[1] "fai %d semanas"
|
||||
msgstr[0] "hai %d semana"
|
||||
msgstr[1] "hai %d semanas"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Descoñecido"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Non foi posíbel bloquear a pantalla: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Non foi posíbel establecer o salvapantallas a unha pantalla en branco: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Non foi posíbel pechar a sesión: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Información da conta..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferenzas do sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear pantalla"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Pechar sesión..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Cartafol persoal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Sistema de ficheiros"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
@ -178,11 +160,55 @@ msgstr "Buscar"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "RESULTADOS DA BUSCA"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Descoñecido"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Non foi posíbel bloquear a pantalla: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Non foi posíbel estabelecer temporalmente o salvapantallas a unha "
|
||||
#~ "pantalla en branco: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Non foi posíbel pechar a sesión: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Información da conta..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra lateral"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Preferencias do sistema..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Bloquear pantalla"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Cambiar de usuario"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Saír da sesión..."
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Apagar..."
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Explorar"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(ver todos)"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Atopar aplicativos ou documentos"
|
||||
|
||||
|
215
po/he.po
Normal file
@ -0,0 +1,215 @@
|
||||
# Hebrew translation for gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# liel <lielft@gmail.com>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-11-13 17:44+0000\n"
|
||||
"PO-Revision-Date: 2009-11-28 17:33+0200\n"
|
||||
"Last-Translator: Liel Fridman <lielft@gmail.com>\n"
|
||||
"Language-Team: Hebrew <he@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "מעטפת GNOME"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "ניהול חלונות והרצת יישומים"
|
||||
|
||||
#: ../js/ui/appDisplay.js:696
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "יש לגרור פריטים לכאן כדי להוסיף מועדפים"
|
||||
|
||||
#: ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "חלון חדש"
|
||||
|
||||
#: ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "הסר מהמועדפים"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "הוסף למועדפים"
|
||||
|
||||
#: ../js/ui/dash.js:237
|
||||
msgid "Find..."
|
||||
msgstr "חפש..."
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:656 ../js/ui/dash.js:718
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "יישומים"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:676 ../js/ui/dash.js:733
|
||||
msgid "PLACES"
|
||||
msgstr "מקומות"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:683 ../js/ui/dash.js:728
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "מסמכים אחרונים"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:708 ../js/ui/dash.js:898
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "תוצאות חיפוש"
|
||||
|
||||
#: ../js/ui/dash.js:723
|
||||
msgid "PREFERENCES"
|
||||
msgstr "העדפות"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "פעילויות"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:84
|
||||
msgid "Connect to..."
|
||||
msgstr "התחבר אל..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "נא להזין פקודה:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "ההרצה של '%s' נכשלה:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "יישומים"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "מסמכים אחרונים"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "לפני פחות מדקה"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "לפני דקה"
|
||||
msgstr[1] "לפני %d דקות"
|
||||
|
||||
#: ../src/shell-global.c:827
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "לפני שעה"
|
||||
msgstr[1] "לפני %d שעות"
|
||||
|
||||
#: ../src/shell-global.c:830
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "לפני יום"
|
||||
msgstr[1] "לפני %d ימים"
|
||||
|
||||
#: ../src/shell-global.c:833
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "לפני שבוע"
|
||||
msgstr[1] "לפני %d שבועות"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "לא ידוע"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "לא ניתן לנעול את המסך: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "לא ניתן זמנית לקבוע שומר מסך כמסך שחור: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "לא ניתן להתנתק: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "מידע על המשתמש..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "סרגל צד"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "העדפות מערכת..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "נעילת המסך"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "החלף משתמש"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "ניתוק..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "כיבוי..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "תיקיית הבית"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "מערכת הקבצים"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "חפש"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
348
po/hu.po
@ -2,13 +2,13 @@
|
||||
# Copyright 2009. Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Gabor Kelemen <kelemeng at gnome dot hu>, 2009.
|
||||
# Gabor Kelemen <kelemeng at gnome dot hu>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-15 11:35+0200\n"
|
||||
"PO-Revision-Date: 2009-08-15 11:35+0200\n"
|
||||
"POT-Creation-Date: 2010-02-16 10:04+0100\n"
|
||||
"PO-Revision-Date: 2010-02-16 10:10+0100\n"
|
||||
"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
|
||||
"Language-Team: Hungarian <gnome at fsf dot hu>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -17,135 +17,6 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Tevékenységek"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a., %k.%M"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Alkalmazások vagy dokumentumok keresése"
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Tallózás"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ALKALMAZÁSOK"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "LEGUTÓBBI DOKUMENTUMOK"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "HELYEK"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Adjon meg egy parancsot:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Kezelő"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "A felhasználót kezelő felhasználókezelő objektum."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Kevesebb, mint egy perce"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d perce"
|
||||
msgstr[1] "%d perce"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d órája"
|
||||
msgstr[1] "%d órája"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d napja"
|
||||
msgstr[1] "%d napja"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d hete"
|
||||
msgstr[1] "%d hete"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Ismeretlen"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nem lehet zárolni a képernyőt: %s "
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Átmenetileg nem lehet beállítani a képernyővédőt a képernyő elsötétítésére: %"
|
||||
"s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nem lehet kijelentkezni: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Fiókinformációk…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Oldalsáv"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Rendszerbeállítások…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Képernyő zárolása"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Felhasználóváltás"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Kijelentkezés…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Leállítás…"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
@ -154,17 +25,222 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Ablakkezelés és alkalmazásindítás"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ALKALMAZÁSOK"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "BEÁLLÍTÁSOK"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Új ablak"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Eltávolítás a Kedvencek közül"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Hozzáadás a Kedvencekhez"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Ide húzással kedvenceket vehet fel"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s felvéve a Kedvencek közé."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s eltávolítva a Kedvencek közül"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Keresés…"
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Keresés…"
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "Nincs találat."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "HELYEK ÉS ESZKÖZÖK"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "LEGUTÓBBI ELEMEK"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
msgid "No extensions installed"
|
||||
msgstr "Nincsenek kiterjesztések telepítve"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Enabled"
|
||||
msgstr "Engedélyezve"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Disabled"
|
||||
msgstr "Tiltva"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Error"
|
||||
msgstr "Hiba"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Out of date"
|
||||
msgstr "Elavult"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
msgid "View Source"
|
||||
msgstr "Forrás megtekintése"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "Web Page"
|
||||
msgstr "Weblap"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
msgid "Undo"
|
||||
msgstr "Visszavonás"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Tevékenységek"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %p %l.%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Kapcsolódás…"
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Adjon meg egy parancsot:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "„%s” végrehajtása meghiúsult:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Elérhető"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Elfoglalt"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Láthatatlan"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Fiókinformációk…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Oldalsáv"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Rendszerbeállítások…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Képernyő zárolása"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Felhasználóváltás"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Kijelentkezés…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Leállítás…"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%k.%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Alkalmazások"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Legutóbbi dokumentumok"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Kevesebb, mint egy perce"
|
||||
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d perce"
|
||||
msgstr[1] "%d perce"
|
||||
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d órája"
|
||||
msgstr[1] "%d órája"
|
||||
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d napja"
|
||||
msgstr[1] "%d napja"
|
||||
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d hete"
|
||||
msgstr[1] "%d hete"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Saját mappa"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Fájlrendszer"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Oldalsáv"
|
||||
|
||||
@ -173,7 +249,7 @@ msgstr "Oldalsáv"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
249
po/it.po
@ -1,15 +1,14 @@
|
||||
# Italian translations for gnome-shell package.
|
||||
# Copyright (C) 2009 the gnome-shell copyright holder
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Milo Casagrande <milo@ubuntu.com>, 2009.
|
||||
#
|
||||
# Milo Casagrande <milo@ubuntu.com>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-09-05 00:19+0000\n"
|
||||
"PO-Revision-Date: 2009-09-06 18:31+0200\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-02-10 22:30+0100\n"
|
||||
"PO-Revision-Date: 2010-02-10 22:31+0100\n"
|
||||
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
|
||||
"Language-Team: Italian <tp@lists.linux.it>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -25,151 +24,136 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestione finestre e avvio applicazioni"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "Preferenze"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Nuova finestra"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Rimuovi dai preferiti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Aggiungi ai preferiti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Trascinare qui per aggiungere ai preferiti"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Trova..."
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Ricerca..."
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "Nessun risultato."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "Risorse e dispositivi"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "Elementi recenti"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Attività"
|
||||
|
||||
# (ndt) proviamo col k, se non funge, sappiamo il perché...
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
#: ../js/ui/panel.js:557
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k.%M"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
msgid "Find..."
|
||||
msgstr "Trova..."
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Connetti a..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Esplora"
|
||||
|
||||
#: ../js/ui/dash.js:511
|
||||
msgid "(see all)"
|
||||
msgstr "(vedi tutto)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:705 ../js/ui/dash.js:761 ../js/ui/dash.js:893
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:725
|
||||
msgid "PLACES"
|
||||
msgstr "Risorse"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:732 ../js/ui/dash.js:773 ../js/ui/dash.js:867
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "Documenti recenti"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:751 ../js/ui/dash.js:856 ../js/ui/dash.js:882
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "Risultati ricerca"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Inserire un comando:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Esecuzione di «%s» non riuscita:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%k.%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documenti recenti"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Meno di un minuto fa"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuto fa"
|
||||
msgstr[1] "%d minuti fa"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ora fa"
|
||||
msgstr[1] "%d ore fa"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d giorno fa"
|
||||
msgstr[1] "%d giorni fa"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d settimana fa"
|
||||
msgstr[1] "%d settimane fa"
|
||||
|
||||
# (ndt) valutare se vada al femminile
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Sconosciuto"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Impossibile bloccare lo schermo: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Impossibile impostare temporaneamente il salva schermo a schermo nero: %s "
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Impossibile terminare la sessione: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informazioni account..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra laterale"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferenze di sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Blocca schermo"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambia utente"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Termina sessione..."
|
||||
|
||||
# (ndt) da valutare... pare che ora anche Windows usi 'Arresta...'...
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Spegni..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Cartella home"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "File system"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Cerca"
|
||||
|
||||
@ -179,19 +163,58 @@ msgstr "Cerca"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
# (ndt) è da valutare se è troppo lunga, è in una casella di ricerca
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Trova programmi e documenti"
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "Risorse"
|
||||
|
||||
# (ndt) no idea...
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Manager"
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Frequente"
|
||||
|
||||
# (ndt) no idea...
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "L'oggetto user manager che controlla questo utente."
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Altro"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(vedi tutto)"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "Risultati ricerca"
|
||||
|
||||
# (ndt) valutare se vada al femminile
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Sconosciuto"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Impossibile bloccare lo schermo: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Impossibile impostare temporaneamente il salva schermo a schermo nero: %s "
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Impossibile terminare la sessione: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Informazioni account..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra laterale"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Preferenze di sistema..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Blocca schermo"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Cambia utente"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Termina sessione..."
|
||||
|
||||
# (ndt) da valutare... pare che ora anche Windows usi 'Arresta...'...
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Spegni..."
|
||||
|
182
po/nb.po
@ -1,14 +1,14 @@
|
||||
# Norwegian bokmål translation of gnome-shell.
|
||||
# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Kjartan Maraas <kmaraas@broadpark.no>, 2009.
|
||||
# Kjartan Maraas <kmaraas@broadpark.no>, 2009-2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 0.4\n"
|
||||
"Project-Id-Version: gnome-shell 2.28.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-21 12:36+0200\n"
|
||||
"PO-Revision-Date: 2009-08-21 12:44+0200\n"
|
||||
"POT-Creation-Date: 2010-02-14 13:45+0100\n"
|
||||
"PO-Revision-Date: 2010-02-14 13:46+0100\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@broadpark.no>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,138 +24,140 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Vindushåndtering og oppstart av programmer"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Finn programmer eller dokumenter"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Bla gjennom"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:504 ../js/ui/dash.js:577
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMMER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:509 ../js/ui/dash.js:604
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SISTE DOKUMENTER"
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "BRUKERVALG"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Nytt vindu"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Fjern fra favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Legg til i favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Dra hit for å legge til favoritter"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Finn..."
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Søker..."
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "Ingen treff."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:597
|
||||
msgid "PLACES"
|
||||
msgstr "STEDER"
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "STEDER & ENHETER"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "SISTE OPPFØRINGER"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Koble til..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Oppgi en kommando:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Kjøring av «%s» feilet:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programmer"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Siste dokumenter"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre enn ett minutt siden"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minutt siden"
|
||||
msgstr[1] "%d minutter siden"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d time siden"
|
||||
msgstr[1] "%d timer siden"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag siden"
|
||||
msgstr[1] "%d dager siden"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d uke siden"
|
||||
msgstr[1] "%d uker siden"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Ukjent"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Kan ikke låse skjermen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Kan ikke sette skjermsparer midlertidig til blank skjerm: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Kan ikke logge ut: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Kontoinformasjon..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Sidelinje"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Brukervalg for systemet..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lås skjerm"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Bytt bruker"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Logg ut..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Slå av..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Hjemmemappe"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Filsystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Søk"
|
||||
|
||||
@ -164,7 +166,7 @@ msgstr "Søk"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
95
po/pa.po
@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
|
||||
"cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-08-31 22:31+0000\n"
|
||||
"PO-Revision-Date: 2009-09-01 06:51+0530\n"
|
||||
"POT-Creation-Date: 2009-10-09 22:10+0000\n"
|
||||
"PO-Revision-Date: 2009-10-15 06:18+0530\n"
|
||||
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
|
||||
"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -26,80 +26,123 @@ msgstr "ਗਨੋਮ ਸ਼ੈਲ"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "ਵਿੰਡੋ ਪਰਬੰਧ ਅਤੇ ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਓ"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "ਸਰਗਰਮੀਆਂ"
|
||||
#: ../js/ui/appDisplay.js:335
|
||||
msgid "Frequent"
|
||||
msgstr "ਅਕਸਰ"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
#: ../js/ui/appIcon.js:462
|
||||
msgid "New Window"
|
||||
msgstr "ਨਵੀਂ ਵਿੰਡੋ"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
#: ../js/ui/appIcon.js:475
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "ਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"
|
||||
|
||||
#: ../js/ui/appIcon.js:476
|
||||
msgid "Add to Favorites"
|
||||
msgstr "ਪਸੰਦ 'ਚ ਸ਼ਾਮਲ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "ਖੋਜ..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "ਝਲਕ"
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "ਹੋਰ"
|
||||
|
||||
#: ../js/ui/dash.js:451
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(ਸਭ ਵੇਖੋ)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:633 ../js/ui/dash.js:681
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:653
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "ਥਾਵਾਂ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:660 ../js/ui/dash.js:692
|
||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:679
|
||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ਖੋਜ ਨਤੀਜੇ"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ਪਸੰਦ"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:272
|
||||
msgid "Activities"
|
||||
msgstr "ਸਰਗਰਮੀਆਂ"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:464
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "...ਨਾਲ ਕੁਨੈਕਟ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "ਕਮਾਂਡ ਦਿਓ ਜੀ:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:162
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:316
|
||||
msgid "Applications"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#: ../js/ui/widget.js:341
|
||||
msgid "Recent Documents"
|
||||
msgstr "ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "ਇੱਕ ਮਿੰਟ ਤੋਂ ਘੱਟ ਚਿਰ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:815
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:818
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:821
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -180,3 +223,5 @@ msgstr "ਖੋਜ"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "ਝਲਕ"
|
||||
|
169
po/pt_BR.po
@ -2,91 +2,139 @@
|
||||
# Copyright (C) 2009 THE gnome-shell'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Og Maciel <ogmaciel@gnome.org>, 2009.
|
||||
# Rodrigo Flores <mail@rodrigoflores.org>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-14 17:53-0400\n"
|
||||
"PO-Revision-Date: 2009-08-14 17:53-0400\n"
|
||||
"Last-Translator: Og Maciel <ogmaciel@gnome.org>\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-11-12 21:33+0000\n"
|
||||
"PO-Revision-Date: 2009-11-14 11:53-0200\n"
|
||||
"Last-Translator: Amanda Magalhães <amandinhakee@gmail.com>\n"
|
||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gerenciamento de janelas e lançador de aplicações"
|
||||
|
||||
#: ../js/ui/appDisplay.js:696
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arraste até aqui para adicionar aos favoritos"
|
||||
|
||||
#: ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "Nova janela"
|
||||
|
||||
#: ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Remover dos Favoritos"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adicionar aos Favoritos"
|
||||
|
||||
#: ../js/ui/dash.js:237
|
||||
msgid "Find..."
|
||||
msgstr "Procurar..."
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:656 ../js/ui/dash.js:718
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:676 ../js/ui/dash.js:733
|
||||
msgid "PLACES"
|
||||
msgstr "LOCAIS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:683 ../js/ui/dash.js:728
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:708 ../js/ui/dash.js:898
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTADOS DA BUSCA"
|
||||
|
||||
#: ../js/ui/dash.js:723
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERÊNCIAS"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "Atividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Localizar aplicativos ou documentos"
|
||||
#: ../js/ui/placeDisplay.js:84
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar ao..."
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Navegar"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "LOCAIS"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Por favor digite um comando:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Gerenciador"
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "A execução de \"%s\" falhou:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "O objeto gerenciador de usuários que controla este usuário."
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicações"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos Recentes"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Menos de um minuto atrás"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuto atrás"
|
||||
msgstr[1] "%d minutos atrás"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#: ../src/shell-global.c:827
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d hora atrás"
|
||||
msgstr[1] "%d horas atrás"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#: ../src/shell-global.c:830
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dia atrás"
|
||||
msgstr[1] "%d dias atrás"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#: ../src/shell-global.c:833
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -142,3 +190,42 @@ msgstr "Encerrar sessão..."
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Desligar..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Pasta home"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Sistema de arquivos"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Procurar"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Navegar"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(veja todos)"
|
||||
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Localizar aplicativos ou documentos"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Gerenciador"
|
||||
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "O objeto gerenciador de usuários que controla este usuário."
|
||||
|
232
po/ro.po
Normal file
@ -0,0 +1,232 @@
|
||||
# Romanian translation for gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Lucian Adrian Grijincu <lucian.grijincu@gmail.com>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-10-28 22:25+0200\n"
|
||||
"PO-Revision-Date: 2009-10-28 22:33+0200\n"
|
||||
"Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
|
||||
"Language-Team: Romanian <gnomero-list@lists.sourceforge.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
|
||||
"20)) ? 1 : 2);;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Administrare de ferestre și lansare de aplicații"
|
||||
|
||||
#: ../js/ui/appDisplay.js:332
|
||||
msgid "Frequent"
|
||||
msgstr "Frecvent"
|
||||
|
||||
#: ../js/ui/appDisplay.js:867
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Adăugați aici favorite cu mausul"
|
||||
|
||||
#: ../js/ui/appIcon.js:426
|
||||
msgid "New Window"
|
||||
msgstr "Fereastră nouă"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Șterge din favorite"
|
||||
|
||||
#: ../js/ui/appIcon.js:431
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adaugă la favorite"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Caută..."
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Mai multe"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(arată tot)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APPLICAȚII"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:745
|
||||
msgid "PLACES"
|
||||
msgstr "LOCAȚII"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTE RECENTE"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "REZULTATELE CĂUTĂRII"
|
||||
|
||||
#: ../js/ui/dash.js:792
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERINȚE"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
msgid "Activities"
|
||||
msgstr "Activități"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectare la..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduceți o comandă:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Execuția comenzii „%s” a eșuat:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicații"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documente recente"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "În ultimul minut"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "acum un minut"
|
||||
msgstr[1] "acum %d minute"
|
||||
msgstr[2] "acum %d de minute"
|
||||
|
||||
#: ../src/shell-global.c:827
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "acum o oră"
|
||||
msgstr[1] "acum %d ore"
|
||||
msgstr[2] "acum %d de ore"
|
||||
|
||||
#: ../src/shell-global.c:830
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "acum o zi"
|
||||
msgstr[1] "acum %d zile"
|
||||
msgstr[2] "acum %d de zile"
|
||||
|
||||
#: ../src/shell-global.c:833
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "acum o săptămână"
|
||||
msgstr[1] "acum %d săptămâni"
|
||||
msgstr[2] "acum %d de săptămâni"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Necunoscut"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nu s-a putut bloca ecranul: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Nu s-a putut folosi temporar un ecran gol pentru economizorul de "
|
||||
"ecran: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nu se poate ieși din sesiune: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informații despre cont..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Bară laterală"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferințe de sistem..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Blocare ecran"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Alt utilizator"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Ieșire..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Oprire..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Dosar personal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Sistem de fișiere"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Caută"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
233
po/ru.po
Normal file
@ -0,0 +1,233 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Andrey Korzinev <fellrond@gmail.com>, 2009.
|
||||
# Sergey V. Kovylov <serejka@gmail.com>, 2009.
|
||||
# Marina Zhurakhinskaya <marinaz@redhat.com>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-10-09 00:27-0400\n"
|
||||
"PO-Revision-Date: 2009-10-09 00:27-0400\n"
|
||||
"Last-Translator: Marina Zhurakhinskaya <marinaz@redhat.com>\n"
|
||||
"Language-Team: Russian <gnome-cyr@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
|
||||
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Управление окнами и запуск приложений"
|
||||
|
||||
#: ../js/ui/appDisplay.js:335
|
||||
msgid "Frequent"
|
||||
msgstr "Часто используемые"
|
||||
|
||||
#: ../js/ui/appIcon.js:462
|
||||
msgid "New Window"
|
||||
msgstr "Новое окно"
|
||||
|
||||
#: ../js/ui/appIcon.js:475
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Удалить из избранного"
|
||||
|
||||
#: ../js/ui/appIcon.js:476
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Добавить в избранное"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Найти…"
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Ещё"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
#: "(увидеть все)" does not fit when it is next to "НЕДАВНИЕ ДОКУМЕНТЫ", so I'm just using "(все)"
|
||||
msgid "(see all)"
|
||||
msgstr "(все)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ПРИЛОЖЕНИЯ"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "ПАПКИ И РЕСУРСЫ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "НЕДАВНИЕ ДОКУМЕНТЫ"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "РЕЗУЛЬТАТЫ ПОИСКА"
|
||||
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "НАСТРОЙКИ"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:272
|
||||
#. Another word that was considered was "Обзор", but it was decided that it doesn't give a full sense of the actions
|
||||
#. possible when in the overview mode.
|
||||
msgid "Activities"
|
||||
msgstr "Действия"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:464
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
msgid "Connect to..."
|
||||
msgstr "Соединиться с…"
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Введите команду:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Не удалось выполнить «%s»:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:162
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:316
|
||||
msgid "Applications"
|
||||
msgstr "Приложения"
|
||||
|
||||
#: ../js/ui/widget.js:341
|
||||
msgid "Recent Documents"
|
||||
msgstr "Недавние документы"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Менее минуты назад"
|
||||
|
||||
#: ../src/shell-global.c:815
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d минуту назад"
|
||||
msgstr[1] "%d минуты назад"
|
||||
msgstr[2] "%d минут назад"
|
||||
|
||||
#: ../src/shell-global.c:818
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d час назад"
|
||||
msgstr[1] "%d часа назад"
|
||||
msgstr[2] "%d часов назад"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d день назад"
|
||||
msgstr[1] "%d дня назад"
|
||||
msgstr[2] "%d дней назад"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d неделю назад"
|
||||
msgstr[1] "%d недели назад"
|
||||
msgstr[2] "%d недель назад"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Неизвестно"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Не удалось заблокировать экран: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Не удалось временно установить пустую экранную заставку: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Не удалось завершить сеанс пользователя: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Информация о пользователе…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Боковая панель"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Системные настройки…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Заблокировать экран"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Сменить пользователя"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Завершить сеанс…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Выключить…"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Домашняя папка"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Файловая система"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
293
po/sl.po
Normal file
@ -0,0 +1,293 @@
|
||||
# Slovenian translation of gnome-shell package.
|
||||
# Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Matej Urbančič <mateju@svn.gnome.org>, 2009 - 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-02-15 17:28+0000\n"
|
||||
"PO-Revision-Date: 2010-02-15 19:03+0100\n"
|
||||
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
|
||||
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: Slovenian\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n"
|
||||
"X-Poedit-Language: Slovenian\n"
|
||||
"X-Poedit-Country: SLOVENIA\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Gnome Lupina"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Upravljanje oken in zaganjanje programov"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252
|
||||
#: ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Programi"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "Možnosti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Novo okno"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Odstrani iz priljubljenih"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Dodaj med priljubljene"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "S potegom na to mesto se izbor doda med priljubljene"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "Program \"%s\" je dodan med priljubljeno."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Program \"%s\" je odstranjen iz priljubljenih."
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Najdi ..."
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Iskanje ..."
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "Ni zadetkov iskanja"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900
|
||||
#: ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "Mesta in naprave"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907
|
||||
#: ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "Nedavni predmeti"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
msgid "No extensions installed"
|
||||
msgstr "Ni nameščenih razširitev"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Enabled"
|
||||
msgstr "Omogočeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Disabled"
|
||||
msgstr "Onemogočeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Error"
|
||||
msgstr "Napaka"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Out of date"
|
||||
msgstr "Zastarelo"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
msgid "View Source"
|
||||
msgstr "Poglej vir"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "Web Page"
|
||||
msgstr "Spletna stran"
|
||||
|
||||
#: ../js/ui/overview.js:95
|
||||
msgid "Undo"
|
||||
msgstr "Razveljavi"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Dejavnosti"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a. %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Povezava z ..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Vnos ukaza:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Izvajanje '%s' je spodletelo:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Razpoložljivo"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Zasedeno"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Nevidno"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Podrobnosti računa ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Stranska vrstica"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Sistemske možnosti ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Zakleni zaslon"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Preklop uporabnika"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Odjava ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Izklopi ..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programi"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Nedavni dokumenti"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Pred manj kot eno minuto"
|
||||
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Pred %d minutami"
|
||||
msgstr[1] "Pred %d minuto"
|
||||
msgstr[2] "Pred %d minutama"
|
||||
msgstr[3] "Pred %d minutami"
|
||||
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Pred %d urami"
|
||||
msgstr[1] "Pred %d uro"
|
||||
msgstr[2] "Pred %d urama"
|
||||
msgstr[3] "Pred %d urami"
|
||||
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Pred %d dnevi"
|
||||
msgstr[1] "Pred %d dnevom"
|
||||
msgstr[2] "Pred %d dnevoma"
|
||||
msgstr[3] "Pred %d dnevi"
|
||||
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Pred %d tedni"
|
||||
msgstr[1] "Pred %d tednom"
|
||||
msgstr[2] "Pred %d tednoma"
|
||||
msgstr[3] "Pred %d tedni"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Domača mapa"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Datotečni sistem"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Poišči"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "Mesta"
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "Rezultati iskanja"
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Neznano"
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Ni mogoče zakleniti zaslona: %s"
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Ni mogoče začasno nastaviti črnega zaslona za ohranjevalnik zaslona: %s"
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Ni se mogoče odjaviti: %s"
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Pogosto"
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Več"
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(poglej vse)"
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Prebrskaj"
|
||||
|
177
po/sr.po
Normal file
@ -0,0 +1,177 @@
|
||||
# Serbian translation for gnome-shell.
|
||||
# Copyright (C) 2010 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Милош Поповић <gpopac@gmail.com>, 2010.
|
||||
# Милош Поповић <gpopac@gmail.com>, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-01-18 20:13+0000\n"
|
||||
"PO-Revision-Date: 2010-01-19 00:14+0000\n"
|
||||
"Last-Translator: Милош Поповић <gpopac@gmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n%"
|
||||
"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Гномова шкољка"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Управник прозорима и покретач програма"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ПРОГРАМИ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ПОСТАВКЕ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:647
|
||||
msgid "New Window"
|
||||
msgstr "Нови прозор"
|
||||
|
||||
#: ../js/ui/appDisplay.js:651
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Уклони из омиљених"
|
||||
|
||||
#: ../js/ui/appDisplay.js:652
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додај у омиљене"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1004
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Превуците овде како би додали у омиљене"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Нађи..."
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
msgid "Searching..."
|
||||
msgstr "Тражим..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "No matching results."
|
||||
msgstr "Ништа није пронађено."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "МЕСТА И УРЕЂАЈИ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "СКОРАШЊЕ СТАВКЕ"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Активности"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Повежи се на..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Унесите наредбу:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Није успело покретање „%s“:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Програми"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Скорашњи документи"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Пре мање од једног минута"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Пре %d минут"
|
||||
msgstr[1] "Пре %d минута"
|
||||
msgstr[2] "Пре %d минута"
|
||||
msgstr[3] "Пре %d минута"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Пре %d сат"
|
||||
msgstr[1] "Пре %d сата"
|
||||
msgstr[2] "Пре %d сата"
|
||||
msgstr[3] "Пре %d сата"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Пре %d дан"
|
||||
msgstr[1] "Пре %d дана"
|
||||
msgstr[2] "Пре %d дана"
|
||||
msgstr[3] "Пре %d дана"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Пре %d недеље"
|
||||
msgstr[1] "Пре %d недеље"
|
||||
msgstr[2] "Пре %d недеље"
|
||||
msgstr[3] "Пре %d недеља"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Лична фасцикла"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Систем датотека"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Тражи"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
177
po/sr@latin.po
Normal file
@ -0,0 +1,177 @@
|
||||
# Serbian translation for gnome-shell.
|
||||
# Copyright (C) 2010 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Miloš Popović <gpopac@gmail.com>, 2010.
|
||||
# Miloš Popović <gpopac@gmail.com>, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-01-18 20:13+0000\n"
|
||||
"PO-Revision-Date: 2010-01-19 00:14+0000\n"
|
||||
"Last-Translator: Miloš Popović <gpopac@gmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n%"
|
||||
"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Gnomova školjka"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Upravnik prozorima i pokretač programa"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMI"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "POSTAVKE"
|
||||
|
||||
#: ../js/ui/appDisplay.js:647
|
||||
msgid "New Window"
|
||||
msgstr "Novi prozor"
|
||||
|
||||
#: ../js/ui/appDisplay.js:651
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Ukloni iz omiljenih"
|
||||
|
||||
#: ../js/ui/appDisplay.js:652
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Dodaj u omiljene"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1004
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Prevucite ovde kako bi dodali u omiljene"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Nađi..."
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
msgid "Searching..."
|
||||
msgstr "Tražim..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "No matching results."
|
||||
msgstr "Ništa nije pronađeno."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "MESTA I UREĐAJI"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "SKORAŠNJE STAVKE"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Aktivnosti"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Poveži se na..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Unesite naredbu:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Nije uspelo pokretanje „%s“:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programi"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Skorašnji dokumenti"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Pre manje od jednog minuta"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Pre %d minut"
|
||||
msgstr[1] "Pre %d minuta"
|
||||
msgstr[2] "Pre %d minuta"
|
||||
msgstr[3] "Pre %d minuta"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Pre %d sat"
|
||||
msgstr[1] "Pre %d sata"
|
||||
msgstr[2] "Pre %d sata"
|
||||
msgstr[3] "Pre %d sata"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Pre %d dan"
|
||||
msgstr[1] "Pre %d dana"
|
||||
msgstr[2] "Pre %d dana"
|
||||
msgstr[3] "Pre %d dana"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Pre %d nedelje"
|
||||
msgstr[1] "Pre %d nedelje"
|
||||
msgstr[2] "Pre %d nedelje"
|
||||
msgstr[3] "Pre %d nedelja"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Lična fascikla"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Sistem datoteka"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Traži"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
184
po/sv.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-09-01 00:31+0200\n"
|
||||
"PO-Revision-Date: 2009-09-01 00:31+0100\n"
|
||||
"POT-Creation-Date: 2009-12-01 23:52+0100\n"
|
||||
"PO-Revision-Date: 2009-12-01 23:53+0100\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
|
||||
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,149 +24,139 @@ msgstr "GNOME-skal"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Fönsterhantering och programstarter"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
#: ../js/ui/appDisplay.js:580
|
||||
#: ../js/ui/appIcon.js:425
|
||||
msgid "New Window"
|
||||
msgstr "Nytt fönster"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:454
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H.%M"
|
||||
#: ../js/ui/appDisplay.js:584
|
||||
#: ../js/ui/appIcon.js:429
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Ta bort från favoriter"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
#: ../js/ui/appDisplay.js:585
|
||||
#: ../js/ui/appIcon.js:430
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Lägg till som favorit"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1029
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Dra hit för att lägga till favorit"
|
||||
|
||||
#: ../js/ui/dash.js:236
|
||||
msgid "Find..."
|
||||
msgstr "Sök..."
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Bläddra"
|
||||
|
||||
#: ../js/ui/dash.js:451
|
||||
msgid "(see all)"
|
||||
msgstr "(se alla)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:633
|
||||
#: ../js/ui/dash.js:681
|
||||
#: ../js/ui/dash.js:620
|
||||
#: ../js/ui/dash.js:682
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAM"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:653
|
||||
#: ../js/ui/dash.js:640
|
||||
#: ../js/ui/dash.js:697
|
||||
msgid "PLACES"
|
||||
msgstr "PLATSER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:660
|
||||
#: ../js/ui/dash.js:647
|
||||
#: ../js/ui/dash.js:692
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SENASTE DOKUMENT"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:679
|
||||
#: ../js/ui/dash.js:672
|
||||
#: ../js/ui/dash.js:862
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "SÖKRESULTAT"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/dash.js:687
|
||||
msgid "PREFERENCES"
|
||||
msgstr "INSTÄLLNINGAR"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:227
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:440
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H.%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:84
|
||||
msgid "Connect to..."
|
||||
msgstr "Anslut till..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Ange ett kommando:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Körning av \"%s\" misslyckades:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H.%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Program"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Senaste dokument"
|
||||
|
||||
#: ../src/shell-global.c:826
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre än en minut sedan"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../src/shell-global.c:829
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minut sedan"
|
||||
msgstr[1] "%d minuter sedan"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:832
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d timme sedan"
|
||||
msgstr[1] "%d timmar sedan"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:835
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag sedan"
|
||||
msgstr[1] "%d dagar sedan"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:838
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d vecka sedan"
|
||||
msgstr[1] "%d veckor sedan"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Okänt"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Kan inte låsa skärmen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Kan inte temporärt ställa in skärmsläckaren till blank skärm: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Kan inte logga ut: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Kontoinformation..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Sidopanel"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systeminställningar..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lås skärmen"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Växla användare"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Logga ut..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Stäng av..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Hemmapp"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Filsystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Sök"
|
||||
|
||||
@ -175,11 +165,37 @@ msgstr "Sök"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(se alla)"
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Okänt"
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Kan inte låsa skärmen: %s"
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr "Kan inte temporärt ställa in skärmsläckaren till blank skärm: %s"
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Kan inte logga ut: %s"
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Kontoinformation..."
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Sidopanel"
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Systeminställningar..."
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Lås skärmen"
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Växla användare"
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Logga ut..."
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Stäng av..."
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Bläddra"
|
||||
#~ msgid "Find apps or documents"
|
||||
#~ msgstr "Hitta program eller dokument"
|
||||
#~ msgid "DOCUMENTS"
|
||||
|
250
po/vi.po
Normal file
@ -0,0 +1,250 @@
|
||||
# Vietnamese translation for gnome-shell.
|
||||
# Copyright (C) 2010 GNOME i18n Project for Vietnamese.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-02-16 19:32+0700\n"
|
||||
"PO-Revision-Date: 2010-02-16 19:36+0700\n"
|
||||
"Last-Translator: Duy <pclouds@gmail.com>\n"
|
||||
"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Quản lý cửa sổ và chạy ứng dụng"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ỨNG DỤNG"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
msgid "PREFERENCES"
|
||||
msgstr "TUỲ THÍCH"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
msgid "New Window"
|
||||
msgstr "Cửa sổ mới"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Bỏ đánh dấu ưa thích"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Đánh dấu ưa thích"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Kéo vào đây để thêm vào danh mục ưa thích"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "Đã được đánh dấu ưa thích cho %s."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Đã bỏ đánh dấu ưa thích cho %s"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Tìm"
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
msgid "Searching..."
|
||||
msgstr "Đang tìm..."
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
msgid "No matching results."
|
||||
msgstr "Không tìm thấy."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ĐỊA ĐIỂM & THIẾT BỊ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "MỤC GẦN ĐÂY"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
msgid "No extensions installed"
|
||||
msgstr "Chưa cài phần mở rộng"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Enabled"
|
||||
msgstr "Bật"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Disabled"
|
||||
msgstr "Tắt"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Error"
|
||||
msgstr "Lỗi"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Out of date"
|
||||
msgstr "Hết hạn"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
msgid "View Source"
|
||||
msgstr "Xem mã nguồn"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "Web Page"
|
||||
msgstr "Trang Web"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
msgid "Undo"
|
||||
msgstr "Hoàn lại"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
msgid "Activities"
|
||||
msgstr "Hoạt động"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
msgid "Connect to..."
|
||||
msgstr "Kết nối đến..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Vui lòng nhập lệnh:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Lỗi thực hiện '%s':"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Có mặt"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Bận"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Giấu mặt"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Thông tin tài khoản..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Thanh bên"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Thiết lập hệ thống..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Khoá màn hình"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Chuyển người dùng"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Đăng xuất..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Tắt máy..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Ứng dụng"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Tài liệu gần đây"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Chưa đến một phút"
|
||||
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d phút trước"
|
||||
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d giờ trước"
|
||||
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ngày trước"
|
||||
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d tuần trước"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Thư mục chính"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Hệ tập tin"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Tìm"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|