Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
33100cd204 | |||
39a8243f27 | |||
5f50922d32 | |||
1137ca0fce | |||
36f3429ad2 | |||
703092f2c9 | |||
fd75c7c7b4 | |||
8abbd5dacb | |||
ed0fa7e1b7 | |||
15f1245927 | |||
25434e42d0 | |||
d6749589e8 | |||
8fea88879a | |||
d9e778f501 | |||
885b6ffaef | |||
4c64920f45 | |||
7369ea6125 | |||
20b7d34577 | |||
6cc4c33b13 | |||
5abf9a0425 | |||
17a0b27109 | |||
2bcdae4d5d | |||
0244c6d5b8 | |||
bc6be40fdd | |||
8c22b58611 |
17
configure.ac
17
configure.ac
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[2.91.5],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[2.91.6],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -66,6 +66,11 @@ GJS_MIN_VERSION=0.7.8
|
||||
MUTTER_MIN_VERSION=2.91.4
|
||||
GTK_MIN_VERSION=2.91.7
|
||||
GIO_MIN_VERSION=2.25.9
|
||||
LIBECAL_REQUIRED=1.6.0
|
||||
LIBEDATASERVER_REQUIRED=1.2.0
|
||||
LIBEDATASERVERUI2_REQUIRED=1.2.0
|
||||
LIBEDATASERVERUI3_REQUIRED=2.91.6
|
||||
|
||||
|
||||
# Collect more than 20 libraries for a prize!
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION
|
||||
@ -113,6 +118,16 @@ PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 2.90.0],
|
||||
AC_SUBST([HAVE_BLUETOOTH],[0])
|
||||
AC_MSG_RESULT([no])])
|
||||
|
||||
# Default to libedataserverui-3.0, but allow falling back to 1.2
|
||||
PKG_CHECK_EXISTS(libedataserverui-3.0,
|
||||
[EDS_API=3.0
|
||||
LIBEDATASERVERUI_REQUIRED=$LIBEDATASERVERUI3_REQUIRED],
|
||||
[EDS_API=1.2
|
||||
LIBEDATASERVERUI_REQUIRED=$LIBEDATASERVERUI2_REQUIRED])
|
||||
PKG_CHECK_MODULES(LIBECAL, libecal-1.2 >= $LIBECAL_REQUIRED libedataserver-1.2 >= $LIBEDATASERVER_REQUIRED libedataserverui-$EDS_API >= $LIBEDATASERVERUI_REQUIRED)
|
||||
AC_SUBST(LIBECAL_CFLAGS)
|
||||
AC_SUBST(LIBECAL_LIBS)
|
||||
|
||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
||||
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
||||
MUTTER_LIB_DIR=`$PKG_CONFIG --variable=libdir mutter-plugins`
|
||||
|
@ -25,6 +25,8 @@ dist_images_DATA = \
|
||||
themedir = $(pkgdatadir)/theme
|
||||
dist_theme_DATA = \
|
||||
theme/add-workspace.svg \
|
||||
theme/calendar-arrow-left.svg \
|
||||
theme/calendar-arrow-right.svg \
|
||||
theme/close-window.svg \
|
||||
theme/close.svg \
|
||||
theme/corner-ripple.png \
|
||||
|
82
data/theme/calendar-arrow-left.svg
Normal file
82
data/theme/calendar-arrow-left.svg
Normal file
@ -0,0 +1,82 @@
|
||||
<?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="16"
|
||||
height="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48+devel r9942 custom"
|
||||
sodipodi:docname="New document 4">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="8.984481"
|
||||
inkscape:cy="5.6224906"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:window-width="930"
|
||||
inkscape:window-height="681"
|
||||
inkscape:window-x="1892"
|
||||
inkscape:window-y="272"
|
||||
inkscape:window-maximized="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17403"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<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"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="path18028"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="84.5"
|
||||
sodipodi:cy="337.5"
|
||||
sodipodi:r1="5"
|
||||
sodipodi:r2="2.5"
|
||||
sodipodi:arg1="0.52359878"
|
||||
sodipodi:arg2="1.5707963"
|
||||
inkscape:flatsided="true"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
|
||||
transform="matrix(0,1.3621708,0.99186247,0,-325.48222,929.32667)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
82
data/theme/calendar-arrow-right.svg
Normal file
82
data/theme/calendar-arrow-right.svg
Normal file
@ -0,0 +1,82 @@
|
||||
<?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="16"
|
||||
height="16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48+devel r9942 custom"
|
||||
sodipodi:docname="arrow-left.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="7.7366092"
|
||||
inkscape:cy="6.4536271"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:window-width="930"
|
||||
inkscape:window-height="681"
|
||||
inkscape:window-x="1892"
|
||||
inkscape:window-y="272"
|
||||
inkscape:window-maximized="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17403"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<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"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="path18028"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="84.5"
|
||||
sodipodi:cy="337.5"
|
||||
sodipodi:r1="5"
|
||||
sodipodi:r2="2.5"
|
||||
sodipodi:arg1="0.52359878"
|
||||
sodipodi:arg2="1.5707963"
|
||||
inkscape:flatsided="true"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
|
||||
transform="matrix(0,1.3621708,-0.99186247,0,342.48324,929.32667)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
@ -674,6 +674,17 @@ StTooltip StLabel {
|
||||
|
||||
/* Calendar popup */
|
||||
|
||||
#calendarArea {
|
||||
/* this is the width of the entire popup */
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.calendar-vertical-separator {
|
||||
-stipple-width: 1px;
|
||||
-stipple-color: #505050;
|
||||
width: 1.5em;
|
||||
}
|
||||
|
||||
#calendarPopup {
|
||||
border-radius: 5px;
|
||||
background: rgba(0,0,0,0.9);
|
||||
@ -686,37 +697,155 @@ StTooltip StLabel {
|
||||
}
|
||||
|
||||
.calendar {
|
||||
spacing-rows: 5px;
|
||||
spacing-columns: 3px;
|
||||
padding: .4em 1.75em;
|
||||
spacing-rows: 0px;
|
||||
spacing-columns: 0px;
|
||||
}
|
||||
|
||||
.calendar-change-month {
|
||||
.calendar-month-label {
|
||||
color: #666666;
|
||||
font-size: 10px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.calendar-change-month:hover {
|
||||
background: #314a6c;
|
||||
border-radius: 5px;
|
||||
.calendar-change-month-back {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url("calendar-arrow-left.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
.calendar-change-month-back:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
.calendar-change-month-back:active {
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
.calendar-change-month:active {
|
||||
background: #213050;
|
||||
border-radius: 5px;
|
||||
.calendar-change-month-forward {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url("calendar-arrow-right.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
.calendar-change-month-forward:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
.calendar-change-month-forward:active {
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
.datemenu-date-label {
|
||||
padding: .4em 1.75em;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.calendar-day-base {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.calendar-day-base:hover {
|
||||
background: #777777;
|
||||
}
|
||||
|
||||
.calendar-day-base:active {
|
||||
background: #555555;
|
||||
}
|
||||
|
||||
.calendar-day-heading {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.calendar-week-number {
|
||||
color: #666666;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Hack used in lieu of border-collapse - see calendar.js */
|
||||
.calendar-day {
|
||||
padding: 1px 2px;
|
||||
border: 1px solid #333333;
|
||||
color: #cccccc;
|
||||
border-top-width: 0;
|
||||
border-left-width: 0;
|
||||
}
|
||||
.calendar-day-top {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
.calendar-day-left {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.calendar-work-day {
|
||||
}
|
||||
|
||||
.calendar-nonwork-day {
|
||||
background-color: rgba(128, 128, 128, .1);
|
||||
}
|
||||
|
||||
.calendar-today {
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
background: #ffffff;
|
||||
color: black;
|
||||
border-radius: 5px;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: #3c3c3c;
|
||||
background-gradient-end: #131313;
|
||||
}
|
||||
|
||||
.calendar-other-month-day {
|
||||
color: #cccccc;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.calendar-day-with-events {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.events-header-vbox {
|
||||
spacing: 10px;
|
||||
}
|
||||
|
||||
.events-header {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.events-header-hbox {
|
||||
spacing: 8px;
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
.events-day-header {
|
||||
font-size: 14px;
|
||||
color: rgba(153, 153, 153, 1.0);
|
||||
}
|
||||
|
||||
.events-day-dayname {
|
||||
font-size: 12px;
|
||||
color: rgba(153, 153, 153, 1.0);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.events-day-time {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.events-day-task {
|
||||
font-size: 12px;
|
||||
color: rgba(153, 153, 153, 1.0);
|
||||
}
|
||||
|
||||
.events-day-name-box {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.events-time-box {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.events-event-box {
|
||||
}
|
||||
|
||||
.url-highlighter {
|
||||
@ -895,10 +1024,6 @@ StTooltip StLabel {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.calendar-calendarweek {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
/* App Switcher */
|
||||
#altTabPopup {
|
||||
padding: 8px;
|
||||
|
@ -19,6 +19,7 @@ nobase_dist_js_DATA = \
|
||||
ui/chrome.js \
|
||||
ui/ctrlAltTab.js \
|
||||
ui/dash.js \
|
||||
ui/dateMenu.js \
|
||||
ui/dnd.js \
|
||||
ui/docDisplay.js \
|
||||
ui/endSessionDialog.js \
|
||||
|
@ -15,7 +15,7 @@ const POPUP_APPICON_SIZE = 96;
|
||||
const POPUP_SCROLL_TIME = 0.10; // seconds
|
||||
const POPUP_FADE_TIME = 0.1; // seconds
|
||||
|
||||
const APP_ICON_HOVER_TIMEOUT = 750; // milliseconds
|
||||
const APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
|
||||
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
||||
|
||||
|
@ -27,6 +27,7 @@ BoxPointer.prototype = {
|
||||
_init: function(arrowSide, binProperties) {
|
||||
this._arrowSide = arrowSide;
|
||||
this._arrowOrigin = 0;
|
||||
this._arrowCorner = null;
|
||||
this.actor = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this._container = new Shell.GenericContainer();
|
||||
@ -212,47 +213,140 @@ BoxPointer.prototype = {
|
||||
cr.translate(rise, 0);
|
||||
}
|
||||
|
||||
cr.moveTo(borderRadius, halfBorder);
|
||||
let [x1, y1] = [halfBorder, halfBorder];
|
||||
let [x2, y2] = [boxWidth - halfBorder, boxHeight - halfBorder];
|
||||
|
||||
cr.moveTo(x1 + borderRadius, y1);
|
||||
if (this._arrowSide == St.Side.TOP) {
|
||||
cr.lineTo(this._arrowOrigin - halfBase, halfBorder);
|
||||
cr.lineTo(this._arrowOrigin, halfBorder - rise);
|
||||
cr.lineTo(this._arrowOrigin + halfBase, halfBorder);
|
||||
}
|
||||
cr.lineTo(boxWidth - borderRadius, halfBorder);
|
||||
if (this._arrowCorner == St.Corner.TOPLEFT) {
|
||||
cr.moveTo(x1, y1);
|
||||
cr.lineTo(x1, y1 - rise);
|
||||
cr.lineTo(x1 + halfBase, y1);
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
} else if (this._arrowCorner == St.Corner.TOPRIGHT) {
|
||||
cr.lineTo(x2 - halfBase, y1);
|
||||
cr.lineTo(x2, y1 - rise);
|
||||
} else if (this._arrowOrigin < (x1 + (borderRadius + halfBase))) {
|
||||
cr.lineTo(this._arrowOrigin, y1);
|
||||
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||
cr.lineTo(this._arrowOrigin + halfBase, y1);
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
} else if (this._arrowOrigin > (x2 - (borderRadius + halfBase))) {
|
||||
cr.lineTo(this._arrowOrigin - halfBase, y1);
|
||||
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||
cr.lineTo(this._arrowOrigin, y1);
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
} else {
|
||||
cr.lineTo(this._arrowOrigin - halfBase, y1);
|
||||
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||
cr.lineTo(this._arrowOrigin + halfBase, y1);
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
}
|
||||
} else
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
|
||||
cr.arc(boxWidth - borderRadius - halfBorder, borderRadius + halfBorder, borderRadius,
|
||||
3*Math.PI/2, Math.PI*2);
|
||||
// top-right corner
|
||||
if (this._arrowCorner != St.Corner.TOPRIGHT)
|
||||
cr.arc(x2 - borderRadius, y1 + borderRadius, borderRadius,
|
||||
3*Math.PI/2, Math.PI*2);
|
||||
|
||||
if (this._arrowSide == St.Side.RIGHT) {
|
||||
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin - halfBase);
|
||||
cr.lineTo(boxWidth - halfBorder + rise, this._arrowOrigin);
|
||||
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin + halfBase);
|
||||
}
|
||||
cr.lineTo(boxWidth - halfBorder, boxHeight - borderRadius);
|
||||
if (this._arrowCorner == St.Corner.TOPRIGHT) {
|
||||
cr.lineTo(x2, y1);
|
||||
cr.lineTo(x2 + rise, y1);
|
||||
cr.lineTo(x2, y1 + halfBase);
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
} else if (this._arrowCorner == St.Corner.BOTTOMRIGHT) {
|
||||
cr.moveTo(x2, y2 - halfBase);
|
||||
cr.lineTo(x2 + rise, y2);
|
||||
} else if (this._arrowOrigin < (y1 + (borderRadius + halfBase))) {
|
||||
cr.lineTo(x2, this._arrowOrigin);
|
||||
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||
cr.lineTo(x2, this._arrowOrigin + halfBase);
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
} else if (this._arrowOrigin > (y2 - (borderRadius + halfBase))) {
|
||||
cr.lineTo(x2, this._arrowOrigin - halfBase);
|
||||
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||
cr.lineTo(x2, this._arrowOrigin);
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
} else {
|
||||
cr.lineTo(x2, this._arrowOrigin - halfBase);
|
||||
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||
cr.lineTo(x2, this._arrowOrigin + halfBase);
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
}
|
||||
} else
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
|
||||
cr.arc(boxWidth - borderRadius - halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||
0, Math.PI/2);
|
||||
// bottom-right corner
|
||||
if (this._arrowCorner != St.Corner.BOTTOMRIGHT)
|
||||
cr.arc(x2 - borderRadius, y2 - borderRadius, borderRadius,
|
||||
0, Math.PI/2);
|
||||
|
||||
if (this._arrowSide == St.Side.BOTTOM) {
|
||||
cr.lineTo(this._arrowOrigin + halfBase, boxHeight - halfBorder);
|
||||
cr.lineTo(this._arrowOrigin, boxHeight - halfBorder + rise);
|
||||
cr.lineTo(this._arrowOrigin - halfBase, boxHeight - halfBorder);
|
||||
}
|
||||
cr.lineTo(borderRadius, boxHeight - halfBorder);
|
||||
if (this._arrowCorner == St.Corner.BOTTOMLEFT) {
|
||||
cr.lineTo(x1 + halfBase, y2);
|
||||
cr.lineTo(x1, y2 + rise);
|
||||
} else if (this._arrowCorner == St.Corner.BOTTOMRIGHT) {
|
||||
cr.lineTo(x2, y2 + rise);
|
||||
cr.lineTo(x2 - halfBase, y2);
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
} else if (this._arrowOrigin < (x1 + (borderRadius + halfBase))) {
|
||||
cr.lineTo(this._arrowOrigin + halfBase, y2);
|
||||
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||
cr.lineTo(this._arrowOrigin, y2);
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
} else if (this._arrowOrigin > (x2 - (borderRadius + halfBase))) {
|
||||
cr.lineTo(this._arrowOrigin, y2);
|
||||
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||
cr.lineTo(this._arrowOrigin - halfBase, y2);
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
} else {
|
||||
cr.lineTo(this._arrowOrigin + halfBase, y2);
|
||||
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||
cr.lineTo(this._arrowOrigin - halfBase, y2);
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
}
|
||||
} else
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
|
||||
cr.arc(borderRadius + halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||
Math.PI/2, Math.PI);
|
||||
// bottom-left corner
|
||||
if (this._arrowCorner != St.Corner.BOTTOMLEFT)
|
||||
cr.arc(x1 + borderRadius, y2 - borderRadius, borderRadius,
|
||||
Math.PI/2, Math.PI);
|
||||
|
||||
if (this._arrowSide == St.Side.LEFT) {
|
||||
cr.lineTo(halfBorder, this._arrowOrigin + halfBase);
|
||||
cr.lineTo(halfBorder - rise, this._arrowOrigin);
|
||||
cr.lineTo(halfBorder, this._arrowOrigin - halfBase);
|
||||
}
|
||||
cr.lineTo(halfBorder, borderRadius);
|
||||
if (this._arrowCorner == St.Corner.TOPLEFT) {
|
||||
cr.lineTo(x2, y1 + halfBase);
|
||||
cr.lineTo(x1 - rise, y1);
|
||||
} else if (this._arrowCorner == St.Corner.BOTTOMLEFT) {
|
||||
cr.lineTo(x1 + rise, y2);
|
||||
cr.moveTo(x1, y2 - halfBase);
|
||||
} else if (this._arrowOrigin < (y1 + (borderRadius + halfBase))) {
|
||||
cr.lineTo(x1, this._arrowOrigin + halfBase);
|
||||
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||
cr.lineTo(x1, this._arrowOrigin);
|
||||
cr.lineTo(x1, y1 + borderRadius);
|
||||
} else if (this._arrowOrigin > (y2 - (borderRadius + halfBase))) {
|
||||
cr.lineTo(x1, this._arrowOrigin);
|
||||
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||
cr.lineTo(x1, this._arrowOrigin - halfBase);
|
||||
cr.lineTo(x1, y1 + borderRadius);
|
||||
} else {
|
||||
cr.lineTo(x1, this._arrowOrigin + halfBase);
|
||||
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||
cr.lineTo(x1, this._arrowOrigin - halfBase);
|
||||
cr.lineTo(x1, y1 + borderRadius);
|
||||
}
|
||||
} else
|
||||
cr.lineTo(x1, y1 + borderRadius);
|
||||
|
||||
cr.arc(borderRadius + halfBorder, borderRadius + halfBorder, borderRadius,
|
||||
Math.PI, 3*Math.PI/2);
|
||||
// top-left corner
|
||||
if (this._arrowCorner != St.Corner.TOPLEFT)
|
||||
cr.arc(x1 + borderRadius, y1 + borderRadius, borderRadius,
|
||||
Math.PI, 3*Math.PI/2);
|
||||
else
|
||||
cr.lineTo(x1, y1);
|
||||
|
||||
Clutter.cairo_set_source_color(cr, backgroundColor);
|
||||
cr.fillPreserve();
|
||||
@ -269,7 +363,7 @@ BoxPointer.prototype = {
|
||||
// Position correctly relative to the sourceActor
|
||||
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
|
||||
|
||||
let [sourceCenterX, sourceCenterY] = [sourceX + (sourceWidth / 2), sourceY + (sourceHeight / 2)];
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
@ -277,10 +371,14 @@ BoxPointer.prototype = {
|
||||
// separated from its sourceActor
|
||||
let primary = global.get_primary_monitor();
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let arrowRise = themeNode.get_length('-arrow-rise');
|
||||
let halfBorder = themeNode.get_length('-arrow-border-width') / 2;
|
||||
let halfBase = themeNode.get_length('-arrow-base') / 2;
|
||||
let borderRadius = themeNode.get_length('-arrow-border-radius');
|
||||
|
||||
let margin = 2 * borderRadius + halfBorder;
|
||||
|
||||
let resX, resY;
|
||||
this._arrowCorner = null;
|
||||
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
@ -304,40 +402,59 @@ BoxPointer.prototype = {
|
||||
case St.Side.BOTTOM:
|
||||
switch (alignment) {
|
||||
case St.Align.START:
|
||||
resX = sourceX - 2 * borderRadius;
|
||||
resX = sourceCenterX - (halfBase + borderRadius + halfBorder);
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
resX = sourceX - Math.floor((natWidth - sourceWidth) / 2);
|
||||
resX = sourceCenterX - (natWidth / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
resX = sourceX - (natWidth - sourceWidth) + 2 * borderRadius;
|
||||
resX = sourceCenterX - natWidth + (halfBase + borderRadius + halfBorder);
|
||||
break;
|
||||
}
|
||||
if (sourceCenterX < margin) {
|
||||
// Not enough space to the top
|
||||
this._arrowCorner = (this._arrowSide == St.Side.TOP) ? St.Corner.TOPLEFT : St.Corner.BOTTOMLEFT;
|
||||
resX = 10;
|
||||
} else if (sourceCenterX > (primary.width - margin)) {
|
||||
// Not enough space to the botom
|
||||
this._arrowCorner = (this._arrowSide == St.Side.TOP) ? St.Corner.TOPRIGHT : St.Corner.BOTTOMRIGHT;
|
||||
resX = primary.width - (10 + natWidth);
|
||||
}
|
||||
|
||||
resX = Math.min(resX, primary.x + primary.width - natWidth - arrowRise - gap);
|
||||
resX = Math.max(resX, primary.x);
|
||||
resX = Math.max(resX, 10);
|
||||
resX = Math.min(resX, primary.width - (10 + natWidth));
|
||||
|
||||
this.setArrowOrigin((sourceX - resX) + Math.floor(sourceWidth / 2));
|
||||
this.setArrowOrigin(sourceCenterX - resX);
|
||||
break;
|
||||
|
||||
case St.Side.LEFT:
|
||||
case St.Side.RIGHT:
|
||||
switch (alignment) {
|
||||
case St.Align.START:
|
||||
resY = sourceY - 2 * borderRadius;
|
||||
resY = sourceCenterY - (halfBase + borderRadius + halfBorder);
|
||||
break;
|
||||
case St.Align.MIDDLE:
|
||||
resY = sourceY - Math.floor((natHeight - sourceHeight) / 2);
|
||||
resY = sourceCenterY - (natHeight / 2);
|
||||
break;
|
||||
case St.Align.END:
|
||||
resY = sourceY - (natHeight - sourceHeight) + 2 * borderRadius;
|
||||
resY = sourceCenterY - natHeight + (halfBase + borderRadius + halfBorder);
|
||||
break;
|
||||
}
|
||||
if (sourceCenterY < margin) {
|
||||
// Not enough space to the left
|
||||
this._arrowCorner = (this._arrowSide == St.Side.LEFT) ? St.Corner.TOPLEFT : St.Corner.TORIGHT;
|
||||
resY = 10;
|
||||
}
|
||||
else if (sourceCenterY > (primary.height - margin)) {
|
||||
// Not enough space to the right
|
||||
this._arrowCorner = (this._arrowSide == St.Side.LEFT) ? St.Corner.BOTTOMLEFT : St.Corner.BOTTOMRIGHT;
|
||||
resY = primary.height - (10 + natHeight);
|
||||
}
|
||||
|
||||
resY = Math.min(resY, primary.y + primary.height - natHeight - arrowRise - gap);
|
||||
resY = Math.max(resY, primary.y);
|
||||
resY = Math.max(resY, 10);
|
||||
resY = Math.min(resY, primary.height - (10 + natHeight));
|
||||
|
||||
this.setArrowOrigin((sourceY - resY) + Math.floor(sourceHeight / 2));
|
||||
this.setArrowOrigin(sourceCenterY - resY);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4,19 +4,78 @@ const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Gettext_gtk30 = imports.gettext.domain('gtk30');
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
|
||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
|
||||
// in org.gnome.desktop.interface
|
||||
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||
|
||||
function _sameDay(dateA, dateB) {
|
||||
return (dateA.getDate() == dateB.getDate() &&
|
||||
dateA.getMonth() == dateB.getMonth() &&
|
||||
dateA.getYear() == dateB.getYear());
|
||||
}
|
||||
|
||||
function _sameYear(dateA, dateB) {
|
||||
return (dateA.getYear() == dateB.getYear());
|
||||
}
|
||||
|
||||
/* TODO: maybe needs config - right now we assume that Saturday and
|
||||
* Sunday are non-work days (not true in e.g. Israel, it's Sunday and
|
||||
* Monday there)
|
||||
*/
|
||||
function _isWorkDay(date) {
|
||||
return date.getDay() != 0 && date.getDay() != 6;
|
||||
}
|
||||
|
||||
function _getBeginningOfDay(date) {
|
||||
let ret = new Date(date.getTime());
|
||||
ret.setHours(0);
|
||||
ret.setMinutes(0);
|
||||
ret.setSeconds(0);
|
||||
ret.setMilliseconds(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function _getEndOfDay(date) {
|
||||
let ret = new Date(date.getTime());
|
||||
ret.setHours(23);
|
||||
ret.setMinutes(59);
|
||||
ret.setSeconds(59);
|
||||
ret.setMilliseconds(999);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function _formatEventTime(event, clockFormat) {
|
||||
let ret;
|
||||
if (event.allDay) {
|
||||
/* Translators: Shown in calendar event list for all day events */
|
||||
ret = _("All Day");
|
||||
} else {
|
||||
switch (clockFormat) {
|
||||
case '24h':
|
||||
ret = event.date.toLocaleFormat('%H:%M');
|
||||
break;
|
||||
|
||||
default:
|
||||
/* explicit fall-through */
|
||||
case '12h':
|
||||
ret = event.date.toLocaleFormat('%l:%M %p');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function _getCalendarWeekForDate(date) {
|
||||
// Based on the algorithms found here:
|
||||
// http://en.wikipedia.org/wiki/Talk:ISO_week_date
|
||||
@ -43,12 +102,259 @@ function _getDigitWidth(actor){
|
||||
return width;
|
||||
}
|
||||
|
||||
function Calendar() {
|
||||
function _getCalendarDayAbbreviation(dayNumber) {
|
||||
let abbreviations = [
|
||||
/* Translators: Calendar grid abbreviation for Sunday.
|
||||
*
|
||||
* NOTE: These abbreviations are always shown together and in
|
||||
* order, e.g. "S M T W T F S".
|
||||
*/
|
||||
_("S"),
|
||||
/* Translators: Calendar grid abbreviation for Monday */
|
||||
_("M"),
|
||||
/* Translators: Calendar grid abbreviation for Tuesday */
|
||||
_("T"),
|
||||
/* Translators: Calendar grid abbreviation for Wednesday */
|
||||
_("W"),
|
||||
/* Translators: Calendar grid abbreviation for Thursday */
|
||||
_("T"),
|
||||
/* Translators: Calendar grid abbreviation for Friday */
|
||||
_("F"),
|
||||
/* Translators: Calendar grid abbreviation for Saturday */
|
||||
_("S")
|
||||
];
|
||||
return abbreviations[dayNumber];
|
||||
}
|
||||
|
||||
function _getEventDayAbbreviation(dayNumber) {
|
||||
let abbreviations = [
|
||||
/* Translators: Event list abbreviation for Sunday.
|
||||
*
|
||||
* NOTE: These abbreviations are normally not shown together
|
||||
* so they need to be unique (e.g. Tuesday and Thursday cannot
|
||||
* both be 'T').
|
||||
*/
|
||||
_("Su"),
|
||||
/* Translators: Event list abbreviation for Monday */
|
||||
_("M"),
|
||||
/* Translators: Event list abbreviation for Tuesday */
|
||||
_("T"),
|
||||
/* Translators: Event list abbreviation for Wednesday */
|
||||
_("W"),
|
||||
/* Translators: Event list abbreviation for Thursday */
|
||||
_("Th"),
|
||||
/* Translators: Event list abbreviation for Friday */
|
||||
_("F"),
|
||||
/* Translators: Event list abbreviation for Saturday */
|
||||
_("S")
|
||||
];
|
||||
return abbreviations[dayNumber];
|
||||
}
|
||||
|
||||
// Abstraction for an appointment/event in a calendar
|
||||
|
||||
function CalendarEvent(date, summary, allDay) {
|
||||
this._init(date, summary, allDay);
|
||||
}
|
||||
|
||||
CalendarEvent.prototype = {
|
||||
_init: function(date, summary, allDay) {
|
||||
this.date = date;
|
||||
this.summary = summary;
|
||||
this.allDay = allDay;
|
||||
}
|
||||
};
|
||||
|
||||
// Interface for appointments/events - e.g. the contents of a calendar
|
||||
//
|
||||
|
||||
// First, an implementation with no events
|
||||
function EmptyEventSource() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Calendar.prototype = {
|
||||
EmptyEventSource.prototype = {
|
||||
_init: function() {
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
},
|
||||
|
||||
getEvents: function(begin, end) {
|
||||
let result = [];
|
||||
return result;
|
||||
},
|
||||
|
||||
hasEvents: function(day) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(EmptyEventSource.prototype);
|
||||
|
||||
// Second, wrap native Evolution event source
|
||||
function EvolutionEventSource() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
EvolutionEventSource.prototype = {
|
||||
_init: function() {
|
||||
this._native = new Shell.EvolutionEventSource();
|
||||
this._native.connect('changed', Lang.bind(this, function() {
|
||||
this.emit('changed');
|
||||
}));
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
this._native.request_range(begin.getTime(), end.getTime());
|
||||
},
|
||||
|
||||
getEvents: function(begin, end) {
|
||||
let result = [];
|
||||
let nativeEvents = this._native.get_events(begin.getTime(), end.getTime());
|
||||
for (let n = 0; n < nativeEvents.length; n++) {
|
||||
let nativeEvent = nativeEvents[n];
|
||||
result.push(new CalendarEvent(new Date(nativeEvent.msec_begin), nativeEvent.summary, nativeEvent.all_day));
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
hasEvents: function(day) {
|
||||
let dayBegin = _getBeginningOfDay(day);
|
||||
let dayEnd = _getEndOfDay(day);
|
||||
|
||||
let events = this.getEvents(dayBegin, dayEnd);
|
||||
|
||||
if (events.length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(EvolutionEventSource.prototype);
|
||||
|
||||
// Finally, an implementation with fake events
|
||||
function FakeEventSource() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
FakeEventSource.prototype = {
|
||||
_init: function() {
|
||||
|
||||
this._fakeEvents = [];
|
||||
|
||||
// Generate fake events
|
||||
//
|
||||
let midnightToday = _getBeginningOfDay(new Date());
|
||||
let summary = '';
|
||||
|
||||
// '10-oclock pow-wow' is an event occuring IN THE PAST every four days at 10am
|
||||
for (let n = 0; n < 10; n++) {
|
||||
let t = new Date(midnightToday.getTime() - n * 4 * 86400 * 1000);
|
||||
t.setHours(10);
|
||||
summary = '10-oclock pow-wow (n=' + n + ')';
|
||||
this._fakeEvents.push(new CalendarEvent(t, summary, false));
|
||||
}
|
||||
|
||||
// '11-oclock thing' is an event occuring every three days at 11am
|
||||
for (let n = 0; n < 10; n++) {
|
||||
let t = new Date(midnightToday.getTime() + n * 3 * 86400 * 1000);
|
||||
t.setHours(11);
|
||||
summary = '11-oclock thing (n=' + n + ')';
|
||||
this._fakeEvents.push(new CalendarEvent(t, summary, false));
|
||||
}
|
||||
|
||||
// 'Weekly Meeting' is an event occuring every seven days at 1:45pm (two days displaced)
|
||||
for (let n = 0; n < 5; n++) {
|
||||
let t = new Date(midnightToday.getTime() + (n * 7 + 2) * 86400 * 1000);
|
||||
t.setHours(13);
|
||||
t.setMinutes(45);
|
||||
summary = 'Weekly Meeting (n=' + n + ')';
|
||||
this._fakeEvents.push(new CalendarEvent(t, summary, false));
|
||||
}
|
||||
|
||||
// 'Fun All Day' is an all-day event occuring every fortnight (three days displayed)
|
||||
for (let n = 0; n < 10; n++) {
|
||||
let t = new Date(midnightToday.getTime() + (n * 14 + 3) * 86400 * 1000);
|
||||
summary = 'Fun All Day (n=' + n + ')';
|
||||
this._fakeEvents.push(new CalendarEvent(t, summary, true));
|
||||
}
|
||||
|
||||
// 'Get Married' is an event that actually reflects reality (Dec 4, 2010) :-)
|
||||
this._fakeEvents.push(new CalendarEvent(new Date(2010, 11, 4, 16, 0), 'Get Married', false));
|
||||
|
||||
// ditto for 'NE Patriots vs NY Jets'
|
||||
this._fakeEvents.push(new CalendarEvent(new Date(2010, 11, 6, 20, 30), 'NE Patriots vs NY Jets', false));
|
||||
|
||||
// An event for tomorrow @6:30pm that is added/removed every five
|
||||
// seconds (to check that the ::changed signal works)
|
||||
let transientEventDate = new Date(midnightToday.getTime() + 86400 * 1000);
|
||||
transientEventDate.setHours(18);
|
||||
transientEventDate.setMinutes(30);
|
||||
transientEventDate.setSeconds(0);
|
||||
Mainloop.timeout_add(5000, Lang.bind(this, this._updateTransientEvent));
|
||||
this._includeTransientEvent = false;
|
||||
this._transientEvent = new CalendarEvent(transientEventDate, 'A Transient Event', false);
|
||||
this._transientEventCounter = 1;
|
||||
},
|
||||
|
||||
_updateTransientEvent: function() {
|
||||
this._includeTransientEvent = !this._includeTransientEvent;
|
||||
this._transientEventCounter = this._transientEventCounter + 1;
|
||||
this._transientEvent.summary = 'A Transient Event (' + this._transientEventCounter + ')';
|
||||
this.emit('changed');
|
||||
Mainloop.timeout_add(5000, Lang.bind(this, this._updateTransientEvent));
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
},
|
||||
|
||||
getEvents: function(begin, end) {
|
||||
let result = [];
|
||||
//log('begin:' + begin);
|
||||
//log('end: ' + end);
|
||||
for(let n = 0; n < this._fakeEvents.length; n++) {
|
||||
let event = this._fakeEvents[n];
|
||||
if (event.date >= begin && event.date <= end) {
|
||||
result.push(event);
|
||||
}
|
||||
//log('when:' + event.date + ' summary:' + event.summary);
|
||||
}
|
||||
if (this._includeTransientEvent && this._transientEvent.date >= begin && this._transientEvent.date <= end)
|
||||
result.push(this._transientEvent);
|
||||
result.sort(function(event1, event2) {
|
||||
return event1.date.getTime() - event2.date.getTime();
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
hasEvents: function(day) {
|
||||
let dayBegin = _getBeginningOfDay(day);
|
||||
let dayEnd = _getEndOfDay(day);
|
||||
|
||||
let events = this.getEvents(dayBegin, dayEnd);
|
||||
|
||||
if (events.length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
Signals.addSignalMethods(FakeEventSource.prototype);
|
||||
|
||||
// Calendar:
|
||||
// @eventSource: is an object implementing the EventSource API, e.g. the
|
||||
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
|
||||
function Calendar(eventSource) {
|
||||
this._init(eventSource);
|
||||
}
|
||||
|
||||
Calendar.prototype = {
|
||||
_init: function(eventSource) {
|
||||
this._eventSource = eventSource;
|
||||
|
||||
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||
|
||||
// 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.
|
||||
@ -71,6 +377,7 @@ Calendar.prototype = {
|
||||
}
|
||||
|
||||
// Find the ordering for month/year in the calendar heading
|
||||
this._headerFormatWithoutYear = '%B';
|
||||
switch (Gettext_gtk30.gettext('calendar:MY')) {
|
||||
case 'calendar:MY':
|
||||
this._headerFormat = '%B %Y';
|
||||
@ -85,7 +392,7 @@ Calendar.prototype = {
|
||||
}
|
||||
|
||||
// Start off with the current date
|
||||
this.date = new Date();
|
||||
this._selectedDate = new Date();
|
||||
|
||||
this.actor = new St.Table({ homogeneous: false,
|
||||
style_class: 'calendar',
|
||||
@ -100,9 +407,10 @@ Calendar.prototype = {
|
||||
|
||||
// Sets the calendar to show a specific date
|
||||
setDate: function(date) {
|
||||
if (!_sameDay(date, this.date)) {
|
||||
this.date = date;
|
||||
if (!_sameDay(date, this._selectedDate)) {
|
||||
this._selectedDate = date;
|
||||
this._update();
|
||||
this.emit('selected-date-changed', new Date(this._selectedDate));
|
||||
}
|
||||
},
|
||||
|
||||
@ -116,45 +424,36 @@ Calendar.prototype = {
|
||||
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
||||
|
||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChange));
|
||||
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' });
|
||||
let back = new St.Button({ style_class: 'calendar-change-month-back' });
|
||||
this._topBox.add(back);
|
||||
back.connect('clicked', Lang.bind(this, this._prevMonth));
|
||||
back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
|
||||
|
||||
this._dateLabel = new St.Label();
|
||||
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||
this._monthLabel = new St.Label({style_class: 'calendar-month-label'});
|
||||
this._topBox.add(this._monthLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||
|
||||
let forward = new St.Button({ label: forwardlabel, style_class: 'calendar-change-month' });
|
||||
let forward = new St.Button({ style_class: 'calendar-change-month-forward' });
|
||||
this._topBox.add(forward);
|
||||
forward.connect('clicked', Lang.bind(this, this._nextMonth));
|
||||
forward.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
|
||||
|
||||
// Add weekday labels...
|
||||
//
|
||||
// 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);
|
||||
let iter = new Date(this._selectedDate);
|
||||
iter.setSeconds(0); // Leap second protection. Hah!
|
||||
iter.setHours(12);
|
||||
|
||||
if (this._useWeekdate) {
|
||||
this._weekdateHeader = new St.Label();
|
||||
this.actor.add(this._weekdateHeader,
|
||||
{ row: 1,
|
||||
col: 0,
|
||||
x_fill: false, x_align: St.Align.MIDDLE });
|
||||
this._setWeekdateHeaderWidth();
|
||||
} else {
|
||||
this._weekdateHeader = null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < 7; i++) {
|
||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat('%a') }),
|
||||
// Could use iter.toLocaleFormat('%a') but that normally gives three characters
|
||||
// and we want, ideally, a single character for e.g. S M T W T F S
|
||||
let customDayAbbrev = _getCalendarDayAbbreviation(iter.getDay());
|
||||
let label = new St.Label({ style_class: 'calendar-day-base calendar-day-heading',
|
||||
text: customDayAbbrev });
|
||||
this.actor.add(label,
|
||||
{ row: 1,
|
||||
col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
x_fill: false, x_align: St.Align.MIDDLE });
|
||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||
}
|
||||
|
||||
@ -178,33 +477,57 @@ Calendar.prototype = {
|
||||
switch (event.get_scroll_direction()) {
|
||||
case Clutter.ScrollDirection.UP:
|
||||
case Clutter.ScrollDirection.LEFT:
|
||||
this._prevMonth();
|
||||
this._onPrevMonthButtonClicked();
|
||||
break;
|
||||
case Clutter.ScrollDirection.DOWN:
|
||||
case Clutter.ScrollDirection.RIGHT:
|
||||
this._nextMonth();
|
||||
this._onNextMonthButtonClicked();
|
||||
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);
|
||||
_onPrevMonthButtonClicked: function() {
|
||||
let newDate = new Date(this._selectedDate);
|
||||
let oldMonth = newDate.getMonth();
|
||||
if (oldMonth == 0) {
|
||||
newDate.setMonth(11);
|
||||
newDate.setFullYear(newDate.getFullYear() - 1);
|
||||
if (newDate.getMonth() != 11) {
|
||||
let day = 32 - new Date(newDate.getFullYear() - 1, 11, 32).getDate();
|
||||
newDate = new Date(newDate.getFullYear() - 1, 11, day);
|
||||
}
|
||||
}
|
||||
this._update();
|
||||
else {
|
||||
newDate.setMonth(oldMonth - 1);
|
||||
if (newDate.getMonth() != oldMonth - 1) {
|
||||
let day = 32 - new Date(newDate.getFullYear(), oldMonth - 1, 32).getDate();
|
||||
newDate = new Date(newDate.getFullYear(), oldMonth - 1, day);
|
||||
}
|
||||
}
|
||||
|
||||
this.setDate(newDate);
|
||||
},
|
||||
|
||||
_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);
|
||||
_onNextMonthButtonClicked: function() {
|
||||
let newDate = new Date(this._selectedDate);
|
||||
let oldMonth = newDate.getMonth();
|
||||
if (oldMonth == 11) {
|
||||
newDate.setMonth(0);
|
||||
newDate.setFullYear(newDate.getFullYear() + 1);
|
||||
if (newDate.getMonth() != 0) {
|
||||
let day = 32 - new Date(newDate.getFullYear() + 1, 0, 32).getDate();
|
||||
newDate = new Date(newDate.getFullYear() + 1, 0, day);
|
||||
}
|
||||
}
|
||||
this._update();
|
||||
else {
|
||||
newDate.setMonth(oldMonth + 1);
|
||||
if (newDate.getMonth() != oldMonth + 1) {
|
||||
let day = 32 - new Date(newDate.getFullYear(), oldMonth + 1, 32).getDate();
|
||||
newDate = new Date(newDate.getFullYear(), oldMonth + 1, day);
|
||||
}
|
||||
}
|
||||
|
||||
this.setDate(newDate);
|
||||
},
|
||||
|
||||
_onSettingsChange: function() {
|
||||
@ -214,7 +537,12 @@ Calendar.prototype = {
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
this._dateLabel.text = this.date.toLocaleFormat(this._headerFormat);
|
||||
let now = new Date();
|
||||
|
||||
if (_sameYear(this._selectedDate, now))
|
||||
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormatWithoutYear);
|
||||
else
|
||||
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormat);
|
||||
|
||||
// Remove everything but the topBox and the weekday labels
|
||||
let children = this.actor.get_children();
|
||||
@ -222,45 +550,215 @@ Calendar.prototype = {
|
||||
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);
|
||||
let daysToWeekStart = (7 + iter.getDay() - this._weekStart) % 7;
|
||||
iter.setTime(iter.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
||||
|
||||
let now = new Date();
|
||||
let beginDate = new Date(this._selectedDate);
|
||||
beginDate.setDate(1);
|
||||
beginDate.setSeconds(0);
|
||||
beginDate.setHours(12);
|
||||
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
|
||||
beginDate.setTime(beginDate.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
||||
|
||||
let iter = new Date(beginDate);
|
||||
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';
|
||||
let button = new St.Button({ label: iter.getDate().toString() });
|
||||
|
||||
let iterStr = iter.toUTCString();
|
||||
button.connect('clicked', Lang.bind(this, function() {
|
||||
let newlySelectedDate = new Date(iterStr);
|
||||
this.setDate(newlySelectedDate);
|
||||
}));
|
||||
|
||||
let hasEvents = this._eventSource.hasEvents(iter);
|
||||
let styleClass = 'calendar-day-base calendar-day';
|
||||
if (_isWorkDay(iter))
|
||||
styleClass += ' calendar-work-day'
|
||||
else
|
||||
label.style_class = 'calendar-day';
|
||||
styleClass += ' calendar-nonwork-day'
|
||||
|
||||
// Hack used in lieu of border-collapse - see gnome-shell.css
|
||||
if (row == 2)
|
||||
styleClass = 'calendar-day-top ' + styleClass;
|
||||
if (iter.getDay() == this._weekStart)
|
||||
styleClass = 'calendar-day-left ' + styleClass;
|
||||
|
||||
if (_sameDay(now, iter))
|
||||
styleClass += ' calendar-today';
|
||||
else if (iter.getMonth() != this._selectedDate.getMonth())
|
||||
styleClass += ' calendar-other-month-day';
|
||||
|
||||
if (_sameDay(this._selectedDate, iter))
|
||||
button.add_style_pseudo_class('active');
|
||||
|
||||
if (hasEvents)
|
||||
styleClass += ' calendar-day-with-events'
|
||||
|
||||
button.style_class = styleClass;
|
||||
|
||||
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||
this.actor.add(label,
|
||||
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
this.actor.add(button,
|
||||
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 });
|
||||
|
||||
if (this._useWeekdate && iter.getDay() == 4) {
|
||||
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
|
||||
style_class: 'calendar-day calendar-calendarweek'});
|
||||
style_class: 'calendar-day-base calendar-week-number'});
|
||||
this.actor.add(label,
|
||||
{ row: row, col: 0,
|
||||
x_fill: false, x_align: St.Align.MIDDLE });
|
||||
{ row: row, col: 0, y_align: St.Align.MIDDLE });
|
||||
}
|
||||
|
||||
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())
|
||||
if (iter.getMonth() > this._selectedDate.getMonth() || iter.getYear() > this._selectedDate.getYear())
|
||||
break;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
// Signal to the event source that we are interested in events
|
||||
// only from this date range
|
||||
this._eventSource.requestRange(beginDate, iter);
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Calendar.prototype);
|
||||
|
||||
function EventsList(eventSource) {
|
||||
this._init(eventSource);
|
||||
}
|
||||
|
||||
EventsList.prototype = {
|
||||
_init: function(eventSource) {
|
||||
this.actor = new St.BoxLayout({ vertical: true, style_class: 'events-header-vbox'});
|
||||
this._date = new Date();
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||
this._desktopSettings.connect('changed', Lang.bind(this, this._update));
|
||||
let weekStartString = Gettext_gtk30.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;
|
||||
}
|
||||
|
||||
this._update();
|
||||
},
|
||||
|
||||
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
|
||||
if (includeDayName) {
|
||||
dayNameBox.add(new St.Label( { style_class: 'events-day-dayname',
|
||||
text: day } ),
|
||||
{ x_fill: true } );
|
||||
}
|
||||
timeBox.add(new St.Label( { style_class: 'events-day-time',
|
||||
text: time} ),
|
||||
{ x_fill: true } );
|
||||
eventTitleBox.add(new St.Label( { style_class: 'events-day-task',
|
||||
text: desc} ));
|
||||
},
|
||||
|
||||
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
|
||||
let events = this._eventSource.getEvents(begin, end);
|
||||
|
||||
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
|
||||
|
||||
if (events.length == 0 && !showNothingScheduled)
|
||||
return;
|
||||
|
||||
let vbox = new St.BoxLayout( {vertical: true} );
|
||||
this.actor.add(vbox);
|
||||
|
||||
vbox.add(new St.Label({ style_class: 'events-day-header', text: header }));
|
||||
let box = new St.BoxLayout({style_class: 'events-header-hbox'});
|
||||
let dayNameBox = new St.BoxLayout({ vertical: true, style_class: 'events-day-name-box' });
|
||||
let timeBox = new St.BoxLayout({ vertical: true, style_class: 'events-time-box' });
|
||||
let eventTitleBox = new St.BoxLayout({ vertical: true, style_class: 'events-event-box' });
|
||||
box.add(dayNameBox, {x_fill: false});
|
||||
box.add(timeBox, {x_fill: false});
|
||||
box.add(eventTitleBox, {expand: true});
|
||||
vbox.add(box);
|
||||
|
||||
for (let n = 0; n < events.length; n++) {
|
||||
let event = events[n];
|
||||
let dayString = _getEventDayAbbreviation(event.date.getDay());
|
||||
let timeString = _formatEventTime(event, clockFormat);
|
||||
let summaryString = event.summary;
|
||||
this._addEvent(dayNameBox, timeBox, eventTitleBox, includeDayName, dayString, timeString, summaryString);
|
||||
}
|
||||
|
||||
if (events.length == 0 && showNothingScheduled) {
|
||||
let now = new Date();
|
||||
/* Translators: Text to show if there are no events */
|
||||
let nothingEvent = new CalendarEvent(now, _("Nothing Scheduled"), true);
|
||||
let timeString = _formatEventTime(nothingEvent, clockFormat);
|
||||
this._addEvent(dayNameBox, timeBox, eventTitleBox, false, "", timeString, nothingEvent.summary);
|
||||
}
|
||||
},
|
||||
|
||||
_showOtherDay: function(day) {
|
||||
this.actor.destroy_children();
|
||||
|
||||
let dayBegin = _getBeginningOfDay(day);
|
||||
let dayEnd = _getEndOfDay(day);
|
||||
|
||||
let dayString;
|
||||
let now = new Date();
|
||||
if (_sameYear(day, now))
|
||||
dayString = day.toLocaleFormat('%A, %B %d');
|
||||
else
|
||||
dayString = day.toLocaleFormat('%A, %B %d, %Y');
|
||||
this._addPeriod(dayString, dayBegin, dayEnd, false, true);
|
||||
},
|
||||
|
||||
_showToday: function() {
|
||||
this.actor.destroy_children();
|
||||
|
||||
let now = new Date();
|
||||
let dayBegin = _getBeginningOfDay(now);
|
||||
let dayEnd = _getEndOfDay(now);
|
||||
this._addPeriod(_("Today"), dayBegin, dayEnd, false, true);
|
||||
|
||||
let tomorrowBegin = new Date(dayBegin.getTime() + 86400 * 1000);
|
||||
let tomorrowEnd = new Date(dayEnd.getTime() + 86400 * 1000);
|
||||
this._addPeriod(_("Tomorrow"), tomorrowBegin, tomorrowEnd, false, true);
|
||||
|
||||
if (dayEnd.getDay() <= 4 + this._weekStart) {
|
||||
/* If now is within the first 5 days we show "This week" and
|
||||
* include events up until and including Saturday/Sunday
|
||||
* (depending on whether a week starts on Sunday/Monday).
|
||||
*/
|
||||
let thisWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
|
||||
let thisWeekEnd = new Date(dayEnd.getTime() + (6 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
|
||||
this._addPeriod(_("This week"), thisWeekBegin, thisWeekEnd, true, false);
|
||||
} else {
|
||||
/* otherwise it's one of the two last days of the week ... show
|
||||
* "Next week" and include events up until and including *next*
|
||||
* Saturday/Sunday
|
||||
*/
|
||||
let nextWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
|
||||
let nextWeekEnd = new Date(dayEnd.getTime() + (13 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
|
||||
this._addPeriod(_("Next week"), nextWeekBegin, nextWeekEnd, true, false);
|
||||
}
|
||||
},
|
||||
|
||||
// Sets the event list to show events from a specific date
|
||||
setDate: function(date) {
|
||||
if (!_sameDay(date, this._date)) {
|
||||
this._date = date;
|
||||
this._update();
|
||||
}
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
let today = new Date();
|
||||
if (_sameDay (this._date, today)) {
|
||||
this._showToday();
|
||||
} else {
|
||||
this._showOtherDay(this._date);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
212
js/ui/dateMenu.js
Normal file
212
js/ui/dateMenu.js
Normal file
@ -0,0 +1,212 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Cairo = imports.cairo;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Util = imports.misc.util;
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Calendar = imports.ui.calendar;
|
||||
|
||||
// in org.gnome.desktop.interface
|
||||
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||
|
||||
// in org.gnome.shell.clock
|
||||
const CLOCK_SHOW_DATE_KEY = 'show-date';
|
||||
const CLOCK_SHOW_SECONDS_KEY = 'show-seconds';
|
||||
|
||||
function _onVertSepRepaint (area)
|
||||
{
|
||||
let cr = area.get_context();
|
||||
let themeNode = area.get_theme_node();
|
||||
let [width, height] = area.get_surface_size();
|
||||
let stippleColor = new Clutter.Color();
|
||||
let stippleWidth = themeNode.get_length('-stipple-width');
|
||||
let x = Math.floor(width/2) + 0.5;
|
||||
themeNode.lookup_color('-stipple-color', false, stippleColor);
|
||||
cr.moveTo(x, 0);
|
||||
cr.lineTo(x, height);
|
||||
Clutter.cairo_set_source_color(cr, stippleColor);
|
||||
cr.setDash([1, 3], 1); // Hard-code for now
|
||||
cr.setLineWidth(stippleWidth);
|
||||
cr.stroke();
|
||||
};
|
||||
|
||||
function DateMenuButton() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DateMenuButton.prototype = {
|
||||
__proto__: PanelMenu.Button.prototype,
|
||||
|
||||
_init: function() {
|
||||
let item;
|
||||
let hbox;
|
||||
let vbox;
|
||||
|
||||
//this._eventSource = new Calendar.EmptyEventSource();
|
||||
//this._eventSource = new Calendar.FakeEventSource();
|
||||
this._eventSource = new Calendar.EvolutionEventSource();
|
||||
|
||||
PanelMenu.Button.prototype._init.call(this, St.Align.START);
|
||||
|
||||
this._clock = new St.Label();
|
||||
this.actor.set_child(this._clock);
|
||||
|
||||
hbox = new St.BoxLayout({name: 'calendarArea'});
|
||||
this.menu.addActor(hbox);
|
||||
|
||||
// Fill up the first column
|
||||
|
||||
vbox = new St.BoxLayout({vertical: true});
|
||||
hbox.add(vbox);
|
||||
|
||||
// Date
|
||||
this._date = new St.Label();
|
||||
this._date.style_class = 'datemenu-date-label';
|
||||
vbox.add(this._date);
|
||||
|
||||
this._eventList = new Calendar.EventsList(this._eventSource);
|
||||
|
||||
// Calendar
|
||||
this._calendar = new Calendar.Calendar(this._eventSource);
|
||||
this._calendar.connect('selected-date-changed',
|
||||
Lang.bind(this, function(calendar, date) {
|
||||
this._eventList.setDate(date);
|
||||
}));
|
||||
vbox.add(this._calendar.actor);
|
||||
|
||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||
item.setColumnWidths(1);
|
||||
vbox.add(item.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
||||
item = new PopupMenu.PopupMenuItem(_("Date and Time Settings"));
|
||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||
vbox.add(item.actor);
|
||||
|
||||
// Add vertical separator
|
||||
|
||||
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
||||
pseudo_class: 'highlighted' });
|
||||
item.connect('repaint', Lang.bind(this, _onVertSepRepaint));
|
||||
hbox.add(item);
|
||||
|
||||
// Fill up the second column
|
||||
|
||||
vbox = new St.BoxLayout({vertical: true});
|
||||
hbox.add(vbox);
|
||||
|
||||
// Event list
|
||||
vbox.add(this._eventList.actor);
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Open Calendar"));
|
||||
item.connect('activate', Lang.bind(this, this._onOpenCalendarActivate));
|
||||
vbox.add(item.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
||||
|
||||
// Whenever the menu is opened, select today
|
||||
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
|
||||
if (isOpen) {
|
||||
let now = new Date();
|
||||
this._calendar.setDate(now);
|
||||
// No need to update this._eventList as ::selected-date-changed
|
||||
// signal will fire
|
||||
}
|
||||
}));
|
||||
|
||||
// Done with hbox for calendar and event list
|
||||
|
||||
// Track changes to clock settings
|
||||
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||
this._clockSettings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
||||
this._desktopSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||
this._clockSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||
|
||||
// Start the clock
|
||||
this._updateClockAndDate();
|
||||
},
|
||||
|
||||
_updateClockAndDate: function() {
|
||||
let format = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
||||
let showDate = this._clockSettings.get_boolean(CLOCK_SHOW_DATE_KEY);
|
||||
let showSeconds = this._clockSettings.get_boolean(CLOCK_SHOW_SECONDS_KEY);
|
||||
|
||||
let clockFormat;
|
||||
let dateFormat;
|
||||
|
||||
switch (format) {
|
||||
case '24h':
|
||||
if (showDate)
|
||||
/* Translators: This is the time format with date used
|
||||
in 24-hour mode. */
|
||||
clockFormat = showSeconds ? _("%a %b %e, %R:%S")
|
||||
: _("%a %b %e, %R");
|
||||
else
|
||||
/* Translators: This is the time format without date used
|
||||
in 24-hour mode. */
|
||||
clockFormat = showSeconds ? _("%a %R:%S")
|
||||
: _("%a %R");
|
||||
break;
|
||||
case '12h':
|
||||
default:
|
||||
if (showDate)
|
||||
/* Translators: This is a time format with date used
|
||||
for AM/PM. */
|
||||
clockFormat = showSeconds ? _("%a %b %e, %l:%M:%S %p")
|
||||
: _("%a %b %e, %l:%M %p");
|
||||
else
|
||||
/* Translators: This is a time format without date used
|
||||
for AM/PM. */
|
||||
clockFormat = showSeconds ? _("%a %l:%M:%S %p")
|
||||
: _("%a %l:%M %p");
|
||||
break;
|
||||
}
|
||||
|
||||
let displayDate = new Date();
|
||||
let msecRemaining;
|
||||
if (showSeconds) {
|
||||
msecRemaining = 1000 - displayDate.getMilliseconds();
|
||||
if (msecRemaining < 50) {
|
||||
displayDate.setSeconds(displayDate.getSeconds() + 1);
|
||||
msecRemaining += 1000;
|
||||
}
|
||||
} else {
|
||||
msecRemaining = 60000 - (1000 * displayDate.getSeconds() +
|
||||
displayDate.getMilliseconds());
|
||||
if (msecRemaining < 500) {
|
||||
displayDate.setMinutes(displayDate.getMinutes() + 1);
|
||||
msecRemaining += 60000;
|
||||
}
|
||||
}
|
||||
|
||||
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
|
||||
|
||||
/* Translators: This is the date format to use when the calendar popup is
|
||||
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
*/
|
||||
dateFormat = _("%A %B %e, %Y");
|
||||
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
||||
|
||||
Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClockAndDate));
|
||||
return false;
|
||||
},
|
||||
|
||||
_onPreferencesActivate: function() {
|
||||
this.menu.close();
|
||||
Util.spawnDesktop('gnome-datetime-panel');
|
||||
},
|
||||
|
||||
_onOpenCalendarActivate: function() {
|
||||
this.menu.close();
|
||||
// TODO: pass '-c calendar' (to force the calendar at startup)
|
||||
// TODO: pass the selected day
|
||||
Util.spawnDesktop('evolution');
|
||||
},
|
||||
};
|
@ -67,6 +67,8 @@ let xdndHandler = null;
|
||||
let statusIconDispatcher = null;
|
||||
let _errorLogStack = [];
|
||||
let _startDate;
|
||||
let _defaultCssStylesheet = null;
|
||||
let _cssStylesheet = null;
|
||||
|
||||
let background = null;
|
||||
|
||||
@ -111,6 +113,7 @@ function start() {
|
||||
global.stage.color = DEFAULT_BACKGROUND_COLOR;
|
||||
global.stage.no_clear_hint = true;
|
||||
|
||||
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
|
||||
loadTheme();
|
||||
|
||||
let shellwm = global.window_manager;
|
||||
@ -204,15 +207,44 @@ function start() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getThemeStylesheet:
|
||||
*
|
||||
* Get the theme CSS file that the shell will load
|
||||
*
|
||||
* Returns: A file path that contains the theme CSS,
|
||||
* null if using the default
|
||||
*/
|
||||
function getThemeStylesheet()
|
||||
{
|
||||
return _cssStylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* setThemeStylesheet:
|
||||
* @cssStylesheet: A file path that contains the theme CSS,
|
||||
* set it to null to use the default
|
||||
*
|
||||
* Set the theme CSS file that the shell will load
|
||||
*/
|
||||
function setThemeStylesheet(cssStylesheet)
|
||||
{
|
||||
_cssStylesheet = cssStylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* loadTheme:
|
||||
*
|
||||
* Reloads the theme CSS file from the default theme.
|
||||
* Reloads the theme CSS file
|
||||
*/
|
||||
function loadTheme() {
|
||||
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 });
|
||||
|
||||
let cssStylesheet = _defaultCssStylesheet;
|
||||
if (_cssStylesheet != null)
|
||||
cssStylesheet = _cssStylesheet;
|
||||
|
||||
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
|
||||
themeContext.set_theme (theme);
|
||||
}
|
||||
|
||||
@ -265,10 +297,8 @@ function _relayout() {
|
||||
|
||||
// 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.
|
||||
// will be updated when it is next shown.
|
||||
overview.hide();
|
||||
panel.hideCalendar();
|
||||
}
|
||||
|
||||
// metacity-clutter currently uses the same prefs as plain metacity,
|
||||
|
@ -254,6 +254,7 @@ Notification.prototype = {
|
||||
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
||||
this.isTransient = false;
|
||||
this.expanded = false;
|
||||
this._destroyed = false;
|
||||
this._useActionIcons = false;
|
||||
this._customContent = false;
|
||||
this._bannerBodyText = null;
|
||||
@ -274,7 +275,11 @@ Notification.prototype = {
|
||||
this._capturedEventId = 0;
|
||||
this._keyPressId = 0;
|
||||
|
||||
source.connect('destroy', Lang.bind(this, this.destroy));
|
||||
source.connect('destroy', Lang.bind(this,
|
||||
// Avoid passing 'source' as an argument to this.destroy()
|
||||
function () {
|
||||
this.destroy();
|
||||
}));
|
||||
|
||||
this.actor = new St.Table({ name: 'notification',
|
||||
reactive: true });
|
||||
@ -767,6 +772,9 @@ Notification.prototype = {
|
||||
},
|
||||
|
||||
destroy: function(reason) {
|
||||
if (this._destroyed)
|
||||
return;
|
||||
this._destroyed = true;
|
||||
if (!reason)
|
||||
reason = NotificationDestroyedReason.DISMISSED;
|
||||
this.emit('destroy', reason);
|
||||
|
142
js/ui/panel.js
142
js/ui/panel.js
@ -17,6 +17,7 @@ const Overview = imports.ui.overview;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const StatusMenu = imports.ui.statusMenu;
|
||||
const DateMenu = imports.ui.dateMenu;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
@ -43,10 +44,6 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
|
||||
if (Config.HAVE_BLUETOOTH)
|
||||
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
||||
|
||||
const STANDARD_TRAY_INDICATOR_FACTORIES = [
|
||||
imports.ui.status.keyboard.ModifierIndicatorFactory
|
||||
];
|
||||
|
||||
// in org.gnome.desktop.interface
|
||||
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||
|
||||
@ -496,121 +493,6 @@ AppMenuButton.prototype = {
|
||||
|
||||
Signals.addSignalMethods(AppMenuButton.prototype);
|
||||
|
||||
function ClockButton() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ClockButton.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.Bin({ style_class: 'panel-button',
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
track_hover: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('button-press-event',
|
||||
Lang.bind(this, this._toggleCalendar));
|
||||
|
||||
this._clock = new St.Label();
|
||||
this.actor.set_child(this._clock);
|
||||
|
||||
this._calendarPopup = null;
|
||||
|
||||
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||
this._clockSettings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
||||
|
||||
this._desktopSettings.connect('changed', Lang.bind(this, this._updateClock));
|
||||
this._clockSettings.connect('changed', Lang.bind(this, this._updateClock));
|
||||
|
||||
// Start the clock
|
||||
this._updateClock();
|
||||
},
|
||||
|
||||
closeCalendar: function() {
|
||||
if (!this._calendarPopup || !this._calendarPopup.isOpen)
|
||||
return;
|
||||
|
||||
this._calendarPopup.hide();
|
||||
|
||||
this.actor.remove_style_pseudo_class('pressed');
|
||||
},
|
||||
|
||||
openCalendar: function() {
|
||||
this._calendarPopup.show();
|
||||
|
||||
this.actor.add_style_pseudo_class('pressed');
|
||||
},
|
||||
|
||||
_toggleCalendar: function() {
|
||||
if (this._calendarPopup == null) {
|
||||
this._calendarPopup = new CalendarPopup();
|
||||
this._calendarPopup.actor.hide();
|
||||
}
|
||||
|
||||
if (!this._calendarPopup.isOpen)
|
||||
this.openCalendar();
|
||||
else
|
||||
this.closeCalendar();
|
||||
},
|
||||
|
||||
_updateClock: function() {
|
||||
let format = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
||||
let showDate = this._clockSettings.get_boolean(CLOCK_SHOW_DATE_KEY);
|
||||
let showSeconds = this._clockSettings.get_boolean(CLOCK_SHOW_SECONDS_KEY);
|
||||
|
||||
let clockFormat;
|
||||
switch (format) {
|
||||
case '24h':
|
||||
if (showDate)
|
||||
/* Translators: This is the time format with date used
|
||||
in 24-hour mode. */
|
||||
clockFormat = showSeconds ? _("%a %b %e, %R:%S")
|
||||
: _("%a %b %e, %R");
|
||||
else
|
||||
/* Translators: This is the time format without date used
|
||||
in 24-hour mode. */
|
||||
clockFormat = showSeconds ? _("%a %R:%S")
|
||||
: _("%a %R");
|
||||
break;
|
||||
case '12h':
|
||||
default:
|
||||
if (showDate)
|
||||
/* Translators: This is a time format with date used
|
||||
for AM/PM. */
|
||||
clockFormat = showSeconds ? _("%a %b %e, %l:%M:%S %p")
|
||||
: _("%a %b %e, %l:%M %p");
|
||||
else
|
||||
/* Translators: This is a time format without date used
|
||||
for AM/PM. */
|
||||
clockFormat = showSeconds ? _("%a %l:%M:%S %p")
|
||||
: _("%a %l:%M %p");
|
||||
break;
|
||||
}
|
||||
|
||||
let displayDate = new Date();
|
||||
let msecRemaining;
|
||||
if (showSeconds) {
|
||||
msecRemaining = 1000 - displayDate.getMilliseconds();
|
||||
if (msecRemaining < 50) {
|
||||
displayDate.setSeconds(displayDate.getSeconds() + 1);
|
||||
msecRemaining += 1000;
|
||||
}
|
||||
} else {
|
||||
msecRemaining = 60000 - (1000 * displayDate.getSeconds() +
|
||||
displayDate.getMilliseconds());
|
||||
if (msecRemaining < 500) {
|
||||
displayDate.setMinutes(displayDate.getMinutes() + 1);
|
||||
msecRemaining += 60000;
|
||||
}
|
||||
}
|
||||
|
||||
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
|
||||
Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClock));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function Panel() {
|
||||
this._init();
|
||||
}
|
||||
@ -807,22 +689,19 @@ Panel.prototype = {
|
||||
this._menus.addMenu(appMenuButton.menu);
|
||||
|
||||
/* center */
|
||||
|
||||
this._clockButton = new ClockButton();
|
||||
this._centerBox.add(this._clockButton.actor, { y_fill: true });
|
||||
this._dateMenu = new DateMenu.DateMenuButton();
|
||||
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
||||
this._menus.addMenu(this._dateMenu.menu);
|
||||
|
||||
/* right */
|
||||
|
||||
// On-off indicators (for keyboard leds and accessx) are in indicatorBox
|
||||
// System status applets live in statusBox, and legacy tray icons
|
||||
// System status applets live in statusBox, while legacy tray icons
|
||||
// live in trayBox
|
||||
// The trayBox is hidden when there are no tray icons.
|
||||
this._indicatorBox = new St.BoxLayout({ name: 'indicatorBox' });
|
||||
this._trayBox = new St.BoxLayout({ name: 'legacyTray' });
|
||||
this._statusBox = new St.BoxLayout({ name: 'statusTray' });
|
||||
|
||||
this._trayBox.hide();
|
||||
this._rightBox.add(this._indicatorBox);
|
||||
this._rightBox.add(this._trayBox);
|
||||
this._rightBox.add(this._statusBox);
|
||||
|
||||
@ -874,13 +753,6 @@ Panel.prototype = {
|
||||
},
|
||||
|
||||
startStatusArea: function() {
|
||||
for (let i = 0; i < STANDARD_TRAY_INDICATOR_FACTORIES.length; i++) {
|
||||
let factory = new STANDARD_TRAY_INDICATOR_FACTORIES[i];
|
||||
let indicators = factory.getIndicators();
|
||||
for (let j = 0; j < indicators.length; j++)
|
||||
this._indicatorBox.add(indicators[j]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < STANDARD_TRAY_ICON_ORDER.length; i++) {
|
||||
let role = STANDARD_TRAY_ICON_ORDER[i];
|
||||
let constructor = STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION[role];
|
||||
@ -898,10 +770,6 @@ Panel.prototype = {
|
||||
this._rightBox.add(this._statusmenu.actor);
|
||||
},
|
||||
|
||||
hideCalendar: function() {
|
||||
this._clockButton.closeCalendar();
|
||||
},
|
||||
|
||||
startupAnimation: function() {
|
||||
this.actor.y = -this.actor.height;
|
||||
Tweener.addTween(this.actor,
|
||||
|
@ -204,52 +204,3 @@ XKBIndicator.prototype = {
|
||||
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
||||
}
|
||||
};
|
||||
|
||||
function ModifierIndicatorFactory() {
|
||||
this._init.call(this);
|
||||
}
|
||||
|
||||
ModifierIndicatorFactory.prototype = {
|
||||
_init: function() {
|
||||
this._settings = new Gio.Settings({ schema: INDICATOR_SCHEMA });
|
||||
this._settings.connect('changed::show-keyboard-leds-indicator', Lang.bind(this, this._changed));
|
||||
|
||||
this._config = Gkbd.Configuration.get();
|
||||
this._config.connect('indicators-changed', Lang.bind(this, this._changed));
|
||||
|
||||
this._scrollLock = new St.Icon({ icon_name: 'kbdled-scroll-lock', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
|
||||
this._numLock = new St.Icon({ icon_name: 'kbdled-num-lock', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
|
||||
this._capsLock = new St.Icon({ icon_name: 'kbdled-caps-lock', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
|
||||
|
||||
this._changed();
|
||||
},
|
||||
|
||||
getIndicators: function() {
|
||||
return [this._scrollLock, this._numLock, this._capsLock];
|
||||
},
|
||||
|
||||
_changed: function() {
|
||||
let enable = this._settings.get_boolean('show-keyboard-leds-indicator');
|
||||
|
||||
if (enable) {
|
||||
if (this._config.get_scroll_lock_state())
|
||||
this._scrollLock.show();
|
||||
else
|
||||
this._scrollLock.hide();
|
||||
|
||||
if (this._config.get_num_lock_state())
|
||||
this._numLock.show();
|
||||
else
|
||||
this._numLock.hide();
|
||||
|
||||
if (this._config.get_caps_lock_state())
|
||||
this._capsLock.show();
|
||||
else
|
||||
this._capsLock.hide();
|
||||
} else {
|
||||
this._scrollLock.hide();
|
||||
this._numLock.hide();
|
||||
this._capsLock.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
17
po/et.po
17
po/et.po
@ -13,14 +13,14 @@ 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: 2011-01-21 18:46+0000\n"
|
||||
"PO-Revision-Date: 2011-01-24 08:04+0200\n"
|
||||
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
|
||||
"POT-Creation-Date: 2011-01-29 18:34+0000\n"
|
||||
"PO-Revision-Date: 2011-02-01 13:51+0300\n"
|
||||
"Last-Translator: Mattias Põldaru <mahfiaz gmail com>\n"
|
||||
"Language-Team: Estonian <gnome-et@linux.ee>\n"
|
||||
"Language: et\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: et\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Language: Estonian\n"
|
||||
"X-Poedit-Country: Estonia\n"
|
||||
@ -242,6 +242,9 @@ msgstr ""
|
||||
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
|
||||
|
||||
msgid "Command not found"
|
||||
msgstr ""
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
msgid "Could not parse command:"
|
||||
@ -309,17 +312,17 @@ msgid "Logging out of the system."
|
||||
msgstr "Süsteemist väljalogimine"
|
||||
|
||||
msgid "Shut Down"
|
||||
msgstr "Seiska"
|
||||
msgstr "Lülita välja"
|
||||
|
||||
msgid "Click Shut Down to quit these applications and shut down the system."
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "The system will shut down automatically in %d seconds."
|
||||
msgstr "Süsteem seisatakse automaatselt %d sekundi pärast."
|
||||
msgstr "%d sekundi pärast lülitub süsteem automaatselt välja."
|
||||
|
||||
msgid "Shutting down the system."
|
||||
msgstr "Süsteemi seiskamine."
|
||||
msgstr "Süsteemi väljalülitamine."
|
||||
|
||||
msgid "Restart"
|
||||
msgstr "Taaskäivita"
|
||||
|
170
po/gl.po
170
po/gl.po
@ -10,8 +10,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-01-27 03:33+0100\n"
|
||||
"PO-Revision-Date: 2011-01-26 21:02+0100\n"
|
||||
"POT-Creation-Date: 2011-02-01 02:40+0100\n"
|
||||
"PO-Revision-Date: 2011-02-01 02:44+0100\n"
|
||||
"Last-Translator: Fran Diéguez <frandieguez@ubuntu.com>\n"
|
||||
"Language-Team: Galician <gnome-gl-list@gnome.org>\n"
|
||||
"Language: gl\n"
|
||||
@ -79,8 +79,8 @@ msgstr "Se é verdadeiro, móstrase a data da semana ISO no calendario."
|
||||
msgid "List of desktop file IDs for favorite applications"
|
||||
msgstr "Mostra os ID de ficheiros desktop para os aplicativos preferidos"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||
#, fuzzy
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#, no-c-format
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -89,31 +89,35 @@ msgid ""
|
||||
"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."
|
||||
"'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux' and "
|
||||
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
|
||||
"at the optimal thread count on the system."
|
||||
msgstr ""
|
||||
"Estabelece a tubería GStreamer usada para codificar gravacións. Segue a "
|
||||
"sintaxe usada para gst-launch. A tubería debería ter un sumideiro («sink») "
|
||||
"de ensamblaxe/desensamblaxe onde o vídeo que se está gravando grávase. "
|
||||
"Xeralmente terá unha orixe de ensamblado/desensamblado; a saída dese punto "
|
||||
"escribirase no ficheiro de saída. Porén, a tubería tamén pode tomar parte na "
|
||||
"súa propia saída; isto pódese usar para enviar a saída a un servidor "
|
||||
"«icecast» a través de shout2send ou similar. Cando non está estabelecido ou "
|
||||
"está a un valor baleiro, usarase a tubería predeterminada. Actualmente é "
|
||||
"«videorate ! theoraenc ! oggmux» e grava en Ogg Theora."
|
||||
"de ensamblaxe/desensamblaxe onde o vídeo gravado se grava. Xeralmente terá "
|
||||
"unha orixe de ensamblado/desensamblado; a saída dese punto escribirase no "
|
||||
"ficheiro de saída. Porén, a tubería tamén pode tomar parte na súa propia "
|
||||
"saída; isto pódese usar para enviar a saída a un servidor «icecast» a través "
|
||||
"de shout2send ou similar. Cando non está estabelecido ou está a un valor "
|
||||
"baleiro, usarase a tubería predeterminada. Actualmente é «! vp8enc "
|
||||
"quality=10 speed=2 threads=%T ! queue ! webmmux'» e grava en WEBM usando o "
|
||||
"códec VP8. Úsase %T como suposición para o número de fillos óptimos no "
|
||||
"sistema."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
msgid "Show date in clock"
|
||||
msgstr "Mostrar a data no reloxo"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
msgid "Show the week date in the calendar"
|
||||
msgstr "Mostrar a data da semana no calendario"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
msgid "Show time with seconds"
|
||||
msgstr "Mostrar a hora con segundos"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
msgid ""
|
||||
"The applications corresponding to these identifiers will be displayed in the "
|
||||
"favorites area."
|
||||
@ -121,7 +125,7 @@ msgstr ""
|
||||
"Os aplicativos que corresponden a estes identificadores mostraranse na área "
|
||||
"de preferidos."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -131,7 +135,7 @@ msgstr ""
|
||||
"baseado na data actual e usa esta extensión. Debería cambiar ao grabar nun "
|
||||
"formato de contedor diferente."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
msgid ""
|
||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||
"screencast recorder in frames-per-second."
|
||||
@ -139,11 +143,11 @@ msgstr ""
|
||||
"A taxa de marcos do screencast resultante grabado polo grabador de "
|
||||
"screencasts de GNOME Shell en marcos-por-segundo."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
msgid "The gstreamer pipeline used to encode the screencast"
|
||||
msgstr "A tubería de gstreamer usada para codificar o screencast"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
msgid ""
|
||||
"The shell normally monitors active applications in order to present the most "
|
||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||
@ -155,15 +159,15 @@ msgstr ""
|
||||
"privados, vostede pode desactivar isto por motivos de privacidade. Teña en "
|
||||
"conta que facendo isto non eliminará os datos gardados."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
msgid "Uuids of extensions to disable"
|
||||
msgstr "Os Uuid das extensións a desactivar"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||
msgid "Whether to collect stats about applications usage"
|
||||
msgstr "Indica se recoller estatísticas sobre o uso dos aplicativos"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||
msgid "disabled OpenSearch providers"
|
||||
msgstr "fornecedores de OpenSearch desactivados"
|
||||
|
||||
@ -321,43 +325,47 @@ msgstr ""
|
||||
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
msgstr "Anchura das liñas verticais e horizontais que contén o punto de mira."
|
||||
|
||||
#: ../js/misc/util.js:86
|
||||
msgid "Command not found"
|
||||
msgstr "Orde non atopada"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:108
|
||||
#: ../js/misc/util.js:113
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Non foi posíbel analizar a orde:"
|
||||
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:135
|
||||
msgid "No such application"
|
||||
msgstr "Non existe o aplicativo"
|
||||
|
||||
#: ../js/misc/util.js:143 ../js/ui/runDialog.js:351
|
||||
#: ../js/misc/util.js:148
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Produciuse un fallo na execución de «%s»:"
|
||||
|
||||
#. Translators: Filter to display all applications
|
||||
#: ../js/ui/appDisplay.js:155
|
||||
#: ../js/ui/appDisplay.js:164
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:236
|
||||
#: ../js/ui/appDisplay.js:245
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:266
|
||||
#: ../js/ui/appDisplay.js:275
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:563
|
||||
#: ../js/ui/appDisplay.js:572
|
||||
msgid "New Window"
|
||||
msgstr "Xanela nova"
|
||||
|
||||
#: ../js/ui/appDisplay.js:567
|
||||
#: ../js/ui/appDisplay.js:576
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Eliminar dos favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:568
|
||||
#: ../js/ui/appDisplay.js:577
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Engadir aos favoritos"
|
||||
|
||||
@ -482,71 +490,31 @@ msgstr "Ver fonte"
|
||||
msgid "Web Page"
|
||||
msgstr "Páxina web"
|
||||
|
||||
#: ../js/ui/messageTray.js:1765
|
||||
#: ../js/ui/messageTray.js:1786
|
||||
msgid "System Information"
|
||||
msgstr "Información do sistema"
|
||||
|
||||
#: ../js/ui/overview.js:75
|
||||
#: ../js/ui/overview.js:88
|
||||
msgid "Undo"
|
||||
msgstr "Desfacer"
|
||||
|
||||
#: ../js/ui/overview.js:140
|
||||
#: ../js/ui/overview.js:159
|
||||
msgid "Windows"
|
||||
msgstr "Xanelas"
|
||||
|
||||
#: ../js/ui/overview.js:143
|
||||
#: ../js/ui/overview.js:162
|
||||
msgid "Applications"
|
||||
msgstr "Aplicativos"
|
||||
|
||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
|
||||
#: ../js/ui/panel.js:479
|
||||
#: ../js/ui/panel.js:480
|
||||
#, c-format
|
||||
msgid "Quit %s"
|
||||
msgstr "Saír de %s"
|
||||
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:564
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %e de %b, %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:565
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e de %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:569
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:570
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:577
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e de %b, %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:578
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e de %b, %H:%M"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:582
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:583
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#. 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:728
|
||||
#: ../js/ui/panel.js:614
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
@ -701,7 +669,7 @@ msgstr "Produciuse un erro ao explorar o dispositivo"
|
||||
msgid "The requested device cannot be browsed, error is '%s'"
|
||||
msgstr "O dispositivo solicitado non pode explorarse, o erro foi «%s»"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:251 ../js/ui/status/keyboard.js:78
|
||||
#: ../js/ui/status/bluetooth.js:251
|
||||
msgid "Keyboard Settings"
|
||||
msgstr "Configuracións do teclado"
|
||||
|
||||
@ -776,6 +744,10 @@ msgstr "Introduza o PIN mencionado no dispositivo."
|
||||
msgid "OK"
|
||||
msgstr "Aceptar"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:78
|
||||
msgid "Localization Settings"
|
||||
msgstr "Configuracións do son"
|
||||
|
||||
#: ../js/ui/status/power.js:85
|
||||
msgid "Power Settings"
|
||||
msgstr "Configuracións de enerxía"
|
||||
@ -910,14 +882,14 @@ msgstr "%s rematou de iniarse"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "«%s» está preparado"
|
||||
|
||||
#: ../js/ui/workspacesView.js:244
|
||||
#: ../js/ui/workspacesView.js:243
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"Non é posíbel engadir unha área de traballo nova porque chegouse ao límite "
|
||||
"de áreas de traballo."
|
||||
|
||||
#: ../js/ui/workspacesView.js:260
|
||||
#: ../js/ui/workspacesView.js:259
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Non é posíbel quitar a primeira área de traballo."
|
||||
|
||||
@ -943,32 +915,32 @@ msgstr[1] "%u entradas"
|
||||
msgid "System Sounds"
|
||||
msgstr "Sons do sistema"
|
||||
|
||||
#: ../src/shell-global.c:1366
|
||||
#: ../src/shell-global.c:1365
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hai menos dun minuto"
|
||||
|
||||
#: ../src/shell-global.c:1370
|
||||
#: ../src/shell-global.c:1369
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "hai %d minuto"
|
||||
msgstr[1] "hai %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:1375
|
||||
#: ../src/shell-global.c:1374
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "hai %d hora"
|
||||
msgstr[1] "hai %d horas"
|
||||
|
||||
#: ../src/shell-global.c:1380
|
||||
#: ../src/shell-global.c:1379
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "hai %d día"
|
||||
msgstr[1] "hai %d días"
|
||||
|
||||
#: ../src/shell-global.c:1385
|
||||
#: ../src/shell-global.c:1384
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -999,9 +971,29 @@ msgstr "Buscar"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~| msgid "Sound Settings"
|
||||
#~ msgid "Localization Settings"
|
||||
#~ msgstr "Configuracións do son"
|
||||
#~ msgid "%a %b %e, %R:%S"
|
||||
#~ msgstr "%a %e de %b, %R:%S"
|
||||
|
||||
#~ msgid "%a %b %e, %R"
|
||||
#~ msgstr "%a %e de %b, %R"
|
||||
|
||||
#~ msgid "%a %R:%S"
|
||||
#~ msgstr "%a %R:%S"
|
||||
|
||||
#~ msgid "%a %R"
|
||||
#~ msgstr "%a %R"
|
||||
|
||||
#~ msgid "%a %b %e, %l:%M:%S %p"
|
||||
#~ msgstr "%a %e de %b, %H:%M:%S"
|
||||
|
||||
#~ msgid "%a %b %e, %l:%M %p"
|
||||
#~ msgstr "%a %e de %b, %H:%M"
|
||||
|
||||
#~ msgid "%a %l:%M:%S %p"
|
||||
#~ msgstr "%a %H:%M:%S"
|
||||
|
||||
#~ msgid "%a %l:%M %p"
|
||||
#~ msgstr "%a %l:%M %p"
|
||||
|
||||
#~ msgid "Clock"
|
||||
#~ msgstr "Reloxo"
|
||||
|
68
po/he.po
68
po/he.po
@ -8,8 +8,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-01-23 02:42+0200\n"
|
||||
"PO-Revision-Date: 2011-01-23 02:43+0200\n"
|
||||
"POT-Creation-Date: 2011-01-30 23:03+0200\n"
|
||||
"PO-Revision-Date: 2011-01-30 23:03+0200\n"
|
||||
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
|
||||
"Language-Team: Hebrew <he@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -319,43 +319,47 @@ msgid "Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
msgstr ""
|
||||
"Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
|
||||
#: ../js/misc/util.js:86
|
||||
msgid "Command not found"
|
||||
msgstr "הפקודה לא נמצאה"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:108
|
||||
#: ../js/misc/util.js:113
|
||||
msgid "Could not parse command:"
|
||||
msgstr "לא ניתן לפענח את הפקודה:"
|
||||
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:135
|
||||
msgid "No such application"
|
||||
msgstr "אין כזה יישום"
|
||||
|
||||
#: ../js/misc/util.js:143 ../js/ui/runDialog.js:351
|
||||
#: ../js/misc/util.js:148
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "ההרצה של '%s' נכשלה:"
|
||||
|
||||
#. Translators: Filter to display all applications
|
||||
#: ../js/ui/appDisplay.js:155
|
||||
#: ../js/ui/appDisplay.js:164
|
||||
msgid "All"
|
||||
msgstr "הכול"
|
||||
|
||||
#: ../js/ui/appDisplay.js:236
|
||||
#: ../js/ui/appDisplay.js:245
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "יישומים"
|
||||
|
||||
#: ../js/ui/appDisplay.js:266
|
||||
#: ../js/ui/appDisplay.js:275
|
||||
msgid "PREFERENCES"
|
||||
msgstr "העדפות"
|
||||
|
||||
#: ../js/ui/appDisplay.js:563
|
||||
#: ../js/ui/appDisplay.js:572
|
||||
msgid "New Window"
|
||||
msgstr "חלון חדש"
|
||||
|
||||
#: ../js/ui/appDisplay.js:567
|
||||
#: ../js/ui/appDisplay.js:576
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "הסרה מהמועדפים"
|
||||
|
||||
#: ../js/ui/appDisplay.js:568
|
||||
#: ../js/ui/appDisplay.js:577
|
||||
msgid "Add to Favorites"
|
||||
msgstr "הוספה למועדפים"
|
||||
|
||||
@ -476,71 +480,71 @@ msgstr "צפייה במקור"
|
||||
msgid "Web Page"
|
||||
msgstr "דף אינטרנט"
|
||||
|
||||
#: ../js/ui/messageTray.js:1765
|
||||
#: ../js/ui/messageTray.js:1778
|
||||
msgid "System Information"
|
||||
msgstr "פרטי המערכת"
|
||||
|
||||
#: ../js/ui/overview.js:75
|
||||
#: ../js/ui/overview.js:88
|
||||
msgid "Undo"
|
||||
msgstr "ביטול"
|
||||
|
||||
#: ../js/ui/overview.js:140
|
||||
#: ../js/ui/overview.js:159
|
||||
msgid "Windows"
|
||||
msgstr "חלונות"
|
||||
|
||||
#: ../js/ui/overview.js:143
|
||||
#: ../js/ui/overview.js:162
|
||||
msgid "Applications"
|
||||
msgstr "יישומים"
|
||||
|
||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
|
||||
#: ../js/ui/panel.js:483
|
||||
#: ../js/ui/panel.js:479
|
||||
#, c-format
|
||||
msgid "Quit %s"
|
||||
msgstr "יציאה מ־%s"
|
||||
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:568
|
||||
#: ../js/ui/panel.js:564
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %b %e, %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:569
|
||||
#: ../js/ui/panel.js:565
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %b %e, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:573
|
||||
#: ../js/ui/panel.js:569
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:574
|
||||
#: ../js/ui/panel.js:570
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:581
|
||||
#: ../js/ui/panel.js:577
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %b %e, %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:582
|
||||
#: ../js/ui/panel.js:578
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %b %e, %l:%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:586
|
||||
#: ../js/ui/panel.js:582
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:587
|
||||
#: ../js/ui/panel.js:583
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#. 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:732
|
||||
#: ../js/ui/panel.js:728
|
||||
msgid "Activities"
|
||||
msgstr "פעילויות"
|
||||
|
||||
@ -912,12 +916,12 @@ msgstr "%s סיים את תהליך ההתחלה"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' מוכן"
|
||||
|
||||
#: ../js/ui/workspacesView.js:244
|
||||
#: ../js/ui/workspacesView.js:243
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr "לא ניתן להוסיף מרחבי עבודה כיוון שהם ממלאים את המכסה המרבית."
|
||||
|
||||
#: ../js/ui/workspacesView.js:260
|
||||
#: ../js/ui/workspacesView.js:259
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "לא ניתן להסיר את מרחב העבודה הראשון."
|
||||
|
||||
@ -945,11 +949,11 @@ msgstr[2] "2 קלטים"
|
||||
msgid "System Sounds"
|
||||
msgstr "צלילי מערכת"
|
||||
|
||||
#: ../src/shell-global.c:1366
|
||||
#: ../src/shell-global.c:1365
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "לפני פחות מדקה"
|
||||
|
||||
#: ../src/shell-global.c:1370
|
||||
#: ../src/shell-global.c:1369
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -957,7 +961,7 @@ msgstr[0] "לפני דקה"
|
||||
msgstr[1] "לפני %d דקות"
|
||||
msgstr[2] "לפני 2 דקות"
|
||||
|
||||
#: ../src/shell-global.c:1375
|
||||
#: ../src/shell-global.c:1374
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -965,7 +969,7 @@ msgstr[0] "לפני שעה"
|
||||
msgstr[1] "לפני %d שעות"
|
||||
msgstr[2] "לפני שעתיים"
|
||||
|
||||
#: ../src/shell-global.c:1380
|
||||
#: ../src/shell-global.c:1379
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -973,7 +977,7 @@ msgstr[0] "לפני יום"
|
||||
msgstr[1] "לפני %d ימים"
|
||||
msgstr[2] "לפני יומיים"
|
||||
|
||||
#: ../src/shell-global.c:1385
|
||||
#: ../src/shell-global.c:1384
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
105
po/it.po
105
po/it.po
@ -8,8 +8,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-01-21 01:16+0100\n"
|
||||
"PO-Revision-Date: 2011-01-15 01:19+0100\n"
|
||||
"POT-Creation-Date: 2011-01-29 16:06+0100\n"
|
||||
"PO-Revision-Date: 2011-01-29 16:06+0100\n"
|
||||
"Last-Translator: Luca Ferretti <lferrett@gnome.org>\n"
|
||||
"Language-Team: Italian <tp@lists.linux.it>\n"
|
||||
"Language: it\n"
|
||||
@ -76,7 +76,8 @@ msgstr "Se VERO, mostra il giorno della settimana ISO nel calendario."
|
||||
msgid "List of desktop file IDs for favorite applications"
|
||||
msgstr "Elenco di ID di file desktop per le applicazioni preferite"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#, fuzzy, no-c-format
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -85,7 +86,9 @@ msgid ""
|
||||
"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."
|
||||
"'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux' and "
|
||||
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
|
||||
"at the optimal thread count on the system."
|
||||
msgstr ""
|
||||
"Imposta la pipeline di GStreamer utilizzata per codificare le registrazioni, "
|
||||
"seguendo la sintassi di gst-launch. La pipeline dovrebbe disporre di un sink "
|
||||
@ -97,19 +100,19 @@ msgstr ""
|
||||
"alcun valore, viene usata la pipeline predefinita il cui valore è "
|
||||
"\"videorate ! theoraenc ! oggmux\" e che registra nel formato Ogg Theora."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
msgid "Show date in clock"
|
||||
msgstr "Mostra la data nell'orologio"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
msgid "Show the week date in the calendar"
|
||||
msgstr "Mostra il giorno della settimana nel calendario"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
msgid "Show time with seconds"
|
||||
msgstr "Mostra l'ora con i secondi"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
msgid ""
|
||||
"The applications corresponding to these identifiers will be displayed in the "
|
||||
"favorites area."
|
||||
@ -117,7 +120,7 @@ msgstr ""
|
||||
"Le applicazioni che corrispondono a questi identificatori vengono "
|
||||
"visualizzate nell'area dei preferiti."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -127,7 +130,7 @@ msgstr ""
|
||||
"data corrente e utilizza questa estensione. Dovrebbe essere modificato "
|
||||
"quando si registra utilizzando un diverso formato contenitore."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
msgid ""
|
||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||
"screencast recorder in frames-per-second."
|
||||
@ -135,12 +138,12 @@ msgstr ""
|
||||
"Il framerate in fotogrammi al secondo dello screencast registrato attraverso "
|
||||
"il registratore della GNOME Shell."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
msgid "The gstreamer pipeline used to encode the screencast"
|
||||
msgstr "La pipeline di gstreamer utilizzata per codificare lo screencast"
|
||||
|
||||
# (ndt) quel "in launchers" non mi convince...
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
msgid ""
|
||||
"The shell normally monitors active applications in order to present the most "
|
||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||
@ -152,16 +155,16 @@ msgstr ""
|
||||
"disabilitare questa funzionalità per motivi di privacy. I dati già salvati "
|
||||
"non verranno comunque rimossi."
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
msgid "Uuids of extensions to disable"
|
||||
msgstr "UUID delle estensioni da disabilitare"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||
msgid "Whether to collect stats about applications usage"
|
||||
msgstr ""
|
||||
"Indica se raccogliere statistiche riguardo l'utilizzo delle applicazioni"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||
msgid "disabled OpenSearch providers"
|
||||
msgstr ""
|
||||
|
||||
@ -290,43 +293,47 @@ msgstr ""
|
||||
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
msgstr ""
|
||||
|
||||
#: ../js/misc/util.js:86
|
||||
msgid "Command not found"
|
||||
msgstr ""
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:108
|
||||
#: ../js/misc/util.js:113
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Impossibile analizzare il comando:"
|
||||
|
||||
#: ../js/misc/util.js:130
|
||||
#: ../js/misc/util.js:135
|
||||
msgid "No such application"
|
||||
msgstr "Applicazione inesistente"
|
||||
|
||||
#: ../js/misc/util.js:143 ../js/ui/runDialog.js:351
|
||||
#: ../js/misc/util.js:148
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Esecuzione di «%s» non riuscita:"
|
||||
|
||||
#. Translators: Filter to display all applications
|
||||
#: ../js/ui/appDisplay.js:155
|
||||
#: ../js/ui/appDisplay.js:164
|
||||
msgid "All"
|
||||
msgstr "Tutte"
|
||||
|
||||
#: ../js/ui/appDisplay.js:236
|
||||
#: ../js/ui/appDisplay.js:245
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APPLICAZIONI"
|
||||
|
||||
#: ../js/ui/appDisplay.js:266
|
||||
#: ../js/ui/appDisplay.js:275
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENZE"
|
||||
|
||||
#: ../js/ui/appDisplay.js:563
|
||||
#: ../js/ui/appDisplay.js:572
|
||||
msgid "New Window"
|
||||
msgstr "Nuova finestra"
|
||||
|
||||
#: ../js/ui/appDisplay.js:567
|
||||
#: ../js/ui/appDisplay.js:576
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Rimuovi dai preferiti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:568
|
||||
#: ../js/ui/appDisplay.js:577
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Aggiungi ai preferiti"
|
||||
|
||||
@ -459,72 +466,72 @@ msgstr "Visualizza sorgente"
|
||||
msgid "Web Page"
|
||||
msgstr "Pagina web"
|
||||
|
||||
#: ../js/ui/messageTray.js:1765
|
||||
#: ../js/ui/messageTray.js:1778
|
||||
msgid "System Information"
|
||||
msgstr "Informazione di sistema"
|
||||
|
||||
#: ../js/ui/overview.js:75
|
||||
#: ../js/ui/overview.js:88
|
||||
msgid "Undo"
|
||||
msgstr "Annulla"
|
||||
|
||||
#: ../js/ui/overview.js:140
|
||||
#: ../js/ui/overview.js:159
|
||||
msgid "Windows"
|
||||
msgstr "Finestre"
|
||||
|
||||
#: ../js/ui/overview.js:143
|
||||
#: ../js/ui/overview.js:162
|
||||
msgid "Applications"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
|
||||
#: ../js/ui/panel.js:479
|
||||
#: ../js/ui/panel.js:483
|
||||
#, c-format
|
||||
msgid "Quit %s"
|
||||
msgstr "Chiudi %s"
|
||||
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:564
|
||||
#: ../js/ui/panel.js:568
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %e %b, %k.%M.%S"
|
||||
|
||||
# (ndt) proviamo col k, se non funge, sappiamo il perché...
|
||||
#: ../js/ui/panel.js:565
|
||||
#: ../js/ui/panel.js:569
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e %b, %k.%M"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:569
|
||||
#: ../js/ui/panel.js:573
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %k.%M.%S"
|
||||
|
||||
#: ../js/ui/panel.js:570
|
||||
#: ../js/ui/panel.js:574
|
||||
msgid "%a %R"
|
||||
msgstr "%a %k.%M"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:577
|
||||
#: ../js/ui/panel.js:581
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e %b, %l.%M.%S %P"
|
||||
|
||||
#: ../js/ui/panel.js:578
|
||||
#: ../js/ui/panel.js:582
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e %b, %l.%M %P"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:582
|
||||
#: ../js/ui/panel.js:586
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l.%M.%S %P"
|
||||
|
||||
#: ../js/ui/panel.js:583
|
||||
#: ../js/ui/panel.js:587
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l.%M %P"
|
||||
|
||||
#. 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:728
|
||||
#: ../js/ui/panel.js:732
|
||||
msgid "Activities"
|
||||
msgstr "Attività"
|
||||
|
||||
@ -553,7 +560,7 @@ msgstr "RISORSE E DISPOSITIVI"
|
||||
#. simply result in invisible toggle switches.
|
||||
#: ../js/ui/popupMenu.js:33
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
msgstr "toggle-switch-us"
|
||||
|
||||
#: ../js/ui/runDialog.js:209
|
||||
msgid "Please enter a command:"
|
||||
@ -683,7 +690,7 @@ msgstr "Errore nell'esplorare il dispositivo"
|
||||
msgid "The requested device cannot be browsed, error is '%s'"
|
||||
msgstr "Non è possibile esplorare il dispositivo richiesto, l'errore è «%s»"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:251 ../js/ui/status/keyboard.js:78
|
||||
#: ../js/ui/status/bluetooth.js:251
|
||||
msgid "Keyboard Settings"
|
||||
msgstr "Impostazioni tastiera"
|
||||
|
||||
@ -758,6 +765,10 @@ msgstr "Inserire il PIN indicato sul dispositivo."
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:78
|
||||
msgid "Localization Settings"
|
||||
msgstr "Impostazioni localizzazione"
|
||||
|
||||
#: ../js/ui/status/power.js:85
|
||||
msgid "Power Settings"
|
||||
msgstr "Impostazioni alimentazione"
|
||||
@ -896,14 +907,14 @@ msgid "'%s' is ready"
|
||||
msgstr "«%s» è pronto"
|
||||
|
||||
# (ndt) un po' liberetta...
|
||||
#: ../js/ui/workspacesView.js:244
|
||||
#: ../js/ui/workspacesView.js:243
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"Impossibile aggiungere un nuovo spazio di lavoro: raggiunto il limite "
|
||||
"massimo consentito."
|
||||
|
||||
#: ../js/ui/workspacesView.js:260
|
||||
#: ../js/ui/workspacesView.js:259
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Impossibile rimuovere il primo spazio di lavoro."
|
||||
|
||||
@ -929,32 +940,32 @@ msgstr[1] "%u ingressi"
|
||||
msgid "System Sounds"
|
||||
msgstr "Audio di sistema"
|
||||
|
||||
#: ../src/shell-global.c:1366
|
||||
#: ../src/shell-global.c:1365
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Meno di un minuto fa"
|
||||
|
||||
#: ../src/shell-global.c:1370
|
||||
#: ../src/shell-global.c:1369
|
||||
#, 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:1375
|
||||
#: ../src/shell-global.c:1374
|
||||
#, 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:1380
|
||||
#: ../src/shell-global.c:1379
|
||||
#, 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:1385
|
||||
#: ../src/shell-global.c:1384
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
173
po/pa.po
173
po/pa.po
@ -7,8 +7,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: 2011-01-15 00:23+0000\n"
|
||||
"PO-Revision-Date: 2011-01-16 11:07+0530\n"
|
||||
"POT-Creation-Date: 2011-01-27 20:47+0000\n"
|
||||
"PO-Revision-Date: 2011-01-29 07:39+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"
|
||||
@ -74,7 +74,8 @@ msgstr "ਜੇ ਚੋਣ ਕੀਤੀ ਤਾਂ ਕੈਲੰਡਰ ਵਿੱਚ
|
||||
msgid "List of desktop file IDs for favorite applications"
|
||||
msgstr "ਪਸੰਦੀਦਾ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਡੈਸਕਟਾਪ ਫਾਇਲ ID ਦੀ ਲਿਸਟ ਹੈ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#, no-c-format
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -83,29 +84,31 @@ msgid ""
|
||||
"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."
|
||||
"'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux' and "
|
||||
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
|
||||
"at the optimal thread count on the system."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
msgid "Show date in clock"
|
||||
msgstr "ਘੜੀ ਵਿੱਚ ਮਿਤੀ ਵੇਖੋ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
msgid "Show the week date in the calendar"
|
||||
msgstr "ਕੈਲੰਡਰ ਵਿੱਚ ਹਫ਼ਤਾ ਮਿਤੀ ਵੇਖੋ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
msgid "Show time with seconds"
|
||||
msgstr "ਸਮਾਂ ਵਿੱਚ ਸਕਿੰਟ ਵੇਖੋ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
msgid ""
|
||||
"The applications corresponding to these identifiers will be displayed in the "
|
||||
"favorites area."
|
||||
msgstr ""
|
||||
"ਇਹਨਾਂ ਐਂਡਟਟੀਫਾਇਰ ਨਾਲ ਸਬੰਧਿਤ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਪਸੰਦੀਦਾ ਖੇਤਰ 'ਚ ਵੇਖਾਇਆ ਜਾਵੇਗਾ।"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
msgid ""
|
||||
"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 "
|
||||
@ -117,7 +120,7 @@ msgstr ""
|
||||
"ਰਿਕਾਰਡ ਕੀਤਾ "
|
||||
"ਜਾਵੇਗਾ।"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
msgid ""
|
||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||
"screencast recorder in frames-per-second."
|
||||
@ -126,11 +129,11 @@ msgstr ""
|
||||
"ਫਰੇਮ ਪ੍ਰਤੀ "
|
||||
"ਸਕਿੰਟ 'ਚ ਹੈ।"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
msgid "The gstreamer pipeline used to encode the screencast"
|
||||
msgstr "ਸਕਰੀਨਕਾਸਟ ਇੰਕੋਡ ਕਰਨ ਲਈ ਵਰਤਣ ਵਾਸਤੇ ਜੀਸਟਰੀਮਰ ਪਾਇਪਲਾਇਨ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
msgid ""
|
||||
"The shell normally monitors active applications in order to present the most "
|
||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||
@ -145,14 +148,18 @@ msgstr ""
|
||||
"ਕਰਨ ਨਾਲ ਪਹਿਲਾਂ "
|
||||
"ਸੰਭਾਲਿਆ ਗਿਆ ਡਾਟਾ ਹਟਾਇਆ ਨਹੀਂ ਜਾਵੇਗਾ।"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
msgid "Uuids of extensions to disable"
|
||||
msgstr "ਇਕਟੈਨਸ਼ਨ ਦੀ Uuids ਬੰਦ ਹੈ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||
msgid "Whether to collect stats about applications usage"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ ਵਰਤੋਂ ਬਾਰੇ ਅੰਕੜੇ ਇੱਕਠੇ ਕਰਨੇ ਹਨ"
|
||||
|
||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||
msgid "disabled OpenSearch providers"
|
||||
msgstr "ਓਪਨਸਰਚ ਉਪਲੱਬਧ ਕਰਵਾਉਣ ਵਾਲੇ ਬੰਦ ਹਨ"
|
||||
|
||||
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:1
|
||||
msgid "Clip the crosshairs at the center"
|
||||
msgstr "ਸੈਂਟਰ ਉੱਤੇ ਕਰਾਂਸਹੇਅਰ ਕਲਿੱਪ ਕਰੋ"
|
||||
@ -290,45 +297,47 @@ msgstr ""
|
||||
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
|
||||
msgstr "ਵਰਟੀਕਲ ਤੇ ਹਰੀਜੱਟਲ ਲਾਈਨਾਂ ਦੀ ਚੌੜਾਈ, ਜੋ ਕਿ ਕਰਾਂਸਹੇਅਰ ਬਣਾਉਂਦੀਆਂ ਹਨ"
|
||||
|
||||
#: ../js/misc/util.js:86
|
||||
msgid "Command not found"
|
||||
msgstr "ਕਮਾਂਡ ਨਹੀਂ ਲੱਭੀ"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:108
|
||||
#| msgid "Please enter a command:"
|
||||
#: ../js/misc/util.js:113
|
||||
msgid "Could not parse command:"
|
||||
msgstr "ਕਮਾਂਡ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ:"
|
||||
|
||||
#: ../js/misc/util.js:130
|
||||
#| msgid "Applications"
|
||||
#: ../js/misc/util.js:135
|
||||
msgid "No such application"
|
||||
msgstr "ਇੰਞ ਦੀ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਹੈ"
|
||||
|
||||
#: ../js/misc/util.js:143 ../js/ui/runDialog.js:364
|
||||
#: ../js/misc/util.js:148
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ:"
|
||||
|
||||
#. Translators: Filter to display all applications
|
||||
#: ../js/ui/appDisplay.js:155
|
||||
#: ../js/ui/appDisplay.js:164
|
||||
msgid "All"
|
||||
msgstr "ਸਭ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:236
|
||||
#: ../js/ui/appDisplay.js:245
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:266
|
||||
#: ../js/ui/appDisplay.js:275
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ਪਸੰਦ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:563
|
||||
#: ../js/ui/appDisplay.js:572
|
||||
msgid "New Window"
|
||||
msgstr "ਨਵੀਂ ਵਿੰਡੋ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:567
|
||||
#: ../js/ui/appDisplay.js:576
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "ਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:568
|
||||
#: ../js/ui/appDisplay.js:577
|
||||
msgid "Add to Favorites"
|
||||
msgstr "ਪਸੰਦ 'ਚ ਸ਼ਾਮਲ ਕਰੋ"
|
||||
|
||||
@ -352,12 +361,10 @@ msgstr "ਤਾਜ਼ਾ ਆਈਟਮਾਂ"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:63
|
||||
#, c-format
|
||||
#| msgid "Log Out..."
|
||||
msgid "Log Out %s"
|
||||
msgstr "%s ਲਾਗਆਉਟ"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
|
||||
#| msgid "Log Out..."
|
||||
msgid "Log Out"
|
||||
msgstr "ਲਾਗਆਉਟ"
|
||||
|
||||
@ -381,7 +388,6 @@ msgid "Logging out of the system."
|
||||
msgstr "ਸਿਸਟਮ ਲਾਗ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
|
||||
#| msgid "Shut Down..."
|
||||
msgid "Shut Down"
|
||||
msgstr "ਬੰਦ ਕਰੋ"
|
||||
|
||||
@ -399,7 +405,6 @@ msgid "Shutting down the system."
|
||||
msgstr "ਸਿਸਟਮ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
|
||||
#| msgid "Restart..."
|
||||
msgid "Restart"
|
||||
msgstr "ਮੁੜ-ਚਾਲੂ ਕਰੋ"
|
||||
|
||||
@ -421,7 +426,7 @@ msgstr "ਸਿਸਟਮ ਮੁੜ-ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ
|
||||
msgid "Confirm"
|
||||
msgstr "ਪੁਸ਼ਟੀ"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:469
|
||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
|
||||
msgid "Cancel"
|
||||
msgstr "ਰੱਦ ਕਰੋ"
|
||||
|
||||
@ -455,89 +460,88 @@ msgstr "ਸਰੋਤ ਵੇਖੋ"
|
||||
msgid "Web Page"
|
||||
msgstr "ਵੈੱਬ ਪੇਜ਼"
|
||||
|
||||
#: ../js/ui/messageTray.js:1748
|
||||
#| msgid "Account Information..."
|
||||
#: ../js/ui/messageTray.js:1765
|
||||
msgid "System Information"
|
||||
msgstr "ਸਿਸਟਮ ਜਾਣਕਾਰੀ"
|
||||
|
||||
#: ../js/ui/overview.js:75
|
||||
#: ../js/ui/overview.js:88
|
||||
msgid "Undo"
|
||||
msgstr "ਵਾਪਸ"
|
||||
|
||||
#: ../js/ui/overview.js:140
|
||||
#: ../js/ui/overview.js:159
|
||||
msgid "Windows"
|
||||
msgstr "ਵਿੰਡੋ"
|
||||
|
||||
#: ../js/ui/overview.js:143
|
||||
#: ../js/ui/overview.js:162
|
||||
msgid "Applications"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
|
||||
#: ../js/ui/panel.js:479
|
||||
#: ../js/ui/panel.js:483
|
||||
#, c-format
|
||||
msgid "Quit %s"
|
||||
msgstr "%s ਬੰਦ ਕਰੋ"
|
||||
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:564
|
||||
#: ../js/ui/panel.js:568
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a, %e %b %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:565
|
||||
#: ../js/ui/panel.js:569
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:569
|
||||
#: ../js/ui/panel.js:573
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:570
|
||||
#: ../js/ui/panel.js:574
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:577
|
||||
#: ../js/ui/panel.js:581
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e %b, %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:578
|
||||
#: ../js/ui/panel.js:582
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e %b, %l:%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:582
|
||||
#: ../js/ui/panel.js:586
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:583
|
||||
#: ../js/ui/panel.js:587
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#. 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:728
|
||||
#: ../js/ui/panel.js:732
|
||||
msgid "Activities"
|
||||
msgstr "ਸਰਗਰਮੀਆਂ"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:112
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "'%s' ਅਣ-ਮਾਊਂਟ ਕਰਨ ਲਈ ਫੇਲ੍ਹ"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:115
|
||||
#: ../js/ui/placeDisplay.js:109
|
||||
msgid "Retry"
|
||||
msgstr "ਮੁੜ-ਕੋਸ਼ਿਸ਼"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:160
|
||||
#: ../js/ui/placeDisplay.js:150
|
||||
msgid "Connect to..."
|
||||
msgstr "...ਨਾਲ ਕੁਨੈਕਟ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:559
|
||||
#: ../js/ui/placeDisplay.js:386
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ਥਾਵਾਂ ਤੇ ਜੰਤਰ"
|
||||
|
||||
@ -550,7 +554,7 @@ msgstr "ਥਾਵਾਂ ਤੇ ਜੰਤਰ"
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-us"
|
||||
|
||||
#: ../js/ui/runDialog.js:222
|
||||
#: ../js/ui/runDialog.js:209
|
||||
msgid "Please enter a command:"
|
||||
msgstr "ਕਮਾਂਡ ਦਿਓ ਜੀ:"
|
||||
|
||||
@ -634,7 +638,7 @@ msgstr "ਵੱਧ ਕਨਟਰਾਸਟ"
|
||||
msgid "Large Text"
|
||||
msgstr "ਵੱਡੇ ਅੱਖਰ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:240
|
||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
|
||||
msgid "Bluetooth"
|
||||
msgstr "ਬਲਿਊਟੁੱਥ"
|
||||
|
||||
@ -650,106 +654,111 @@ msgstr "...ਜੰਤਰ ਨੂੰ ਫਾਇਲਾਂ ਭੇਜੋ"
|
||||
msgid "Setup a New Device..."
|
||||
msgstr "...ਨਵਾਂ ਜੰਤਰ ਸੈਟਅੱਪ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:94
|
||||
#: ../js/ui/status/bluetooth.js:95
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "ਬਲਿਊਟੁੱਥ ਸੈਟਿੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:191
|
||||
#: ../js/ui/status/bluetooth.js:192
|
||||
msgid "Connection"
|
||||
msgstr "ਕੁਨੈਕਸ਼ਨ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:227
|
||||
#: ../js/ui/status/bluetooth.js:228
|
||||
msgid "Send Files..."
|
||||
msgstr "...ਫਾਇਲਾਂ ਭੇਜੋ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:232
|
||||
#: ../js/ui/status/bluetooth.js:233
|
||||
msgid "Browse Files..."
|
||||
msgstr "...ਫਾਇਲਾਂ ਦੀ ਝਲਕ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:241
|
||||
#: ../js/ui/status/bluetooth.js:242
|
||||
msgid "Error browsing device"
|
||||
msgstr "ਜੰਤਰ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਗਲਤੀ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:242
|
||||
#: ../js/ui/status/bluetooth.js:243
|
||||
#, c-format
|
||||
msgid "The requested device cannot be browsed, error is '%s'"
|
||||
msgstr "ਮੰਗ ਕੀਤੇ ਗਏ ਜੰਤਰ ਨੂੰ ਬਰਾਊਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ, ਗਲਤੀ ਸੀ '%s'"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:250 ../js/ui/status/keyboard.js:78
|
||||
#: ../js/ui/status/bluetooth.js:251
|
||||
msgid "Keyboard Settings"
|
||||
msgstr "ਕੀਬੋਰਡ ਸੈਟਿੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:255
|
||||
#: ../js/ui/status/bluetooth.js:256
|
||||
msgid "Mouse Settings"
|
||||
msgstr "ਮਾਊਸ ਸੈਟਿੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:262 ../js/ui/status/volume.js:63
|
||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:63
|
||||
msgid "Sound Settings"
|
||||
msgstr "ਸਾਊਂਡ ਸੈਟਿੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:336 ../js/ui/status/bluetooth.js:370
|
||||
#: ../js/ui/status/bluetooth.js:410 ../js/ui/status/bluetooth.js:443
|
||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
|
||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
|
||||
msgid "Bluetooth Agent"
|
||||
msgstr "ਬਲਿਊਟੁੱਥ ਏਜੰਟ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:371
|
||||
#: ../js/ui/status/bluetooth.js:372
|
||||
#, c-format
|
||||
msgid "Authorization request from %s"
|
||||
msgstr "'%s' ਤੋਂ ਪਰਮਾਣਕਿਤਾ ਮੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:377
|
||||
#: ../js/ui/status/bluetooth.js:378
|
||||
#, c-format
|
||||
msgid "Device %s wants access to the service '%s'"
|
||||
msgstr "ਜੰਤਰ %s ਸਰਵਿਸ '%s' ਨੂੰ ਵਰਤਣੀ ਚਾਹੁੰਦਾ ਹੈ।"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:379
|
||||
#: ../js/ui/status/bluetooth.js:380
|
||||
msgid "Always grant access"
|
||||
msgstr "ਹਮੇਸ਼ਾ ਪਹੁੰਚ ਮਨਜ਼ੂਰ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:380
|
||||
#: ../js/ui/status/bluetooth.js:381
|
||||
msgid "Grant this time only"
|
||||
msgstr "ਕੇਵਲ ਇਸ ਸਮੇਂ ਹੀ ਮਨਜ਼ੂਰ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:381
|
||||
#: ../js/ui/status/bluetooth.js:382
|
||||
msgid "Reject"
|
||||
msgstr "ਨਾ-ਮਨਜ਼ੂਰ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:411
|
||||
#: ../js/ui/status/bluetooth.js:412
|
||||
#, c-format
|
||||
msgid "Pairing confirmation for %s"
|
||||
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਪੁਸ਼ਟੀ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:417 ../js/ui/status/bluetooth.js:451
|
||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
|
||||
#, c-format
|
||||
msgid "Device %s wants to pair with this computer"
|
||||
msgstr "ਜੰਤਰ %s ਇਸ ਕੰਪਿਊਟਰ ਨਾਲ ਪੇਅਰ ਹੋਣਾ ਚਾਹੁੰਦਾ ਹੈ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:418
|
||||
#: ../js/ui/status/bluetooth.js:419
|
||||
#, c-format
|
||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
|
||||
msgstr "ਪੁਸ਼ਟੀ ਕਰੋ ਜੀ ਕਿ ਪਿੰਨ '%s' ਜੰਤਰ ਉੱਤੇ ਮੌਜੂਦ ਪਿੰਨ ਨਾਲ ਮਿਲਦਾ ਹੈ।"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:420
|
||||
#: ../js/ui/status/bluetooth.js:421
|
||||
msgid "Matches"
|
||||
msgstr "ਮਿਲਦਾ ਹੈ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:421
|
||||
#: ../js/ui/status/bluetooth.js:422
|
||||
msgid "Does not match"
|
||||
msgstr "ਮਿਲਦਾ ਨਹੀਂ ਹੈ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:444
|
||||
#: ../js/ui/status/bluetooth.js:445
|
||||
#, c-format
|
||||
msgid "Pairing request for %s"
|
||||
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਮੰਗ"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:452
|
||||
#: ../js/ui/status/bluetooth.js:453
|
||||
msgid "Please enter the PIN mentioned on the device."
|
||||
msgstr "ਜੰਤਰ ਉੱਤੇ ਦਿੱਤਾ ਗਿਆ ਪਿੰਨ ਦਿਉ ਜੀ।"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:468
|
||||
#: ../js/ui/status/bluetooth.js:469
|
||||
msgid "OK"
|
||||
msgstr "ਠੀਕ ਹੈ"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:78
|
||||
#| msgid "Sound Settings"
|
||||
msgid "Localization Settings"
|
||||
msgstr "ਲੋਕਲਾਈਜ਼ੇਸ਼ਨ ਸੈਟਿੰਗ"
|
||||
|
||||
#: ../js/ui/status/power.js:85
|
||||
msgid "Power Settings"
|
||||
msgstr "ਪਾਵਰ ਸੈਟਿੰਗ"
|
||||
@ -884,14 +893,14 @@ msgstr "%s ਸ਼ੁਰੂ ਹੋਣਾ ਖਤਮ ਹੋਇਆ"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' ਤਿਆਰ ਹੈ"
|
||||
|
||||
#: ../js/ui/workspacesView.js:244
|
||||
#: ../js/ui/workspacesView.js:243
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"ਨਵਾਂ ਵਰਕਸਪੇਸ ਜੋੜਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਕਿਉਂਕਿ ਵਰਕਸਪੇਸਾਂ ਦੀ ਵੱਧੋ-ਵੱਧ ਗਿਣਤੀ ਪੂਰੀ ਹੋ "
|
||||
"ਚੁੱਕੀ ਹੈ।"
|
||||
|
||||
#: ../js/ui/workspacesView.js:260
|
||||
#: ../js/ui/workspacesView.js:259
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "ਪਹਿਲਾਂ ਵਰਕਸਪੇਸ ਨਹੀਂ ਹਟਾਇਆ ਜਾ ਸਕਦਾ।"
|
||||
|
||||
@ -917,32 +926,32 @@ msgstr[1] "%u ਇੰਪੁੱਟ"
|
||||
msgid "System Sounds"
|
||||
msgstr "ਸਿਸਟਮ ਸਾਊਂਡ"
|
||||
|
||||
#: ../src/shell-global.c:1233
|
||||
#: ../src/shell-global.c:1365
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "ਇੱਕ ਮਿੰਟ ਤੋਂ ਘੱਟ ਚਿਰ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:1237
|
||||
#: ../src/shell-global.c:1369
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:1242
|
||||
#: ../src/shell-global.c:1374
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:1247
|
||||
#: ../src/shell-global.c:1379
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:1252
|
||||
#: ../src/shell-global.c:1384
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
22
src/Makefile-calendar-client.am
Normal file
22
src/Makefile-calendar-client.am
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
noinst_LTLIBRARIES += libcalendar-client.la
|
||||
|
||||
libcalendar_client_la_SOURCES = \
|
||||
calendar-client/calendar-client.h calendar-client/calendar-client.c \
|
||||
calendar-client/calendar-debug.h \
|
||||
calendar-client/calendar-sources.c calendar-client/calendar-sources.h \
|
||||
$(NULL)
|
||||
|
||||
libcalendar_client_la_CFLAGS = \
|
||||
-I$(top_srcdir)/src \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DDATADIR=\""$(datadir)"\" \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DG_LOG_DOMAIN=\"CalendarClient\" \
|
||||
$(LIBECAL_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
libcalendar_client_la_LIBADD = $(LIBECAL_LIBS)
|
||||
|
||||
EXTRA_DIST += calendar-client/README
|
@ -27,6 +27,7 @@ include Makefile-gdmuser.am
|
||||
include Makefile-st.am
|
||||
include Makefile-tray.am
|
||||
include Makefile-gvc.am
|
||||
include Makefile-calendar-client.am
|
||||
|
||||
gnome_shell_cflags = \
|
||||
$(MUTTER_PLUGIN_CFLAGS) \
|
||||
@ -89,6 +90,8 @@ libgnome_shell_la_SOURCES = \
|
||||
shell-doc-system.c \
|
||||
shell-drawing.c \
|
||||
shell-embedded-window.c \
|
||||
shell-evolution-event-source.h \
|
||||
shell-evolution-event-source.c \
|
||||
shell-generic-container.c \
|
||||
shell-gtk-embed.c \
|
||||
shell-global.c \
|
||||
@ -212,7 +215,9 @@ libgnome_shell_la_LIBADD = \
|
||||
libst-1.0.la \
|
||||
libgdmuser-1.0.la \
|
||||
libtray.la \
|
||||
libgvc.la
|
||||
libgvc.la \
|
||||
libcalendar-client.la \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||
|
||||
|
1
src/calendar-client/README
Normal file
1
src/calendar-client/README
Normal file
@ -0,0 +1 @@
|
||||
Please keep in sync with gnome-panel.
|
2169
src/calendar-client/calendar-client.c
Normal file
2169
src/calendar-client/calendar-client.c
Normal file
File diff suppressed because it is too large
Load Diff
149
src/calendar-client/calendar-client.h
Normal file
149
src/calendar-client/calendar-client.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <mark@skynet.ie>
|
||||
* William Jon McCann <mccann@jhu.edu>
|
||||
* Martin Grimme <martin@pycage.de>
|
||||
* Christian Kellner <gicmo@xatom.net>
|
||||
*/
|
||||
|
||||
#ifndef __CALENDAR_CLIENT_H__
|
||||
#define __CALENDAR_CLIENT_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CALENDAR_EVENT_APPOINTMENT = 1 << 0,
|
||||
CALENDAR_EVENT_TASK = 1 << 1,
|
||||
CALENDAR_EVENT_ALL = (1 << 2) - 1
|
||||
} CalendarEventType;
|
||||
|
||||
#define CALENDAR_TYPE_CLIENT (calendar_client_get_type ())
|
||||
#define CALENDAR_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CALENDAR_TYPE_CLIENT, CalendarClient))
|
||||
#define CALENDAR_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CALENDAR_TYPE_CLIENT, CalendarClientClass))
|
||||
#define CALENDAR_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CALENDAR_TYPE_CLIENT))
|
||||
#define CALENDAR_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CALENDAR_TYPE_CLIENT))
|
||||
#define CALENDAR_CLIENT_GET_CLASS(o)(G_TYPE_INSTANCE_GET_CLASS ((o), CALENDAR_TYPE_CLIENT, CalendarClientClass))
|
||||
|
||||
typedef struct _CalendarClient CalendarClient;
|
||||
typedef struct _CalendarClientClass CalendarClientClass;
|
||||
typedef struct _CalendarClientPrivate CalendarClientPrivate;
|
||||
|
||||
struct _CalendarClient
|
||||
{
|
||||
GObject parent;
|
||||
CalendarClientPrivate *priv;
|
||||
};
|
||||
|
||||
struct _CalendarClientClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* appointments_changed) (CalendarClient *client);
|
||||
void (* tasks_changed) (CalendarClient *client);
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t start_time;
|
||||
time_t end_time;
|
||||
} CalendarOccurrence;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *uid;
|
||||
char *rid;
|
||||
char *uri;
|
||||
char *summary;
|
||||
char *description;
|
||||
char *color_string;
|
||||
time_t start_time;
|
||||
time_t end_time;
|
||||
guint is_all_day : 1;
|
||||
|
||||
/* Only used internally */
|
||||
GSList *occurrences;
|
||||
} CalendarAppointment;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *uid;
|
||||
char *summary;
|
||||
char *description;
|
||||
char *color_string;
|
||||
char *url;
|
||||
time_t start_time;
|
||||
time_t due_time;
|
||||
guint percent_complete;
|
||||
time_t completed_time;
|
||||
int priority;
|
||||
} CalendarTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
CalendarAppointment appointment;
|
||||
CalendarTask task;
|
||||
} event;
|
||||
CalendarEventType type;
|
||||
} CalendarEvent;
|
||||
|
||||
#define CALENDAR_EVENT(e) ((CalendarEvent *)(e))
|
||||
#define CALENDAR_APPOINTMENT(e) ((CalendarAppointment *)(e))
|
||||
#define CALENDAR_TASK(e) ((CalendarTask *)(e))
|
||||
|
||||
typedef void (* CalendarDayIter) (CalendarClient *client,
|
||||
guint day,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
GType calendar_client_get_type (void) G_GNUC_CONST;
|
||||
CalendarClient *calendar_client_new (void);
|
||||
|
||||
void calendar_client_get_date (CalendarClient *client,
|
||||
guint *year,
|
||||
guint *month,
|
||||
guint *day);
|
||||
void calendar_client_select_month (CalendarClient *client,
|
||||
guint month,
|
||||
guint year);
|
||||
void calendar_client_select_day (CalendarClient *client,
|
||||
guint day);
|
||||
|
||||
GSList *calendar_client_get_events (CalendarClient *client,
|
||||
CalendarEventType event_mask);
|
||||
void calendar_client_foreach_appointment_day (CalendarClient *client,
|
||||
CalendarDayIter iter_func,
|
||||
gpointer user_data);
|
||||
|
||||
void calendar_client_set_task_completed (CalendarClient *client,
|
||||
char *task_uid,
|
||||
gboolean task_completed,
|
||||
guint percent_complete);
|
||||
|
||||
void calendar_event_free (CalendarEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALENDAR_CLIENT_H__ */
|
52
src/calendar-client/calendar-debug.h
Normal file
52
src/calendar-client/calendar-debug.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <mark@skynet.ie>
|
||||
*/
|
||||
|
||||
#ifndef __CALENDAR_DEBUG_H__
|
||||
#define __CALENDAR_DEBUG_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef CALENDAR_ENABLE_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef G_HAVE_ISO_VARARGS
|
||||
# define dprintf(...) fprintf (stderr, __VA_ARGS__);
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
# define dprintf(args...) fprintf (stderr, args);
|
||||
#endif
|
||||
|
||||
#else /* if !defined (CALENDAR_DEBUG) */
|
||||
|
||||
#ifdef G_HAVE_ISO_VARARGS
|
||||
# define dprintf(...)
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
# define dprintf(args...)
|
||||
#endif
|
||||
|
||||
#endif /* CALENDAR_ENABLE_DEBUG */
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALENDAR_DEBUG_H__ */
|
658
src/calendar-client/calendar-sources.c
Normal file
658
src/calendar-client/calendar-sources.c
Normal file
@ -0,0 +1,658 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <mark@skynet.ie>
|
||||
* William Jon McCann <mccann@jhu.edu>
|
||||
* Martin Grimme <martin@pycage.de>
|
||||
* Christian Kellner <gicmo@xatom.net>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "calendar-sources.h"
|
||||
|
||||
#include <libintl.h>
|
||||
#include <string.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#define HANDLE_LIBICAL_MEMORY
|
||||
#include <libecal/e-cal.h>
|
||||
#include <libedataserver/e-source-list.h>
|
||||
#include <libedataserverui/e-passwords.h>
|
||||
|
||||
#undef CALENDAR_ENABLE_DEBUG
|
||||
#include "calendar-debug.h"
|
||||
|
||||
#ifndef _
|
||||
#define _(x) gettext(x)
|
||||
#endif
|
||||
|
||||
#ifndef N_
|
||||
#define N_(x) x
|
||||
#endif
|
||||
|
||||
#define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate))
|
||||
|
||||
#define CALENDAR_SOURCES_EVO_DIR "/apps/evolution"
|
||||
#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/calendar/sources"
|
||||
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/display"
|
||||
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR "/selected_calendars"
|
||||
#define CALENDAR_SOURCES_TASK_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/tasks/sources"
|
||||
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR CALENDAR_SOURCES_EVO_DIR "/calendar/tasks"
|
||||
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR "/selected_tasks"
|
||||
|
||||
typedef struct _CalendarSourceData CalendarSourceData;
|
||||
|
||||
struct _CalendarSourceData
|
||||
{
|
||||
ECalSourceType source_type;
|
||||
CalendarSources *sources;
|
||||
guint changed_signal;
|
||||
|
||||
GSList *clients;
|
||||
GSList *selected_sources;
|
||||
ESourceList *esource_list;
|
||||
|
||||
guint selected_sources_listener;
|
||||
char *selected_sources_dir;
|
||||
|
||||
guint timeout_id;
|
||||
|
||||
guint loaded : 1;
|
||||
};
|
||||
|
||||
struct _CalendarSourcesPrivate
|
||||
{
|
||||
CalendarSourceData appointment_sources;
|
||||
CalendarSourceData task_sources;
|
||||
|
||||
GConfClient *gconf_client;
|
||||
};
|
||||
|
||||
static void calendar_sources_class_init (CalendarSourcesClass *klass);
|
||||
static void calendar_sources_init (CalendarSources *sources);
|
||||
static void calendar_sources_finalize (GObject *object);
|
||||
|
||||
static void backend_died_cb (ECal *client, CalendarSourceData *source_data);
|
||||
static void calendar_sources_esource_list_changed (ESourceList *source_list,
|
||||
CalendarSourceData *source_data);
|
||||
|
||||
enum
|
||||
{
|
||||
APPOINTMENT_SOURCES_CHANGED,
|
||||
TASK_SOURCES_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint signals [LAST_SIGNAL] = { 0, };
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static CalendarSources *calendar_sources_singleton = NULL;
|
||||
|
||||
GType
|
||||
calendar_sources_get_type (void)
|
||||
{
|
||||
static GType sources_type = 0;
|
||||
|
||||
if (!sources_type)
|
||||
{
|
||||
static const GTypeInfo sources_info =
|
||||
{
|
||||
sizeof (CalendarSourcesClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) calendar_sources_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (CalendarSources),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) calendar_sources_init,
|
||||
};
|
||||
|
||||
sources_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"CalendarSources",
|
||||
&sources_info, 0);
|
||||
}
|
||||
|
||||
return sources_type;
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_class_init (CalendarSourcesClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = calendar_sources_finalize;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (CalendarSourcesPrivate));
|
||||
|
||||
signals [APPOINTMENT_SOURCES_CHANGED] =
|
||||
g_signal_new ("appointment-sources-changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (CalendarSourcesClass,
|
||||
appointment_sources_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
signals [TASK_SOURCES_CHANGED] =
|
||||
g_signal_new ("task-sources-changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (CalendarSourcesClass,
|
||||
task_sources_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_init (CalendarSources *sources)
|
||||
{
|
||||
sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
|
||||
|
||||
sources->priv->appointment_sources.source_type = E_CAL_SOURCE_TYPE_EVENT;
|
||||
sources->priv->appointment_sources.sources = sources;
|
||||
sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
|
||||
sources->priv->appointment_sources.timeout_id = 0;
|
||||
|
||||
sources->priv->task_sources.source_type = E_CAL_SOURCE_TYPE_TODO;
|
||||
sources->priv->task_sources.sources = sources;
|
||||
sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
|
||||
sources->priv->task_sources.timeout_id = 0;
|
||||
|
||||
sources->priv->gconf_client = gconf_client_get_default ();
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_finalize_source_data (CalendarSources *sources,
|
||||
CalendarSourceData *source_data)
|
||||
{
|
||||
if (source_data->loaded)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (source_data->selected_sources_dir)
|
||||
{
|
||||
gconf_client_remove_dir (sources->priv->gconf_client,
|
||||
source_data->selected_sources_dir,
|
||||
NULL);
|
||||
|
||||
g_free (source_data->selected_sources_dir);
|
||||
source_data->selected_sources_dir = NULL;
|
||||
}
|
||||
|
||||
if (source_data->selected_sources_listener)
|
||||
{
|
||||
gconf_client_notify_remove (sources->priv->gconf_client,
|
||||
source_data->selected_sources_listener);
|
||||
source_data->selected_sources_listener = 0;
|
||||
}
|
||||
|
||||
for (l = source_data->clients; l; l = l->next)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
|
||||
G_CALLBACK (backend_died_cb),
|
||||
source_data);
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
g_slist_free (source_data->clients);
|
||||
source_data->clients = NULL;
|
||||
|
||||
if (source_data->esource_list)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (source_data->esource_list,
|
||||
G_CALLBACK (calendar_sources_esource_list_changed),
|
||||
source_data);
|
||||
g_object_unref (source_data->esource_list);
|
||||
}
|
||||
source_data->esource_list = NULL;
|
||||
|
||||
for (l = source_data->selected_sources; l; l = l->next)
|
||||
g_free (l->data);
|
||||
g_slist_free (source_data->selected_sources);
|
||||
source_data->selected_sources = NULL;
|
||||
|
||||
if (source_data->timeout_id != 0)
|
||||
{
|
||||
g_source_remove (source_data->timeout_id);
|
||||
source_data->timeout_id = 0;
|
||||
}
|
||||
|
||||
source_data->loaded = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_finalize (GObject *object)
|
||||
{
|
||||
CalendarSources *sources = CALENDAR_SOURCES (object);
|
||||
|
||||
calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
|
||||
calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
|
||||
|
||||
if (sources->priv->gconf_client)
|
||||
g_object_unref (sources->priv->gconf_client);
|
||||
sources->priv->gconf_client = NULL;
|
||||
|
||||
if (G_OBJECT_CLASS (parent_class)->finalize)
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
CalendarSources *
|
||||
calendar_sources_get (void)
|
||||
{
|
||||
gpointer singleton_location = &calendar_sources_singleton;
|
||||
|
||||
if (calendar_sources_singleton)
|
||||
return g_object_ref (calendar_sources_singleton);
|
||||
|
||||
calendar_sources_singleton = g_object_new (CALENDAR_TYPE_SOURCES, NULL);
|
||||
g_object_add_weak_pointer (G_OBJECT (calendar_sources_singleton),
|
||||
singleton_location);
|
||||
|
||||
return calendar_sources_singleton;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_source_selected (ESource *esource,
|
||||
GSList *selected_sources)
|
||||
{
|
||||
const char *uid;
|
||||
GSList *l;
|
||||
|
||||
uid = e_source_peek_uid (esource);
|
||||
|
||||
for (l = selected_sources; l; l = l->next)
|
||||
{
|
||||
const char *source = l->data;
|
||||
|
||||
if (!strcmp (source, uid))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
auth_func_cb (ECal *ecal,
|
||||
const char *prompt,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
ESource *source;
|
||||
const gchar *auth_domain;
|
||||
const gchar *component_name;
|
||||
|
||||
source = e_cal_get_source (ecal);
|
||||
auth_domain = e_source_get_property (source, "auth-domain");
|
||||
component_name = auth_domain ? auth_domain : "Calendar";
|
||||
|
||||
return e_passwords_get_password (component_name, key);
|
||||
}
|
||||
|
||||
/* The clients are just created here but not loaded */
|
||||
static ECal *
|
||||
get_ecal_from_source (ESource *esource,
|
||||
ECalSourceType source_type,
|
||||
GSList *existing_clients)
|
||||
{
|
||||
ECal *retval;
|
||||
|
||||
if (existing_clients)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = existing_clients; l; l = l->next)
|
||||
{
|
||||
ECal *client = E_CAL (l->data);
|
||||
|
||||
if (e_source_equal (esource, e_cal_get_source (client)))
|
||||
{
|
||||
dprintf (" load_esource: found existing source ... returning that\n");
|
||||
|
||||
return g_object_ref (client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retval = e_cal_new (esource, source_type);
|
||||
if (!retval)
|
||||
{
|
||||
g_warning ("Could not load source '%s' from '%s'\n",
|
||||
e_source_peek_name (esource),
|
||||
e_source_peek_relative_uri (esource));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e_cal_set_auth_func (retval, auth_func_cb, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* - Order doesn't matter
|
||||
* - Can just compare object pointers since we
|
||||
* re-use client connections
|
||||
*/
|
||||
static gboolean
|
||||
compare_ecal_lists (GSList *a,
|
||||
GSList *b)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (g_slist_length (a) != g_slist_length (b))
|
||||
return FALSE;
|
||||
|
||||
for (l = a; l; l = l->next)
|
||||
{
|
||||
if (!g_slist_find (b, l->data))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
debug_dump_selected_sources (GSList *selected_sources)
|
||||
{
|
||||
#ifdef CALENDAR_ENABLE_DEBUG
|
||||
GSList *l;
|
||||
|
||||
dprintf ("Selected sources:\n");
|
||||
for (l = selected_sources; l; l = l->next)
|
||||
{
|
||||
char *source = l->data;
|
||||
|
||||
dprintf (" %s\n", source);
|
||||
}
|
||||
dprintf ("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
debug_dump_ecal_list (GSList *ecal_list)
|
||||
{
|
||||
#ifdef CALENDAR_ENABLE_DEBUG
|
||||
GSList *l;
|
||||
|
||||
dprintf ("Loaded clients:\n");
|
||||
for (l = ecal_list; l; l = l->next)
|
||||
{
|
||||
ECal *client = l->data;
|
||||
ESource *source = e_cal_get_source (client);
|
||||
|
||||
dprintf (" %s %s %s\n",
|
||||
e_source_peek_uid (source),
|
||||
e_source_peek_name (source),
|
||||
e_cal_get_uri (client));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_load_esource_list (CalendarSourceData *source_data);
|
||||
|
||||
static gboolean
|
||||
backend_restart (gpointer data)
|
||||
{
|
||||
CalendarSourceData *source_data = data;
|
||||
|
||||
calendar_sources_load_esource_list (source_data);
|
||||
|
||||
source_data->timeout_id = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
backend_died_cb (ECal *client, CalendarSourceData *source_data)
|
||||
{
|
||||
const char *uristr;
|
||||
|
||||
source_data->clients = g_slist_remove (source_data->clients, client);
|
||||
if (g_slist_length (source_data->clients) < 1)
|
||||
{
|
||||
g_slist_free (source_data->clients);
|
||||
source_data->clients = NULL;
|
||||
}
|
||||
uristr = e_cal_get_uri (client);
|
||||
g_warning ("The calendar backend for %s has crashed.", uristr);
|
||||
|
||||
if (source_data->timeout_id != 0)
|
||||
{
|
||||
g_source_remove (source_data->timeout_id);
|
||||
source_data->timeout_id = 0;
|
||||
}
|
||||
|
||||
source_data->timeout_id = g_timeout_add_seconds (2, backend_restart,
|
||||
source_data);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_load_esource_list (CalendarSourceData *source_data)
|
||||
{
|
||||
GSList *clients = NULL;
|
||||
GSList *groups, *l;
|
||||
gboolean emit_signal = FALSE;
|
||||
|
||||
g_return_if_fail (source_data->esource_list != NULL);
|
||||
|
||||
debug_dump_selected_sources (source_data->selected_sources);
|
||||
|
||||
dprintf ("Source groups:\n");
|
||||
groups = e_source_list_peek_groups (source_data->esource_list);
|
||||
for (l = groups; l; l = l->next)
|
||||
{
|
||||
GSList *esources, *s;
|
||||
|
||||
dprintf (" %s\n", e_source_group_peek_uid (l->data));
|
||||
dprintf (" sources:\n");
|
||||
|
||||
esources = e_source_group_peek_sources (l->data);
|
||||
for (s = esources; s; s = s->next)
|
||||
{
|
||||
ESource *esource = E_SOURCE (s->data);
|
||||
ECal *client;
|
||||
|
||||
dprintf (" type = '%s' uid = '%s', name = '%s', relative uri = '%s': \n",
|
||||
source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task",
|
||||
e_source_peek_uid (esource),
|
||||
e_source_peek_name (esource),
|
||||
e_source_peek_relative_uri (esource));
|
||||
|
||||
if (is_source_selected (esource, source_data->selected_sources) &&
|
||||
(client = get_ecal_from_source (esource, source_data->source_type, source_data->clients)))
|
||||
{
|
||||
clients = g_slist_prepend (clients, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
dprintf ("\n");
|
||||
|
||||
if (source_data->loaded &&
|
||||
!compare_ecal_lists (source_data->clients, clients))
|
||||
emit_signal = TRUE;
|
||||
|
||||
for (l = source_data->clients; l; l = l->next)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
|
||||
G_CALLBACK (backend_died_cb),
|
||||
source_data);
|
||||
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
g_slist_free (source_data->clients);
|
||||
source_data->clients = g_slist_reverse (clients);
|
||||
|
||||
/* connect to backend_died after we disconnected the previous signal
|
||||
* handlers. If we do it before, we'll lose some handlers (for clients that
|
||||
* were already there before) */
|
||||
for (l = source_data->clients; l; l = l->next)
|
||||
{
|
||||
g_signal_connect (G_OBJECT (l->data), "backend_died",
|
||||
G_CALLBACK (backend_died_cb), source_data);
|
||||
}
|
||||
|
||||
if (emit_signal)
|
||||
{
|
||||
dprintf ("Emitting %s-sources-changed signal\n",
|
||||
source_data->source_type == E_CAL_SOURCE_TYPE_EVENT ? "appointment" : "task");
|
||||
g_signal_emit (source_data->sources, source_data->changed_signal, 0);
|
||||
}
|
||||
|
||||
debug_dump_ecal_list (source_data->clients);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_esource_list_changed (ESourceList *source_list,
|
||||
CalendarSourceData *source_data)
|
||||
|
||||
{
|
||||
dprintf ("ESourceList changed, reloading\n");
|
||||
|
||||
calendar_sources_load_esource_list (source_data);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_selected_sources_notify (GConfClient *client,
|
||||
guint cnx_id,
|
||||
GConfEntry *entry,
|
||||
CalendarSourceData *source_data)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (!entry->value ||
|
||||
entry->value->type != GCONF_VALUE_LIST ||
|
||||
gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
|
||||
return;
|
||||
|
||||
dprintf ("Selected sources key (%s) changed, reloading\n", entry->key);
|
||||
|
||||
for (l = source_data->selected_sources; l; l = l->next)
|
||||
g_free (l->data);
|
||||
source_data->selected_sources = NULL;
|
||||
|
||||
for (l = gconf_value_get_list (entry->value); l; l = l->next)
|
||||
{
|
||||
const char *source = gconf_value_get_string (l->data);
|
||||
|
||||
source_data->selected_sources =
|
||||
g_slist_prepend (source_data->selected_sources,
|
||||
g_strdup (source));
|
||||
}
|
||||
source_data->selected_sources =
|
||||
g_slist_reverse (source_data->selected_sources);
|
||||
|
||||
calendar_sources_load_esource_list (source_data);
|
||||
}
|
||||
|
||||
static void
|
||||
calendar_sources_load_sources (CalendarSources *sources,
|
||||
CalendarSourceData *source_data,
|
||||
const char *sources_key,
|
||||
const char *selected_sources_key,
|
||||
const char *selected_sources_dir)
|
||||
{
|
||||
GConfClient *gconf_client;
|
||||
GError *error;
|
||||
|
||||
dprintf ("---------------------------\n");
|
||||
dprintf ("Loading sources:\n");
|
||||
dprintf (" sources_key: %s\n", sources_key);
|
||||
dprintf (" selected_sources_key: %s\n", selected_sources_key);
|
||||
dprintf (" selected_sources_dir: %s\n", selected_sources_dir);
|
||||
|
||||
gconf_client = sources->priv->gconf_client;
|
||||
|
||||
error = NULL;
|
||||
source_data->selected_sources = gconf_client_get_list (gconf_client,
|
||||
selected_sources_key,
|
||||
GCONF_VALUE_STRING,
|
||||
&error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Failed to get selected sources from '%s': %s\n",
|
||||
selected_sources_key,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
gconf_client_add_dir (gconf_client,
|
||||
selected_sources_dir,
|
||||
GCONF_CLIENT_PRELOAD_NONE,
|
||||
NULL);
|
||||
source_data->selected_sources_dir = g_strdup (selected_sources_dir);
|
||||
|
||||
source_data->selected_sources_listener =
|
||||
gconf_client_notify_add (gconf_client,
|
||||
selected_sources_dir,
|
||||
(GConfClientNotifyFunc) calendar_sources_selected_sources_notify,
|
||||
source_data, NULL, NULL);
|
||||
|
||||
source_data->esource_list = e_source_list_new_for_gconf (gconf_client, sources_key);
|
||||
g_signal_connect (source_data->esource_list, "changed",
|
||||
G_CALLBACK (calendar_sources_esource_list_changed),
|
||||
source_data);
|
||||
|
||||
calendar_sources_load_esource_list (source_data);
|
||||
|
||||
source_data->loaded = TRUE;
|
||||
|
||||
dprintf ("---------------------------\n");
|
||||
}
|
||||
|
||||
GSList *
|
||||
calendar_sources_get_appointment_sources (CalendarSources *sources)
|
||||
{
|
||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||
|
||||
if (!sources->priv->appointment_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_sources (sources,
|
||||
&sources->priv->appointment_sources,
|
||||
CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY,
|
||||
CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY,
|
||||
CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_DIR);
|
||||
}
|
||||
|
||||
return sources->priv->appointment_sources.clients;
|
||||
}
|
||||
|
||||
GSList *
|
||||
calendar_sources_get_task_sources (CalendarSources *sources)
|
||||
{
|
||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||
|
||||
if (!sources->priv->task_sources.loaded)
|
||||
{
|
||||
calendar_sources_load_sources (sources,
|
||||
&sources->priv->task_sources,
|
||||
CALENDAR_SOURCES_TASK_SOURCES_KEY,
|
||||
CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY,
|
||||
CALENDAR_SOURCES_SELECTED_TASK_SOURCES_DIR);
|
||||
}
|
||||
|
||||
return sources->priv->task_sources.clients;
|
||||
}
|
66
src/calendar-client/calendar-sources.h
Normal file
66
src/calendar-client/calendar-sources.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <mark@skynet.ie>
|
||||
* William Jon McCann <mccann@jhu.edu>
|
||||
* Martin Grimme <martin@pycage.de>
|
||||
* Christian Kellner <gicmo@xatom.net>
|
||||
*/
|
||||
|
||||
#ifndef __CALENDAR_SOURCES_H__
|
||||
#define __CALENDAR_SOURCES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALENDAR_TYPE_SOURCES (calendar_sources_get_type ())
|
||||
#define CALENDAR_SOURCES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CALENDAR_TYPE_SOURCES, CalendarSources))
|
||||
#define CALENDAR_SOURCES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CALENDAR_TYPE_SOURCES, CalendarSourcesClass))
|
||||
#define CALENDAR_IS_SOURCES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CALENDAR_TYPE_SOURCES))
|
||||
#define CALENDAR_IS_SOURCES_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CALENDAR_TYPE_SOURCES))
|
||||
#define CALENDAR_SOURCES_GET_CLASS(o)(G_TYPE_INSTANCE_GET_CLASS ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesClass))
|
||||
|
||||
typedef struct _CalendarSources CalendarSources;
|
||||
typedef struct _CalendarSourcesClass CalendarSourcesClass;
|
||||
typedef struct _CalendarSourcesPrivate CalendarSourcesPrivate;
|
||||
|
||||
struct _CalendarSources
|
||||
{
|
||||
GObject parent;
|
||||
CalendarSourcesPrivate *priv;
|
||||
};
|
||||
|
||||
struct _CalendarSourcesClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* appointment_sources_changed) (CalendarSources *sources);
|
||||
void (* task_sources_changed) (CalendarSources *sources);
|
||||
};
|
||||
|
||||
|
||||
GType calendar_sources_get_type (void) G_GNUC_CONST;
|
||||
CalendarSources *calendar_sources_get (void);
|
||||
GSList *calendar_sources_get_appointment_sources (CalendarSources *sources);
|
||||
GSList *calendar_sources_get_task_sources (CalendarSources *sources);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALENDAR_SOURCES_H__ */
|
265
src/shell-evolution-event-source.c
Normal file
265
src/shell-evolution-event-source.c
Normal file
@ -0,0 +1,265 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "calendar-client/calendar-client.h"
|
||||
#include "shell-evolution-event-source.h"
|
||||
|
||||
|
||||
struct _ShellEvolutionEventSourceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _ShellEvolutionEventSource {
|
||||
GObject parent;
|
||||
CalendarClient *client;
|
||||
/* The month that we are currently requesting events from */
|
||||
gint req_year;
|
||||
gint req_mon; /* starts at 1, not zero */
|
||||
};
|
||||
|
||||
/* Signals */
|
||||
enum
|
||||
{
|
||||
CHANGED_SIGNAL,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (ShellEvolutionEventSource, shell_evolution_event_source, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
on_tasks_changed (CalendarClient *client,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellEvolutionEventSource *source = SHELL_EVOLUTION_EVENT_SOURCE (user_data);
|
||||
/* g_print ("on tasks changed\n"); */
|
||||
g_signal_emit (source, signals[CHANGED_SIGNAL], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_appointments_changed (CalendarClient *client,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellEvolutionEventSource *source = SHELL_EVOLUTION_EVENT_SOURCE (user_data);
|
||||
/* g_print ("on appointments changed\n"); */
|
||||
g_signal_emit (source, signals[CHANGED_SIGNAL], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_evolution_event_source_init (ShellEvolutionEventSource *source)
|
||||
{
|
||||
source->client = calendar_client_new ();
|
||||
g_signal_connect (source->client,
|
||||
"tasks-changed",
|
||||
G_CALLBACK (on_tasks_changed),
|
||||
source);
|
||||
g_signal_connect (source->client,
|
||||
"appointments-changed",
|
||||
G_CALLBACK (on_appointments_changed),
|
||||
source);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_evolution_event_source_finalize (GObject *object)
|
||||
{
|
||||
ShellEvolutionEventSource *source = SHELL_EVOLUTION_EVENT_SOURCE (object);
|
||||
g_object_unref (source->client);
|
||||
G_OBJECT_CLASS (shell_evolution_event_source_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_evolution_event_source_class_init (ShellEvolutionEventSourceClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = shell_evolution_event_source_finalize;
|
||||
|
||||
signals[CHANGED_SIGNAL] =
|
||||
g_signal_new ("changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
}
|
||||
|
||||
ShellEvolutionEventSource *
|
||||
shell_evolution_event_source_new (void)
|
||||
{
|
||||
return SHELL_EVOLUTION_EVENT_SOURCE (g_object_new (SHELL_TYPE_EVOLUTION_EVENT_SOURCE, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
shell_evolution_event_source_request_range (ShellEvolutionEventSource *source,
|
||||
gint64 msec_begin,
|
||||
gint64 msec_end)
|
||||
{
|
||||
GDateTime *middle_utc, *middle;
|
||||
|
||||
/* The CalendarClient type is a convenience wrapper on top of
|
||||
* Evolution Data Server. It is based on the assumption that only
|
||||
* a single month is shown at a time.
|
||||
*
|
||||
* To avoid reimplemting all the work already done in CalendarClient
|
||||
* we make the same assumption. This means that we only show events
|
||||
* in the month that is in the middle of @msec_begin and
|
||||
* @msec_end. Since the Shell displays a month at a time (plus the
|
||||
* days before and after) it works out just fine.
|
||||
*/
|
||||
|
||||
middle_utc = g_date_time_new_from_unix_utc ((msec_begin + msec_end) / 2 / 1000);
|
||||
/* CalendarClient uses localtime rather than UTC */
|
||||
middle = g_date_time_to_local (middle_utc);
|
||||
g_date_time_unref (middle_utc);
|
||||
g_date_time_get_ymd (middle, &source->req_year, &source->req_mon, NULL);
|
||||
g_date_time_unref (middle);
|
||||
calendar_client_select_month (source->client, source->req_mon - 1, source->req_year);
|
||||
}
|
||||
|
||||
static gint
|
||||
event_cmp (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const ShellEvolutionEvent *ea;
|
||||
const ShellEvolutionEvent *eb;
|
||||
|
||||
ea = a;
|
||||
eb = b;
|
||||
if (ea->msec_begin < eb->msec_begin)
|
||||
return -1;
|
||||
else if (ea->msec_begin > eb->msec_begin)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_evolution_event_source_get_events:
|
||||
* @source: A #ShellEvolutionEventSource.
|
||||
* @msec_begin: Start date (milli-seconds since Epoch).
|
||||
* @msec_end: End date (milli-seconds since Epoch).
|
||||
*
|
||||
* Gets all events that occur between @msec_begin and @msec_end.
|
||||
*
|
||||
* Returns: (element-type ShellEvolutionEvent) (transfer full): List of events.
|
||||
*/
|
||||
GList *
|
||||
shell_evolution_event_source_get_events (ShellEvolutionEventSource *source,
|
||||
gint64 msec_begin,
|
||||
gint64 msec_end)
|
||||
{
|
||||
GList *result;
|
||||
GDateTime *cur_date;
|
||||
GDateTime *begin_date_utc, *begin_date;
|
||||
GDateTime *end_date_utc, *end_date;
|
||||
|
||||
g_return_val_if_fail (msec_begin <= msec_end, NULL);
|
||||
|
||||
result = NULL;
|
||||
|
||||
begin_date_utc = g_date_time_new_from_unix_utc (msec_begin / 1000);
|
||||
end_date_utc = g_date_time_new_from_unix_utc (msec_end / 1000);
|
||||
|
||||
/* CalendarClient uses localtime rather than UTC */
|
||||
begin_date = g_date_time_to_local (begin_date_utc);
|
||||
end_date = g_date_time_to_local (end_date_utc);
|
||||
g_date_time_unref (begin_date_utc);
|
||||
g_date_time_unref (end_date_utc);
|
||||
|
||||
cur_date = g_date_time_ref (begin_date);
|
||||
do
|
||||
{
|
||||
gint year, mon, day;
|
||||
GDateTime *next_date;
|
||||
|
||||
g_date_time_get_ymd (cur_date, &year, &mon, &day);
|
||||
/* g_print ("y=%04d m=%02d d=%02d\n", year, mon, day); */
|
||||
|
||||
/* Silently drop events not in range (see comment in
|
||||
* shell_evolution_event_source_request_range() above)
|
||||
*/
|
||||
if (!(year == source->req_year && mon == source->req_mon))
|
||||
{
|
||||
/* g_print ("skipping day\n"); */
|
||||
}
|
||||
else
|
||||
{
|
||||
GSList *events;
|
||||
GSList *l;
|
||||
calendar_client_select_day (source->client, day);
|
||||
events = calendar_client_get_events (source->client, CALENDAR_EVENT_APPOINTMENT);
|
||||
/* g_print ("num_events: %d\n", g_slist_length (events)); */
|
||||
for (l = events; l; l = l->next)
|
||||
{
|
||||
CalendarAppointment *appointment = l->data;
|
||||
ShellEvolutionEvent *event;
|
||||
gint64 start_time;
|
||||
|
||||
if (appointment->is_all_day)
|
||||
{
|
||||
start_time = g_date_time_to_unix (cur_date) * G_GINT64_CONSTANT (1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
start_time = appointment->start_time * G_GINT64_CONSTANT (1000);
|
||||
}
|
||||
event = shell_evolution_event_new (appointment->summary,
|
||||
appointment->is_all_day,
|
||||
start_time);
|
||||
result = g_list_prepend (result, event);
|
||||
}
|
||||
g_slist_foreach (events, (GFunc) calendar_event_free, NULL);
|
||||
g_slist_free (events);
|
||||
}
|
||||
|
||||
next_date = g_date_time_add_days (cur_date, 1);
|
||||
g_date_time_unref (cur_date);
|
||||
cur_date = next_date;
|
||||
}
|
||||
while (g_date_time_difference (end_date, cur_date) > 0);
|
||||
g_date_time_unref (begin_date);
|
||||
g_date_time_unref (end_date);
|
||||
|
||||
result = g_list_sort (result, event_cmp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ShellEvolutionEvent,
|
||||
shell_evolution_event,
|
||||
shell_evolution_event_copy,
|
||||
shell_evolution_event_free);
|
||||
|
||||
void
|
||||
shell_evolution_event_free (ShellEvolutionEvent *event)
|
||||
{
|
||||
g_free (event->summary);
|
||||
g_free (event);
|
||||
}
|
||||
|
||||
ShellEvolutionEvent *
|
||||
shell_evolution_event_copy (ShellEvolutionEvent *event)
|
||||
{
|
||||
ShellEvolutionEvent *copy;
|
||||
copy = g_memdup (event, sizeof (ShellEvolutionEvent));
|
||||
copy->summary = g_strdup (event->summary);
|
||||
return copy;
|
||||
}
|
||||
|
||||
ShellEvolutionEvent *
|
||||
shell_evolution_event_new (const gchar *summary,
|
||||
gboolean all_day,
|
||||
gint64 msec_begin)
|
||||
{
|
||||
ShellEvolutionEvent *event;
|
||||
event = g_new0 (ShellEvolutionEvent, 1);
|
||||
event->summary = g_strdup (summary);
|
||||
event->all_day = all_day;
|
||||
event->msec_begin = msec_begin;
|
||||
return event;
|
||||
}
|
45
src/shell-evolution-event-source.h
Normal file
45
src/shell-evolution-event-source.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __SHELL_EVOLUTION_EVENT_SOURCE_H__
|
||||
#define __SHELL_EVOLUTION_EVENT_SOURCE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ShellEvolutionEvent ShellEvolutionEvent;
|
||||
|
||||
struct _ShellEvolutionEvent
|
||||
{
|
||||
gchar *summary;
|
||||
gboolean all_day;
|
||||
gint64 msec_begin;
|
||||
};
|
||||
|
||||
GType shell_evolution_event_get_type (void) G_GNUC_CONST;
|
||||
ShellEvolutionEvent *shell_evolution_event_new (const gchar *summary,
|
||||
gboolean all_day,
|
||||
gint64 msec_begin);
|
||||
ShellEvolutionEvent *shell_evolution_event_copy (ShellEvolutionEvent *event);
|
||||
void shell_evolution_event_free (ShellEvolutionEvent *event);
|
||||
|
||||
typedef struct _ShellEvolutionEventSource ShellEvolutionEventSource;
|
||||
typedef struct _ShellEvolutionEventSourceClass ShellEvolutionEventSourceClass;
|
||||
|
||||
#define SHELL_TYPE_EVOLUTION_EVENT_SOURCE (shell_evolution_event_source_get_type ())
|
||||
#define SHELL_EVOLUTION_EVENT_SOURCE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_EVOLUTION_EVENT_SOURCE, ShellEvolutionEventSource))
|
||||
#define SHELL_EVOLUTION_EVENT_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_EVOLUTION_EVENT_SOURCE, ShellEvolutionEventSourceClass))
|
||||
#define SHELL_IS_EVOLUTION_EVENT_SOURCE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_EVOLUTION_EVENT_SOURCE))
|
||||
#define SHELL_IS_EVOLUTION_EVENT_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_EVOLUTION_EVENT_SOURCE))
|
||||
#define SHELL_EVOLUTION_EVENT_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_EVOLUTION_EVENT_SOURCE, ShellEvolutionEventSourceClass))
|
||||
|
||||
GType shell_evolution_event_source_get_type (void) G_GNUC_CONST;
|
||||
ShellEvolutionEventSource *shell_evolution_event_source_new (void);
|
||||
void shell_evolution_event_source_request_range (ShellEvolutionEventSource *source,
|
||||
gint64 msec_begin,
|
||||
gint64 msec_end);
|
||||
GList *shell_evolution_event_source_get_events (ShellEvolutionEventSource *source,
|
||||
gint64 msec_begin,
|
||||
gint64 msec_end);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SHELL_EVOLUTION_EVENT_SOURCE_H__ */
|
@ -24,6 +24,7 @@
|
||||
#define __NA_TRAY_CHILD_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkx.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -315,19 +315,13 @@ pending_message_free (PendingMessage *message)
|
||||
g_free (message);
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
na_tray_manager_handle_client_message_message_data (GdkXEvent *xev,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
static void
|
||||
na_tray_manager_handle_message_data (NaTrayManager *manager,
|
||||
XClientMessageEvent *xevent)
|
||||
{
|
||||
XClientMessageEvent *xevent;
|
||||
NaTrayManager *manager;
|
||||
GList *p;
|
||||
int len;
|
||||
GList *p;
|
||||
int len;
|
||||
|
||||
xevent = (XClientMessageEvent *) xev;
|
||||
manager = data;
|
||||
|
||||
/* Try to see if we can find the pending message in the list */
|
||||
for (p = manager->messages; p; p = p->next)
|
||||
{
|
||||
@ -361,8 +355,6 @@ na_tray_manager_handle_client_message_message_data (GdkXEvent *xev,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -382,13 +374,17 @@ na_tray_manager_handle_begin_message (NaTrayManager *manager,
|
||||
if (!socket)
|
||||
return;
|
||||
|
||||
timeout = xevent->data.l[2];
|
||||
len = xevent->data.l[3];
|
||||
id = xevent->data.l[4];
|
||||
|
||||
/* Check if the same message is already in the queue and remove it if so */
|
||||
for (p = manager->messages; p; p = p->next)
|
||||
{
|
||||
PendingMessage *pmsg = p->data;
|
||||
|
||||
if (xevent->window == pmsg->window &&
|
||||
xevent->data.l[4] == pmsg->id)
|
||||
id == pmsg->id)
|
||||
{
|
||||
/* Hmm, we found it, now remove it */
|
||||
pending_message_free (pmsg);
|
||||
@ -398,10 +394,6 @@ na_tray_manager_handle_begin_message (NaTrayManager *manager,
|
||||
}
|
||||
}
|
||||
|
||||
timeout = xevent->data.l[2];
|
||||
len = xevent->data.l[3];
|
||||
id = xevent->data.l[4];
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
g_signal_emit (manager, manager_signals[MESSAGE_SENT], 0,
|
||||
@ -428,6 +420,9 @@ na_tray_manager_handle_cancel_message (NaTrayManager *manager,
|
||||
{
|
||||
GList *p;
|
||||
GtkSocket *socket;
|
||||
long id;
|
||||
|
||||
id = xevent->data.l[2];
|
||||
|
||||
/* Check if the message is in the queue and remove it if so */
|
||||
for (p = manager->messages; p; p = p->next)
|
||||
@ -435,7 +430,7 @@ na_tray_manager_handle_cancel_message (NaTrayManager *manager,
|
||||
PendingMessage *msg = p->data;
|
||||
|
||||
if (xevent->window == msg->window &&
|
||||
xevent->data.l[4] == msg->id)
|
||||
id == msg->id)
|
||||
{
|
||||
pending_message_free (msg);
|
||||
manager->messages = g_list_remove_link (manager->messages, p);
|
||||
@ -454,39 +449,6 @@ na_tray_manager_handle_cancel_message (NaTrayManager *manager,
|
||||
}
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
na_tray_manager_handle_client_message_opcode (GdkXEvent *xev,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
XClientMessageEvent *xevent;
|
||||
NaTrayManager *manager;
|
||||
|
||||
xevent = (XClientMessageEvent *) xev;
|
||||
manager = data;
|
||||
|
||||
switch (xevent->data.l[1])
|
||||
{
|
||||
case SYSTEM_TRAY_REQUEST_DOCK:
|
||||
/* Ignore this one since we don't know on which window this was received
|
||||
* and so we can't know for which screen this is. It will be handled
|
||||
* in na_tray_manager_window_filter() since we also receive it there */
|
||||
break;
|
||||
|
||||
case SYSTEM_TRAY_BEGIN_MESSAGE:
|
||||
na_tray_manager_handle_begin_message (manager, xevent);
|
||||
return GDK_FILTER_REMOVE;
|
||||
|
||||
case SYSTEM_TRAY_CANCEL_MESSAGE:
|
||||
na_tray_manager_handle_cancel_message (manager, xevent);
|
||||
return GDK_FILTER_REMOVE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
na_tray_manager_window_filter (GdkXEvent *xev,
|
||||
GdkEvent *event,
|
||||
@ -497,8 +459,7 @@ na_tray_manager_window_filter (GdkXEvent *xev,
|
||||
|
||||
if (xevent->type == ClientMessage)
|
||||
{
|
||||
/* We handle this client message here. See comment in
|
||||
* na_tray_manager_handle_client_message_opcode() for details */
|
||||
/* _NET_SYSTEM_TRAY_OPCODE: SYSTEM_TRAY_REQUEST_DOCK */
|
||||
if (xevent->xclient.message_type == manager->opcode_atom &&
|
||||
xevent->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK)
|
||||
{
|
||||
@ -506,6 +467,29 @@ na_tray_manager_window_filter (GdkXEvent *xev,
|
||||
(XClientMessageEvent *) xevent);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
/* _NET_SYSTEM_TRAY_OPCODE: SYSTEM_TRAY_BEGIN_MESSAGE */
|
||||
else if (xevent->xclient.message_type == manager->opcode_atom &&
|
||||
xevent->xclient.data.l[1] == SYSTEM_TRAY_BEGIN_MESSAGE)
|
||||
{
|
||||
na_tray_manager_handle_begin_message (manager,
|
||||
(XClientMessageEvent *) event);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
/* _NET_SYSTEM_TRAY_OPCODE: SYSTEM_TRAY_CANCEL_MESSAGE */
|
||||
else if (xevent->xclient.message_type == manager->opcode_atom &&
|
||||
xevent->xclient.data.l[1] == SYSTEM_TRAY_CANCEL_MESSAGE)
|
||||
{
|
||||
na_tray_manager_handle_cancel_message (manager,
|
||||
(XClientMessageEvent *) event);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
/* _NET_SYSTEM_TRAY_MESSAGE_DATA */
|
||||
else if (xevent->xclient.message_type == manager->message_data_atom)
|
||||
{
|
||||
na_tray_manager_handle_message_data (manager,
|
||||
(XClientMessageEvent *) event);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
}
|
||||
else if (xevent->type == SelectionClear)
|
||||
{
|
||||
@ -563,9 +547,6 @@ na_tray_manager_unmanage (NaTrayManager *manager)
|
||||
TRUE);
|
||||
}
|
||||
|
||||
//FIXME: we should also use gdk_remove_client_message_filter when it's
|
||||
//available
|
||||
// See bug #351254
|
||||
gdk_window_remove_filter (window,
|
||||
na_tray_manager_window_filter, manager);
|
||||
|
||||
@ -736,6 +717,8 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
|
||||
|
||||
message_data_atom = gdk_atom_intern ("_NET_SYSTEM_TRAY_MESSAGE_DATA",
|
||||
FALSE);
|
||||
manager->message_data_atom = gdk_x11_atom_to_xatom_for_display (display,
|
||||
message_data_atom);
|
||||
|
||||
/* Add a window filter */
|
||||
#if 0
|
||||
@ -744,17 +727,8 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
|
||||
G_CALLBACK (na_tray_manager_selection_clear_event),
|
||||
manager);
|
||||
#endif
|
||||
/* This is for SYSTEM_TRAY_REQUEST_DOCK and SelectionClear */
|
||||
gdk_window_add_filter (window,
|
||||
na_tray_manager_window_filter, manager);
|
||||
/* This is for SYSTEM_TRAY_BEGIN_MESSAGE and SYSTEM_TRAY_CANCEL_MESSAGE */
|
||||
gdk_display_add_client_message_filter (display, opcode_atom,
|
||||
na_tray_manager_handle_client_message_opcode,
|
||||
manager);
|
||||
/* This is for _NET_SYSTEM_TRAY_MESSAGE_DATA */
|
||||
gdk_display_add_client_message_filter (display, message_data_atom,
|
||||
na_tray_manager_handle_client_message_message_data,
|
||||
manager);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -50,6 +50,7 @@ struct _NaTrayManager
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
GdkAtom selection_atom;
|
||||
Atom opcode_atom;
|
||||
Atom message_data_atom;
|
||||
#endif
|
||||
|
||||
GtkWidget *invisible;
|
||||
|
@ -62,7 +62,8 @@ fi
|
||||
# libxklavier, libxml2, ORBit2, pam, python, readline,
|
||||
# spidermonkey ({mozilla,firefox,xulrunner}-js), startup-notification,
|
||||
# xdamage, icon-naming-utils, upower, libtool-ltdl, libvorbis,
|
||||
# libgcrypt, libtasn1, libgnome-keyring, libgtop, cups
|
||||
# libgcrypt, libtasn1, libgnome-keyring, libgtop, cups,
|
||||
# evolution-data-server
|
||||
#
|
||||
# Non-devel packages needed by gnome-shell and its deps:
|
||||
# glxinfo, gstreamer-plugins-base, gstreamer-plugins-good,
|
||||
@ -83,7 +84,7 @@ if test "x$system" = xUbuntu -o "x$system" = xDebian -o "x$system" = xLinuxMint
|
||||
xulrunner-dev xserver-xephyr gnome-terminal libcroco3-dev
|
||||
libgstreamer0.10-dev gstreamer0.10-plugins-base gstreamer0.10-plugins-good
|
||||
libltdl-dev libvorbis-dev libxklavier-dev libgnome-keyring-dev
|
||||
libupower-glib-dev libcups2-dev
|
||||
libupower-glib-dev libcups2-dev evolution-data-server-dev
|
||||
"
|
||||
|
||||
if apt-cache show autopoint > /dev/null 2> /dev/null; then
|
||||
@ -121,7 +122,7 @@ if test "x$system" = xFedora ; then
|
||||
startup-notification-devel xorg-x11-server-Xephyr gnome-terminal zenity
|
||||
icon-naming-utils upower-devel libtool-ltdl-devel libvorbis-devel
|
||||
libxklavier-devel libgcrypt-devel libtasn1-devel libtasn1-tools
|
||||
libgnome-keyring-devel libgtop2-devel cups-devel
|
||||
libgnome-keyring-devel libgtop2-devel cups-devel evolution-data-server-devel
|
||||
"
|
||||
|
||||
if expr $version \>= 14 > /dev/null ; then
|
||||
@ -147,7 +148,7 @@ if test "x$system" = xSUSE -o "x$system" = "xSUSE LINUX" ; then
|
||||
libgtop-devel libpulse-devel libtiff-devel cups-devel libffi-devel \
|
||||
orbit2-devel libwnck-devel xorg-x11-proto-devel readline-devel \
|
||||
mozilla-xulrunner191-devel libcroco-devel \
|
||||
xorg-x11-devel xorg-x11 xorg-x11-server-extra \
|
||||
xorg-x11-devel xorg-x11 xorg-x11-server-extra evolution-data-server-devel \
|
||||
; do
|
||||
if ! rpm -q $pkg > /dev/null 2>&1; then
|
||||
reqd="$pkg $reqd"
|
||||
@ -168,7 +169,7 @@ if test "x$system" = xMandrivaLinux ; then
|
||||
intltool ffi5-devel libwnck-1-devel GL-devel ORBit2-devel \
|
||||
readline-devel libxulrunner-devel \
|
||||
libxdamage-devel mesa-demos x11-server-xephyr zenity \
|
||||
libcroco0.6-devel \
|
||||
libcroco0.6-devel libevolution-data-server3-devel \
|
||||
; do
|
||||
if ! rpm -q --whatprovides $pkg > /dev/null 2>&1; then
|
||||
reqd="$pkg $reqd"
|
||||
|
@ -88,17 +88,10 @@
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gtk-theme-engine-clearlooks">
|
||||
<branch repo="git.gnome.org" module="gtk-theme-engine-clearlooks"/>
|
||||
<dependencies>
|
||||
<dep package="gtk3"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<autotools id="gnome-themes-standard">
|
||||
<branch repo="git.gnome.org" module="gnome-themes-standard"/>
|
||||
<dependencies>
|
||||
<dep package="gtk-theme-engine-clearlooks"/>
|
||||
<dep package="gtk3"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
|
Reference in New Issue
Block a user