Merge lp:~seb128/unity-control-center/users-backport-commits into lp:unity-control-center

Proposed by Sebastien Bacher
Status: Merged
Approved by: Iain Lane
Approved revision: 12729
Merged at revision: 12731
Proposed branch: lp:~seb128/unity-control-center/users-backport-commits
Merge into: lp:unity-control-center
Diff against target: 6301 lines (+1896/-2469)
38 files modified
configure.ac (+2/-18)
debian/control (+1/-1)
debian/rules (+1/-2)
panels/user-accounts/Makefile.am (+15/-15)
panels/user-accounts/data/Makefile.am (+1/-12)
panels/user-accounts/data/account-dialog.ui (+3/-1)
panels/user-accounts/data/account-fingerprint.ui (+1/-1)
panels/user-accounts/data/history-dialog.ui (+175/-0)
panels/user-accounts/data/icons/Makefile.am (+0/-32)
panels/user-accounts/data/password-dialog.ui (+7/-2)
panels/user-accounts/data/photo-dialog.ui (+1/-0)
panels/user-accounts/data/user-accounts-dialog.ui (+129/-65)
panels/user-accounts/frob-account-dialog.c (+3/-3)
panels/user-accounts/um-account-dialog.c (+110/-43)
panels/user-accounts/um-account-dialog.h (+3/-2)
panels/user-accounts/um-fingerprint-dialog.c (+10/-16)
panels/user-accounts/um-fingerprint-dialog.h (+2/-2)
panels/user-accounts/um-history-dialog.c (+377/-0)
panels/user-accounts/um-history-dialog.h (+41/-0)
panels/user-accounts/um-password-dialog.c (+125/-62)
panels/user-accounts/um-password-dialog.h (+2/-2)
panels/user-accounts/um-photo-dialog.c (+15/-16)
panels/user-accounts/um-photo-dialog.h (+2/-2)
panels/user-accounts/um-realm-manager.c (+13/-4)
panels/user-accounts/um-realm-manager.h (+1/-0)
panels/user-accounts/um-user-manager.c (+0/-734)
panels/user-accounts/um-user-manager.h (+0/-121)
panels/user-accounts/um-user-module.c (+1/-1)
panels/user-accounts/um-user-panel.c (+331/-189)
panels/user-accounts/um-user-panel.h (+13/-15)
panels/user-accounts/um-user.c (+0/-991)
panels/user-accounts/um-user.h (+0/-109)
panels/user-accounts/um-utils.c (+332/-6)
panels/user-accounts/um-utils.h (+18/-0)
panels/user-accounts/user-accounts.gresource.xml (+23/-0)
po/POTFILES.in (+2/-1)
shell/cc-editable-entry.c (+127/-1)
shell/cc-editable-entry.h (+9/-0)
To merge this branch: bzr merge lp:~seb128/unity-control-center/users-backport-commits
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Iain Lane Approve
Unity Control Center development team Pending
Review via email: mp+207686@code.launchpad.net

Commit message

update to the GNOME 3.8 codebase, remove quite some custom code to use
libaccountsservice. The update also includes a view of the login history
informations and bugfixes.

Description of the change

update to the GNOME 3.8 codebase, remove quite some custom code to use
libaccountsservice. The update also includes a view of the login history
informations and bugfixes.

To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

The changes are a bit much to review, but that's basically the list of commits on https://git.gnome.org/browse/gnome-control-center/log/panels/user-accounts?h=gnome-3-8 (first 2 screens).

That features quite some fixes and dropping code in favor of using accountsservice
diffstat: 37 files changed, 1757 insertions(+), 2467 deletions(-)

I've tested the update, builds/works fine here

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote :

Is login history meant to work? It's just blank for my user.

Also, I get some Gtk warnings:

(unity-control-center:15501): Gtk-WARNING **: Unknown property: CcEditableEntry.width-chars

(unity-control-center:15501): Gtk-WARNING **: Unknown property: CcEditableEntry.max-width-chars

(unity-control-center:15501): Gtk-WARNING **: Unknown property: CcEditableEntry.ellipsize

I think you need de1fc65ab3f843d6525e07c5a32661a2dd5feb5e for those?

review: Needs Fixing
Revision history for this message
Sebastien Bacher (seb128) wrote :

> Is login history meant to work? It's just blank for my user.

it's supposed to be working yet, it has entries here for my user and test users (though the log seems incomplete)

Do you have an history if you go check the LoginHistory priority for your user in d-feet?

> I think you need de1fc65ab3f843d6525e07c5a32661a2dd5feb5e for those?

Thanks, I'm having a look to that

12726. By Sebastien Bacher

updated translations template

12727. By Sebastien Bacher

backport commit needed to fix warnings

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
12728. By Sebastien Bacher

Include "pty" sessions in the login history, that's the type lightdm uses

Revision history for this message
Sebastien Bacher (seb128) wrote :

> Is login history meant to work? It's just blank for my user.

Seems like wtmp is not really well described, our session types use "pty", I've added that to the sessions to list, which seems to work

The merge request should be good to go now

12729. By Sebastien Bacher

the type is "pts" not "pty", should be correct this time

Revision history for this message
Iain Lane (laney) wrote :

Looks good now, thanks for that!

(be nice to forward the change upstream, even if they then decide to reject it)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote :

> (be nice to forward the change upstream, even if they then decide to reject it)

https://bugzilla.gnome.org/show_bug.cgi?id=725053

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2014-02-21 18:46:14 +0000
3+++ configure.ac 2014-02-24 09:46:44 +0000
4@@ -70,17 +70,6 @@
5
6 AC_CHECK_LIB(m, floor)
7
8-AC_ARG_ENABLE([systemd],
9- AS_HELP_STRING([--enable-systemd], [Use systemd]),
10- [with_systemd=$enableval],
11- [with_systemd=no])
12-if test "$with_systemd" = "yes" ; then
13- SYSTEMD=libsystemd-login
14- AC_DEFINE(HAVE_SYSTEMD, 1, [Define to 1 if systemd is available])
15-else
16- SYSTEMD=
17-fi
18-
19 # IBus support
20 IBUS_REQUIRED_VERSION=1.4.99
21
22@@ -115,6 +104,7 @@
23 LIBWACOM_REQUIRED_VERSION=0.7
24 CLUTTER_REQUIRED_VERSION=1.11.3
25 GOA_REQUIRED_VERSION=3.5.90
26+ACCOUNTSSERVICE_REQUIRED_VERSION=0.6.30
27
28 COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION
29 glib-2.0 >= $GLIB_REQUIRED_VERSION
30@@ -163,7 +153,7 @@
31 gnome-desktop-3.0
32 gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED_VERSION
33 pwquality
34- $SYSTEMD)
35+ accountsservice >= $ACCOUNTSSERVICE_REQUIRED_VERSION)
36
37 AM_PROG_VALAC([0.20.0])
38
39@@ -480,7 +470,6 @@
40 panels/user-accounts/Makefile
41 panels/user-accounts/data/Makefile
42 panels/user-accounts/data/unity-user-accounts-panel.desktop.in
43-panels/user-accounts/data/icons/Makefile
44 panels/wacom/Makefile
45 panels/wacom/calibrator/Makefile
46 panels/wacom/unity-wacom-panel.desktop.in
47@@ -516,11 +505,6 @@
48 else
49 AC_MSG_NOTICE([ Appearance panel Flickr support disabled])
50 fi
51-if test "x$with_systemd" = "xyes"; then
52- AC_MSG_NOTICE([** systemd (Systemd session tracking)])
53-else
54- AC_MSG_NOTICE([ Using ConsoleKit for session tracking])
55-fi
56 if test "x$have_wacom" = "xyes"; then
57 AC_MSG_NOTICE([** wacom (Wacom tablet panel)])
58 else
59
60=== modified file 'debian/control'
61--- debian/control 2014-02-21 18:46:14 +0000
62+++ debian/control 2014-02-24 09:46:44 +0000
63@@ -15,6 +15,7 @@
64 gsettings-desktop-schemas-dev (>= 3.7.2.2),
65 hardening-wrapper,
66 intltool (>= 0.37.1),
67+ libaccountsservice-dev (>= 0.6.30),
68 libcanberra-gtk3-dev,
69 libcheese-gtk-dev (>= 2.91.91.1),
70 libcolord-dev,
71@@ -40,7 +41,6 @@
72 libpulse-dev (>= 1:2.0),
73 libpwquality-dev,
74 libupower-glib-dev (>= 0.9.1),
75- libsystemd-login-dev,
76 libtimezonemap1-dev,
77 libwacom-dev (>= 0.7),
78 libx11-dev,
79
80=== modified file 'debian/rules'
81--- debian/rules 2014-02-21 18:17:40 +0000
82+++ debian/rules 2014-02-24 09:46:44 +0000
83@@ -11,8 +11,7 @@
84
85 DEB_CONFIGURE_SCRIPT := ./autogen.sh
86 DEB_CONFIGURE_EXTRA_FLAGS += --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \
87- --disable-update-mimedb \
88- --enable-systemd
89+ --disable-update-mimedb
90
91 DEB_DH_MAKESHLIBS_ARGS_unity-control-center = --no-act
92
93
94=== modified file 'panels/user-accounts/Makefile.am'
95--- panels/user-accounts/Makefile.am 2013-11-29 06:28:37 +0000
96+++ panels/user-accounts/Makefile.am 2014-02-24 09:46:44 +0000
97@@ -8,9 +8,6 @@
98 ccpanels_LTLIBRARIES = libuser-accounts.la
99
100 AM_CPPFLAGS = \
101- -DDATADIR=\""$(datadir)"\" \
102- -DUIDIR=\""$(pkgdatadir)/ui/user-accounts"\" \
103- -DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
104 -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
105 -DUM_PIXMAP_DIR=\""$(pkgdatadir)/pixmaps"\" \
106 -DHAVE_LIBPWQUALITY \
107@@ -24,16 +21,14 @@
108 endif
109
110 BUILT_SOURCES = \
111- um-realm-generated.c \
112- um-realm-generated.h
113+ um-realm-generated.c \
114+ um-realm-generated.h \
115+ um-resources.c \
116+ um-resources.h
117
118 libuser_accounts_la_SOURCES = \
119 um-account-type.h \
120 um-account-type.c \
121- um-user.h \
122- um-user.c \
123- um-user-manager.h \
124- um-user-manager.c \
125 um-account-dialog.h \
126 um-account-dialog.c \
127 um-password-dialog.h \
128@@ -60,6 +55,8 @@
129 um-user-module.c \
130 um-realm-manager.c \
131 um-realm-manager.h \
132+ um-history-dialog.h \
133+ um-history-dialog.c \
134 $(BUILT_SOURCES)
135
136 libuser_accounts_la_LIBADD = \
137@@ -83,6 +80,12 @@
138 --c-generate-object-manager $<
139 um-realm-generated.h: um-realm-generated.c
140
141+resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/user-accounts.gresource.xml)
142+um-resources.c: user-accounts.gresource.xml $(resource_files)
143+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name um $<
144+um-resources.h: user-accounts.gresource.xml $(resource_files)
145+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name um $<
146+
147 noinst_PROGRAMS = frob-account-dialog
148
149 frob_account_dialog_SOURCES = \
150@@ -91,10 +94,6 @@
151 um-account-dialog.c \
152 um-realm-manager.c \
153 um-realm-manager.h \
154- um-user.h \
155- um-user.c \
156- um-user-manager.c \
157- um-user-manager.h \
158 um-utils.h \
159 um-utils.c \
160 $(BUILT_SOURCES)
161@@ -103,8 +102,7 @@
162 $(libuser_accounts_la_LIBADD)
163
164 frob_account_dialog_CFLAGS = \
165- $(AM_CFLAGS) \
166- -DUIDIR=\""$(pkgdatadir)/ui/user-accounts"\"
167+ $(AM_CFLAGS)
168
169 polkitdir = $(datadir)/polkit-1/actions
170 polkit_in_files = com.canonical.controlcenter.user-accounts.policy.in
171@@ -114,6 +112,8 @@
172
173 EXTRA_DIST = \
174 $(polkit_in_files) \
175+ $(resource_files) \
176+ user-accounts.gresource.xml \
177 $(NULL)
178
179 CLEANFILES = \
180
181=== modified file 'panels/user-accounts/data/Makefile.am'
182--- panels/user-accounts/data/Makefile.am 2013-11-29 06:28:37 +0000
183+++ panels/user-accounts/data/Makefile.am 2014-02-24 09:46:44 +0000
184@@ -1,13 +1,3 @@
185-SUBDIRS = icons
186-
187-uidir = $(pkgdatadir)/ui/user-accounts
188-ui_DATA = \
189- account-dialog.ui \
190- password-dialog.ui \
191- photo-dialog.ui \
192- user-accounts-dialog.ui \
193- account-fingerprint.ui
194-
195 @INTLTOOL_DESKTOP_RULE@
196
197 desktopdir = $(datadir)/applications
198@@ -16,8 +6,7 @@
199
200 EXTRA_DIST = \
201 unity-user-accounts-panel.desktop.in.in \
202- org.freedesktop.realmd.xml \
203- $(ui_DATA)
204+ org.freedesktop.realmd.xml
205
206 CLEANFILES = \
207 unity-user-accounts-panel.desktop \
208
209=== modified file 'panels/user-accounts/data/account-dialog.ui'
210--- panels/user-accounts/data/account-dialog.ui 2012-09-16 20:15:22 +0000
211+++ panels/user-accounts/data/account-dialog.ui 2014-02-24 09:46:44 +0000
212@@ -1,6 +1,6 @@
213 <?xml version="1.0"?>
214 <interface>
215- <!-- interface-requires gtk+ 2.12 -->
216+ <!-- interface-requires gtk+ 3.8 -->
217 <!-- interface-naming-policy toplevel-contextual -->
218 <object class="GtkListStore" id="username-model">
219 <columns>
220@@ -285,6 +285,7 @@
221 <child internal-child="entry">
222 <object class="GtkEntry" id="combobox-entry">
223 <property name="can_focus">True</property>
224+ <property name="activates_default">True</property>
225 </object>
226 </child>
227 </object>
228@@ -322,6 +323,7 @@
229 <property name="can_focus">True</property>
230 <property name="hexpand">True</property>
231 <property name="invisible_char">●</property>
232+ <property name="activates_default">True</property>
233 <property name="invisible_char_set">True</property>
234 </object>
235 <packing>
236
237=== modified file 'panels/user-accounts/data/account-fingerprint.ui'
238--- panels/user-accounts/data/account-fingerprint.ui 2011-08-25 16:31:16 +0000
239+++ panels/user-accounts/data/account-fingerprint.ui 2014-02-24 09:46:44 +0000
240@@ -1,6 +1,6 @@
241 <?xml version="1.0"?>
242 <interface>
243- <requires lib="gtk+" version="2.16"/>
244+ <!-- interface-requires gtk+ 3.8 -->
245 <!-- interface-naming-policy toplevel-contextual -->
246 <object class="GtkListStore" id="model1">
247 <columns>
248
249=== added file 'panels/user-accounts/data/history-dialog.ui'
250--- panels/user-accounts/data/history-dialog.ui 1970-01-01 00:00:00 +0000
251+++ panels/user-accounts/data/history-dialog.ui 2014-02-24 09:46:44 +0000
252@@ -0,0 +1,175 @@
253+<?xml version="1.0" encoding="UTF-8"?>
254+<interface>
255+ <!-- interface-requires gtk+ 3.8 -->
256+ <object class="GtkDialog" id="dialog">
257+ <property name="can_focus">False</property>
258+ <property name="title" translatable="yes">Login History</property>
259+ <property name="resizable">False</property>
260+ <property name="modal">True</property>
261+ <property name="window_position">center-on-parent</property>
262+ <property name="icon_name">system-users</property>
263+ <property name="type_hint">dialog</property>
264+ <child internal-child="vbox">
265+ <object class="GtkBox" id="dialog-vbox1">
266+ <property name="can_focus">False</property>
267+ <property name="orientation">vertical</property>
268+ <property name="spacing">2</property>
269+ <child internal-child="action_area">
270+ <object class="GtkButtonBox" id="dialog-action_area1">
271+ <property name="can_focus">False</property>
272+ <property name="layout_style">end</property>
273+ <child>
274+ <object class="GtkButton" id="close-button">
275+ <property name="label" translatable="yes">Close</property>
276+ <property name="visible">True</property>
277+ <property name="can_focus">True</property>
278+ <property name="receives_default">True</property>
279+ </object>
280+ <packing>
281+ <property name="expand">False</property>
282+ <property name="fill">True</property>
283+ <property name="position">1</property>
284+ </packing>
285+ </child>
286+ </object>
287+ <packing>
288+ <property name="expand">False</property>
289+ <property name="fill">True</property>
290+ <property name="pack_type">end</property>
291+ <property name="position">0</property>
292+ </packing>
293+ </child>
294+ <child>
295+ <object class="GtkBox" id="box1">
296+ <property name="visible">True</property>
297+ <property name="can_focus">False</property>
298+ <property name="orientation">vertical</property>
299+ <child>
300+ <object class="GtkBox" id="box3">
301+ <property name="visible">True</property>
302+ <property name="can_focus">False</property>
303+ <property name="margin_left">6</property>
304+ <property name="margin_right">6</property>
305+ <property name="spacing">6</property>
306+ <child>
307+ <object class="GtkButton" id="previous-button">
308+ <property name="visible">True</property>
309+ <property name="can_focus">True</property>
310+ <property name="receives_default">True</property>
311+ <child internal-child="accessible">
312+ <object class="AtkObject" id="previous-button-atkobject">
313+ <property name="accessible-name" translatable="yes">Previous Week</property>
314+ </object>
315+ </child>
316+ <child>
317+ <object class="GtkArrow" id="arrow1">
318+ <property name="visible">True</property>
319+ <property name="can_focus">False</property>
320+ <property name="arrow_type">left</property>
321+ </object>
322+ </child>
323+ </object>
324+ <packing>
325+ <property name="expand">False</property>
326+ <property name="fill">True</property>
327+ <property name="position">0</property>
328+ </packing>
329+ </child>
330+ <child>
331+ <object class="GtkLabel" id="week-label">
332+ <property name="visible">True</property>
333+ <property name="can_focus">False</property>
334+ <attributes>
335+ <attribute name="weight" value="bold"/>
336+ </attributes>
337+ </object>
338+ <packing>
339+ <property name="expand">True</property>
340+ <property name="fill">True</property>
341+ <property name="position">1</property>
342+ </packing>
343+ </child>
344+ <child>
345+ <object class="GtkButton" id="next-button">
346+ <property name="visible">True</property>
347+ <property name="can_focus">True</property>
348+ <property name="receives_default">True</property>
349+ <child internal-child="accessible">
350+ <object class="AtkObject" id="next-button-atkobject">
351+ <property name="accessible-name" translatable="yes">Next Week</property>
352+ </object>
353+ </child>
354+ <child>
355+ <object class="GtkArrow" id="arrow2">
356+ <property name="visible">True</property>
357+ <property name="can_focus">False</property>
358+ <child internal-child="accessible">
359+ <object class="AtkObject" id="arrow2-atkobject">
360+ <property name="accessible-name" translatable="yes">Next week</property>
361+ </object>
362+ </child>
363+ </object>
364+ </child>
365+ </object>
366+ <packing>
367+ <property name="expand">False</property>
368+ <property name="fill">True</property>
369+ <property name="position">2</property>
370+ </packing>
371+ </child>
372+ </object>
373+ <packing>
374+ <property name="expand">False</property>
375+ <property name="fill">True</property>
376+ <property name="position">0</property>
377+ </packing>
378+ </child>
379+ <child>
380+ <object class="GtkScrolledWindow" id="scrolledwindow1">
381+ <property name="width_request">350</property>
382+ <property name="height_request">300</property>
383+ <property name="visible">True</property>
384+ <property name="can_focus">True</property>
385+ <property name="hexpand">True</property>
386+ <property name="vexpand">True</property>
387+ <property name="border_width">6</property>
388+ <property name="hscrollbar_policy">never</property>
389+ <property name="shadow_type">in</property>
390+ <child>
391+ <object class="GtkViewport" id="viewport1">
392+ <property name="visible">True</property>
393+ <property name="can_focus">False</property>
394+ <child>
395+ <object class="GtkGrid" id="history-grid">
396+ <property name="visible">True</property>
397+ <property name="can_focus">False</property>
398+ <property name="hexpand">True</property>
399+ <property name="border_width">12</property>
400+ <property name="row_spacing">12</property>
401+ <property name="column_spacing">12</property>
402+ <property name="column_homogeneous">True</property>
403+ </object>
404+ </child>
405+ </object>
406+ </child>
407+ </object>
408+ <packing>
409+ <property name="expand">True</property>
410+ <property name="fill">True</property>
411+ <property name="position">1</property>
412+ </packing>
413+ </child>
414+ </object>
415+ <packing>
416+ <property name="expand">True</property>
417+ <property name="fill">True</property>
418+ <property name="position">1</property>
419+ </packing>
420+ </child>
421+ </object>
422+ </child>
423+ <action-widgets>
424+ <action-widget response="0">close-button</action-widget>
425+ </action-widgets>
426+ </object>
427+</interface>
428
429=== removed file 'panels/user-accounts/data/icons/Makefile.am'
430--- panels/user-accounts/data/icons/Makefile.am 2012-03-08 15:09:09 +0000
431+++ panels/user-accounts/data/icons/Makefile.am 1970-01-01 00:00:00 +0000
432@@ -1,32 +0,0 @@
433-pixmapsdir = $(pkgdatadir)/pixmaps
434-pixmaps_DATA = \
435- gnome-about-me-lock.png \
436- gnome-about-me-lock-open.png \
437- left-index-finger.svg \
438- left-little-finger.svg \
439- left-middle-finger.svg \
440- left-ring-finger.svg \
441- left-thumb.svg \
442- print_error.svg \
443- print_ok.svg \
444- right-index-finger.svg \
445- right-little-finger.svg \
446- right-middle-finger.svg \
447- right-ring-finger.svg \
448- right-thumb.svg \
449- left-index-finger.png \
450- left-middle-finger.png \
451- left-little-finger.png \
452- left-ring-finger.png \
453- left-thumb.png \
454- print_error.png \
455- print_ok.png \
456- right-index-finger.png \
457- right-middle-finger.png \
458- right-little-finger.png \
459- right-ring-finger.png \
460- right-thumb.png
461-
462-EXTRA_DIST = $(pixmaps_DATA)
463-
464--include $(top_srcdir)/git.mk
465
466=== removed file 'panels/user-accounts/data/icons/gnome-about-me-lock-open.png'
467Binary files panels/user-accounts/data/icons/gnome-about-me-lock-open.png 2010-10-30 22:04:15 +0000 and panels/user-accounts/data/icons/gnome-about-me-lock-open.png 1970-01-01 00:00:00 +0000 differ
468=== removed file 'panels/user-accounts/data/icons/gnome-about-me-lock.png'
469Binary files panels/user-accounts/data/icons/gnome-about-me-lock.png 2010-10-30 22:04:15 +0000 and panels/user-accounts/data/icons/gnome-about-me-lock.png 1970-01-01 00:00:00 +0000 differ
470=== modified file 'panels/user-accounts/data/password-dialog.ui'
471--- panels/user-accounts/data/password-dialog.ui 2012-07-16 10:29:25 +0000
472+++ panels/user-accounts/data/password-dialog.ui 2014-02-24 09:46:44 +0000
473@@ -1,6 +1,6 @@
474 <?xml version="1.0"?>
475 <interface>
476- <!-- interface-requires gtk+ 2.12 -->
477+ <!-- interface-requires gtk+ 3.8 -->
478 <!-- interface-naming-policy toplevel-contextual -->
479 <object class="GtkListStore" id="action-model">
480 <columns>
481@@ -133,6 +133,7 @@
482 <property name="visible">True</property>
483 <property name="can_focus">True</property>
484 <property name="visibility">False</property>
485+ <property name="activates_default">True</property>
486 </object>
487 <packing>
488 <property name="left_attach">1</property>
489@@ -208,6 +209,7 @@
490 <property name="visibility">False</property>
491 <property name="secondary-icon-name">system-run-symbolic</property>
492 <property name="secondary-icon-tooltip-text" translatable="yes">Generate a password</property>
493+ <property name="activates_default">True</property>
494 </object>
495 <packing>
496 <property name="position">0</property>
497@@ -249,7 +251,7 @@
498 <object class="GtkLabel" id="strength-indicator-label">
499 <property name="visible">True</property>
500 <property name="xalign">0</property>
501- <property name="label" translatable="yes">Fair</property>
502+ <property name="label"></property>
503 </object>
504 <packing>
505 <property name="position">1</property>
506@@ -289,6 +291,7 @@
507 <property name="visible">True</property>
508 <property name="can_focus">True</property>
509 <property name="visibility">False</property>
510+ <property name="activates_default">True</property>
511 </object>
512 <packing>
513 <property name="left_attach">1</property>
514@@ -394,6 +397,8 @@
515 <object class="GtkLabel" id="user-name">
516 <property name="visible">True</property>
517 <property name="xalign">0</property>
518+ <property name="ellipsize">end</property>
519+ <property name="max_width_chars">30</property>
520 <attributes>
521 <attribute name="weight" value="bold"/>
522 <attribute name="scale" value="1.200000"/>
523
524=== modified file 'panels/user-accounts/data/photo-dialog.ui'
525--- panels/user-accounts/data/photo-dialog.ui 2010-10-30 22:04:15 +0000
526+++ panels/user-accounts/data/photo-dialog.ui 2014-02-24 09:46:44 +0000
527@@ -1,5 +1,6 @@
528 <?xml version="1.0"?>
529 <interface>
530+ <!-- interface-requires gtk+ 3.8 -->
531 <object class="GtkAdjustment" id="browse-scale-adjustment">
532 <property name="lower">0</property>
533 <property name="upper">100</property>
534
535=== modified file 'panels/user-accounts/data/user-accounts-dialog.ui'
536--- panels/user-accounts/data/user-accounts-dialog.ui 2014-02-14 03:32:04 +0000
537+++ panels/user-accounts/data/user-accounts-dialog.ui 2014-02-24 09:46:44 +0000
538@@ -1,6 +1,5 @@
539-
540 <interface>
541- <requires lib="gtk+" version="2.16"/>
542+ <!-- interface-requires gtk+ 3.8 -->
543 <!-- interface-naming-policy toplevel-contextual -->
544 <object class="GtkListStore" id="shortname-model">
545 <columns>
546@@ -50,7 +49,7 @@
547 <child>
548 <object class="GtkHBox" id="hbox2">
549 <property name="visible">True</property>
550- <property name="spacing">12</property>
551+ <property name="spacing">18</property>
552 <child>
553 <object class="GtkVBox" id="userlist-vbox">
554 <property name="visible">True</property>
555@@ -131,16 +130,16 @@
556 <property name="orientation">vertical</property>
557 <property name="spacing">6</property>
558 <child>
559- <object class="GtkTable" id="table1">
560+ <object class="GtkGrid" id="grid1">
561 <property name="visible">True</property>
562- <property name="n_rows">7</property>
563- <property name="n_columns">2</property>
564+ <property name="can_focus">False</property>
565 <property name="column_spacing">10</property>
566 <child>
567 <object class="GtkNotebook" id="account-fingerprint-notebook">
568 <property name="visible">True</property>
569 <property name="show_tabs">False</property>
570 <property name="show_border">False</property>
571+ <property name="hexpand">True</property>
572 <child>
573 <object class="GtkLabel" id="account-fingerprint-value-label">
574 <property name="visible">True</property>
575@@ -167,10 +166,9 @@
576 </object>
577 <packing>
578 <property name="left_attach">1</property>
579- <property name="right_attach">2</property>
580 <property name="top_attach">6</property>
581- <property name="bottom_attach">7</property>
582- <property name="y_options">0</property>
583+ <property name="width">1</property>
584+ <property name="height">1</property>
585 </packing>
586 </child>
587 <child>
588@@ -178,13 +176,13 @@
589 <property name="visible">True</property>
590 <property name="model">account-type-model</property>
591 <property name="text-column">0</property>
592+ <property name="hexpand">True</property>
593 </object>
594 <packing>
595 <property name="left_attach">1</property>
596- <property name="right_attach">2</property>
597 <property name="top_attach">1</property>
598- <property name="bottom_attach">2</property>
599- <property name="y_options">0</property>
600+ <property name="width">1</property>
601+ <property name="height">1</property>
602 </packing>
603 </child>
604 <child>
605@@ -199,10 +197,10 @@
606 </style>
607 </object>
608 <packing>
609+ <property name="left_attach">0</property>
610 <property name="top_attach">1</property>
611- <property name="bottom_attach">2</property>
612- <property name="x_options">GTK_FILL</property>
613- <property name="y_options">0</property>
614+ <property name="width">1</property>
615+ <property name="height">1</property>
616 </packing>
617 </child>
618 <child>
619@@ -214,9 +212,11 @@
620 <property name="visible">True</property>
621 <property name="scale">1.2</property>
622 <property name="weight">700</property>
623+ <property name="width-chars">30</property>
624+ <property name="max-width-chars">30</property>
625+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
626 </object>
627 <packing>
628- <property name="expand">True</property>
629 <property name="fill">True</property>
630 <property name="position">1</property>
631 </packing>
632@@ -224,8 +224,9 @@
633 </object>
634 <packing>
635 <property name="left_attach">1</property>
636- <property name="right_attach">2</property>
637- <property name="y_options">0</property>
638+ <property name="top_attach">0</property>
639+ <property name="width">1</property>
640+ <property name="height">1</property>
641 </packing>
642 </child>
643 <child>
644@@ -239,10 +240,10 @@
645 </attributes>
646 </object>
647 <packing>
648+ <property name="left_attach">0</property>
649 <property name="top_attach">3</property>
650- <property name="bottom_attach">4</property>
651- <property name="x_options">GTK_FILL</property>
652- <property name="y_options">0</property>
653+ <property name="width">1</property>
654+ <property name="height">1</property>
655 </packing>
656 </child>
657 <child>
658@@ -257,22 +258,22 @@
659 </style>
660 </object>
661 <packing>
662+ <property name="left_attach">0</property>
663 <property name="top_attach">4</property>
664- <property name="bottom_attach">5</property>
665- <property name="x_options">GTK_FILL</property>
666- <property name="y_options">0</property>
667+ <property name="width">1</property>
668+ <property name="height">1</property>
669 </packing>
670 </child>
671 <child>
672 <object class="UmEditableButton" id="account-password-button">
673 <property name="visible">True</property>
674+ <property name="hexpand">True</property>
675 </object>
676 <packing>
677 <property name="left_attach">1</property>
678- <property name="right_attach">2</property>
679 <property name="top_attach">4</property>
680- <property name="bottom_attach">5</property>
681- <property name="y_options">0</property>
682+ <property name="width">1</property>
683+ <property name="height">1</property>
684 </packing>
685 </child>
686 <child>
687@@ -287,10 +288,10 @@
688 </style>
689 </object>
690 <packing>
691+ <property name="left_attach">0</property>
692 <property name="top_attach">5</property>
693- <property name="bottom_attach">6</property>
694- <property name="x_options">GTK_FILL</property>
695- <property name="y_options">0</property>
696+ <property name="width">1</property>
697+ <property name="height">1</property>
698 </packing>
699 </child>
700 <child>
701@@ -312,10 +313,9 @@
702 </object>
703 <packing>
704 <property name="left_attach">1</property>
705- <property name="right_attach">2</property>
706 <property name="top_attach">5</property>
707- <property name="bottom_attach">6</property>
708- <property name="y_options">0</property>
709+ <property name="width">1</property>
710+ <property name="height">1</property>
711 </packing>
712 </child>
713 <child>
714@@ -330,10 +330,10 @@
715 </style>
716 </object>
717 <packing>
718+ <property name="left_attach">0</property>
719 <property name="top_attach">6</property>
720- <property name="bottom_attach">7</property>
721- <property name="x_options">GTK_FILL</property>
722- <property name="y_options">0</property>
723+ <property name="width">1</property>
724+ <property name="height">1</property>
725 </packing>
726 </child>
727 <child>
728@@ -342,6 +342,7 @@
729 <child>
730 <object class="GtkLabel" id="label4">
731 <property name="visible">True</property>
732+ <property name="hexpand">True</property>
733 </object>
734 <packing>
735 <property name="expand">True</property>
736@@ -399,8 +400,10 @@
737 </child>
738 </object>
739 <packing>
740- <property name="x_options">GTK_FILL</property>
741- <property name="y_options">0</property>
742+ <property name="left_attach">0</property>
743+ <property name="top_attach">0</property>
744+ <property name="width">1</property>
745+ <property name="height">1</property>
746 </packing>
747 </child>
748 <child>
749@@ -415,10 +418,10 @@
750 </style>
751 </object>
752 <packing>
753+ <property name="left_attach">0</property>
754 <property name="top_attach">2</property>
755- <property name="bottom_attach">3</property>
756- <property name="x_options">GTK_FILL</property>
757- <property name="y_options">0</property>
758+ <property name="width">1</property>
759+ <property name="height">1</property>
760 </packing>
761 </child>
762 <child>
763@@ -426,42 +429,76 @@
764 <property name="visible">True</property>
765 <property name="model">language-model</property>
766 <property name="text-column">1</property>
767+ <property name="hexpand">True</property>
768 </object>
769 <packing>
770 <property name="left_attach">1</property>
771- <property name="right_attach">2</property>
772 <property name="top_attach">2</property>
773- <property name="bottom_attach">3</property>
774- <property name="x_options">GTK_FILL</property>
775- <property name="y_options">0</property>
776+ <property name="width">1</property>
777+ <property name="height">1</property>
778 </packing>
779 </child>
780 <child>
781- <object class="GtkLabel" id="show-login-name-spacer">
782+ <object class="GtkLabel" id="last-login-label">
783 <property name="visible">True</property>
784- </object>
785- <packing>
786- <property name="right_attach">2</property>
787- <property name="top_attach">7</property>
788- <property name="bottom_attach">8</property>
789- </packing>
790- </child>
791- <child>
792- <object class="GtkCheckButton" id="show-login-name-checkbutton">
793- <property name="label" translatable="yes">_Show my login name in the menu bar</property>
794+ <property name="xalign">1</property>
795+ <property name="label" translatable="yes">Last Login</property>
796 <property name="use_underline">True</property>
797+ <property name="mnemonic_widget">last-login-value-label</property>
798+ <style>
799+ <class name="dim-label"/>
800+ </style>
801+ </object>
802+ <packing>
803+ <property name="left_attach">0</property>
804+ <property name="top_attach">7</property>
805+ <property name="width">1</property>
806+ <property name="height">1</property>
807+ </packing>
808+ </child>
809+ <child>
810+ <object class="GtkGrid" id="last-login-grid">
811 <property name="visible">True</property>
812- <property name="can_focus">True</property>
813- <property name="receives_default">False</property>
814- <property name="xalign">0</property>
815- <property name="draw_indicator">True</property>
816+ <property name="can_focus">False</property>
817+ <child>
818+ <object class="GtkLabel" id="last-login-value-label">
819+ <property name="visible">True</property>
820+ <property name="can_focus">False</property>
821+ <property name="margin_left">6</property>
822+ <property name="margin_right">6</property>
823+ <property name="margin_top">6</property>
824+ <property name="margin_bottom">6</property>
825+ <property name="hexpand">True</property>
826+ <property name="xalign">0</property>
827+ </object>
828+ <packing>
829+ <property name="left_attach">0</property>
830+ <property name="top_attach">0</property>
831+ <property name="width">1</property>
832+ <property name="height">1</property>
833+ </packing>
834+ </child>
835+ <child>
836+ <object class="GtkButton" id="last-login-history-button">
837+ <property name="label" translatable="yes">History</property>
838+ <property name="visible">True</property>
839+ <property name="can_focus">True</property>
840+ <property name="receives_default">True</property>
841+ <property name="xalign">1</property>
842+ </object>
843+ <packing>
844+ <property name="left_attach">1</property>
845+ <property name="top_attach">0</property>
846+ <property name="width">1</property>
847+ <property name="height">1</property>
848+ </packing>
849+ </child>
850 </object>
851 <packing>
852- <property name="right_attach">2</property>
853- <property name="top_attach">8</property>
854- <property name="bottom_attach">9</property>
855- <property name="x_options">GTK_FILL</property>
856- <property name="y_options">0</property>
857+ <property name="left_attach">1</property>
858+ <property name="top_attach">7</property>
859+ <property name="width">1</property>
860+ <property name="height">1</property>
861 </packing>
862 </child>
863 </object>
864@@ -471,6 +508,33 @@
865 <property name="position">0</property>
866 </packing>
867 </child>
868+ <child>
869+ <object class="GtkLabel" id="show-login-name-spacer">
870+ <property name="visible">True</property>
871+ <property name="can_focus">False</property>
872+ </object>
873+ <packing>
874+ <property name="expand">True</property>
875+ <property name="fill">True</property>
876+ <property name="position">1</property>
877+ </packing>
878+ </child>
879+ <child>
880+ <object class="GtkCheckButton" id="show-login-name-checkbutton">
881+ <property name="label" translatable="yes">_Show my login name in the menu bar</property>
882+ <property name="visible">True</property>
883+ <property name="can_focus">True</property>
884+ <property name="receives_default">False</property>
885+ <property name="use_underline">True</property>
886+ <property name="xalign">0</property>
887+ <property name="draw_indicator">True</property>
888+ </object>
889+ <packing>
890+ <property name="expand">False</property>
891+ <property name="fill">True</property>
892+ <property name="position">2</property>
893+ </packing>
894+ </child>
895 </object>
896 <packing>
897 <property name="expand">True</property>
898
899=== modified file 'panels/user-accounts/frob-account-dialog.c'
900--- panels/user-accounts/frob-account-dialog.c 2012-06-12 10:03:29 +0000
901+++ panels/user-accounts/frob-account-dialog.c 2014-02-24 09:46:44 +0000
902@@ -27,13 +27,13 @@
903 gpointer user_data)
904 {
905 GMainLoop *loop = user_data;
906- UmUser *user;
907+ ActUser *user;
908
909 user = um_account_dialog_finish (UM_ACCOUNT_DIALOG (object), result);
910 if (user == NULL) {
911 g_printerr ("No user created\n");
912 } else {
913- g_printerr ("User created: %s\n", um_user_get_user_name (user));
914+ g_printerr ("User created: %s\n", act_user_get_user_name (user));
915 g_object_unref (user);
916 }
917
918@@ -52,7 +52,7 @@
919 dialog = um_account_dialog_new ();
920 loop = g_main_loop_new (NULL, FALSE);
921
922- um_account_dialog_show (dialog, NULL, on_dialog_complete, loop);
923+ um_account_dialog_show (dialog, NULL, NULL, on_dialog_complete, loop);
924
925 g_main_loop_run (loop);
926 g_main_loop_unref (loop);
927
928=== modified file 'panels/user-accounts/um-account-dialog.c'
929--- panels/user-accounts/um-account-dialog.c 2012-12-12 11:57:06 +0000
930+++ panels/user-accounts/um-account-dialog.c 2014-02-24 09:46:44 +0000
931@@ -24,10 +24,10 @@
932 #include <glib.h>
933 #include <glib/gi18n.h>
934 #include <gtk/gtk.h>
935+#include <act/act.h>
936
937 #include "um-account-dialog.h"
938 #include "um-realm-manager.h"
939-#include "um-user-manager.h"
940 #include "um-utils.h"
941
942 typedef enum {
943@@ -49,6 +49,9 @@
944 GAsyncResult *result,
945 gpointer user_data);
946
947+static void um_account_dialog_response (GtkDialog *dialog,
948+ gint response_id);
949+
950 #define UM_ACCOUNT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_ACCOUNT_DIALOG, \
951 UmAccountDialogClass))
952 #define UM_IS_ACCOUNT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_ACCOUNT_DIALOG))
953@@ -60,6 +63,7 @@
954 GtkWidget *container_widget;
955 GSimpleAsyncResult *async;
956 GCancellable *cancellable;
957+ GPermission *permission;
958 GtkSpinner *spinner;
959
960 /* Buttons to switch modes between local/enterprise */
961@@ -149,7 +153,7 @@
962
963 static void
964 complete_dialog (UmAccountDialog *self,
965- UmUser *user)
966+ ActUser *user)
967 {
968 if (user != NULL) {
969 g_simple_async_result_set_op_res_gpointer (self->async,
970@@ -162,34 +166,48 @@
971 }
972
973 static void
974-create_user_done (UmUserManager *manager,
975+user_loaded_cb (ActUser *user,
976+ GParamSpec *pspec,
977+ UmAccountDialog *self)
978+{
979+ finish_action (self);
980+ complete_dialog (self, user);
981+}
982+
983+static void
984+create_user_done (ActUserManager *manager,
985 GAsyncResult *res,
986 UmAccountDialog *self)
987 {
988- UmUser *user;
989+ ActUser *user;
990 GError *error;
991
992- finish_action (self);
993-
994 /* Note that user is returned without an extra reference */
995
996 error = NULL;
997- if (!um_user_manager_create_user_finish (manager, res, &user, &error)) {
998+ user = act_user_manager_create_user_finish (manager, res, &error);
999+
1000+ if (user == NULL) {
1001+ finish_action (self);
1002 g_debug ("Failed to create user: %s", error->message);
1003- if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED))
1004+ if (!g_error_matches (error, ACT_USER_MANAGER_ERROR, ACT_USER_MANAGER_ERROR_PERMISSION_DENIED))
1005 show_error_dialog (self, _("Failed to add account"), error);
1006 g_error_free (error);
1007 gtk_widget_grab_focus (self->local_name);
1008 } else {
1009- g_debug ("Created user: %s", um_user_get_user_name (user));
1010- complete_dialog (self, user);
1011+ g_debug ("Created user: %s", act_user_get_user_name (user));
1012+ /* Check if the returned object is fully loaded before returning it */
1013+ if (act_user_is_loaded (user))
1014+ user_loaded_cb (user, NULL, self);
1015+ else
1016+ g_signal_connect (user, "notify::is-loaded", G_CALLBACK (user_loaded_cb), self);
1017 }
1018 }
1019
1020 static void
1021 local_create_user (UmAccountDialog *self)
1022 {
1023- UmUserManager *manager;
1024+ ActUserManager *manager;
1025 const gchar *username;
1026 const gchar *name;
1027 gint account_type;
1028@@ -206,16 +224,14 @@
1029
1030 g_debug ("Creating local user: %s", username);
1031
1032- manager = um_user_manager_ref_default ();
1033- um_user_manager_create_user (manager,
1034- username,
1035- name,
1036- account_type,
1037- self->cancellable,
1038- (GAsyncReadyCallback)create_user_done,
1039- self,
1040- NULL);
1041- g_object_unref (manager);
1042+ manager = act_user_manager_get_default ();
1043+ act_user_manager_create_user_async (manager,
1044+ username,
1045+ name,
1046+ account_type,
1047+ self->cancellable,
1048+ (GAsyncReadyCallback)create_user_done,
1049+ self);
1050 }
1051
1052 static gboolean
1053@@ -258,13 +274,19 @@
1054 UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
1055 GtkTreeModel *model;
1056 const char *name;
1057+ GtkWidget *entry;
1058
1059 model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->local_username));
1060 gtk_list_store_clear (GTK_LIST_STORE (model));
1061
1062 name = gtk_entry_get_text (GTK_ENTRY (editable));
1063- generate_username_choices (name, GTK_LIST_STORE (model));
1064- gtk_combo_box_set_active (GTK_COMBO_BOX (self->local_username), 0);
1065+ if (strlen (name) == 0) {
1066+ entry = gtk_bin_get_child (GTK_BIN (self->local_username));
1067+ gtk_entry_set_text (GTK_ENTRY (entry), "");
1068+ } else {
1069+ generate_username_choices (name, GTK_LIST_STORE (model));
1070+ gtk_combo_box_set_active (GTK_COMBO_BOX (self->local_username), 0);
1071+ }
1072
1073 dialog_validate (self);
1074 }
1075@@ -352,6 +374,7 @@
1076 g_free (name);
1077 if (match) {
1078 g_debug ("ignoring duplicate realm: %s", realm_name);
1079+ g_object_unref (common);
1080 return;
1081 }
1082 ret = gtk_tree_model_iter_next (model, &iter);
1083@@ -389,14 +412,13 @@
1084 {
1085 UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
1086 GError *error = NULL;
1087- UmUser *user = NULL;
1088+ ActUser *user;
1089
1090- um_user_manager_cache_user_finish (UM_USER_MANAGER (source),
1091- result, &user, &error);
1092+ user = act_user_manager_cache_user_finish (ACT_USER_MANAGER (source), result, &error);
1093
1094 /* This is where we're finally done */
1095- if (error == NULL) {
1096- g_debug ("Successfully cached remote user: %s", um_user_get_user_name (user));
1097+ if (user != NULL) {
1098+ g_debug ("Successfully cached remote user: %s", act_user_get_user_name (user));
1099 finish_action (self);
1100 complete_dialog (self, user);
1101
1102@@ -406,6 +428,8 @@
1103 finish_action (self);
1104 g_error_free (error);
1105 }
1106+
1107+ g_object_unref (self);
1108 }
1109
1110 static void
1111@@ -415,7 +439,7 @@
1112 {
1113 UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
1114 UmRealmCommon *common;
1115- UmUserManager *manager;
1116+ ActUserManager *manager;
1117 GError *error = NULL;
1118 gchar *login;
1119
1120@@ -428,18 +452,16 @@
1121 * should also lookup information about this via the realm and make
1122 * sure all that is functional.
1123 */
1124- manager = um_user_manager_ref_default ();
1125+ manager = act_user_manager_get_default ();
1126 login = um_realm_calculate_login (common, gtk_entry_get_text (self->enterprise_login));
1127 g_return_if_fail (login != NULL);
1128
1129 g_debug ("Caching remote user: %s", login);
1130
1131- um_user_manager_cache_user (manager, login, self->cancellable,
1132- on_register_user, g_object_ref (self),
1133- g_object_unref);
1134+ act_user_manager_cache_user_async (manager, login, self->cancellable,
1135+ on_register_user, g_object_ref (self));
1136
1137 g_free (login);
1138- g_object_unref (manager);
1139
1140 } else {
1141 show_error_dialog (self, _("Failed to register account"), error);
1142@@ -645,9 +667,19 @@
1143 {
1144 UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
1145 GError *error = NULL;
1146- GBytes *creds;
1147+ GBytes *creds = NULL;
1148
1149 um_realm_login_finish (result, &creds, &error);
1150+
1151+ /*
1152+ * User login is valid, but cannot authenticate right now (eg: user needs
1153+ * to change password at next login etc.)
1154+ */
1155+ if (g_error_matches (error, UM_REALM_ERROR, UM_REALM_ERROR_CANNOT_AUTH)) {
1156+ g_clear_error (&error);
1157+ creds = NULL;
1158+ }
1159+
1160 if (error == NULL) {
1161
1162 /* Already joined to the domain, just register this user */
1163@@ -656,7 +688,8 @@
1164 enterprise_permit_user_login (self);
1165
1166 /* Join the domain, try using the user's creds */
1167- } else if (!um_realm_join_as_user (self->selected_realm,
1168+ } else if (creds == NULL ||
1169+ !um_realm_join_as_user (self->selected_realm,
1170 gtk_entry_get_text (self->enterprise_login),
1171 gtk_entry_get_text (self->enterprise_password),
1172 creds, self->cancellable,
1173@@ -1024,7 +1057,6 @@
1174 {
1175 GtkBuilder *builder;
1176 GtkWidget *widget;
1177- const gchar *filename;
1178 GError *error = NULL;
1179 GtkDialog *dialog;
1180 GtkWidget *content;
1181@@ -1033,10 +1065,9 @@
1182
1183 builder = gtk_builder_new ();
1184
1185- filename = UIDIR "/account-dialog.ui";
1186- if (!g_file_test (filename, G_FILE_TEST_EXISTS))
1187- filename = "data/account-dialog.ui";
1188- if (!gtk_builder_add_from_file (builder, filename, &error)) {
1189+ if (!gtk_builder_add_from_resource (builder,
1190+ "/org/gnome/control-center/user-accounts/account-dialog.ui",
1191+ &error)) {
1192 g_error ("%s", error->message);
1193 g_error_free (error);
1194 return;
1195@@ -1069,6 +1100,7 @@
1196
1197 gtk_dialog_add_button (dialog, _("Cancel"), GTK_RESPONSE_CANCEL);
1198 widget = gtk_dialog_add_button (dialog, _("_Add"), GTK_RESPONSE_OK);
1199+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
1200 gtk_widget_grab_default (widget);
1201
1202 widget = (GtkWidget *) gtk_builder_get_object (builder, "account-dialog");
1203@@ -1084,6 +1116,28 @@
1204 }
1205
1206 static void
1207+on_permission_acquired (GObject *source_object,
1208+ GAsyncResult *res,
1209+ gpointer user_data)
1210+{
1211+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
1212+ GError *error = NULL;
1213+
1214+ /* Paired with begin_action in um_account_dialog_response () */
1215+ finish_action (self);
1216+
1217+ if (g_permission_acquire_finish (self->permission, res, &error)) {
1218+ g_return_if_fail (g_permission_get_allowed (self->permission));
1219+ um_account_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
1220+ } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
1221+ g_warning ("Failed to acquire permission: %s", error->message);
1222+ }
1223+
1224+ g_clear_error (&error);
1225+ g_object_unref (self);
1226+}
1227+
1228+static void
1229 um_account_dialog_response (GtkDialog *dialog,
1230 gint response_id)
1231 {
1232@@ -1091,6 +1145,14 @@
1233
1234 switch (response_id) {
1235 case GTK_RESPONSE_OK:
1236+ /* We don't (or no longer) have necessary permissions */
1237+ if (self->permission && !g_permission_get_allowed (self->permission)) {
1238+ begin_action (self);
1239+ g_permission_acquire_async (self->permission, self->cancellable,
1240+ on_permission_acquired, g_object_ref (self));
1241+ return;
1242+ }
1243+
1244 switch (self->mode) {
1245 case UM_LOCAL:
1246 local_create_user (self);
1247@@ -1140,6 +1202,7 @@
1248
1249 if (self->cancellable)
1250 g_object_unref (self->cancellable);
1251+ g_clear_object (&self->permission);
1252 g_object_unref (self->enterprise_realms);
1253
1254 G_OBJECT_CLASS (um_account_dialog_parent_class)->finalize (obj);
1255@@ -1166,6 +1229,7 @@
1256 void
1257 um_account_dialog_show (UmAccountDialog *self,
1258 GtkWindow *parent,
1259+ GPermission *permission,
1260 GAsyncReadyCallback callback,
1261 gpointer user_data)
1262 {
1263@@ -1181,6 +1245,9 @@
1264 g_object_unref (self->cancellable);
1265 self->cancellable = g_cancellable_new ();
1266
1267+ g_clear_object (&self->permission);
1268+ self->permission = permission ? g_object_ref (permission) : NULL;
1269+
1270 local_prepare (self);
1271 enterprise_prepare (self);
1272 mode_change (self, UM_LOCAL);
1273@@ -1192,11 +1259,11 @@
1274 gtk_widget_grab_focus (self->local_name);
1275 }
1276
1277-UmUser *
1278+ActUser *
1279 um_account_dialog_finish (UmAccountDialog *self,
1280 GAsyncResult *result)
1281 {
1282- UmUser *user;
1283+ ActUser *user;
1284
1285 g_return_val_if_fail (UM_IS_ACCOUNT_DIALOG (self), NULL);
1286 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
1287
1288=== modified file 'panels/user-accounts/um-account-dialog.h'
1289--- panels/user-accounts/um-account-dialog.h 2012-09-06 23:07:09 +0000
1290+++ panels/user-accounts/um-account-dialog.h 2014-02-24 09:46:44 +0000
1291@@ -22,8 +22,8 @@
1292 #ifndef __UM_ACCOUNT_DIALOG_H__
1293 #define __UM_ACCOUNT_DIALOG_H__
1294
1295+#include <act/act.h>
1296 #include <gtk/gtk.h>
1297-#include "um-user.h"
1298
1299 G_BEGIN_DECLS
1300
1301@@ -38,9 +38,10 @@
1302 UmAccountDialog *um_account_dialog_new (void);
1303 void um_account_dialog_show (UmAccountDialog *self,
1304 GtkWindow *parent,
1305+ GPermission *permission,
1306 GAsyncReadyCallback callback,
1307 gpointer user_data);
1308-UmUser * um_account_dialog_finish (UmAccountDialog *self,
1309+ActUser * um_account_dialog_finish (UmAccountDialog *self,
1310 GAsyncResult *result);
1311
1312 G_END_DECLS
1313
1314=== modified file 'panels/user-accounts/um-fingerprint-dialog.c'
1315--- panels/user-accounts/um-fingerprint-dialog.c 2014-02-18 03:09:04 +0000
1316+++ panels/user-accounts/um-fingerprint-dialog.c 2014-02-24 09:46:44 +0000
1317@@ -256,7 +256,7 @@
1318 delete_fingerprints_question (GtkWindow *parent,
1319 GtkWidget *label1,
1320 GtkWidget *label2,
1321- UmUser *user)
1322+ ActUser *user)
1323 {
1324 GtkWidget *question;
1325 GtkWidget *button;
1326@@ -446,8 +446,8 @@
1327
1328 data->num_stages_done++;
1329 name = g_strdup_printf ("image%d", data->num_stages_done);
1330- path = g_build_filename (UM_PIXMAP_DIR, "print_ok.png", NULL);
1331- gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
1332+ path = g_strdup_printf ("/org/gnome/control-center/user-accounts/print_ok.png");
1333+ gtk_image_set_from_resource (GTK_IMAGE (WID (name)), path);
1334 g_free (name);
1335 g_free (path);
1336 }
1337@@ -577,16 +577,12 @@
1338 }
1339 /* And set the right image */
1340 {
1341- char *filename;
1342-
1343- filename = g_strdup_printf ("%s.png", data->finger);
1344- path = g_build_filename (UM_PIXMAP_DIR, filename, NULL);
1345- g_free (filename);
1346+ path = g_strdup_printf ("/org/gnome/control-center/user-accounts/%s.png", data->finger);
1347 }
1348 for (i = 1; i <= data->num_enroll_stages; i++) {
1349 char *name;
1350 name = g_strdup_printf ("image%d", i);
1351- gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
1352+ gtk_image_set_from_resource (GTK_IMAGE (WID (name)), path);
1353 g_free (name);
1354 }
1355 g_free (path);
1356@@ -628,13 +624,12 @@
1357 enroll_fingerprints (GtkWindow *parent,
1358 GtkWidget *label1,
1359 GtkWidget *label2,
1360- UmUser *user)
1361+ ActUser *user)
1362 {
1363 GDBusProxy *device;
1364 GtkBuilder *dialog;
1365 EnrollData *data;
1366 GtkWidget *ass;
1367- const char *filename;
1368 char *msg;
1369 GVariant *result;
1370 GError *error = NULL;
1371@@ -692,10 +687,9 @@
1372 }
1373
1374 dialog = gtk_builder_new ();
1375- filename = UIDIR "/account-fingerprint.ui";
1376- if (!g_file_test (filename, G_FILE_TEST_EXISTS))
1377- filename = "data/account-fingerprint.ui";
1378- if (!gtk_builder_add_from_file (dialog, filename, &error)) {
1379+ if (!gtk_builder_add_from_resource (dialog,
1380+ "/org/gnome/control-center/user-accounts/account-fingerprint.ui",
1381+ &error)) {
1382 g_error ("%s", error->message);
1383 g_error_free (error);
1384 return;
1385@@ -766,7 +760,7 @@
1386 fingerprint_button_clicked (GtkWindow *parent,
1387 GtkWidget *label1,
1388 GtkWidget *label2,
1389- UmUser *user)
1390+ ActUser *user)
1391 {
1392 bindtextdomain ("fprintd", GNOMELOCALEDIR);
1393 bind_textdomain_codeset ("fprintd", "UTF-8");
1394
1395=== modified file 'panels/user-accounts/um-fingerprint-dialog.h'
1396--- panels/user-accounts/um-fingerprint-dialog.h 2010-10-30 22:04:15 +0000
1397+++ panels/user-accounts/um-fingerprint-dialog.h 2014-02-24 09:46:44 +0000
1398@@ -18,11 +18,11 @@
1399 */
1400
1401 #include <gtk/gtk.h>
1402-#include "um-user.h"
1403+#include <act/act.h>
1404
1405 gboolean set_fingerprint_label (GtkWidget *label1,
1406 GtkWidget *label2);
1407 void fingerprint_button_clicked (GtkWindow *parent,
1408 GtkWidget *label1,
1409 GtkWidget *label2,
1410- UmUser *user);
1411+ ActUser *user);
1412
1413=== added file 'panels/user-accounts/um-history-dialog.c'
1414--- panels/user-accounts/um-history-dialog.c 1970-01-01 00:00:00 +0000
1415+++ panels/user-accounts/um-history-dialog.c 2014-02-24 09:46:44 +0000
1416@@ -0,0 +1,377 @@
1417+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1418+ *
1419+ * Copyright 2012 Red Hat, Inc,
1420+ *
1421+ * This program is free software; you can redistribute it and/or modify
1422+ * it under the terms of the GNU General Public License as published by
1423+ * the Free Software Foundation; either version 2 of the License, or
1424+ * (at your option) any later version.
1425+ *
1426+ * This program is distributed in the hope that it will be useful,
1427+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1428+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1429+ * GNU General Public License for more details.
1430+ *
1431+ * You should have received a copy of the GNU General Public License
1432+ * along with this program; if not, write to the Free Software
1433+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1434+ *
1435+ * Written by: Ondrej Holy <oholy@redhat.com>
1436+ */
1437+
1438+#include "config.h"
1439+
1440+#include <unistd.h>
1441+#include <stdlib.h>
1442+#include <sys/types.h>
1443+#include <sys/wait.h>
1444+
1445+#include <glib.h>
1446+#include <glib/gi18n.h>
1447+#include <gtk/gtk.h>
1448+#include <act/act.h>
1449+
1450+#include "um-history-dialog.h"
1451+#include "um-utils.h"
1452+
1453+struct _UmHistoryDialog {
1454+ GtkWidget *dialog;
1455+ GtkBuilder *builder;
1456+
1457+ GDateTime *week;
1458+ GDateTime *current_week;
1459+
1460+ ActUser *user;
1461+};
1462+
1463+typedef struct {
1464+ gint64 login_time;
1465+ gint64 logout_time;
1466+ const gchar *type;
1467+} UmLoginHistory;
1468+
1469+static GtkWidget *
1470+get_widget (UmHistoryDialog *um,
1471+ const char *name)
1472+{
1473+ return (GtkWidget *)gtk_builder_get_object (um->builder, name);
1474+}
1475+
1476+static void
1477+close_history_dialog (GtkButton *button,
1478+ UmHistoryDialog *um)
1479+{
1480+ gtk_widget_hide (um->dialog);
1481+
1482+ um_history_dialog_set_user (um, NULL);
1483+
1484+ if (um->week) {
1485+ g_date_time_unref (um->week);
1486+ um->week = NULL;
1487+ }
1488+
1489+ if (um->current_week) {
1490+ g_date_time_unref (um->current_week);
1491+ um->current_week = NULL;
1492+ }
1493+}
1494+
1495+static void
1496+show_week_label (UmHistoryDialog *um)
1497+{
1498+ gchar *label, *from, *to;
1499+ GDateTime *date;
1500+ GTimeSpan span;
1501+
1502+ span = g_date_time_difference (um->current_week, um->week);
1503+ if (span == 0) {
1504+ label = g_strdup (_("This Week"));
1505+ }
1506+ else if (span == G_TIME_SPAN_DAY * 7) {
1507+ label = g_strdup (_("Last Week"));
1508+ }
1509+ else {
1510+ date = g_date_time_add_days (um->week, 6);
1511+ from = g_date_time_format (um->week, "%b %e");
1512+ if (g_date_time_get_year (um->week) == g_date_time_get_year (um->current_week)) {
1513+ to = g_date_time_format (date, "%b %e");
1514+ }
1515+ else {
1516+ to = g_date_time_format (date, "%b %e, %Y");
1517+ }
1518+
1519+ label = g_strconcat (from, " - ", to, NULL);
1520+
1521+ g_date_time_unref (date);
1522+ g_free (from);
1523+ g_free (to);
1524+ }
1525+
1526+ gtk_label_set_label (GTK_LABEL (get_widget (um, "week-label")), label);
1527+
1528+ g_free (label);
1529+}
1530+
1531+static void
1532+clear_history (UmHistoryDialog *um)
1533+{
1534+ GtkWidget *grid;
1535+ GList *list, *it;
1536+
1537+ grid = get_widget (um, "history-grid");
1538+ list = gtk_container_get_children (GTK_CONTAINER (grid));
1539+ for (it = list; it != NULL; it = it->next) {
1540+ gtk_container_remove (GTK_CONTAINER (grid), GTK_WIDGET (it->data));
1541+ }
1542+ g_list_free (list);
1543+}
1544+
1545+static GArray *
1546+get_login_history (ActUser *user)
1547+{
1548+ GArray *login_history;
1549+ GVariantIter *iter, *iter2;
1550+ GVariant *variant;
1551+ const GVariant *value;
1552+ const gchar *key;
1553+ UmLoginHistory history;
1554+
1555+ login_history = NULL;
1556+ value = act_user_get_login_history (user);
1557+ g_variant_get ((GVariant *) value, "a(xxa{sv})", &iter);
1558+ while (g_variant_iter_loop (iter, "(xxa{sv})", &history.login_time, &history.logout_time, &iter2)) {
1559+ while (g_variant_iter_loop (iter2, "{sv}", &key, &variant)) {
1560+ if (g_strcmp0 (key, "type") == 0) {
1561+ history.type = g_variant_get_string (variant, NULL);
1562+ }
1563+ }
1564+
1565+ if (login_history == NULL) {
1566+ login_history = g_array_new (FALSE, TRUE, sizeof (UmLoginHistory));
1567+ }
1568+
1569+ g_array_append_val (login_history, history);
1570+ }
1571+
1572+ return login_history;
1573+}
1574+
1575+static void
1576+set_sensitivity (UmHistoryDialog *um)
1577+{
1578+ GArray *login_history;
1579+ UmLoginHistory history;
1580+ gboolean sensitive = FALSE;
1581+
1582+ login_history = get_login_history (um->user);
1583+ if (login_history != NULL) {
1584+ history = g_array_index (login_history, UmLoginHistory, 0);
1585+ sensitive = g_date_time_to_unix (um->week) > history.login_time;
1586+ g_array_free (login_history, TRUE);
1587+ }
1588+ gtk_widget_set_sensitive (get_widget (um, "previous-button"), sensitive);
1589+
1590+ sensitive = (g_date_time_compare (um->current_week, um->week) == 1);
1591+ gtk_widget_set_sensitive (get_widget (um, "next-button"), sensitive);
1592+}
1593+
1594+static void
1595+add_record (GtkWidget *grid, GDateTime *datetime, gchar *record_string, gint line)
1596+{
1597+ gchar *date, *time, *str;
1598+ GtkWidget *label;
1599+
1600+ date = get_smart_date (datetime);
1601+ time = g_date_time_format (datetime, "%k:%M");
1602+ str = g_strconcat (date, ", ", time, NULL);
1603+ label = gtk_label_new (str);
1604+ gtk_widget_set_halign (label, GTK_ALIGN_START);
1605+ gtk_grid_attach (GTK_GRID (grid), label, 1, line, 1, 1);
1606+ g_free (str);
1607+ g_free (date);
1608+ g_free (time);
1609+ g_date_time_unref (datetime);
1610+
1611+ label = gtk_label_new (record_string);
1612+ gtk_widget_set_halign (label, GTK_ALIGN_START);
1613+ gtk_grid_attach (GTK_GRID (grid), label, 2, line, 1, 1);
1614+}
1615+
1616+static void
1617+show_week (UmHistoryDialog *um)
1618+{
1619+ GArray *login_history;
1620+ GDateTime *datetime, *temp;
1621+ gint64 from, to;
1622+ gint i, line;
1623+ GtkWidget *grid;
1624+ UmLoginHistory history;
1625+
1626+ show_week_label (um);
1627+ clear_history (um);
1628+ set_sensitivity (um);
1629+
1630+ login_history = get_login_history (um->user);
1631+ if (login_history == NULL) {
1632+ return;
1633+ }
1634+
1635+ /* Find first record for week */
1636+ from = g_date_time_to_unix (um->week);
1637+ temp = g_date_time_add_weeks (um->week, 1);
1638+ to = g_date_time_to_unix (temp);
1639+ g_date_time_unref (temp);
1640+ for (i = login_history->len - 1; i >= 0; i--) {
1641+ history = g_array_index (login_history, UmLoginHistory, i);
1642+ if (history.login_time < to) {
1643+ break;
1644+ }
1645+ }
1646+
1647+ /* Add new session records */
1648+ grid = get_widget (um, "history-grid");
1649+ line = 0;
1650+ for (;i >= 0; i--) {
1651+ history = g_array_index (login_history, UmLoginHistory, i);
1652+ if (history.logout_time > 0 && history.logout_time < from) {
1653+ break;
1654+ }
1655+
1656+ /* Display only x-session and tty records */
1657+ if (!g_str_has_prefix (history.type, ":") &&
1658+ !g_str_has_prefix (history.type, "tty")&&
1659+ !g_str_has_prefix (history.type, "pts")) {
1660+ continue;
1661+ }
1662+
1663+ if (history.logout_time > 0 && history.logout_time < to) {
1664+ datetime = g_date_time_new_from_unix_local (history.logout_time);
1665+ add_record (grid, datetime, "Session Ended", line);
1666+ line++;
1667+ }
1668+
1669+ if (history.login_time >= from) {
1670+ datetime = g_date_time_new_from_unix_local (history.login_time);
1671+ add_record (grid, datetime, "Session Started", line);
1672+ line++;
1673+ }
1674+ }
1675+
1676+ gtk_widget_show_all (grid);
1677+
1678+ g_array_free (login_history, TRUE);
1679+}
1680+
1681+static void
1682+show_previous (GtkButton *button,
1683+ UmHistoryDialog *um)
1684+{
1685+ GDateTime *temp;
1686+
1687+ temp = um->week;
1688+ um->week = g_date_time_add_weeks (um->week, -1);
1689+ g_date_time_unref (temp);
1690+
1691+ show_week (um);
1692+}
1693+
1694+static void
1695+show_next (GtkButton *button,
1696+ UmHistoryDialog *um)
1697+{
1698+ GDateTime *temp;
1699+
1700+ temp = um->week;
1701+ um->week = g_date_time_add_weeks (um->week, 1);
1702+ g_date_time_unref (temp);
1703+
1704+ show_week (um);
1705+}
1706+
1707+void
1708+um_history_dialog_set_user (UmHistoryDialog *um,
1709+ ActUser *user)
1710+{
1711+ if (um->user) {
1712+ g_clear_object (&um->user);
1713+ }
1714+
1715+ if (user) {
1716+ um->user = g_object_ref (user);
1717+ }
1718+}
1719+
1720+void
1721+um_history_dialog_show (UmHistoryDialog *um,
1722+ GtkWindow *parent)
1723+{
1724+ GDateTime *temp, *local;
1725+
1726+ /* Set the first day of this week */
1727+ local = g_date_time_new_now_local ();
1728+ temp = g_date_time_new_local (g_date_time_get_year (local),
1729+ g_date_time_get_month (local),
1730+ g_date_time_get_day_of_month (local),
1731+ 0, 0, 0);
1732+ um->week = g_date_time_add_days (temp, 1 - g_date_time_get_day_of_week (temp));
1733+ um->current_week = g_date_time_ref (um->week);
1734+ g_date_time_unref (local);
1735+ g_date_time_unref (temp);
1736+
1737+ show_week (um);
1738+
1739+ gtk_window_set_transient_for (GTK_WINDOW (um->dialog), parent);
1740+ gtk_window_present (GTK_WINDOW (um->dialog));
1741+}
1742+
1743+UmHistoryDialog *
1744+um_history_dialog_new (void)
1745+{
1746+ GError *error = NULL;
1747+ UmHistoryDialog *um;
1748+ GtkWidget *widget;
1749+
1750+ um = g_new0 (UmHistoryDialog, 1);
1751+ um->builder = gtk_builder_new ();
1752+
1753+ if (!gtk_builder_add_from_resource (um->builder, "/org/gnome/control-center/user-accounts/history-dialog.ui", &error)) {
1754+ g_error ("%s", error->message);
1755+ g_error_free (error);
1756+ g_free (um);
1757+
1758+ return NULL;
1759+ }
1760+
1761+ um->dialog = get_widget (um, "dialog");
1762+ g_signal_connect (um->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
1763+
1764+ widget = get_widget (um, "close-button");
1765+ g_signal_connect (widget, "clicked", G_CALLBACK (close_history_dialog), um);
1766+
1767+ widget = get_widget (um, "next-button");
1768+ g_signal_connect (widget, "clicked", G_CALLBACK (show_next), um);
1769+
1770+ widget = get_widget (um, "previous-button");
1771+ g_signal_connect (widget, "clicked", G_CALLBACK (show_previous), um);
1772+
1773+ return um;
1774+}
1775+
1776+void
1777+um_history_dialog_free (UmHistoryDialog *um)
1778+{
1779+ gtk_widget_destroy (um->dialog);
1780+
1781+ g_clear_object (&um->user);
1782+ g_clear_object (&um->builder);
1783+
1784+ if (um->week) {
1785+ g_date_time_unref (um->week);
1786+ }
1787+
1788+ if (um->current_week) {
1789+ g_date_time_unref (um->current_week);
1790+ }
1791+
1792+ g_free (um);
1793+}
1794
1795=== added file 'panels/user-accounts/um-history-dialog.h'
1796--- panels/user-accounts/um-history-dialog.h 1970-01-01 00:00:00 +0000
1797+++ panels/user-accounts/um-history-dialog.h 2014-02-24 09:46:44 +0000
1798@@ -0,0 +1,41 @@
1799+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1800+ *
1801+ * Copyright 2012 Red Hat, Inc,
1802+ *
1803+ * This program is free software; you can redistribute it and/or modify
1804+ * it under the terms of the GNU General Public License as published by
1805+ * the Free Software Foundation; either version 2 of the License, or
1806+ * (at your option) any later version.
1807+ *
1808+ * This program is distributed in the hope that it will be useful,
1809+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1810+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1811+ * GNU General Public License for more details.
1812+ *
1813+ * You should have received a copy of the GNU General Public License
1814+ * along with this program; if not, write to the Free Software
1815+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1816+ *
1817+ * Written by: Ondrej Holy <oholy@redhat.com>
1818+ */
1819+
1820+#ifndef __UM_HISTORY_DIALOG_H__
1821+#define __UM_HISTORY_DIALOG_H__
1822+
1823+#include <gtk/gtk.h>
1824+#include <act/act-user.h>
1825+
1826+G_BEGIN_DECLS
1827+
1828+typedef struct _UmHistoryDialog UmHistoryDialog;
1829+
1830+UmHistoryDialog *um_history_dialog_new (void);
1831+void um_history_dialog_free (UmHistoryDialog *dialog);
1832+void um_history_dialog_set_user (UmHistoryDialog *dialog,
1833+ ActUser *user);
1834+void um_history_dialog_show (UmHistoryDialog *dialog,
1835+ GtkWindow *parent);
1836+
1837+G_END_DECLS
1838+
1839+#endif
1840
1841=== modified file 'panels/user-accounts/um-password-dialog.c'
1842--- panels/user-accounts/um-password-dialog.c 2013-11-28 04:33:51 +0000
1843+++ panels/user-accounts/um-password-dialog.c 2014-02-24 09:46:44 +0000
1844@@ -29,9 +29,9 @@
1845 #include <glib.h>
1846 #include <glib/gi18n.h>
1847 #include <gtk/gtk.h>
1848+#include <act/act.h>
1849
1850 #include "um-password-dialog.h"
1851-#include "um-user-manager.h"
1852 #include "um-utils.h"
1853 #include "run-passwd.h"
1854 #include "pw-utils.h"
1855@@ -51,7 +51,7 @@
1856 GtkWidget *show_password_button;
1857 GtkWidget *ok_button;
1858
1859- UmUser *user;
1860+ ActUser *user;
1861 gboolean using_ecryptfs;
1862
1863 GtkWidget *old_password_label;
1864@@ -61,6 +61,39 @@
1865 PasswdHandler *passwd_handler;
1866 };
1867
1868+typedef enum {
1869+ UM_PASSWORD_DIALOG_MODE_NORMAL = 0,
1870+ UM_PASSWORD_DIALOG_MODE_SET_AT_LOGIN,
1871+ UM_PASSWORD_DIALOG_MODE_NO_PASSWORD,
1872+ UM_PASSWORD_DIALOG_MODE_LOCK_ACCOUNT,
1873+ UM_PASSWORD_DIALOG_MODE_UNLOCK_ACCOUNT
1874+} UmPasswordDialogMode;
1875+
1876+static int
1877+update_password_strength (UmPasswordDialog *um)
1878+{
1879+ const gchar *password;
1880+ const gchar *old_password;
1881+ const gchar *username;
1882+ gint strength_level;
1883+ const gchar *hint;
1884+ const gchar *long_hint;
1885+
1886+ password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
1887+ old_password = gtk_entry_get_text (GTK_ENTRY (um->old_password_entry));
1888+ username = act_user_get_user_name (um->user);
1889+
1890+ pw_strength (password, old_password, username,
1891+ &hint, &long_hint, &strength_level);
1892+
1893+ gtk_level_bar_set_value (GTK_LEVEL_BAR (um->strength_indicator), strength_level);
1894+ gtk_label_set_label (GTK_LABEL (um->strength_indicator_label), hint);
1895+ gtk_widget_set_tooltip_text (um->strength_indicator, long_hint);
1896+ gtk_widget_set_tooltip_text (um->strength_indicator_label, long_hint);
1897+
1898+ return strength_level;
1899+}
1900+
1901 static void
1902 generate_one_password (GtkWidget *widget,
1903 UmPasswordDialog *um)
1904@@ -198,26 +231,54 @@
1905 password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
1906 hint = gtk_entry_get_text (GTK_ENTRY (um->normal_hint_entry));
1907
1908- if (mode == 0 && um_user_get_uid (um->user) == getuid ()) {
1909- GdkDisplay *display;
1910- GdkCursor *cursor;
1911-
1912- /* When setting a password for the current user,
1913- * use passwd directly, to preserve the audit trail
1914- * and to e.g. update the keyring password.
1915- */
1916- passwd_change_password (um->passwd_handler, password, (PasswdCallback) password_changed_cb, um);
1917- gtk_widget_set_sensitive (um->dialog, FALSE);
1918- display = gtk_widget_get_display (um->dialog);
1919- cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
1920- gdk_window_set_cursor (gtk_widget_get_window (um->dialog), cursor);
1921- gdk_display_flush (display);
1922- g_object_unref (cursor);
1923- }
1924- else {
1925- um_user_set_password (um->user, mode, password, hint);
1926- finish_password_change (um);
1927- }
1928+ switch (mode) {
1929+ case UM_PASSWORD_DIALOG_MODE_NORMAL:
1930+ act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_REGULAR);
1931+ if (act_user_get_uid (um->user) == getuid ()) {
1932+ GdkDisplay *display;
1933+ GdkCursor *cursor;
1934+
1935+ /* When setting a password for the current user,
1936+ * use passwd directly, to preserve the audit trail
1937+ * and to e.g. update the keyring password.
1938+ */
1939+ passwd_change_password (um->passwd_handler, password,
1940+ (PasswdCallback) password_changed_cb, um);
1941+ gtk_widget_set_sensitive (um->dialog, FALSE);
1942+ display = gtk_widget_get_display (um->dialog);
1943+ cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
1944+ gdk_window_set_cursor (gtk_widget_get_window (um->dialog), cursor);
1945+ gdk_display_flush (display);
1946+ g_object_unref (cursor);
1947+ return;
1948+ }
1949+
1950+ act_user_set_password (um->user, password, hint);
1951+ break;
1952+
1953+ case UM_PASSWORD_DIALOG_MODE_SET_AT_LOGIN:
1954+ act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
1955+ act_user_set_automatic_login (um->user, FALSE);
1956+ break;
1957+
1958+ case UM_PASSWORD_DIALOG_MODE_NO_PASSWORD:
1959+ act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_NONE);
1960+ break;
1961+
1962+ case UM_PASSWORD_DIALOG_MODE_LOCK_ACCOUNT:
1963+ act_user_set_locked (um->user, TRUE);
1964+ act_user_set_automatic_login (um->user, FALSE);
1965+ break;
1966+
1967+ case UM_PASSWORD_DIALOG_MODE_UNLOCK_ACCOUNT:
1968+ act_user_set_locked (um->user, FALSE);
1969+ break;
1970+
1971+ default:
1972+ g_assert_not_reached ();
1973+ }
1974+
1975+ finish_password_change (um);
1976 }
1977
1978 static void
1979@@ -227,18 +288,27 @@
1980 const gchar *old_password;
1981 const gchar *tooltip;
1982 gboolean can_change;
1983+ int strength_level;
1984
1985 password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
1986 verify = gtk_entry_get_text (GTK_ENTRY (um->verify_entry));
1987 old_password = gtk_entry_get_text (GTK_ENTRY (um->old_password_entry));
1988
1989- if (strlen (password) < pw_min_length ()) {
1990+ /* Don't update the password strength if we didn't enter anything */
1991+ if (password && *password == '\0' &&
1992+ verify && *verify == '\0' &&
1993+ old_password && *old_password == '\0')
1994+ return;
1995+
1996+ strength_level = update_password_strength (um);
1997+
1998+ if (strength_level < 1) {
1999 can_change = FALSE;
2000 if (password[0] == '\0') {
2001 tooltip = _("You need to enter a new password");
2002 }
2003 else {
2004- tooltip = _("The new password is too short");
2005+ tooltip = _("The new password is not strong enough");
2006 }
2007 }
2008 else if (strcmp (password, verify) != 0) {
2009@@ -312,29 +382,6 @@
2010 }
2011
2012 static void
2013-update_password_strength (UmPasswordDialog *um)
2014-{
2015- const gchar *password;
2016- const gchar *old_password;
2017- const gchar *username;
2018- gint strength_level;
2019- const gchar *hint;
2020- const gchar *long_hint;
2021-
2022- password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
2023- old_password = gtk_entry_get_text (GTK_ENTRY (um->old_password_entry));
2024- username = um_user_get_user_name (um->user);
2025-
2026- pw_strength (password, old_password, username,
2027- &hint, &long_hint, &strength_level);
2028-
2029- gtk_level_bar_set_value (GTK_LEVEL_BAR (um->strength_indicator), strength_level);
2030- gtk_label_set_label (GTK_LABEL (um->strength_indicator_label), hint);
2031- gtk_widget_set_tooltip_text (um->strength_indicator, long_hint);
2032- gtk_widget_set_tooltip_text (um->strength_indicator_label, long_hint);
2033-}
2034-
2035-static void
2036 update_password_match (UmPasswordDialog *um)
2037 {
2038 const char *password;
2039@@ -405,6 +452,14 @@
2040 GError *error,
2041 UmPasswordDialog *um)
2042 {
2043+ GtkTreeModel *model;
2044+ GtkTreeIter iter;
2045+ gint mode;
2046+
2047+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (um->action_combo));
2048+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (um->action_combo), &iter);
2049+ gtk_tree_model_get (model, &iter, 1, &mode, -1);
2050+
2051 if (error) {
2052 um->old_password_ok = FALSE;
2053 set_entry_validation_error (GTK_ENTRY (um->old_password_entry),
2054@@ -415,6 +470,11 @@
2055 clear_entry_validation_error (GTK_ENTRY (um->old_password_entry));
2056 }
2057
2058+ /* Check if we are still in normal mode */
2059+ if (mode != UM_PASSWORD_DIALOG_MODE_NORMAL){
2060+ return;
2061+ }
2062+
2063 update_sensitivity (um);
2064 }
2065
2066@@ -510,7 +570,6 @@
2067 {
2068 GtkBuilder *builder;
2069 GError *error;
2070- const gchar *filename;
2071 UmPasswordDialog *um;
2072 GtkWidget *widget;
2073 const char *old_label;
2074@@ -520,10 +579,9 @@
2075 builder = gtk_builder_new ();
2076
2077 error = NULL;
2078- filename = UIDIR "/password-dialog.ui";
2079- if (!g_file_test (filename, G_FILE_TEST_EXISTS))
2080- filename = "data/password-dialog.ui";
2081- if (!gtk_builder_add_from_file (builder, filename, &error)) {
2082+ if (!gtk_builder_add_from_resource (builder,
2083+ "/org/gnome/control-center/user-accounts/password-dialog.ui",
2084+ &error)) {
2085 g_error ("%s", error->message);
2086 g_error_free (error);
2087 return NULL;
2088@@ -662,7 +720,7 @@
2089 {
2090 if (um->user) {
2091 gint mode;
2092- gboolean locked = um_user_get_locked (um->user);
2093+ gboolean locked = act_user_get_locked (um->user);
2094
2095 gtk_tree_model_get (model, iter, 1, &mode, -1);
2096
2097@@ -672,10 +730,15 @@
2098 if (mode == 2 && um->using_ecryptfs)
2099 return FALSE;
2100
2101- if (mode == 3 && locked)
2102+ /* We don't allow the current user to disable their own account,
2103+ * as this can lead to them being 'locked out'.
2104+ */
2105+ if (mode == UM_PASSWORD_DIALOG_MODE_LOCK_ACCOUNT &&
2106+ (locked || act_user_get_uid (um->user) == getuid ()
2107+ || would_demote_only_admin (um->user)))
2108 return FALSE;
2109
2110- if (mode == 4 && !locked)
2111+ if (mode == UM_PASSWORD_DIALOG_MODE_UNLOCK_ACCOUNT && !locked)
2112 return FALSE;
2113
2114 return TRUE;
2115@@ -686,7 +749,7 @@
2116
2117 void
2118 um_password_dialog_set_user (UmPasswordDialog *um,
2119- UmUser *user)
2120+ ActUser *user)
2121 {
2122 GdkPixbuf *pixbuf;
2123 GtkTreeModel *model;
2124@@ -698,22 +761,22 @@
2125 if (user) {
2126 um->user = g_object_ref (user);
2127
2128- um->using_ecryptfs = is_using_ecryptfs (um_user_get_user_name (user));
2129+ um->using_ecryptfs = is_using_ecryptfs (act_user_get_user_name (user));
2130
2131- pixbuf = um_user_render_icon (user, FALSE, 48);
2132+ pixbuf = render_user_icon (user, UM_ICON_STYLE_NONE, 48);
2133 gtk_image_set_from_pixbuf (GTK_IMAGE (um->user_icon), pixbuf);
2134 g_object_unref (pixbuf);
2135
2136 gtk_label_set_label (GTK_LABEL (um->user_name),
2137- um_user_get_real_name (user));
2138+ act_user_get_real_name (user));
2139
2140 gtk_entry_set_text (GTK_ENTRY (um->password_entry), "");
2141 gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
2142 gtk_entry_set_text (GTK_ENTRY (um->normal_hint_entry), "");
2143 gtk_entry_set_text (GTK_ENTRY (um->old_password_entry), "");
2144 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->show_password_button), FALSE);
2145- if (um_user_get_uid (um->user) == getuid () &&
2146- um_user_get_password_mode (um->user) == UM_PASSWORD_MODE_REGULAR) {
2147+ if (act_user_get_uid (um->user) == getuid () &&
2148+ act_user_get_password_mode (um->user) == ACT_USER_PASSWORD_MODE_REGULAR) {
2149 gtk_widget_show (um->old_password_label);
2150 gtk_widget_show (um->old_password_entry);
2151 um->old_password_ok = FALSE;
2152@@ -723,7 +786,7 @@
2153 gtk_widget_hide (um->old_password_entry);
2154 um->old_password_ok = TRUE;
2155 }
2156- if (um_user_get_uid (um->user) == getuid()) {
2157+ if (act_user_get_uid (um->user) == getuid()) {
2158 if (um->passwd_handler != NULL)
2159 passwd_destroy (um->passwd_handler);
2160 um->passwd_handler = passwd_init ();
2161
2162=== modified file 'panels/user-accounts/um-password-dialog.h'
2163--- panels/user-accounts/um-password-dialog.h 2012-09-06 23:07:09 +0000
2164+++ panels/user-accounts/um-password-dialog.h 2014-02-24 09:46:44 +0000
2165@@ -23,7 +23,7 @@
2166 #define __UM_PASSWORD_DIALOG_H__
2167
2168 #include <gtk/gtk.h>
2169-#include "um-user.h"
2170+#include <act/act.h>
2171
2172 G_BEGIN_DECLS
2173
2174@@ -32,7 +32,7 @@
2175 UmPasswordDialog *um_password_dialog_new (void);
2176 void um_password_dialog_free (UmPasswordDialog *dialog);
2177 void um_password_dialog_set_user (UmPasswordDialog *dialog,
2178- UmUser *user);
2179+ ActUser *user);
2180 void um_password_dialog_set_privileged (UmPasswordDialog *dialog,
2181 gboolean privileged);
2182 void um_password_dialog_show (UmPasswordDialog *dialog,
2183
2184=== modified file 'panels/user-accounts/um-photo-dialog.c'
2185--- panels/user-accounts/um-photo-dialog.c 2014-02-18 03:09:04 +0000
2186+++ panels/user-accounts/um-photo-dialog.c 2014-02-24 09:46:44 +0000
2187@@ -26,6 +26,7 @@
2188 #include <glib.h>
2189 #include <glib/gi18n.h>
2190 #include <gtk/gtk.h>
2191+#include <act/act.h>
2192 #define GNOME_DESKTOP_USE_UNSTABLE_API
2193 #include <libgnome-desktop/gnome-desktop-thumbnail.h>
2194
2195@@ -36,7 +37,6 @@
2196 #endif /* HAVE_CHEESE */
2197
2198 #include "um-photo-dialog.h"
2199-#include "um-user-manager.h"
2200 #include "um-crop-area.h"
2201 #include "um-utils.h"
2202
2203@@ -55,7 +55,7 @@
2204
2205 GnomeDesktopThumbnailFactory *thumb_factory;
2206
2207- UmUser *user;
2208+ ActUser *user;
2209 };
2210
2211 static void
2212@@ -74,7 +74,7 @@
2213 pb = um_crop_area_get_picture (UM_CROP_AREA (um->crop_area));
2214 pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
2215
2216- um_user_set_icon_data (um->user, pb2);
2217+ set_user_icon_data (um->user, pb2);
2218
2219 g_object_unref (pb2);
2220 g_object_unref (pb);
2221@@ -247,7 +247,7 @@
2222 none_icon_selected (GtkMenuItem *menuitem,
2223 UmPhotoDialog *um)
2224 {
2225- um_user_set_icon_file (um->user, NULL);
2226+ act_user_set_icon_file (um->user, "");
2227 }
2228
2229 static void
2230@@ -276,7 +276,7 @@
2231 g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
2232 pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
2233
2234- um_user_set_icon_data (um->user, pb2);
2235+ set_user_icon_data (um->user, pb2);
2236
2237 g_object_unref (pb2);
2238 g_object_unref (pb);
2239@@ -337,7 +337,7 @@
2240 const char *filename;
2241
2242 filename = g_object_get_data (G_OBJECT (menuitem), "filename");
2243- um_user_set_icon_file (um->user, filename);
2244+ act_user_set_icon_file (um->user, filename);
2245 }
2246
2247 static GtkWidget *
2248@@ -458,7 +458,7 @@
2249 y++;
2250
2251 #ifdef HAVE_CHEESE
2252- um->take_photo_menuitem = gtk_menu_item_new_with_label (_("Take a photo..."));
2253+ um->take_photo_menuitem = gtk_menu_item_new_with_label (_("Take a photo…"));
2254 gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (um->take_photo_menuitem),
2255 0, ROW_SPAN - 1, y, y + 1);
2256 g_signal_connect (G_OBJECT (um->take_photo_menuitem), "activate",
2257@@ -476,7 +476,7 @@
2258 y++;
2259 #endif /* HAVE_CHEESE */
2260
2261- menuitem = gtk_menu_item_new_with_label (_("Browse for more pictures..."));
2262+ menuitem = gtk_menu_item_new_with_label (_("Browse for more pictures…"));
2263 gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
2264 0, ROW_SPAN - 1, y, y + 1);
2265 g_signal_connect (G_OBJECT (menuitem), "activate",
2266@@ -652,11 +652,11 @@
2267
2268 void
2269 um_photo_dialog_set_user (UmPhotoDialog *um,
2270- UmUser *user)
2271+ ActUser *user)
2272 {
2273- UmUserManager *manager;
2274+ ActUserManager *manager;
2275 GSList *list, *l;
2276- UmUser *u;
2277+ ActUser *u;
2278 GIcon *icon;
2279 GEmblem *emblem;
2280 GList *children, *c;
2281@@ -675,9 +675,8 @@
2282 children = gtk_container_get_children (GTK_CONTAINER (um->photo_popup));
2283 g_list_foreach (children, (GFunc) clear_tip, NULL);
2284
2285- manager = um_user_manager_ref_default ();
2286- list = um_user_manager_list_users (manager);
2287- g_object_unref (manager);
2288+ manager = act_user_manager_get_default ();
2289+ list = act_user_manager_list_users (manager);
2290
2291 icon = g_themed_icon_new ("avatar-default");
2292 emblem = g_emblem_new (icon);
2293@@ -689,7 +688,7 @@
2294 u = l->data;
2295 if (u == user)
2296 continue;
2297- filename = um_user_get_icon_file (u);
2298+ filename = act_user_get_icon_file (u);
2299 if (filename == NULL)
2300 continue;
2301 for (c = children; c; c = c->next) {
2302@@ -702,7 +701,7 @@
2303 char *tip;
2304
2305 tip = g_strdup_printf (_("Used by %s"),
2306- um_user_get_real_name (u));
2307+ act_user_get_real_name (u));
2308 set_tip (GTK_WIDGET (c->data), tip, emblem);
2309 g_free (tip);
2310 break;
2311
2312=== modified file 'panels/user-accounts/um-photo-dialog.h'
2313--- panels/user-accounts/um-photo-dialog.h 2012-09-06 23:07:09 +0000
2314+++ panels/user-accounts/um-photo-dialog.h 2014-02-24 09:46:44 +0000
2315@@ -23,7 +23,7 @@
2316 #define __UM_PHOTO_DIALOG_H__
2317
2318 #include <gtk/gtk.h>
2319-#include "um-user.h"
2320+#include <act/act.h>
2321
2322 G_BEGIN_DECLS
2323
2324@@ -32,7 +32,7 @@
2325 UmPhotoDialog *um_photo_dialog_new (GtkWidget *button);
2326 void um_photo_dialog_free (UmPhotoDialog *dialog);
2327 void um_photo_dialog_set_user (UmPhotoDialog *dialog,
2328- UmUser *user);
2329+ ActUser *user);
2330
2331 G_END_DECLS
2332
2333
2334=== modified file 'panels/user-accounts/um-realm-manager.c'
2335--- panels/user-accounts/um-realm-manager.c 2012-10-19 08:56:05 +0000
2336+++ panels/user-accounts/um-realm-manager.c 2014-02-24 09:46:44 +0000
2337@@ -537,6 +537,7 @@
2338 GSimpleAsyncResult *async;
2339 GVariant *contents;
2340 GVariant *options;
2341+ GVariant *option;
2342 GVariant *creds;
2343 const gchar *type;
2344
2345@@ -569,7 +570,8 @@
2346 }
2347
2348 creds = g_variant_new ("(ssv)", type, owner, contents);
2349- options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
2350+ option = g_variant_new ("{sv}", "manage-system", g_variant_new_boolean (FALSE));
2351+ options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), &option, 1);
2352
2353 g_debug ("Calling the Join() method with %s credentials", owner);
2354
2355@@ -801,18 +803,25 @@
2356 break;
2357
2358 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
2359- case KRB5KDC_ERR_CLIENT_REVOKED:
2360- case KRB5KDC_ERR_KEY_EXP:
2361 case KRB5KDC_ERR_POLICY:
2362- case KRB5KDC_ERR_ETYPE_NOSUPP:
2363 g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN,
2364 _("Cannot log in as %s at the %s domain"),
2365 login->user, login->domain);
2366 break;
2367 case KRB5KDC_ERR_PREAUTH_FAILED:
2368+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
2369 g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_BAD_PASSWORD,
2370 _("Invalid password, please try again"));
2371 break;
2372+ case KRB5_PREAUTH_FAILED:
2373+ case KRB5KDC_ERR_KEY_EXP:
2374+ case KRB5KDC_ERR_CLIENT_REVOKED:
2375+ case KRB5KDC_ERR_ETYPE_NOSUPP:
2376+ case KRB5_PROG_ETYPE_NOSUPP:
2377+ g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_CANNOT_AUTH,
2378+ _("Cannot log in as %s at the %s domain"),
2379+ login->user, login->domain);
2380+ break;
2381 default:
2382 g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC,
2383 _("Couldn't connect to the %s domain: %s"),
2384
2385=== modified file 'panels/user-accounts/um-realm-manager.h'
2386--- panels/user-accounts/um-realm-manager.h 2012-09-17 12:08:35 +0000
2387+++ panels/user-accounts/um-realm-manager.h 2014-02-24 09:46:44 +0000
2388@@ -29,6 +29,7 @@
2389 typedef enum {
2390 UM_REALM_ERROR_BAD_LOGIN,
2391 UM_REALM_ERROR_BAD_PASSWORD,
2392+ UM_REALM_ERROR_CANNOT_AUTH,
2393 UM_REALM_ERROR_GENERIC,
2394 } UmRealmErrors;
2395
2396
2397=== removed file 'panels/user-accounts/um-user-manager.c'
2398--- panels/user-accounts/um-user-manager.c 2012-09-06 23:07:09 +0000
2399+++ panels/user-accounts/um-user-manager.c 1970-01-01 00:00:00 +0000
2400@@ -1,734 +0,0 @@
2401-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2402- *
2403- * Copyright (C) 2009-2010 Red Hat, Inc.
2404- *
2405- * This program is free software; you can redistribute it and/or modify
2406- * it under the terms of the GNU General Public License as published by
2407- * the Free Software Foundation; either version 2 of the License, or
2408- * (at your option) any later version.
2409- *
2410- * This program is distributed in the hope that it will be useful,
2411- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2412- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2413- * GNU General Public License for more details.
2414- *
2415- * You should have received a copy of the GNU General Public License
2416- * along with this program; if not, write to the Free Software
2417- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2418- *
2419- * Written by: Matthias Clasen <mclasen@redhat.com>
2420- */
2421-
2422-#include "config.h"
2423-
2424-#include <stdlib.h>
2425-#include <stdio.h>
2426-#include <fcntl.h>
2427-#include <unistd.h>
2428-#include <string.h>
2429-#include <signal.h>
2430-#include <errno.h>
2431-#include <sys/stat.h>
2432-#include <sys/types.h>
2433-#include <pwd.h>
2434-
2435-#ifdef HAVE_PATHS_H
2436-#include <paths.h>
2437-#endif /* HAVE_PATHS_H */
2438-
2439-#include <glib.h>
2440-#include <glib/gi18n.h>
2441-#include <glib/gstdio.h>
2442-#include <glib-object.h>
2443-#include <gio/gio.h>
2444-
2445-#include "um-user-manager.h"
2446-
2447-enum {
2448- USERS_LOADED,
2449- USER_ADDED,
2450- USER_REMOVED,
2451- USER_CHANGED,
2452- LAST_SIGNAL
2453-};
2454-
2455-static guint signals [LAST_SIGNAL] = { 0, };
2456-
2457-static void um_user_manager_class_init (UmUserManagerClass *klass);
2458-static void um_user_manager_init (UmUserManager *user_manager);
2459-static void um_user_manager_finalize (GObject *object);
2460-
2461-static gpointer user_manager_object = NULL;
2462-
2463-G_DEFINE_TYPE (UmUserManager, um_user_manager, G_TYPE_OBJECT)
2464-
2465-static void
2466-um_user_manager_class_init (UmUserManagerClass *klass)
2467-{
2468- GObjectClass *object_class = G_OBJECT_CLASS (klass);
2469-
2470- object_class->finalize = um_user_manager_finalize;
2471-
2472- signals [USERS_LOADED] =
2473- g_signal_new ("users-loaded",
2474- G_TYPE_FROM_CLASS (klass),
2475- G_SIGNAL_RUN_LAST,
2476- G_STRUCT_OFFSET (UmUserManagerClass, users_loaded),
2477- NULL, NULL,
2478- g_cclosure_marshal_VOID__VOID,
2479- G_TYPE_NONE, 0);
2480-
2481- signals [USER_ADDED] =
2482- g_signal_new ("user-added",
2483- G_TYPE_FROM_CLASS (klass),
2484- G_SIGNAL_RUN_LAST,
2485- G_STRUCT_OFFSET (UmUserManagerClass, user_added),
2486- NULL, NULL,
2487- g_cclosure_marshal_VOID__OBJECT,
2488- G_TYPE_NONE, 1, UM_TYPE_USER);
2489- signals [USER_REMOVED] =
2490- g_signal_new ("user-removed",
2491- G_TYPE_FROM_CLASS (klass),
2492- G_SIGNAL_RUN_LAST,
2493- G_STRUCT_OFFSET (UmUserManagerClass, user_removed),
2494- NULL, NULL,
2495- g_cclosure_marshal_VOID__OBJECT,
2496- G_TYPE_NONE, 1, UM_TYPE_USER);
2497- signals [USER_CHANGED] =
2498- g_signal_new ("user-changed",
2499- G_TYPE_FROM_CLASS (klass),
2500- G_SIGNAL_RUN_LAST,
2501- G_STRUCT_OFFSET (UmUserManagerClass, user_changed),
2502- NULL, NULL,
2503- g_cclosure_marshal_VOID__OBJECT,
2504- G_TYPE_NONE, 1, UM_TYPE_USER);
2505-}
2506-
2507-
2508-/* We maintain a ring for each group of users with the same real name.
2509- * We need this to pick the right display names.
2510- */
2511-static void
2512-remove_user_from_dupe_ring (UmUserManager *manager,
2513- UmUser *user)
2514-{
2515- GList *dupes;
2516- UmUser *dup;
2517-
2518- dup = NULL;
2519- dupes = g_object_get_data (G_OBJECT (user), "dupes");
2520-
2521- if (!dupes) {
2522- goto out;
2523- }
2524-
2525- if (dupes->next == dupes->prev) {
2526- dup = dupes->next->data;
2527- g_list_free_1 (dupes->next);
2528- g_object_set_data (G_OBJECT (dup), "dupes", NULL);
2529- }
2530- else {
2531- dupes->next->prev = dupes->prev;
2532- dupes->prev->next = dupes->next;
2533- }
2534-
2535- g_list_free_1 (dupes);
2536- g_object_set_data (G_OBJECT (user), "dupes", NULL);
2537-
2538-out:
2539- if (dup) {
2540- um_user_show_short_display_name (dup);
2541- g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
2542- }
2543- um_user_show_short_display_name (user);
2544- g_signal_emit (manager, signals[USER_CHANGED], 0, user);
2545-}
2546-
2547-static gboolean
2548-match_real_name_hrfunc (gpointer key,
2549- gpointer value,
2550- gpointer user)
2551-{
2552- return (value != user && g_strcmp0 (um_user_get_real_name (user), um_user_get_real_name (value)) == 0);
2553-}
2554-
2555-static void
2556-add_user_to_dupe_ring (UmUserManager *manager,
2557- UmUser *user)
2558-{
2559- UmUser *dup;
2560- GList *dupes;
2561- GList *l;
2562-
2563- dup = g_hash_table_find (manager->user_by_object_path,
2564- match_real_name_hrfunc, user);
2565-
2566- if (!dup) {
2567- return;
2568- }
2569-
2570- dupes = g_object_get_data (G_OBJECT (dup), "dupes");
2571- if (!dupes) {
2572- dupes = g_list_append (NULL, dup);
2573- g_object_set_data (G_OBJECT (dup), "dupes", dupes);
2574- dupes->next = dupes->prev = dupes;
2575- }
2576- else {
2577- dup = NULL;
2578- }
2579-
2580- l = g_list_append (NULL, user);
2581- g_object_set_data (G_OBJECT (user), "dupes", l);
2582- l->prev = dupes->prev;
2583- dupes->prev->next = l;
2584- l->next = dupes;
2585- dupes->prev = l;
2586-
2587- if (dup) {
2588- um_user_show_full_display_name (dup);
2589- g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
2590- }
2591- um_user_show_full_display_name (user);
2592- g_signal_emit (manager, signals[USER_CHANGED], 0, user);
2593-}
2594-
2595-static void
2596-user_changed_handler (UmUser *user,
2597- UmUserManager *manager)
2598-{
2599- remove_user_from_dupe_ring (manager, user);
2600- add_user_to_dupe_ring (manager, user);
2601- g_signal_emit (manager, signals[USER_CHANGED], 0, user);
2602-}
2603-
2604-static void
2605-user_added_handler (UmUserManager *manager,
2606- const char *object_path)
2607-{
2608- UmUser *user;
2609-
2610- if (g_hash_table_lookup (manager->user_by_object_path, object_path))
2611- return;
2612-
2613- user = um_user_new_from_object_path (object_path);
2614- if (!user)
2615- return;
2616-
2617- if (um_user_is_system_account (user)) {
2618- g_object_unref (user);
2619- return;
2620- }
2621-
2622- add_user_to_dupe_ring (manager, user);
2623-
2624- g_signal_connect (user, "changed",
2625- G_CALLBACK (user_changed_handler), manager);
2626- g_hash_table_insert (manager->user_by_object_path, g_strdup (um_user_get_object_path (user)), g_object_ref (user));
2627- g_hash_table_insert (manager->user_by_name, g_strdup (um_user_get_user_name (user)), g_object_ref (user));
2628-
2629- g_signal_emit (manager, signals[USER_ADDED], 0, user);
2630- g_object_unref (user);
2631-}
2632-
2633-static void
2634-user_deleted_handler (UmUserManager *manager,
2635- const char *object_path)
2636-{
2637- UmUser *user;
2638-
2639- user = g_hash_table_lookup (manager->user_by_object_path, object_path);
2640- if (!user)
2641- return;
2642- g_object_ref (user);
2643- g_signal_handlers_disconnect_by_func (user, user_changed_handler, manager);
2644-
2645- remove_user_from_dupe_ring (manager, user);
2646-
2647- g_hash_table_remove (manager->user_by_object_path, um_user_get_object_path (user));
2648- g_hash_table_remove (manager->user_by_name, um_user_get_user_name (user));
2649- g_signal_emit (manager, signals[USER_REMOVED], 0, user);
2650- g_object_unref (user);
2651-}
2652-
2653-static void
2654-manager_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, UmUserManager *manager)
2655-{
2656- if (strcmp (signal_name, "UserAdded") == 0) {
2657- if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) {
2658- gchar *object_path;
2659- g_variant_get (parameters, "(&o)", &object_path);
2660- user_added_handler (manager, object_path);
2661- }
2662- }
2663- else if (strcmp (signal_name, "UserDeleted") == 0) {
2664- if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) {
2665- gchar *object_path;
2666- g_variant_get (parameters, "(&o)", &object_path);
2667- user_deleted_handler (manager, object_path);
2668- }
2669- }
2670-}
2671-
2672-static void
2673-got_users (GObject *object,
2674- GAsyncResult *res,
2675- gpointer data)
2676-{
2677- UmUserManager *manager = data;
2678- GVariant *result;
2679- GError *error = NULL;
2680-
2681- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
2682- if (!result) {
2683- manager->no_service = TRUE;
2684- g_error_free (error);
2685- goto done;
2686- }
2687-
2688- if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(ao)"))) {
2689- GVariantIter *iter;
2690- gchar *object_path;
2691-
2692- g_variant_get (result, "(ao)", &iter);
2693- while (g_variant_iter_loop (iter, "&o", &object_path))
2694- user_added_handler (manager, object_path);
2695- g_variant_iter_free (iter);
2696- }
2697-
2698- g_variant_unref (result);
2699-
2700- done:
2701- g_signal_emit (G_OBJECT (manager), signals[USERS_LOADED], 0);
2702-}
2703-
2704-static void
2705-get_users (UmUserManager *manager)
2706-{
2707- g_debug ("calling 'ListCachedUsers'");
2708- g_dbus_proxy_call (manager->proxy,
2709- "ListCachedUsers",
2710- g_variant_new ("()"),
2711- G_DBUS_CALL_FLAGS_NONE,
2712- -1,
2713- NULL,
2714- got_users,
2715- manager);
2716-}
2717-
2718-static void
2719-um_user_manager_init (UmUserManager *manager)
2720-{
2721- GError *error = NULL;
2722- GDBusConnection *bus;
2723-
2724- manager->user_by_object_path = g_hash_table_new_full (g_str_hash,
2725- g_str_equal,
2726- g_free,
2727- g_object_unref);
2728- manager->user_by_name = g_hash_table_new_full (g_str_hash,
2729- g_str_equal,
2730- g_free,
2731- g_object_unref);
2732-
2733- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
2734- if (bus == NULL) {
2735- g_warning ("Couldn't connect to system bus: %s", error->message);
2736- g_error_free (error);
2737- return;
2738- }
2739-
2740- manager->proxy = g_dbus_proxy_new_sync (bus,
2741- G_DBUS_PROXY_FLAGS_NONE,
2742- NULL,
2743- "org.freedesktop.Accounts",
2744- "/org/freedesktop/Accounts",
2745- "org.freedesktop.Accounts",
2746- NULL,
2747- &error);
2748- if (manager->proxy == NULL) {
2749- g_warning ("Couldn't get accounts proxy: %s", error->message);
2750- g_error_free (error);
2751- return;
2752- }
2753-
2754- g_signal_connect (manager->proxy, "g-signal", G_CALLBACK (manager_signal_cb), manager);
2755-
2756- get_users (manager);
2757-}
2758-
2759-static void
2760-clear_dup (gpointer key,
2761- gpointer value,
2762- gpointer data)
2763-{
2764- GList *dupes;
2765-
2766- /* don't bother maintaining the ring, we're destroying the
2767- * entire hash table anyway
2768- */
2769- dupes = g_object_get_data (G_OBJECT (value), "dupes");
2770-
2771- if (dupes) {
2772- g_list_free_1 (dupes);
2773- g_object_set_data (G_OBJECT (value), "dupes", NULL);
2774- }
2775-}
2776-
2777-static void
2778-um_user_manager_finalize (GObject *object)
2779-{
2780- UmUserManager *manager;
2781-
2782- manager = UM_USER_MANAGER (object);
2783-
2784- g_hash_table_foreach (manager->user_by_object_path, clear_dup, NULL);
2785- g_hash_table_destroy (manager->user_by_object_path);
2786- g_hash_table_destroy (manager->user_by_name);
2787-
2788- g_object_unref (manager->proxy);
2789-
2790- G_OBJECT_CLASS (um_user_manager_parent_class)->finalize (object);
2791-}
2792-
2793-UmUserManager *
2794-um_user_manager_ref_default (void)
2795-{
2796- if (user_manager_object != NULL) {
2797- g_object_ref (user_manager_object);
2798- } else {
2799- user_manager_object = g_object_new (UM_TYPE_USER_MANAGER, NULL);
2800- g_object_add_weak_pointer (user_manager_object,
2801- (gpointer *) &user_manager_object);
2802- }
2803-
2804- return UM_USER_MANAGER (user_manager_object);
2805-}
2806-
2807-typedef struct {
2808- UmUserManager *manager;
2809- gchar *user_name;
2810- GAsyncReadyCallback callback;
2811- gpointer data;
2812- GDestroyNotify destroy;
2813-} AsyncUserOpData;
2814-
2815-static void
2816-async_user_op_data_free (gpointer d)
2817-{
2818- AsyncUserOpData *data = d;
2819-
2820- g_object_unref (data->manager);
2821-
2822- g_free (data->user_name);
2823-
2824- if (data->destroy)
2825- data->destroy (data->data);
2826-
2827- g_free (data);
2828-}
2829-
2830-/* Used for both create_user and cache_user */
2831-static void
2832-user_call_done (GObject *proxy,
2833- GAsyncResult *r,
2834- gpointer user_data)
2835-{
2836- AsyncUserOpData *data = user_data;
2837- GSimpleAsyncResult *res;
2838- GVariant *result;
2839- GError *error = NULL;
2840- gchar *remote;
2841-
2842- res = g_simple_async_result_new (G_OBJECT (data->manager),
2843- data->callback,
2844- data->data,
2845- um_user_manager_create_user);
2846- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), r, &error);
2847- if (!result) {
2848- /* dbus-glib fail:
2849- * We have to translate the errors manually here, since
2850- * calling dbus_g_error_has_name on the error returned in
2851- * um_user_manager_create_user_finish doesn't work.
2852- */
2853- remote = g_dbus_error_get_remote_error (error);
2854- if (g_dbus_error_is_remote_error (error) &&
2855- strcmp (remote, "org.freedesktop.Accounts.Error.PermissionDenied") == 0) {
2856- g_simple_async_result_set_error (res,
2857- UM_USER_MANAGER_ERROR,
2858- UM_USER_MANAGER_ERROR_PERMISSION_DENIED,
2859- "Not authorized");
2860- }
2861- if (g_dbus_error_is_remote_error (error) &&
2862- strcmp (remote, "org.freedesktop.Accounts.Error.UserExists") == 0) {
2863- g_simple_async_result_set_error (res,
2864- UM_USER_MANAGER_ERROR,
2865- UM_USER_MANAGER_ERROR_USER_EXISTS,
2866- _("A user with name '%s' already exists."),
2867- data->user_name);
2868- } else if (g_dbus_error_is_remote_error (error) &&
2869- strcmp (remote, "org.freedesktop.Accounts.Error.UserDoesNotExist") == 0) {
2870- g_simple_async_result_set_error (res,
2871- UM_USER_MANAGER_ERROR,
2872- UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
2873- _("No user with the name '%s' exists."),
2874- data->user_name);
2875- }
2876- else {
2877- g_simple_async_result_set_from_error (res, error);
2878- }
2879- g_error_free (error);
2880- g_free (remote);
2881- }
2882- else {
2883- if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))) {
2884- gchar *path;
2885- g_variant_get (result, "(o)", &path);
2886- g_simple_async_result_set_op_res_gpointer (res, path, g_free);
2887- }
2888- else
2889- g_simple_async_result_set_error (res,
2890- UM_USER_MANAGER_ERROR,
2891- UM_USER_MANAGER_ERROR_FAILED,
2892- "Got invalid response from AccountsService");
2893- g_variant_unref (result);
2894- }
2895-
2896- data->callback (G_OBJECT (data->manager), G_ASYNC_RESULT (res), data->data);
2897- async_user_op_data_free (data);
2898- g_object_unref (res);
2899-}
2900-
2901-gboolean
2902-um_user_manager_create_user_finish (UmUserManager *manager,
2903- GAsyncResult *result,
2904- UmUser **user,
2905- GError **error)
2906-{
2907- gchar *path;
2908- GSimpleAsyncResult *res;
2909-
2910- res = G_SIMPLE_ASYNC_RESULT (result);
2911-
2912- *user = NULL;
2913-
2914- if (g_simple_async_result_propagate_error (res, error)) {
2915- return FALSE;
2916- }
2917-
2918- path = g_simple_async_result_get_op_res_gpointer (res);
2919- *user = g_hash_table_lookup (manager->user_by_object_path, path);
2920-
2921- return TRUE;
2922-}
2923-
2924-void
2925-um_user_manager_create_user (UmUserManager *manager,
2926- const char *user_name,
2927- const char *real_name,
2928- gint account_type,
2929- GCancellable *cancellable,
2930- GAsyncReadyCallback done,
2931- gpointer done_data,
2932- GDestroyNotify destroy)
2933-{
2934- AsyncUserOpData *data;
2935-
2936- data = g_new0 (AsyncUserOpData, 1);
2937- data->manager = g_object_ref (manager);
2938- data->user_name = g_strdup (user_name);
2939- data->callback = done;
2940- data->data = done_data;
2941- data->destroy = destroy;
2942-
2943- g_dbus_proxy_call (manager->proxy,
2944- "CreateUser",
2945- g_variant_new ("(ssi)", user_name, real_name, account_type),
2946- G_DBUS_CALL_FLAGS_NONE,
2947- -1,
2948- cancellable,
2949- user_call_done,
2950- data);
2951-}
2952-
2953-gboolean
2954-um_user_manager_cache_user_finish (UmUserManager *manager,
2955- GAsyncResult *result,
2956- UmUser **user,
2957- GError **error)
2958-{
2959- gchar *path;
2960- GSimpleAsyncResult *res;
2961-
2962- res = G_SIMPLE_ASYNC_RESULT (result);
2963-
2964- *user = NULL;
2965-
2966- if (g_simple_async_result_propagate_error (res, error)) {
2967- return FALSE;
2968- }
2969-
2970- path = g_simple_async_result_get_op_res_gpointer (res);
2971- *user = g_hash_table_lookup (manager->user_by_object_path, path);
2972-
2973- return TRUE;
2974-}
2975-
2976-void
2977-um_user_manager_cache_user (UmUserManager *manager,
2978- const char *user_name,
2979- GCancellable *cancellable,
2980- GAsyncReadyCallback done,
2981- gpointer done_data,
2982- GDestroyNotify destroy)
2983-{
2984- AsyncUserOpData *data;
2985-
2986- data = g_new0 (AsyncUserOpData, 1);
2987- data->manager = g_object_ref (manager);
2988- data->user_name = g_strdup (user_name);
2989- data->callback = done;
2990- data->data = done_data;
2991- data->destroy = destroy;
2992-
2993- g_dbus_proxy_call (manager->proxy,
2994- "CacheUser",
2995- g_variant_new ("(s)", user_name),
2996- G_DBUS_CALL_FLAGS_NONE,
2997- -1,
2998- cancellable,
2999- user_call_done,
3000- data);
3001-}
3002-
3003-static void
3004-delete_user_done (GObject *proxy,
3005- GAsyncResult *r,
3006- gpointer user_data)
3007-{
3008- AsyncUserOpData *data = user_data;
3009- GSimpleAsyncResult *res;
3010- GVariant *result;
3011- GError *error = NULL;
3012-
3013- res = g_simple_async_result_new (G_OBJECT (data->manager),
3014- data->callback,
3015- data->data,
3016- um_user_manager_delete_user);
3017- result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), r, &error);
3018- if (!result) {
3019- if (g_dbus_error_is_remote_error (error) &&
3020- strcmp (g_dbus_error_get_remote_error(error), "org.freedesktop.Accounts.Error.PermissionDenied") == 0) {
3021- g_simple_async_result_set_error (res,
3022- UM_USER_MANAGER_ERROR,
3023- UM_USER_MANAGER_ERROR_PERMISSION_DENIED,
3024- "Not authorized");
3025- }
3026- else if (g_dbus_error_is_remote_error (error) &&
3027- strcmp (g_dbus_error_get_remote_error(error), "org.freedesktop.Accounts.Error.UserExists") == 0) {
3028- g_simple_async_result_set_error (res,
3029- UM_USER_MANAGER_ERROR,
3030- UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
3031- _("This user does not exist."));
3032- }
3033- else {
3034- g_simple_async_result_set_from_error (res, error);
3035- g_error_free (error);
3036- }
3037- }
3038- else
3039- g_variant_unref (result);
3040-
3041- data->callback (G_OBJECT (data->manager), G_ASYNC_RESULT (res), data->data);
3042- async_user_op_data_free (data);
3043- g_object_unref (res);
3044-}
3045-
3046-gboolean
3047-um_user_manager_delete_user_finish (UmUserManager *manager,
3048- GAsyncResult *result,
3049- GError **error)
3050-{
3051- GSimpleAsyncResult *res;
3052-
3053- res = G_SIMPLE_ASYNC_RESULT (result);
3054-
3055- if (g_simple_async_result_propagate_error (res, error)) {
3056- return FALSE;
3057- }
3058-
3059- return TRUE;
3060-}
3061-
3062-void
3063-um_user_manager_delete_user (UmUserManager *manager,
3064- UmUser *user,
3065- gboolean remove_files,
3066- GAsyncReadyCallback done,
3067- gpointer done_data,
3068- GDestroyNotify destroy)
3069-{
3070- AsyncUserOpData *data;
3071-
3072- data = g_new0 (AsyncUserOpData, 1);
3073- data->manager = g_object_ref (manager);
3074- data->callback = done;
3075- data->data = done_data;
3076- data->destroy = destroy;
3077-
3078- g_dbus_proxy_call (manager->proxy,
3079- "DeleteUser",
3080- g_variant_new ("(xb)", (gint64) um_user_get_uid (user), remove_files),
3081- G_DBUS_CALL_FLAGS_NONE,
3082- -1,
3083- NULL,
3084- delete_user_done,
3085- data);
3086-}
3087-
3088-GSList *
3089-um_user_manager_list_users (UmUserManager *manager)
3090-{
3091- GSList *list = NULL;
3092- GHashTableIter iter;
3093- gpointer value;
3094-
3095- g_hash_table_iter_init (&iter, manager->user_by_name);
3096- while (g_hash_table_iter_next (&iter, NULL, &value)) {
3097- list = g_slist_prepend (list, value);
3098- }
3099-
3100- return g_slist_sort (list, (GCompareFunc) um_user_collate);
3101-}
3102-
3103-UmUser *
3104-um_user_manager_get_user (UmUserManager *manager,
3105- const gchar *name)
3106-{
3107- return g_hash_table_lookup (manager->user_by_name, name);
3108-}
3109-
3110-UmUser *
3111-um_user_manager_get_user_by_id (UmUserManager *manager,
3112- uid_t uid)
3113-{
3114- struct passwd *pwent;
3115-
3116- pwent = getpwuid (uid);
3117- if (!pwent) {
3118- return NULL;
3119- }
3120-
3121- return um_user_manager_get_user (manager, pwent->pw_name);
3122-}
3123-
3124-gboolean
3125-um_user_manager_no_service (UmUserManager *manager)
3126-{
3127- return manager->no_service;
3128-}
3129-
3130-GQuark
3131-um_user_manager_error_quark (void)
3132-{
3133- return g_quark_from_static_string ("um-user-manager-error-quark");
3134-}
3135
3136=== removed file 'panels/user-accounts/um-user-manager.h'
3137--- panels/user-accounts/um-user-manager.h 2012-09-06 23:07:09 +0000
3138+++ panels/user-accounts/um-user-manager.h 1970-01-01 00:00:00 +0000
3139@@ -1,121 +0,0 @@
3140-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3141- *
3142- * Copyright (C) 2009-2010 Red Hat, Inc.
3143- *
3144- * This program is free software; you can redistribute it and/or modify
3145- * it under the terms of the GNU General Public License as published by
3146- * the Free Software Foundation; either version 2 of the License, or
3147- * (at your option) any later version.
3148- *
3149- * This program is distributed in the hope that it will be useful,
3150- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3151- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3152- * GNU General Public License for more details.
3153- *
3154- * You should have received a copy of the GNU General Public License
3155- * along with this program; if not, write to the Free Software
3156- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3157- *
3158- */
3159-
3160-#ifndef __UM_USER_MANAGER__
3161-#define __UM_USER_MANAGER__
3162-
3163-#include <glib-object.h>
3164-#include <gio/gio.h>
3165-
3166-#include "um-user.h"
3167-
3168-G_BEGIN_DECLS
3169-
3170-#define UM_TYPE_USER_MANAGER (um_user_manager_get_type ())
3171-#define UM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UM_TYPE_USER_MANAGER, UmUserManager))
3172-#define UM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), UM_TYPE_USER_MANAGER, UmUserManagerClass))
3173-#define UM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UM_TYPE_USER_MANAGER))
3174-#define UM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), UM_TYPE_USER_MANAGER))
3175-#define UM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), UM_TYPE_USER_MANAGER, UmUserManagerClass))
3176-
3177-typedef struct
3178-{
3179- GObject parent;
3180-
3181- GDBusProxy *proxy;
3182-
3183- GHashTable *user_by_object_path;
3184- GHashTable *user_by_name;
3185-
3186- gboolean no_service;
3187-} UmUserManager;
3188-
3189-typedef struct
3190-{
3191- GObjectClass parent_class;
3192-
3193- void (* users_loaded) (UmUserManager *user_managaer);
3194- void (* user_added) (UmUserManager *user_manager,
3195- UmUser *user);
3196- void (* user_removed) (UmUserManager *user_manager,
3197- UmUser *user);
3198- void (* user_changed) (UmUserManager *user_manager,
3199- UmUser *user);
3200-} UmUserManagerClass;
3201-
3202-
3203-typedef enum {
3204- UM_USER_MANAGER_ERROR_FAILED,
3205- UM_USER_MANAGER_ERROR_USER_EXISTS,
3206- UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
3207- UM_USER_MANAGER_ERROR_PERMISSION_DENIED
3208-} UmUserManagerError;
3209-
3210-#define UM_USER_MANAGER_ERROR um_user_manager_error_quark ()
3211-
3212-GQuark um_user_manager_error_quark (void);
3213-
3214-GType um_user_manager_get_type (void);
3215-
3216-UmUserManager * um_user_manager_ref_default (void);
3217-
3218-gboolean um_user_manager_no_service (UmUserManager *manager);
3219-
3220-GSList * um_user_manager_list_users (UmUserManager *manager);
3221-UmUser * um_user_manager_get_user (UmUserManager *manager,
3222- const char *user_name);
3223-UmUser * um_user_manager_get_user_by_id (UmUserManager *manager,
3224- uid_t uid);
3225-
3226-void um_user_manager_create_user (UmUserManager *manager,
3227- const char *user_name,
3228- const char *real_name,
3229- gint account_type,
3230- GCancellable *cancellable,
3231- GAsyncReadyCallback done,
3232- gpointer user_data,
3233- GDestroyNotify destroy);
3234-gboolean um_user_manager_create_user_finish (UmUserManager *manager,
3235- GAsyncResult *result,
3236- UmUser **user,
3237- GError **error);
3238-void um_user_manager_cache_user (UmUserManager *manager,
3239- const char *user_name,
3240- GCancellable *cancellable,
3241- GAsyncReadyCallback done,
3242- gpointer user_data,
3243- GDestroyNotify destroy);
3244-gboolean um_user_manager_cache_user_finish (UmUserManager *manager,
3245- GAsyncResult *result,
3246- UmUser **user,
3247- GError **error);
3248-void um_user_manager_delete_user (UmUserManager *manager,
3249- UmUser *user,
3250- gboolean remove_files,
3251- GAsyncReadyCallback done,
3252- gpointer user_data,
3253- GDestroyNotify destroy);
3254-gboolean um_user_manager_delete_user_finish (UmUserManager *manager,
3255- GAsyncResult *result,
3256- GError **error);
3257-
3258-G_END_DECLS
3259-
3260-#endif /* __UM_USER_MANAGER__ */
3261
3262=== modified file 'panels/user-accounts/um-user-module.c'
3263--- panels/user-accounts/um-user-module.c 2012-09-06 23:07:09 +0000
3264+++ panels/user-accounts/um-user-module.c 2014-02-24 09:46:44 +0000
3265@@ -39,7 +39,7 @@
3266 #endif
3267
3268 /* register the panel */
3269- um_user_panel_register (module);
3270+ cc_user_panel_register (module);
3271 }
3272
3273 void
3274
3275=== modified file 'panels/user-accounts/um-user-panel.c'
3276--- panels/user-accounts/um-user-panel.c 2014-02-20 09:30:01 +0000
3277+++ panels/user-accounts/um-user-panel.c 2014-02-24 09:46:44 +0000
3278@@ -32,6 +32,7 @@
3279 #include <glib/gi18n.h>
3280 #include <gtk/gtk.h>
3281 #include <polkit/polkit.h>
3282+#include <act/act.h>
3283
3284 #ifdef HAVE_CHEESE
3285 #include <gst/gst.h>
3286@@ -39,9 +40,6 @@
3287
3288 #include "shell/cc-editable-entry.h"
3289
3290-#include "um-user.h"
3291-#include "um-user-manager.h"
3292-
3293 #include "um-editable-button.h"
3294 #include "um-editable-combo.h"
3295
3296@@ -51,19 +49,21 @@
3297 #include "um-photo-dialog.h"
3298 #include "um-fingerprint-dialog.h"
3299 #include "um-utils.h"
3300+#include "um-resources.h"
3301+#include "um-history-dialog.h"
3302
3303 #include "cc-common-language.h"
3304
3305 #define USER_ACCOUNTS_PERMISSION "com.canonical.controlcenter.user-accounts.administration"
3306 #define INDICATOR_SESSION_SCHEMA "com.canonical.indicator.session"
3307
3308-CC_PANEL_REGISTER (UmUserPanel, um_user_panel)
3309+CC_PANEL_REGISTER (CcUserPanel, cc_user_panel)
3310
3311 #define UM_USER_PANEL_PRIVATE(o) \
3312- (G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, UmUserPanelPrivate))
3313+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, CcUserPanelPrivate))
3314
3315-struct _UmUserPanelPrivate {
3316- UmUserManager *um;
3317+struct _CcUserPanelPrivate {
3318+ ActUserManager *um;
3319 GtkBuilder *builder;
3320
3321 GtkWidget *main_box;
3322@@ -72,12 +72,17 @@
3323
3324 UmPasswordDialog *password_dialog;
3325 UmPhotoDialog *photo_dialog;
3326+ UmHistoryDialog *history_dialog;
3327+ gint other_accounts;
3328+ GtkTreeIter *other_iter;
3329+
3330+ UmAccountDialog *account_dialog;
3331
3332 GSettings *indicator_session_schema;
3333 };
3334
3335 static GtkWidget *
3336-get_widget (UmUserPanelPrivate *d, const char *name)
3337+get_widget (CcUserPanelPrivate *d, const char *name)
3338 {
3339 return (GtkWidget *)gtk_builder_get_object (d->builder, name);
3340 }
3341@@ -94,14 +99,14 @@
3342 NUM_USER_LIST_COLS
3343 };
3344
3345-static UmUser *
3346-get_selected_user (UmUserPanelPrivate *d)
3347+static ActUser *
3348+get_selected_user (CcUserPanelPrivate *d)
3349 {
3350 GtkTreeView *tv;
3351 GtkTreeIter iter;
3352 GtkTreeSelection *selection;
3353 GtkTreeModel *model;
3354- UmUser *user;
3355+ ActUser *user;
3356
3357 tv = (GtkTreeView *)get_widget (d, "list-treeview");
3358 selection = gtk_tree_view_get_selection (tv);
3359@@ -115,15 +120,15 @@
3360 }
3361
3362 static char *
3363-get_name_col_str (UmUser *user)
3364+get_name_col_str (ActUser *user)
3365 {
3366 return g_markup_printf_escaped ("<b>%s</b>\n<small>%s</small>",
3367- um_user_get_display_name (user),
3368- um_user_get_user_name (user));
3369+ act_user_get_real_name (user),
3370+ act_user_get_user_name (user));
3371 }
3372
3373 static void
3374-user_added (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
3375+user_added (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
3376 {
3377 GtkWidget *widget;
3378 GtkTreeModel *model;
3379@@ -131,26 +136,31 @@
3380 GtkTreeIter iter;
3381 GtkTreeIter dummy;
3382 GdkPixbuf *pixbuf;
3383- gchar *text;
3384+ gchar *text, *title;
3385 GtkTreeSelection *selection;
3386 gint sort_key;
3387 gboolean is_autologin;
3388
3389- g_debug ("user added: %d %s\n", um_user_get_uid (user), um_user_get_real_name (user));
3390+ if (act_user_is_system_account (user)) {
3391+ return;
3392+ }
3393+
3394+ g_debug ("user added: %d %s\n", act_user_get_uid (user), act_user_get_real_name (user));
3395 widget = get_widget (d, "list-treeview");
3396 model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
3397 store = GTK_LIST_STORE (model);
3398 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
3399
3400- pixbuf = um_user_render_icon (user, TRUE, 48);
3401+ pixbuf = render_user_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
3402 text = get_name_col_str (user);
3403
3404- is_autologin = um_user_get_automatic_login (user);
3405+ is_autologin = act_user_get_automatic_login (user);
3406
3407- if (um_user_get_uid (user) == getuid ()) {
3408+ if (act_user_get_uid (user) == getuid ()) {
3409 sort_key = 1;
3410 }
3411 else {
3412+ d->other_accounts++;
3413 sort_key = 3;
3414 }
3415 gtk_list_store_append (store, &iter);
3416@@ -172,6 +182,19 @@
3417 !gtk_tree_selection_get_selected (selection, &model, &dummy)) {
3418 gtk_tree_selection_select_iter (selection, &iter);
3419 }
3420+
3421+ /* Show heading for other accounts if new one have been added. */
3422+ if (d->other_accounts == 1 && sort_key == 3) {
3423+ title = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>", _("Other Accounts"));
3424+ gtk_list_store_append (store, &iter);
3425+ gtk_list_store_set (store, &iter,
3426+ TITLE_COL, title,
3427+ HEADING_ROW_COL, TRUE,
3428+ SORT_KEY_COL, 2,
3429+ -1);
3430+ d->other_iter = gtk_tree_iter_copy (&iter);
3431+ g_free (title);
3432+ }
3433 }
3434
3435 static void
3436@@ -180,7 +203,7 @@
3437 GtkTreeIter *prev)
3438 {
3439 GtkTreePath *path;
3440- UmUser *user;
3441+ ActUser *user;
3442
3443 path = gtk_tree_model_get_path (model, iter);
3444 while (gtk_tree_path_prev (path)) {
3445@@ -199,7 +222,7 @@
3446 GtkTreeIter *iter,
3447 GtkTreeIter *next)
3448 {
3449- UmUser *user;
3450+ ActUser *user;
3451
3452 *next = *iter;
3453 while (gtk_tree_model_iter_next (model, next)) {
3454@@ -214,28 +237,32 @@
3455 }
3456
3457 static void
3458-user_removed (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
3459+user_removed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
3460 {
3461 GtkTreeView *tv;
3462 GtkTreeModel *model;
3463 GtkTreeSelection *selection;
3464 GtkListStore *store;
3465 GtkTreeIter iter, next;
3466- UmUser *u;
3467+ ActUser *u;
3468+ gint key;
3469
3470- g_debug ("user removed: %s\n", um_user_get_user_name (user));
3471+ g_debug ("user removed: %s\n", act_user_get_user_name (user));
3472 tv = (GtkTreeView *)get_widget (d, "list-treeview");
3473 selection = gtk_tree_view_get_selection (tv);
3474 model = gtk_tree_view_get_model (tv);
3475 store = GTK_LIST_STORE (model);
3476 if (gtk_tree_model_get_iter_first (model, &iter)) {
3477 do {
3478- gtk_tree_model_get (model, &iter, USER_COL, &u, -1);
3479+ gtk_tree_model_get (model, &iter, USER_COL, &u, SORT_KEY_COL, &key, -1);
3480
3481 if (u != NULL) {
3482- if (um_user_get_uid (user) == um_user_get_uid (u)) {
3483+ if (act_user_get_uid (user) == act_user_get_uid (u)) {
3484 if (!get_next_user_row (model, &iter, &next))
3485 get_previous_user_row (model, &iter, &next);
3486+ if (key == 3) {
3487+ d->other_accounts--;
3488+ }
3489 gtk_list_store_remove (store, &iter);
3490 gtk_tree_selection_select_iter (selection, &next);
3491 g_object_unref (u);
3492@@ -245,18 +272,25 @@
3493 }
3494 } while (gtk_tree_model_iter_next (model, &iter));
3495 }
3496+
3497+ /* Hide heading for other accounts if last one have been removed. */
3498+ if (d->other_iter != NULL && d->other_accounts == 0 && key == 3) {
3499+ gtk_list_store_remove (store, d->other_iter);
3500+ gtk_tree_iter_free (d->other_iter);
3501+ d->other_iter = NULL;
3502+ }
3503 }
3504
3505-static void show_user (UmUser *user, UmUserPanelPrivate *d);
3506+static void show_user (ActUser *user, CcUserPanelPrivate *d);
3507
3508 static void
3509-user_changed (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
3510+user_changed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
3511 {
3512 GtkTreeView *tv;
3513 GtkTreeSelection *selection;
3514 GtkTreeModel *model;
3515 GtkTreeIter iter;
3516- UmUser *current;
3517+ ActUser *current;
3518 GdkPixbuf *pixbuf;
3519 char *text;
3520 gboolean is_autologin;
3521@@ -269,9 +303,9 @@
3522 do {
3523 gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
3524 if (current == user) {
3525- pixbuf = um_user_render_icon (user, TRUE, 48);
3526+ pixbuf = render_user_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
3527 text = get_name_col_str (user);
3528- is_autologin = um_user_get_automatic_login (user);
3529+ is_autologin = act_user_get_automatic_login (user);
3530
3531 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
3532 USER_COL, user,
3533@@ -306,19 +340,21 @@
3534 GAsyncResult *result,
3535 gpointer user_data)
3536 {
3537- UmUserPanelPrivate *d = user_data;
3538+ CcUserPanelPrivate *d = user_data;
3539 UmAccountDialog *dialog;
3540 GtkTreeView *tv;
3541 GtkTreeModel *model;
3542 GtkTreeSelection *selection;
3543 GtkTreeIter iter;
3544- UmUser *current;
3545+ ActUser *current;
3546 GtkTreePath *path;
3547- UmUser *user;
3548+ ActUser *user;
3549+ uid_t user_uid;
3550
3551 dialog = UM_ACCOUNT_DIALOG (object);
3552 user = um_account_dialog_finish (dialog, result);
3553 gtk_widget_destroy (GTK_WIDGET (dialog));
3554+ d->account_dialog = NULL;
3555
3556 if (user == NULL)
3557 return;
3558@@ -326,45 +362,45 @@
3559 tv = (GtkTreeView *)get_widget (d, "list-treeview");
3560 model = gtk_tree_view_get_model (tv);
3561 selection = gtk_tree_view_get_selection (tv);
3562+ user_uid = act_user_get_uid (user);
3563
3564 gtk_tree_model_get_iter_first (model, &iter);
3565 do {
3566 gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
3567- if (user == current) {
3568- path = gtk_tree_model_get_path (model, &iter);
3569- gtk_tree_view_scroll_to_cell (tv, path, NULL, FALSE, 0.0, 0.0);
3570- gtk_tree_selection_select_path (selection, path);
3571- gtk_tree_path_free (path);
3572+ if (current) {
3573+ if (user_uid == act_user_get_uid (current)) {
3574+ path = gtk_tree_model_get_path (model, &iter);
3575+ gtk_tree_view_scroll_to_cell (tv, path, NULL, FALSE, 0.0, 0.0);
3576+ gtk_tree_selection_select_path (selection, path);
3577+ gtk_tree_path_free (path);
3578+ g_object_unref (current);
3579+ break;
3580+ }
3581 g_object_unref (current);
3582- break;
3583 }
3584- if (current)
3585- g_object_unref (current);
3586 } while (gtk_tree_model_iter_next (model, &iter));
3587
3588 g_object_unref (user);
3589 }
3590
3591 static void
3592-add_user (GtkButton *button, UmUserPanelPrivate *d)
3593+add_user (GtkButton *button, CcUserPanelPrivate *d)
3594 {
3595- UmAccountDialog *dialog;
3596-
3597- dialog = um_account_dialog_new ();
3598- um_account_dialog_show (dialog, GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
3599- select_created_user, d);
3600+ d->account_dialog = um_account_dialog_new ();
3601+ um_account_dialog_show (d->account_dialog, GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
3602+ d->permission, select_created_user, d);
3603 }
3604
3605 static void
3606-delete_user_done (UmUserManager *manager,
3607+delete_user_done (ActUserManager *manager,
3608 GAsyncResult *res,
3609- UmUserPanelPrivate *d)
3610+ CcUserPanelPrivate *d)
3611 {
3612 GError *error;
3613
3614 error = NULL;
3615- if (!um_user_manager_delete_user_finish (manager, res, &error)) {
3616- if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
3617+ if (!act_user_manager_delete_user_finish (manager, res, &error)) {
3618+ if (!g_error_matches (error, ACT_USER_MANAGER_ERROR, ACT_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
3619 GtkWidget *dialog;
3620
3621 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
3622@@ -387,9 +423,9 @@
3623 static void
3624 delete_user_response (GtkWidget *dialog,
3625 gint response_id,
3626- UmUserPanelPrivate *d)
3627+ CcUserPanelPrivate *d)
3628 {
3629- UmUser *user;
3630+ ActUser *user;
3631 gboolean remove_files;
3632
3633 gtk_widget_destroy (dialog);
3634@@ -406,27 +442,32 @@
3635
3636 user = get_selected_user (d);
3637
3638- um_user_manager_delete_user (d->um,
3639- user,
3640- remove_files,
3641- (GAsyncReadyCallback)delete_user_done,
3642- d,
3643- NULL);
3644+ /* remove autologin */
3645+ if (act_user_get_automatic_login (user)) {
3646+ act_user_set_automatic_login (user, FALSE);
3647+ }
3648+
3649+ act_user_manager_delete_user_async (d->um,
3650+ user,
3651+ remove_files,
3652+ NULL,
3653+ (GAsyncReadyCallback)delete_user_done,
3654+ d);
3655
3656 g_object_unref (user);
3657 }
3658
3659 static void
3660-delete_user (GtkButton *button, UmUserPanelPrivate *d)
3661+delete_user (GtkButton *button, CcUserPanelPrivate *d)
3662 {
3663- UmUser *user;
3664+ ActUser *user;
3665 GtkWidget *dialog;
3666
3667 user = get_selected_user (d);
3668 if (user == NULL) {
3669 return;
3670 }
3671- else if (um_user_get_uid (user) == getuid ()) {
3672+ else if (act_user_get_uid (user) == getuid ()) {
3673 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
3674 0,
3675 GTK_MESSAGE_INFO,
3676@@ -435,13 +476,13 @@
3677 g_signal_connect (dialog, "response",
3678 G_CALLBACK (gtk_widget_destroy), NULL);
3679 }
3680- else if (um_user_is_logged_in (user)) {
3681+ else if (act_user_is_logged_in_anywhere (user)) {
3682 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
3683 0,
3684 GTK_MESSAGE_INFO,
3685 GTK_BUTTONS_CLOSE,
3686 _("%s is still logged in"),
3687- um_user_get_real_name (user));
3688+ act_user_get_real_name (user));
3689
3690 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3691 _("Deleting a user while they are logged in can leave the system in an inconsistent state."));
3692@@ -454,7 +495,7 @@
3693 GTK_MESSAGE_QUESTION,
3694 GTK_BUTTONS_NONE,
3695 _("Do you want to keep %s's files?"),
3696- um_user_get_real_name (user));
3697+ act_user_get_real_name (user));
3698
3699 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3700 _("It is possible to keep the home directory, mail spool and temporary files around when deleting a user account."));
3701@@ -508,22 +549,22 @@
3702 }
3703
3704 static const gchar *
3705-get_password_mode_text (UmUser *user)
3706+get_password_mode_text (ActUser *user)
3707 {
3708 const gchar *text;
3709
3710- if (um_user_get_locked (user)) {
3711+ if (act_user_get_locked (user)) {
3712 text = C_("Password mode", "Account disabled");
3713 }
3714 else {
3715- switch (um_user_get_password_mode (user)) {
3716- case UM_PASSWORD_MODE_REGULAR:
3717+ switch (act_user_get_password_mode (user)) {
3718+ case ACT_USER_PASSWORD_MODE_REGULAR:
3719 text = get_invisible_text ();
3720 break;
3721- case UM_PASSWORD_MODE_SET_AT_LOGIN:
3722+ case ACT_USER_PASSWORD_MODE_SET_AT_LOGIN:
3723 text = C_("Password mode", "To be set at next login");
3724 break;
3725- case UM_PASSWORD_MODE_NONE:
3726+ case ACT_USER_PASSWORD_MODE_NONE:
3727 text = C_("Password mode", "None");
3728 break;
3729 default:
3730@@ -537,24 +578,24 @@
3731 static void
3732 autologin_changed (GObject *object,
3733 GParamSpec *pspec,
3734- UmUserPanelPrivate *d)
3735+ CcUserPanelPrivate *d)
3736 {
3737 gboolean active;
3738- UmUser *user;
3739+ ActUser *user;
3740
3741 active = gtk_switch_get_active (GTK_SWITCH (object));
3742 user = get_selected_user (d);
3743
3744- if (active != um_user_get_automatic_login (user)) {
3745- um_user_set_automatic_login (user, active);
3746- if (um_user_get_automatic_login (user)) {
3747+ if (active != act_user_get_automatic_login (user)) {
3748+ act_user_set_automatic_login (user, active);
3749+ if (act_user_get_automatic_login (user)) {
3750 GSList *list;
3751 GSList *l;
3752- list = um_user_manager_list_users (d->um);
3753+ list = act_user_manager_list_users (d->um);
3754 for (l = list; l != NULL; l = l->next) {
3755- UmUser *u = l->data;
3756- if (um_user_get_uid (u) != um_user_get_uid (user)) {
3757- um_user_set_automatic_login (user, FALSE);
3758+ ActUser *u = l->data;
3759+ if (act_user_get_uid (u) != act_user_get_uid (user)) {
3760+ act_user_set_automatic_login (user, FALSE);
3761 }
3762 }
3763 g_slist_free (list);
3764@@ -564,21 +605,65 @@
3765 g_object_unref (user);
3766 }
3767
3768+static gchar *
3769+get_login_time_text (ActUser *user)
3770+{
3771+ gchar *text, *date_str, *time_str;
3772+ GDateTime *date_time;
3773+ gint64 time;
3774+
3775+ time = act_user_get_login_time (user);
3776+ if (act_user_is_logged_in (user)) {
3777+ text = g_strdup (_("Logged in"));
3778+ }
3779+ else if (time > 0) {
3780+ date_time = g_date_time_new_from_unix_local (time);
3781+ date_str = get_smart_date (date_time);
3782+ time_str = g_date_time_format (date_time, "%k:%M");
3783+
3784+ text = g_strconcat (date_str, ", ", time_str, NULL);
3785+
3786+ g_date_time_unref (date_time);
3787+ g_free (date_str);
3788+ g_free (time_str);
3789+ }
3790+ else {
3791+ text = g_strdup ("—");
3792+ }
3793+
3794+ return text;
3795+}
3796+
3797+static gboolean
3798+get_autologin_possible (ActUser *user)
3799+{
3800+ gboolean locked;
3801+ gboolean set_password_at_login;
3802+
3803+ locked = act_user_get_locked (user);
3804+ set_password_at_login = (act_user_get_password_mode (user) == ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
3805+
3806+ return !(locked || set_password_at_login);
3807+}
3808+
3809+static void on_permission_changed (GPermission *permission, GParamSpec *pspec, gpointer data);
3810+
3811 static void
3812-show_user (UmUser *user, UmUserPanelPrivate *d)
3813+show_user (ActUser *user, CcUserPanelPrivate *d)
3814 {
3815 GtkWidget *image;
3816 GtkWidget *label;
3817 GtkWidget *label2;
3818 GtkWidget *label3;
3819 GdkPixbuf *pixbuf;
3820- gchar *lang;
3821+ gchar *lang, *text;
3822 GtkWidget *widget;
3823 GtkTreeModel *model;
3824 GtkTreeIter iter;
3825 gboolean show, enable;
3826+ ActUser *current;
3827
3828- pixbuf = um_user_render_icon (user, FALSE, 48);
3829+ pixbuf = render_user_icon (user, UM_ICON_STYLE_NONE, 48);
3830 image = get_widget (d, "user-icon-image");
3831 gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
3832 image = get_widget (d, "user-icon-image2");
3833@@ -588,34 +673,32 @@
3834 um_photo_dialog_set_user (d->photo_dialog, user);
3835
3836 widget = get_widget (d, "full-name-entry");
3837- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), um_user_get_real_name (user));
3838- gtk_widget_set_tooltip_text (widget, um_user_get_user_name (user));
3839+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), act_user_get_real_name (user));
3840+ gtk_widget_set_tooltip_text (widget, act_user_get_user_name (user));
3841
3842 widget = get_widget (d, "account-type-combo");
3843- um_editable_combo_set_active (UM_EDITABLE_COMBO (widget), um_user_get_account_type (user));
3844+ um_editable_combo_set_active (UM_EDITABLE_COMBO (widget), act_user_get_account_type (user));
3845
3846 widget = get_widget (d, "account-password-button");
3847 um_editable_button_set_text (UM_EDITABLE_BUTTON (widget), get_password_mode_text (user));
3848- enable = um_user_is_local_account (user);
3849+ enable = act_user_is_local_account (user);
3850 gtk_widget_set_sensitive (widget, enable);
3851
3852 widget = get_widget (d, "autologin-switch");
3853 g_signal_handlers_block_by_func (widget, autologin_changed, d);
3854- gtk_switch_set_active (GTK_SWITCH (widget), um_user_get_automatic_login (user));
3855+ gtk_switch_set_active (GTK_SWITCH (widget), act_user_get_automatic_login (user));
3856 g_signal_handlers_unblock_by_func (widget, autologin_changed, d);
3857-
3858- if (um_user_get_locked (user))
3859- gtk_widget_set_sensitive (widget, FALSE);
3860+ gtk_widget_set_sensitive (widget, get_autologin_possible (user));
3861
3862 widget = get_widget (d, "account-language-combo");
3863 model = um_editable_combo_get_model (UM_EDITABLE_COMBO (widget));
3864 cc_add_user_languages (model);
3865
3866- lang = g_strdup (um_user_get_language (user));
3867+ lang = g_strdup (act_user_get_language (user));
3868 if (!lang)
3869 lang = cc_common_language_get_current_language ();
3870- cc_common_language_get_iter_for_language (model, lang, &iter);
3871- um_editable_combo_set_active_iter (UM_EDITABLE_COMBO (widget), &iter);
3872+ if (cc_common_language_get_iter_for_language (model, lang, &iter))
3873+ um_editable_combo_set_active_iter (UM_EDITABLE_COMBO (widget), &iter);
3874 g_free (lang);
3875
3876 /* Fingerprint: show when self, possible, and local account */
3877@@ -623,8 +706,8 @@
3878 label = get_widget (d, "account-fingerprint-label");
3879 label2 = get_widget (d, "account-fingerprint-value-label");
3880 label3 = get_widget (d, "account-fingerprint-button-label");
3881- show = (um_user_get_uid (user) == getuid() &&
3882- um_user_is_local_account (user) &&
3883+ show = (act_user_get_uid (user) == getuid() &&
3884+ act_user_is_local_account (user) &&
3885 set_fingerprint_label (label2, label3));
3886 gtk_widget_set_visible (label, show);
3887 gtk_widget_set_visible (widget, show);
3888@@ -634,34 +717,53 @@
3889 label = get_widget (d, "autologin-label");
3890 /* Don't show autologin option if ecryptfs is in use, because it won't
3891 work if user turns it on. */
3892- show = um_user_is_local_account (user) &&
3893- !is_using_ecryptfs (um_user_get_user_name (user));
3894+ show = act_user_is_local_account (user) &&
3895+ !is_using_ecryptfs (act_user_get_user_name (user));
3896 gtk_widget_set_visible (widget, show);
3897 gtk_widget_set_visible (label, show);
3898
3899 /* Menu bar: show when self and have indicator schema */
3900 widget = get_widget (d, "show-login-name-checkbutton");
3901 label = get_widget (d, "show-login-name-spacer");
3902- show = um_user_get_uid (user) == getuid() &&
3903+ show = act_user_get_uid (user) == getuid() &&
3904 d->indicator_session_schema;
3905 gtk_widget_set_visible (widget, show);
3906 gtk_widget_set_visible (label, show);
3907+
3908+ /* Last login: show when administrator or current user */
3909+ widget = get_widget (d, "last-login-value-label");
3910+ label = get_widget (d, "last-login-label");
3911+
3912+ current = act_user_manager_get_user_by_id (d->um, getuid ());
3913+ show = act_user_get_uid (user) == getuid () ||
3914+ act_user_get_account_type (current) == ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR;
3915+ if (show) {
3916+ text = get_login_time_text (user);
3917+ gtk_label_set_text (GTK_LABEL (widget), text);
3918+ g_free (text);
3919+ }
3920+ gtk_widget_set_visible (widget, show);
3921+ gtk_widget_set_visible (label, show);
3922+
3923+ enable = act_user_get_login_history (user) != NULL;
3924+ widget = get_widget (d, "last-login-history-button");
3925+ gtk_widget_set_visible (widget, show);
3926+ gtk_widget_set_sensitive (widget, enable);
3927+
3928+ if (d->permission != NULL)
3929+ on_permission_changed (d->permission, NULL, d);
3930 }
3931
3932-static void on_permission_changed (GPermission *permission, GParamSpec *pspec, gpointer data);
3933-
3934 static void
3935-selected_user_changed (GtkTreeSelection *selection, UmUserPanelPrivate *d)
3936+selected_user_changed (GtkTreeSelection *selection, CcUserPanelPrivate *d)
3937 {
3938 GtkTreeModel *model;
3939 GtkTreeIter iter;
3940- UmUser *user;
3941+ ActUser *user;
3942
3943 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
3944 gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
3945 show_user (user, d);
3946- if (d->permission != NULL)
3947- on_permission_changed (d->permission, NULL, d);
3948 gtk_widget_set_sensitive (get_widget (d, "main-user-vbox"), TRUE);
3949 g_object_unref (user);
3950 } else {
3951@@ -671,16 +773,17 @@
3952
3953 static void
3954 change_name_done (GtkWidget *entry,
3955- UmUserPanelPrivate *d)
3956+ CcUserPanelPrivate *d)
3957 {
3958 const gchar *text;
3959- UmUser *user;
3960+ ActUser *user;
3961
3962 user = get_selected_user (d);
3963
3964 text = cc_editable_entry_get_text (CC_EDITABLE_ENTRY (entry));
3965- if (g_strcmp0 (text, um_user_get_real_name (user)) != 0) {
3966- um_user_set_real_name (user, text);
3967+ if (g_strcmp0 (text, act_user_get_real_name (user)) != 0 &&
3968+ is_valid_name (text)) {
3969+ act_user_set_real_name (user, text);
3970 }
3971
3972 g_object_unref (user);
3973@@ -688,9 +791,9 @@
3974
3975 static void
3976 account_type_changed (UmEditableCombo *combo,
3977- UmUserPanelPrivate *d)
3978+ CcUserPanelPrivate *d)
3979 {
3980- UmUser *user;
3981+ ActUser *user;
3982 GtkTreeModel *model;
3983 GtkTreeIter iter;
3984 gint account_type;
3985@@ -701,8 +804,8 @@
3986 um_editable_combo_get_active_iter (combo, &iter);
3987 gtk_tree_model_get (model, &iter, 1, &account_type, -1);
3988
3989- if (account_type != um_user_get_account_type (user)) {
3990- um_user_set_account_type (user, account_type);
3991+ if (account_type != act_user_get_account_type (user)) {
3992+ act_user_set_account_type (user, account_type);
3993 }
3994
3995 g_object_unref (user);
3996@@ -711,10 +814,10 @@
3997 static void
3998 language_response (GtkDialog *dialog,
3999 gint response_id,
4000- UmUserPanelPrivate *d)
4001+ CcUserPanelPrivate *d)
4002 {
4003 GtkWidget *combo;
4004- UmUser *user;
4005+ ActUser *user;
4006 gchar *lang;
4007 GtkTreeModel *model;
4008 GtkTreeIter iter;
4009@@ -726,10 +829,10 @@
4010
4011 if (response_id == GTK_RESPONSE_OK) {
4012 lang = cc_language_chooser_get_language (GTK_WIDGET (dialog));
4013- um_user_set_language (user, lang);
4014+ act_user_set_language (user, lang);
4015 }
4016 else {
4017- lang = g_strdup (um_user_get_language (user));
4018+ lang = g_strdup (act_user_get_language (user));
4019 if (!lang)
4020 lang = cc_common_language_get_current_language ();
4021 }
4022@@ -745,12 +848,12 @@
4023
4024 static void
4025 language_changed (UmEditableCombo *combo,
4026- UmUserPanelPrivate *d)
4027+ CcUserPanelPrivate *d)
4028 {
4029 GtkTreeModel *model;
4030 GtkTreeIter iter;
4031 gchar *lang;
4032- UmUser *user;
4033+ ActUser *user;
4034
4035 if (!um_editable_combo_get_active_iter (combo, &iter))
4036 return;
4037@@ -761,8 +864,8 @@
4038
4039 gtk_tree_model_get (model, &iter, 0, &lang, -1);
4040 if (lang) {
4041- if (g_strcmp0 (lang, um_user_get_language (user)) != 0) {
4042- um_user_set_language (user, lang);
4043+ if (g_strcmp0 (lang, act_user_get_language (user)) != 0) {
4044+ act_user_set_language (user, lang);
4045 }
4046 g_free (lang);
4047 goto out;
4048@@ -791,9 +894,9 @@
4049 }
4050
4051 static void
4052-change_password (GtkButton *button, UmUserPanelPrivate *d)
4053+change_password (GtkButton *button, CcUserPanelPrivate *d)
4054 {
4055- UmUser *user;
4056+ ActUser *user;
4057
4058 user = get_selected_user (d);
4059
4060@@ -805,14 +908,14 @@
4061 }
4062
4063 static void
4064-change_fingerprint (GtkButton *button, UmUserPanelPrivate *d)
4065+change_fingerprint (GtkButton *button, CcUserPanelPrivate *d)
4066 {
4067 GtkWidget *label, *label2;
4068- UmUser *user;
4069+ ActUser *user;
4070
4071 user = get_selected_user (d);
4072
4073- g_assert (g_strcmp0 (g_get_user_name (), um_user_get_user_name (user)) == 0);
4074+ g_assert (g_strcmp0 (g_get_user_name (), act_user_get_user_name (user)) == 0);
4075
4076 label = get_widget (d, "account-fingerprint-value-label");
4077 label2 = get_widget (d, "account-fingerprint-button-label");
4078@@ -821,13 +924,26 @@
4079 g_object_unref (user);
4080 }
4081
4082+static void
4083+show_history (GtkButton *button, CcUserPanelPrivate *d)
4084+{
4085+ ActUser *user;
4086+
4087+ user = get_selected_user (d);
4088+
4089+ um_history_dialog_set_user (d->history_dialog, user);
4090+ um_history_dialog_show (d->history_dialog, GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)));
4091+
4092+ g_object_unref (user);
4093+}
4094+
4095 static gint
4096 sort_users (GtkTreeModel *model,
4097 GtkTreeIter *a,
4098 GtkTreeIter *b,
4099 gpointer data)
4100 {
4101- UmUser *ua, *ub;
4102+ ActUser *ua, *ub;
4103 gint sa, sb;
4104 gint result;
4105
4106@@ -841,7 +957,7 @@
4107 result = 1;
4108 }
4109 else {
4110- result = um_user_collate (ua, ub);
4111+ result = act_user_collate (ua, ub);
4112 }
4113
4114 if (ua) {
4115@@ -871,14 +987,15 @@
4116 }
4117
4118 static void
4119-users_loaded (UmUserManager *manager,
4120- UmUserPanelPrivate *d)
4121+users_loaded (ActUserManager *manager,
4122+ GParamSpec *pspec,
4123+ CcUserPanelPrivate *d)
4124 {
4125 GSList *list, *l;
4126- UmUser *user;
4127+ ActUser *user;
4128 GtkWidget *dialog;
4129
4130- if (um_user_manager_no_service (d->um)) {
4131+ if (act_user_manager_no_service (d->um)) {
4132 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
4133 GTK_DIALOG_MODAL,
4134 GTK_MESSAGE_OTHER,
4135@@ -894,14 +1011,15 @@
4136 gtk_widget_set_sensitive (d->main_box, FALSE);
4137 }
4138
4139- list = um_user_manager_list_users (d->um);
4140+ list = act_user_manager_list_users (d->um);
4141 g_debug ("Got %d users\n", g_slist_length (list));
4142
4143 g_signal_connect (d->um, "user-changed", G_CALLBACK (user_changed), d);
4144+ g_signal_connect (d->um, "user-is-logged-in-changed", G_CALLBACK (user_changed), d);
4145
4146 for (l = list; l; l = l->next) {
4147 user = l->data;
4148- g_debug ("adding user %s\n", um_user_get_real_name (user));
4149+ g_debug ("adding user %s\n", act_user_get_real_name (user));
4150 user_added (d->um, user, d);
4151 }
4152 g_slist_free (list);
4153@@ -946,10 +1064,10 @@
4154 GParamSpec *pspec,
4155 gpointer data)
4156 {
4157- UmUserPanelPrivate *d = data;
4158+ CcUserPanelPrivate *d = data;
4159 gboolean is_authorized;
4160 gboolean self_selected;
4161- UmUser *user;
4162+ ActUser *user;
4163 GtkWidget *widget;
4164
4165 user = get_selected_user (d);
4166@@ -958,7 +1076,7 @@
4167 }
4168
4169 is_authorized = g_permission_get_allowed (G_PERMISSION (d->permission));
4170- self_selected = um_user_get_uid (user) == geteuid ();
4171+ self_selected = act_user_get_uid (user) == geteuid ();
4172
4173 widget = get_widget (d, "add-user-toolbutton");
4174 gtk_widget_set_sensitive (widget, is_authorized);
4175@@ -981,7 +1099,8 @@
4176 }
4177
4178 widget = get_widget (d, "remove-user-toolbutton");
4179- gtk_widget_set_sensitive (widget, is_authorized && !self_selected);
4180+ gtk_widget_set_sensitive (widget, is_authorized && !self_selected
4181+ && !would_demote_only_admin (user));
4182 if (is_authorized) {
4183 setup_tooltip_with_embedded_icon (widget, _("Delete the selected user account"), NULL, NULL);
4184 }
4185@@ -1001,28 +1120,37 @@
4186 g_object_unref (icon);
4187 }
4188
4189- if (!um_user_is_local_account (user)) {
4190+ if (!act_user_is_local_account (user)) {
4191 um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
4192 remove_unlock_tooltip (get_widget (d, "account-type-combo"));
4193 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
4194 remove_unlock_tooltip (get_widget (d, "autologin-switch"));
4195
4196- } else if (is_authorized && um_user_is_local_account (user)) {
4197- um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
4198+ } else if (is_authorized && act_user_is_local_account (user)) {
4199+ if (would_demote_only_admin (user)) {
4200+ um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
4201+ } else {
4202+ um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
4203+ }
4204 remove_unlock_tooltip (get_widget (d, "account-type-combo"));
4205- gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), TRUE);
4206+
4207+ gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), get_autologin_possible (user));
4208 remove_unlock_tooltip (get_widget (d, "autologin-switch"));
4209 }
4210 else {
4211 um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
4212- add_unlock_tooltip (get_widget (d, "account-type-combo"));
4213+ if (would_demote_only_admin (user)) {
4214+ remove_unlock_tooltip (get_widget (d, "account-type-combo"));
4215+ } else {
4216+ add_unlock_tooltip (get_widget (d, "account-type-combo"));
4217+ }
4218 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
4219 add_unlock_tooltip (get_widget (d, "autologin-switch"));
4220 }
4221
4222 /* The full name entry: insensitive if remote or not authorized and not self */
4223 widget = get_widget (d, "full-name-entry");
4224- if (!um_user_is_local_account (user)) {
4225+ if (!act_user_is_local_account (user)) {
4226 cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), FALSE);
4227 remove_unlock_tooltip (widget);
4228
4229@@ -1060,6 +1188,7 @@
4230 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 0);
4231 }
4232
4233+ um_password_dialog_set_user (d->password_dialog, user);
4234 um_password_dialog_set_privileged (d->password_dialog, is_authorized);
4235
4236 g_object_unref (user);
4237@@ -1072,7 +1201,7 @@
4238 GtkTreeIter *iter,
4239 gpointer search_data)
4240 {
4241- UmUser *user;
4242+ ActUser *user;
4243 const gchar *name;
4244 gchar *normalized_key = NULL;
4245 gchar *normalized_name = NULL;
4246@@ -1097,10 +1226,10 @@
4247
4248 for (i = 0; i < 2; i++) {
4249 if (i == 0) {
4250- name = um_user_get_real_name (user);
4251+ name = act_user_get_real_name (user);
4252 }
4253 else {
4254- name = um_user_get_user_name (user);
4255+ name = act_user_get_user_name (user);
4256 }
4257 g_free (normalized_name);
4258 normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
4259@@ -1134,7 +1263,7 @@
4260 GtkCellRenderer *cell,
4261 GtkTreeModel *model,
4262 GtkTreeIter *iter,
4263- UmUserPanelPrivate *d)
4264+ CcUserPanelPrivate *d)
4265 {
4266 gboolean is_autologin;
4267
4268@@ -1148,7 +1277,7 @@
4269 }
4270
4271 static void
4272-setup_main_window (UmUserPanelPrivate *d)
4273+setup_main_window (CcUserPanelPrivate *d)
4274 {
4275 GtkWidget *userlist;
4276 GtkTreeModel *model;
4277@@ -1163,10 +1292,11 @@
4278 GIcon *icon;
4279 GError *error = NULL;
4280 gchar *names[3];
4281+ gboolean loaded;
4282
4283 userlist = get_widget (d, "list-treeview");
4284 store = gtk_list_store_new (NUM_USER_LIST_COLS,
4285- UM_TYPE_USER,
4286+ ACT_TYPE_USER,
4287 GDK_TYPE_PIXBUF,
4288 G_TYPE_STRING,
4289 G_TYPE_BOOLEAN,
4290@@ -1183,8 +1313,6 @@
4291 match_user, NULL, NULL);
4292 g_object_unref (model);
4293
4294- g_signal_connect (d->um, "users-loaded", G_CALLBACK (users_loaded), d);
4295-
4296 gtk_widget_style_get (userlist, "expander-size", &expander_size, NULL);
4297 gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (userlist), - (expander_size + 6));
4298
4299@@ -1198,15 +1326,8 @@
4300 -1);
4301 g_free (title);
4302
4303- title = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>", _("Other Accounts"));
4304- gtk_list_store_append (store, &iter);
4305- gtk_list_store_set (store, &iter,
4306- TITLE_COL, title,
4307- HEADING_ROW_COL, TRUE,
4308- SORT_KEY_COL, 2,
4309- AUTOLOGIN_COL, FALSE,
4310- -1);
4311- g_free (title);
4312+ d->other_accounts = 0;
4313+ d->other_iter = NULL;
4314
4315 column = gtk_tree_view_column_new ();
4316 cell = gtk_cell_renderer_pixbuf_new ();
4317@@ -1270,6 +1391,10 @@
4318 g_signal_connect (button, "clicked",
4319 G_CALLBACK (change_fingerprint), d);
4320
4321+ button = get_widget (d, "last-login-history-button");
4322+ g_signal_connect (button, "clicked",
4323+ G_CALLBACK (show_history), d);
4324+
4325 d->permission = (GPermission *)polkit_permission_new_sync (USER_ACCOUNTS_PERMISSION, NULL, NULL, &error);
4326 if (d->permission != NULL) {
4327 g_signal_connect (d->permission, "notify",
4328@@ -1295,20 +1420,26 @@
4329 "*",
4330 icon);
4331 g_object_unref (icon);
4332+
4333+ g_object_get (d->um, "is-loaded", &loaded, NULL);
4334+ if (loaded)
4335+ users_loaded (d->um, NULL, d);
4336+ else
4337+ g_signal_connect (d->um, "notify::is-loaded", G_CALLBACK (users_loaded), d);
4338 }
4339
4340 static void
4341-um_user_panel_init (UmUserPanel *self)
4342+cc_user_panel_init (CcUserPanel *self)
4343 {
4344- UmUserPanelPrivate *d;
4345+ CcUserPanelPrivate *d;
4346 GError *error;
4347 volatile GType type G_GNUC_UNUSED;
4348- const gchar *filename;
4349 GtkWidget *button;
4350 GtkStyleContext *context;
4351 GSettingsSchema *schema;
4352
4353 d = self->priv = UM_USER_PANEL_PRIVATE (self);
4354+ g_resources_register (um_get_resource ());
4355
4356 /* register types that the builder might need */
4357 type = um_editable_button_get_type ();
4358@@ -1318,25 +1449,24 @@
4359 gtk_widget_set_size_request (GTK_WIDGET (self), -1, 350);
4360
4361 d->builder = gtk_builder_new ();
4362- d->um = um_user_manager_ref_default ();
4363+ d->um = act_user_manager_get_default ();
4364
4365- filename = UIDIR "/user-accounts-dialog.ui";
4366- if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
4367- filename = "data/user-accounts-dialog.ui";
4368- }
4369 error = NULL;
4370- if (!gtk_builder_add_from_file (d->builder, filename, &error)) {
4371+ if (!gtk_builder_add_from_resource (d->builder,
4372+ "/org/gnome/control-center/user-accounts/user-accounts-dialog.ui",
4373+ &error)) {
4374 g_error ("%s", error->message);
4375 g_error_free (error);
4376 return;
4377 }
4378
4379- setup_main_window (d);
4380 d->password_dialog = um_password_dialog_new ();
4381 button = get_widget (d, "user-icon-button");
4382 d->photo_dialog = um_photo_dialog_new (button);
4383 d->main_box = get_widget (d, "accounts-vbox");
4384 gtk_widget_reparent (d->main_box, GTK_WIDGET (self));
4385+ d->history_dialog = um_history_dialog_new ();
4386+ setup_main_window (d);
4387
4388 context = gtk_widget_get_style_context (get_widget (d, "list-scrolledwindow"));
4389 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
4390@@ -1352,12 +1482,12 @@
4391 }
4392
4393 static void
4394-um_user_panel_dispose (GObject *object)
4395+cc_user_panel_dispose (GObject *object)
4396 {
4397- UmUserPanelPrivate *priv = UM_USER_PANEL (object)->priv;
4398+ CcUserPanelPrivate *priv = UM_USER_PANEL (object)->priv;
4399
4400 if (priv->um) {
4401- g_object_unref (priv->um);
4402+ g_signal_handlers_disconnect_by_data (priv->um, priv);
4403 priv->um = NULL;
4404 }
4405 if (priv->builder) {
4406@@ -1372,6 +1502,14 @@
4407 um_photo_dialog_free (priv->photo_dialog);
4408 priv->photo_dialog = NULL;
4409 }
4410+ if (priv->history_dialog) {
4411+ um_history_dialog_free (priv->history_dialog);
4412+ priv->history_dialog = NULL;
4413+ }
4414+ if (priv->account_dialog) {
4415+ gtk_dialog_response (GTK_DIALOG (priv->account_dialog), GTK_RESPONSE_DELETE_EVENT);
4416+ priv->account_dialog = NULL;
4417+ }
4418 if (priv->language_chooser) {
4419 gtk_widget_destroy (priv->language_chooser);
4420 priv->language_chooser = NULL;
4421@@ -1380,19 +1518,23 @@
4422 g_object_unref (priv->permission);
4423 priv->permission = NULL;
4424 }
4425- G_OBJECT_CLASS (um_user_panel_parent_class)->dispose (object);
4426+ if (priv->other_iter) {
4427+ gtk_tree_iter_free (priv->other_iter);
4428+ priv->other_iter = NULL;
4429+ }
4430+ G_OBJECT_CLASS (cc_user_panel_parent_class)->dispose (object);
4431 }
4432
4433 static GPermission *
4434-um_user_panel_get_permission (CcPanel *panel)
4435+cc_user_panel_get_permission (CcPanel *panel)
4436 {
4437- UmUserPanelPrivate *priv = UM_USER_PANEL (panel)->priv;
4438+ CcUserPanelPrivate *priv = UM_USER_PANEL (panel)->priv;
4439
4440 return priv->permission;
4441 }
4442
4443 static const char *
4444-um_user_panel_get_help_uri (CcPanel *panel)
4445+cc_user_panel_get_help_uri (CcPanel *panel)
4446 {
4447 if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity"))
4448 return "help:ubuntu-help/user-accounts";
4449@@ -1401,23 +1543,23 @@
4450 }
4451
4452 static void
4453-um_user_panel_class_init (UmUserPanelClass *klass)
4454+cc_user_panel_class_init (CcUserPanelClass *klass)
4455 {
4456 GObjectClass *object_class = G_OBJECT_CLASS (klass);
4457 CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
4458
4459- object_class->dispose = um_user_panel_dispose;
4460-
4461- panel_class->get_permission = um_user_panel_get_permission;
4462- panel_class->get_help_uri = um_user_panel_get_help_uri;
4463-
4464- g_type_class_add_private (klass, sizeof (UmUserPanelPrivate));
4465+ object_class->dispose = cc_user_panel_dispose;
4466+
4467+ panel_class->get_permission = cc_user_panel_get_permission;
4468+ panel_class->get_help_uri = cc_user_panel_get_help_uri;
4469+
4470+ g_type_class_add_private (klass, sizeof (CcUserPanelPrivate));
4471 }
4472
4473 void
4474-um_user_panel_register (GIOModule *module)
4475+cc_user_panel_register (GIOModule *module)
4476 {
4477- um_user_panel_register_type (G_TYPE_MODULE (module));
4478+ cc_user_panel_register_type (G_TYPE_MODULE (module));
4479 g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
4480 UM_TYPE_USER_PANEL, "user-accounts", 0);
4481 }
4482
4483=== modified file 'panels/user-accounts/um-user-panel.h'
4484--- panels/user-accounts/um-user-panel.h 2012-09-06 23:07:09 +0000
4485+++ panels/user-accounts/um-user-panel.h 2014-02-24 09:46:44 +0000
4486@@ -26,33 +26,31 @@
4487
4488 G_BEGIN_DECLS
4489
4490-#define UM_TYPE_USER_PANEL um_user_panel_get_type()
4491+#define UM_TYPE_USER_PANEL cc_user_panel_get_type()
4492
4493-#define UM_USER_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_USER_PANEL, UmUserPanel))
4494-#define UM_USER_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_USER_PANEL, UmUserPanelClass))
4495+#define UM_USER_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_USER_PANEL, CcUserPanel))
4496+#define UM_USER_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_USER_PANEL, CcUserPanelClass))
4497 #define UM_IS_USER_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_USER_PANEL))
4498 #define UM_IS_USER_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_USER_PANEL))
4499-#define UM_USER_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_USER_PANEL, UmUserPanelClass))
4500-
4501-typedef struct _UmUserPanel UmUserPanel;
4502-typedef struct _UmUserPanelClass UmUserPanelClass;
4503-typedef struct _UmUserPanelPrivate UmUserPanelPrivate;
4504-
4505-struct _UmUserPanel
4506+#define UM_USER_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_USER_PANEL, CcUserPanelClass))
4507+
4508+typedef struct _CcUserPanel CcUserPanel;
4509+typedef struct _CcUserPanelClass CcUserPanelClass;
4510+typedef struct _CcUserPanelPrivate CcUserPanelPrivate;
4511+
4512+struct _CcUserPanel
4513 {
4514 CcPanel parent;
4515
4516- UmUserPanelPrivate *priv;
4517+ CcUserPanelPrivate *priv;
4518 };
4519
4520-struct _UmUserPanelClass
4521+struct _CcUserPanelClass
4522 {
4523 CcPanelClass parent_class;
4524 };
4525
4526-GType um_user_panel_get_type (void) G_GNUC_CONST;
4527-
4528-void um_user_panel_register (GIOModule *module);
4529+GType cc_user_panel_get_type (void) G_GNUC_CONST;
4530
4531 G_END_DECLS
4532
4533
4534=== removed file 'panels/user-accounts/um-user.c'
4535--- panels/user-accounts/um-user.c 2013-11-28 04:46:27 +0000
4536+++ panels/user-accounts/um-user.c 1970-01-01 00:00:00 +0000
4537@@ -1,991 +0,0 @@
4538-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4539- *
4540- * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
4541- * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
4542- * Copyright (C) 2009 Red Hat, Inc.
4543- *
4544- * This program is free software; you can redistribute it and/or modify
4545- * it under the terms of the GNU General Public License as published by
4546- * the Free Software Foundation; either version 2 of the License, or
4547- * (at your option) any later version.
4548- *
4549- * This program is distributed in the hope that it will be useful,
4550- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4551- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4552- * GNU General Public License for more details.
4553- *
4554- * You should have received a copy of the GNU General Public License
4555- * along with this program; if not, write to the Free Software
4556- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4557- */
4558-
4559-#define _XOPEN_SOURCE
4560-
4561-#include "config.h"
4562-
4563-#include <float.h>
4564-#include <string.h>
4565-#include <sys/types.h>
4566-#include <sys/stat.h>
4567-#include <unistd.h>
4568-
4569-#include <glib.h>
4570-#include <glib/gi18n.h>
4571-#include <glib/gstdio.h>
4572-#include <gio/gio.h>
4573-#include <gtk/gtk.h>
4574-
4575-#include <gio/gunixoutputstream.h>
4576-
4577-#include "um-user.h"
4578-#include "um-account-type.h"
4579-#include "um-utils.h"
4580-
4581-
4582- #define UM_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_USER, UmUserClass))
4583- #define UM_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_USER))
4584-#define UM_USER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), UM_TYPE_USER, UmUserClass))
4585-
4586-#define MAX_FILE_SIZE 65536
4587-
4588-typedef struct {
4589- uid_t uid;
4590- gchar *user_name;
4591- gchar *real_name;
4592- gint account_type;
4593- gint password_mode;
4594- gchar *password_hint;
4595- gchar *email;
4596- gchar *language;
4597- gchar *location;
4598- guint64 login_frequency;
4599- gchar *icon_file;
4600- gboolean locked;
4601- gboolean automatic_login;
4602- gboolean system_account;
4603- gboolean local_account;
4604-} UserProperties;
4605-
4606-static void
4607-user_properties_free (UserProperties *props)
4608-{
4609- g_free (props->user_name);
4610- g_free (props->real_name);
4611- g_free (props->password_hint);
4612- g_free (props->email);
4613- g_free (props->language);
4614- g_free (props->location);
4615- g_free (props->icon_file);
4616- g_free (props);
4617-}
4618-
4619-static UserProperties *
4620-user_properties_get (GDBusConnection *bus,
4621- const gchar *object_path)
4622-{
4623- GVariant *result;
4624- GVariantIter *iter;
4625- gchar *key;
4626- GVariant *value;
4627- UserProperties *props;
4628- GError *error = NULL;
4629-
4630- result = g_dbus_connection_call_sync (bus,
4631- "org.freedesktop.Accounts",
4632- object_path,
4633- "org.freedesktop.DBus.Properties",
4634- "GetAll",
4635- g_variant_new ("(s)", "org.freedesktop.Accounts.User"),
4636- G_VARIANT_TYPE ("(a{sv})"),
4637- G_DBUS_CALL_FLAGS_NONE,
4638- -1,
4639- NULL,
4640- &error);
4641- if (!result) {
4642- g_debug ("Error calling GetAll() when retrieving properties for %s: %s", object_path, error->message);
4643- g_error_free (error);
4644- return NULL;
4645- }
4646-
4647- /* Add some defaults that may not be received from some AccountsService versions */
4648- props = g_new0 (UserProperties, 1);
4649- props->local_account = TRUE;
4650-
4651- g_variant_get (result, "(a{sv})", &iter);
4652- while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
4653- if (strcmp (key, "Uid") == 0) {
4654- g_variant_get (value, "t", &props->uid);
4655- }
4656- else if (strcmp (key, "UserName") == 0) {
4657- g_variant_get (value, "s", &props->user_name);
4658- }
4659- else if (strcmp (key, "RealName") == 0) {
4660- g_variant_get (value, "s", &props->real_name);
4661- }
4662- else if (strcmp (key, "AccountType") == 0) {
4663- g_variant_get (value, "i", &props->account_type);
4664- }
4665- else if (strcmp (key, "Email") == 0) {
4666- g_variant_get (value, "s", &props->email);
4667- }
4668- else if (strcmp (key, "Language") == 0) {
4669- g_variant_get (value, "s", &props->language);
4670- }
4671- else if (strcmp (key, "Location") == 0) {
4672- g_variant_get (value, "s", &props->location);
4673- }
4674- else if (strcmp (key, "LoginFrequency") == 0) {
4675- g_variant_get (value, "t", &props->login_frequency);
4676- }
4677- else if (strcmp (key, "IconFile") == 0) {
4678- g_variant_get (value, "s", &props->icon_file);
4679- }
4680- else if (strcmp (key, "Locked") == 0) {
4681- g_variant_get (value, "b", &props->locked);
4682- }
4683- else if (strcmp (key, "AutomaticLogin") == 0) {
4684- g_variant_get (value, "b", &props->automatic_login);
4685- }
4686- else if (strcmp (key, "SystemAccount") == 0) {
4687- g_variant_get (value, "b", &props->system_account);
4688- }
4689- else if (strcmp (key, "LocalAccount") == 0) {
4690- g_variant_get (value, "b", &props->local_account);
4691- }
4692- else if (strcmp (key, "PasswordMode") == 0) {
4693- g_variant_get (value, "i", &props->password_mode);
4694- }
4695- else if (strcmp (key, "PasswordHint") == 0) {
4696- g_variant_get (value, "s", &props->password_hint);
4697- }
4698- else if (strcmp (key, "HomeDirectory") == 0) {
4699- /* ignore */
4700- }
4701- else if (strcmp (key, "Shell") == 0) {
4702- /* ignore */
4703- }
4704- else {
4705- g_debug ("unhandled property %s", key);
4706- }
4707- }
4708-
4709- g_variant_iter_free (iter);
4710- g_variant_unref (result);
4711-
4712- return props;
4713-}
4714-
4715-
4716-struct _UmUser {
4717- GObject parent;
4718-
4719- GDBusConnection *bus;
4720- GDBusProxy *proxy;
4721- gchar *object_path;
4722-
4723- UserProperties *props;
4724-
4725- gchar *display_name;
4726-};
4727-
4728-typedef struct _UmUserClass
4729-{
4730- GObjectClass parent_class;
4731-} UmUserClass;
4732-
4733-enum {
4734- CHANGED,
4735- LAST_SIGNAL
4736-};
4737-
4738-static guint signals[LAST_SIGNAL] = { 0 };
4739-
4740-static void um_user_finalize (GObject *object);
4741-
4742-G_DEFINE_TYPE (UmUser, um_user, G_TYPE_OBJECT)
4743-
4744-static void
4745-um_user_class_init (UmUserClass *class)
4746-{
4747- GObjectClass *gobject_class;
4748-
4749- gobject_class = G_OBJECT_CLASS (class);
4750-
4751- gobject_class->finalize = um_user_finalize;
4752-
4753- signals[CHANGED] = g_signal_new ("changed",
4754- G_TYPE_FROM_CLASS (class),
4755- G_SIGNAL_RUN_LAST,
4756- 0,
4757- NULL, NULL,
4758- g_cclosure_marshal_VOID__VOID,
4759- G_TYPE_NONE, 0);
4760-}
4761-
4762-
4763-static void
4764-um_user_init (UmUser *user)
4765-{
4766-}
4767-
4768-static void
4769-um_user_finalize (GObject *object)
4770-{
4771- UmUser *user;
4772-
4773- user = UM_USER (object);
4774-
4775- g_free (user->display_name);
4776-
4777- g_object_unref (user->bus);
4778- g_free (user->object_path);
4779-
4780- if (user->proxy != NULL)
4781- g_object_unref (user->proxy);
4782-
4783- if (user->props != NULL)
4784- user_properties_free (user->props);
4785-
4786- (*G_OBJECT_CLASS (um_user_parent_class)->finalize) (object);
4787-}
4788-
4789-uid_t
4790-um_user_get_uid (UmUser *user)
4791-{
4792- g_return_val_if_fail (UM_IS_USER (user), -1);
4793-
4794- return user->props->uid;
4795-}
4796-
4797-const gchar *
4798-um_user_get_real_name (UmUser *user)
4799-{
4800- g_return_val_if_fail (UM_IS_USER (user), NULL);
4801-
4802- return user->props->real_name;
4803-}
4804-
4805-const gchar *
4806-um_user_get_display_name (UmUser *user)
4807-{
4808- g_return_val_if_fail (UM_IS_USER (user), NULL);
4809-
4810- if (user->display_name)
4811- return user->display_name;
4812- if (user->props->real_name &&
4813- *user->props->real_name != '\0')
4814- return user->props->real_name;
4815-
4816- return user->props->user_name;
4817-}
4818-
4819-const gchar *
4820-um_user_get_user_name (UmUser *user)
4821-{
4822- g_return_val_if_fail (UM_IS_USER (user), NULL);
4823-
4824- return user->props->user_name;
4825-}
4826-
4827-gint
4828-um_user_get_account_type (UmUser *user)
4829-{
4830- g_return_val_if_fail (UM_IS_USER (user), UM_ACCOUNT_TYPE_STANDARD);
4831-
4832- return user->props->account_type;
4833-}
4834-
4835-gulong
4836-um_user_get_login_frequency (UmUser *user)
4837-{
4838- g_return_val_if_fail (UM_IS_USER (user), 0);
4839-
4840- return user->props->login_frequency;
4841-}
4842-
4843-gint
4844-um_user_collate (UmUser *user1,
4845- UmUser *user2)
4846-{
4847- const char *str1;
4848- const char *str2;
4849- gulong num1;
4850- gulong num2;
4851-
4852- g_return_val_if_fail (UM_IS_USER (user1), 0);
4853- g_return_val_if_fail (UM_IS_USER (user2), 0);
4854-
4855- num1 = user1->props->login_frequency;
4856- num2 = user2->props->login_frequency;
4857- if (num1 > num2) {
4858- return -1;
4859- }
4860-
4861- if (num1 < num2) {
4862- return 1;
4863- }
4864-
4865- /* if login frequency is equal try names */
4866- if (user1->props->real_name != NULL) {
4867- str1 = user1->props->real_name;
4868- } else {
4869- str1 = user1->props->user_name;
4870- }
4871-
4872- if (user2->props->real_name != NULL) {
4873- str2 = user2->props->real_name;
4874- } else {
4875- str2 = user2->props->user_name;
4876- }
4877-
4878- if (str1 == NULL && str2 != NULL) {
4879- return -1;
4880- }
4881-
4882- if (str1 != NULL && str2 == NULL) {
4883- return 1;
4884- }
4885-
4886- if (str1 == NULL && str2 == NULL) {
4887- return 0;
4888- }
4889-
4890- return g_utf8_collate (str1, str2);
4891-}
4892-
4893-static gboolean
4894-check_user_file (const char *filename,
4895- gssize max_file_size)
4896-{
4897- struct stat fileinfo;
4898-
4899- if (max_file_size < 0) {
4900- max_file_size = G_MAXSIZE;
4901- }
4902-
4903- /* Exists/Readable? */
4904- if (stat (filename, &fileinfo) < 0) {
4905- g_debug ("File does not exist");
4906- return FALSE;
4907- }
4908-
4909- /* Is a regular file */
4910- if (G_UNLIKELY (!S_ISREG (fileinfo.st_mode))) {
4911- g_debug ("File is not a regular file");
4912- return FALSE;
4913- }
4914-
4915- /* Size is kosher? */
4916- if (G_UNLIKELY (fileinfo.st_size > max_file_size)) {
4917- g_debug ("File is too large");
4918- return FALSE;
4919- }
4920-
4921- return TRUE;
4922-}
4923-
4924-static GdkPixbuf *
4925-frame_pixbuf (GdkPixbuf *source)
4926-{
4927- GdkPixbuf *dest;
4928- cairo_t *cr;
4929- cairo_surface_t *surface;
4930- guint w;
4931- guint h;
4932- int frame_width;
4933- double radius;
4934-
4935- frame_width = 2;
4936-
4937- w = gdk_pixbuf_get_width (source) + frame_width * 2;
4938- h = gdk_pixbuf_get_height (source) + frame_width * 2;
4939- radius = w / 10;
4940-
4941- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
4942- w, h);
4943- cr = cairo_create (surface);
4944- cairo_surface_destroy (surface);
4945-
4946- /* set up image */
4947- cairo_rectangle (cr, 0, 0, w, h);
4948- cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
4949- cairo_fill (cr);
4950-
4951- rounded_rectangle (cr, 1.0, 0.5, 0.5, radius, w - 1, h - 1);
4952- cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3);
4953- cairo_fill_preserve (cr);
4954-
4955- gdk_cairo_set_source_pixbuf (cr, source, frame_width, frame_width);
4956- cairo_fill (cr);
4957-
4958- dest = gdk_pixbuf_get_from_surface (surface, 0, 0, w, h);
4959-
4960- cairo_destroy (cr);
4961-
4962- return dest;
4963-}
4964-
4965-GdkPixbuf *
4966-um_user_render_icon (UmUser *user,
4967- gboolean with_frame,
4968- gint icon_size)
4969-{
4970- GdkPixbuf *pixbuf;
4971- GdkPixbuf *framed;
4972- gboolean res;
4973- GError *error;
4974-
4975- g_return_val_if_fail (UM_IS_USER (user), NULL);
4976- g_return_val_if_fail (icon_size > 12, NULL);
4977-
4978- pixbuf = NULL;
4979- if (user->props->icon_file) {
4980- res = check_user_file (user->props->icon_file,
4981- MAX_FILE_SIZE);
4982- if (res) {
4983- pixbuf = gdk_pixbuf_new_from_file_at_size (user->props->icon_file,
4984- icon_size,
4985- icon_size,
4986- NULL);
4987- }
4988- else {
4989- pixbuf = NULL;
4990- }
4991- }
4992-
4993- if (pixbuf != NULL) {
4994- goto out;
4995- }
4996-
4997- error = NULL;
4998- pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
4999-
5000- "avatar-default",
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches