Compare commits
4 Commits
2.91.6
...
opensuse-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c23c92b069 | ||
|
|
acb0b4725f | ||
|
|
6677c366a8 | ||
|
|
97b42a7ccf |
23
Makefile.am
@@ -1,11 +1,16 @@
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
SUBDIRS = po libwindow-settings capplets font-viewer help
|
||||
DIST_SUBDIRS = po libwindow-settings capplets font-viewer help libslab shell typing-break
|
||||
|
||||
SUBDIRS = po libgnome-control-center shell panels \
|
||||
help docs
|
||||
DIST_SUBDIRS = po help shell docs examples panels libgnome-control-center
|
||||
if HAVE_LIBSLAB_DEPS
|
||||
SUBDIRS += libslab
|
||||
endif
|
||||
|
||||
if BUILD_EXAMPLES
|
||||
SUBDIRS += examples
|
||||
if HAVE_LIBSLAB
|
||||
SUBDIRS += shell
|
||||
endif
|
||||
|
||||
if HAVE_TYPING_BREAK
|
||||
SUBDIRS += typing-break
|
||||
endif
|
||||
|
||||
schemasdir = @GCONF_SCHEMA_FILE_DIR@
|
||||
@@ -13,6 +18,8 @@ schemas_in_files = gnome-control-center.schemas.in
|
||||
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
||||
@INTLTOOL_SCHEMAS_RULE@
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
CLEANFILES = \
|
||||
$(schemas_DATA)
|
||||
|
||||
@@ -43,9 +50,9 @@ EXTRA_DIST = \
|
||||
MAINTAINERS \
|
||||
gnome-doc-utils.make
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --disable-scrollkeeper --disable-update-mimedb --enable-gtk-doc --enable-examples
|
||||
DISTCHECK_CONFIGURE_FLAGS = --disable-scrollkeeper --disable-update-mimedb
|
||||
|
||||
GITIGNOREFILES=m4 help/*/*.mo
|
||||
GITIGNOREFILES=m4
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
||||
|
||||
947
NEWS
@@ -1,950 +1,3 @@
|
||||
=============================
|
||||
Version 2.91.6 (2011-02-01)
|
||||
=============================
|
||||
|
||||
Info:
|
||||
- Read version from gnome-version.xml (William Jon McCann)
|
||||
- Don't show update button (William Jon McCann)
|
||||
- Show memory, processor, OS type, storage (William Jon McCann)
|
||||
- Make 64bit detection work reliably (Bastien Nocera)
|
||||
- Make labels translator friendly (Luca Ferretti, #640127)
|
||||
|
||||
Keyboard:
|
||||
- Make shortcuts tab look closer to mockup (William Jon McCann)
|
||||
- Avoid duplicate entries (Matthias Clasen)
|
||||
- Make custom shortcut editing work (Matthias Clasen)
|
||||
- Make custom shortcut dialog non-resizable (Matthias Clasen)
|
||||
- Make scales work (Matthias Clasen)
|
||||
|
||||
Date & Time:
|
||||
- Fix splitting of region strings (Matthias Clasen)
|
||||
- Prevent the panel from growing horizontally (Matthias Clasen)
|
||||
- Add an unlock button (Thomas Wood)
|
||||
|
||||
Default applications:
|
||||
- Removed (William Jon McCann)
|
||||
|
||||
Display:
|
||||
- Hide unsupported size (Bastien Nocera)
|
||||
- Rename rotation options (Bastien Nocera, #563144)
|
||||
|
||||
Media:
|
||||
- Remove icons from non-applications (William Jon McCann, #640010)
|
||||
- Use consistent capitalization (William Jon McCann)
|
||||
- Make 'Other' work more than once (Matthias Clasen)
|
||||
- Remove erroneous quotes (Matthias Clasen)
|
||||
- Improve strings (Matthias Clasen)
|
||||
|
||||
Mouse:
|
||||
- Change tab label to 'Mouse' (William Jon McCann, #639787)
|
||||
- Remove a11y tab (William Jon McCann)
|
||||
|
||||
Network:
|
||||
- Use a better icon (Matthias Clasen)
|
||||
- Use toolbar for source list buttons (William Jon McCann)
|
||||
|
||||
Power:
|
||||
- Make strings translator friendly (Richard Hughes, #640119)
|
||||
|
||||
Printers:
|
||||
- New panel (Marek Kasik)
|
||||
|
||||
Region:
|
||||
- Sort lists (Sergey V. Udaltsov)
|
||||
- Fix infinite loop (Bastien Nocera, #639951)
|
||||
- Remove mouse keys tab and various other cleanups (Bastien Nocera)
|
||||
- Set parents on all dialogs (Bastien Nocera)
|
||||
- Add a language tab (Bastien Nocera)
|
||||
- Share language code with the user accounts panel (Bastien Nocera)
|
||||
- Make language selection work (Bastien Nocera)
|
||||
- Tweak the layout of to the layout tab (Bastien Nocera)
|
||||
- Remove keyboard model selection (Bastien Nocera)
|
||||
- Remove Help buttons (Bastien Nocera)
|
||||
|
||||
Screen:
|
||||
- Use a switch widget (William Jon McCann)
|
||||
- Hide unimplemented Location UI (William Jon McCann)
|
||||
|
||||
Sound:
|
||||
- Fix an assertion (Alban Browaeys, #639280)
|
||||
- Add close button to speaker test (Matthias Clasen, #636898)
|
||||
|
||||
Shell:
|
||||
- Start in overview (Dan Winship, #639180)
|
||||
- Reload icons on theme change (Bastien Nocera, #639268)
|
||||
- Avoid windows with no icons (Bastien Nocera)
|
||||
|
||||
Universal Access:
|
||||
- Make test size control work (Matthias Clasen)
|
||||
- Make 'Sound Settings' button work (Matthias Clasen)
|
||||
- Remove 'Show Panel Icon' checkbox (Matthias Clasen)
|
||||
|
||||
User Accounts:
|
||||
- Sync language code with gdm (Bastien Nocera)
|
||||
- Fix lifecycle issues with the language chooser (Bastien Nocera)
|
||||
- Make fingerprint dialog work better with the shell (Matthias Clasen)
|
||||
- Use toolbar for list buttons (William Jon McCann)
|
||||
- Remove unused UI elements: email, location (William Jon McCann)
|
||||
- Remove Login tab and move autologin (William Jon McCann)
|
||||
- Improve dropdown arrow drawing (Matthias Clasen)
|
||||
- Improve password strengh bar drawing (Matthias Clasen)
|
||||
|
||||
Translation updates:
|
||||
Arabic
|
||||
Estonian
|
||||
Galician
|
||||
Greek
|
||||
Hebrew
|
||||
Italian
|
||||
Norwegian bokmål
|
||||
Punjabi
|
||||
Simplified Chinese
|
||||
Spanish
|
||||
Traditional Chinese
|
||||
Ukrainian
|
||||
|
||||
|
||||
=============================
|
||||
Version 2.91.5 (2010-12-22)
|
||||
=============================
|
||||
|
||||
Common:
|
||||
- Fix 2 typos (Andre Klapper) (#637527)
|
||||
- Require gnome-settings-daemon >= 2.91 (Rodrigo Moya)
|
||||
- Bump libgnomekbd requirement (Rodrigo Moya)
|
||||
- Adapt to new gnome-desktop API (Giovanni Campagna)
|
||||
|
||||
Datetime:
|
||||
- Fix layout and spacing to match mockups (William Jon McCann)
|
||||
- Use a switch for 24 hour time (William Jon McCann)
|
||||
- Keep the time ticking while the dialog is up (William Jon McCann)
|
||||
- Make dialog instant apply (William Jon McCann)
|
||||
- Don't try to set timezone when initially loading model (William Jon McCann)
|
||||
|
||||
Sound:
|
||||
- Do not build with $DISABLE_DEPRECATED (Vincent Untz)
|
||||
- Don't set update policy (Benjamin Otte)
|
||||
|
||||
Translations:
|
||||
- de (Mario Blättermann)
|
||||
- es (Jorge Gonzalez)
|
||||
- et (Ivar Smolin)
|
||||
- gl (Fran Diéguez)
|
||||
- he (Yaron Shahrabani)
|
||||
- nb (Torstein Adolf Winterseth)
|
||||
- pa (A S Alam)
|
||||
- sl (Matej Urbančič)
|
||||
- sv (Daniel Nylander)
|
||||
- vi (Nguyễn Thái Ngọc Duy)
|
||||
|
||||
=============================
|
||||
Version 2.91.3.1 (2010-12-22)
|
||||
=============================
|
||||
|
||||
Shell:
|
||||
- Fix initial window size (Matthias Clasen)
|
||||
- Drop 'Internet & Network' category (Thomas Wood)
|
||||
- Only show panels, not old-style capplets (Thomas)
|
||||
|
||||
Universal access:
|
||||
- Migrate to GSettings (Rodrigo Moya)
|
||||
|
||||
Display:
|
||||
- Use switch (Bastien Nocera)
|
||||
- Fix sizing issues (Thomas)
|
||||
|
||||
Media:
|
||||
- Use GtkAppChooserButton (Cosimo Cecchi)
|
||||
|
||||
Mouse:
|
||||
- Detect touchpads (Bastien)
|
||||
|
||||
Keyboard
|
||||
- Shortcuts UI improvements (Rodrigo)
|
||||
|
||||
Datetime:
|
||||
- Multiple UI improvements (Bastien)
|
||||
- Implement 12h setting (Bastien)
|
||||
- Add NTP support (Bastien)
|
||||
|
||||
Network:
|
||||
- Initial prototype (Richard Hughes)
|
||||
- Remove the old proxy panel (William Jon McCann)
|
||||
|
||||
Background:
|
||||
- Load asynchronously (Bastien)
|
||||
- Support gradients (Bastien)
|
||||
- Multiple UI improvements (Bastien)
|
||||
|
||||
System Information:
|
||||
- Initial prototype (William Jon McCann)
|
||||
|
||||
=============================
|
||||
Version 2.91.3.1 (2010-11-30)
|
||||
=============================
|
||||
|
||||
Common:
|
||||
- Add missing libraries for linking (Rodrigo Moya)
|
||||
|
||||
Display:
|
||||
- Fix run-time warning (Bastien Nocera)
|
||||
|
||||
Media:
|
||||
- Use the correct schema name (Cosimo Cecchi)
|
||||
|
||||
===========================
|
||||
Version 2.91.3 (2010-11-29)
|
||||
===========================
|
||||
|
||||
Background:
|
||||
- One last old gnome_bg remnant (Yanko Kaneti)
|
||||
- Load wallpapers in an idle (William Jon McCann)
|
||||
|
||||
Common:
|
||||
- Fix build for latest gnome-desktop changes (Andreas Proschofsky) (#634859)
|
||||
- Some build fixes (Rodrigo Moya)
|
||||
- Update to GTK+ api changes (Matthias Clasen)
|
||||
- Add keywords to desktop files (Matthias Clasen, Bastien Nocera) (#399754)
|
||||
|
||||
Datetime:
|
||||
- Add missing libraries to libdate_time_la_LIBADD (Rodrigo Moya)
|
||||
- Implement 12/24 hour preferences for the gnome-shell clock (Thomas Wood)
|
||||
|
||||
Default applications:
|
||||
- Remove web browsers and mail readers from XML file (Rodrigo Moya)
|
||||
|
||||
Display:
|
||||
- Remove refresh rate setting (William Jon McCann)
|
||||
- Don't list the resolution in the arrangement box (William Jon McCann)
|
||||
- Indicate the selected display using an outside stroke (William Jon McCann)
|
||||
- Remove unhelpful Monitor: label (William Jon McCann)
|
||||
- Make layout not jump around when selecting monitors (William Jon McCann)
|
||||
- Remove the primary display checkbox (William Jon McCann)
|
||||
- Just say no to tabs and trailing whitespace (William Jon McCann)
|
||||
- Use consistent indentation and spacing (William Jon McCann)
|
||||
- Identify primary display with a black top bar and clock (William Jon McCann)
|
||||
- Allow dragging top bar to set primary display (William Jon McCann)
|
||||
- Use a smaller top bar size (William Jon McCann)
|
||||
- Ensure primary display is set in config (William Jon McCann)
|
||||
- Don't allow setting primary on off displays (William Jon McCann)
|
||||
- Add a save/restore to ensure the labels don't mess up top bar (William Jon McCann)
|
||||
|
||||
Keyboard:
|
||||
- Fix possible accel blocking (Bastien Nocera)
|
||||
|
||||
Media:
|
||||
- Initial port of Nautilus capplet code (Cosimo Cecchi)
|
||||
|
||||
Mouse:
|
||||
- Use a smiley face instead of old ugly lightbulb to test click (William Jon McCann)
|
||||
- Don't force wrapping the label at 180px (William Jon McCann)
|
||||
- Remove dead a11y code (Bastien Nocera)
|
||||
|
||||
Network:
|
||||
- Avoid run-time warnings (Bastien Nocera)
|
||||
|
||||
Power:
|
||||
- Add the first cut of the UI of the power panel, based on a mockup by Alan Day
|
||||
(Richard Hughes)
|
||||
|
||||
Region:
|
||||
- Link against libxklavier also (Didier Roche)
|
||||
|
||||
Screen:
|
||||
- Add screen brightness and lock panel (William Jon McCann)
|
||||
- Improve label for dim checkbox (William Jon McCann)
|
||||
- Connect up the brightness slider and the dim checkbox with gnome-power-manager
|
||||
(Richard Hughes)
|
||||
|
||||
Shell:
|
||||
- Subtract a hacky constant from the screen height for dialog height (William
|
||||
Jon McCann)
|
||||
- Don't change casedness when displaying matches (Matthias Clasen)
|
||||
- Add keyword search (Matthias Clasen)
|
||||
- Start in the right size (Matthias Clasen)
|
||||
- Ensure the background and foreground colours are consistent (Thomas Wood)
|
||||
|
||||
Sound:
|
||||
- Explicit link to libxml (Yanko Kaneti)
|
||||
- Don't allow long profile names to resize toplevel (Bastien Nocera) (#613040)
|
||||
- Replace size_request by get_preferred_width/height (Javier Jardón) (#635117)
|
||||
- Avoid second warning when no theme (Bastien Nocera)
|
||||
- Simplify check_rectangle() macro (Bastien Nocera)
|
||||
- Make level bar descend from GtkWidget (Bastien Nocera)
|
||||
- Show icons for devices (Bastien Nocera)
|
||||
- Remove radio buttons (Bastien Nocera)
|
||||
- Avoid initial resizing (Matthias Clasen)
|
||||
- Remove theme selection (William Jon McCann)
|
||||
- Remove window and button sounds checkbox (William Jon McCann)
|
||||
|
||||
Universal access:
|
||||
- Remove relation with inexistant widget (Bastien Nocera)
|
||||
- Remove an unused frame that added a few extra px of spacing (William Jon McCann)
|
||||
|
||||
User accounts:
|
||||
- Listen for permission changes (Matthias Clasen)
|
||||
- Fix a little annoyance with combo boxes (Matthias Clasen)
|
||||
- Don't show parental controls for now (Matthias Clasen)
|
||||
- Fix packing of the language dialog (Matthias Clasen)
|
||||
- Don't allow opening non-images (Bastien Nocera)
|
||||
- Add "Disable icon" menu item (Bastien Nocera)
|
||||
- Link against missing libraries (Rodrigo Moya)
|
||||
|
||||
Translations:
|
||||
- es (Jorge González)
|
||||
- gl (Fran Diéguez)
|
||||
- he (Yaron Shahrabani)
|
||||
- nb (Kjartan Maraas)
|
||||
- pa (A S Alam)
|
||||
- ro (Cătălin Bălan)
|
||||
- ta (Dr.T.Vasudevan)
|
||||
- ug (Gheyret T.Kenji)
|
||||
- zh_CN (Aron Xu)
|
||||
|
||||
===========================
|
||||
Version 2.91.2 (2010-11-08)
|
||||
===========================
|
||||
|
||||
Common:
|
||||
- Remove typing break (William Jon McCann)
|
||||
- Build against libxml where appropriate (Matthias Clasen)
|
||||
- Fix parallel building (Bastien Nocera)
|
||||
- Remove unnneded lines in autogen.sh (Javier Jardón)
|
||||
- Use GSourceFunc() instead GtkFunction() in g_timeout_add() (Javier Jardón)
|
||||
- Bump gtk3 dep to 2.91.3 for box, etc changes (William Jon McCann)
|
||||
- Prepare for size_request removal in GTK3 (Matthias Clasen) (#633321)
|
||||
|
||||
Background:
|
||||
- Make flickr background setting not segfault (Cosimo Cecchi)
|
||||
- Migrate to GSettings (Rodrigo Moya)
|
||||
- Last bits of new gnome_bg API porting (Tomas Bzatek) (#625899)
|
||||
|
||||
Datetime:
|
||||
- Start implementing new UI designs (Thomas Wood)
|
||||
- Move to system section (William Jon McCann)
|
||||
- Link test program against common libs (Rodrigo Moya)
|
||||
|
||||
Default applications:
|
||||
- Use URL handlers for browser and mailer applications (Rodrigo Moya)
|
||||
- Remove selection of media player (Rodrigo Moya)
|
||||
- Migrate to GSettings (Rodrigo Moya)
|
||||
- Fix run-time warning (Bastien Nocera)
|
||||
|
||||
Display:
|
||||
- Reorganise according to mockups (Bastien Nocera)
|
||||
- Show the resolution in the canvas area (Bastien Nocera)
|
||||
- Remove excess cairo_save() call (Benjamin Otte)
|
||||
- Simplify the layout of the display panel (William Jon McCann)
|
||||
- Readd the checkbox to set primary display (William Jon McCann)
|
||||
- Remove the system-wide setting helper (William Jon McCann)
|
||||
- Make the canvas background color a bit more neutral (William Jon McCann)
|
||||
- Migrate to GSettings (Rodrigo Moya)
|
||||
- Port FooScrollArea to GtkScrollable iface (Bastien Nocera)
|
||||
- Change panel name to Displays (William Jon McCann)
|
||||
- Show aspect ratios with resolutions (Kees Cook)
|
||||
|
||||
Keyboard:
|
||||
- Rename keybindings to keyboard (William Jon McCann)
|
||||
- Move general settings into keyboard panel (William Jon McCann)
|
||||
|
||||
Mouse:
|
||||
- Use new GDK error trap API (Cosimo Cecchi)
|
||||
- Require libXInput (Bastien Nocera)
|
||||
- Migrate to GSettings (Rodrigo Moya)
|
||||
- Add motion acceleration and threshold UI for touchpad settings (Rodrigo Moya)
|
||||
- Don't expand Mouse notebook vertically (William Jon McCann)
|
||||
- Enable 2-finger scrolling through emulation (Chris Bagwell) (#625163)
|
||||
|
||||
Network:
|
||||
- Fix for GtkCombo text changes (Bastien Nocera)
|
||||
- Remove 'has-separator' properties (Bastien Nocera)
|
||||
- Partially migrate to GSettings (Rodrigo Moya)
|
||||
|
||||
Region:
|
||||
- Renamed from 'Keyboard' (William Jon McCann)
|
||||
- Migrate to GSettings (Sergey V. Udaltsov, Rodrigo Moya)
|
||||
- Remove calls to gtk_widget_hide_all() (Bastien Nocera)
|
||||
- Fix warnings with cell renderer changes (Bastien Nocera)
|
||||
- Don't expand vertically on general tab (William Jon McCann)
|
||||
- Remove a11y stuff (William Jon McCann)
|
||||
- Several renaming fixes (Yanko Kaneti)
|
||||
|
||||
Shell:
|
||||
- Handle GtkSizeRequest removal (Bastien Nocera)
|
||||
- Make sure the shell doesn't show up in itself (Bastien Nocera)
|
||||
- Make it build and work against new GApplication (Bastien Nocera)
|
||||
- Fix warning in search renderer (Bastien Nocera)
|
||||
- Tighten up the spacing of the category views (William Jon McCann)
|
||||
- Do a better job of automatically sizing the window to fit contents (William Jon McCann)
|
||||
- Don't use window before it is realized (William Jon McCann)
|
||||
- Add a get_toplevel accessor to CcShell (Gerd Kohlberger) (#621940)
|
||||
|
||||
Sound:
|
||||
- Initial import of sound panel (William Jon McCann)
|
||||
|
||||
Universal access:
|
||||
- Use GSettings for GTK and icon theme settings (Rodrigo Moya)
|
||||
- Adjust for removal of GtkComboBoxEntry (Florian Müllner)
|
||||
- Move to system section (William Jon McCann)
|
||||
- Tweak the design of the panel (William Jon McCann)
|
||||
- Use the UI dir set in the Makefile.am (William Jon McCann)
|
||||
- Dial down the font size on Seeing a bit (William Jon McCann)
|
||||
|
||||
User accounts:
|
||||
- Add user-accounts dialog (William Jon McCann)
|
||||
- Adapt for gtk_box_new() API changes (Yanko Kaneti)
|
||||
- Fix endless loop in load_url_handlers (Yanko Kaneti)
|
||||
|
||||
Translations:
|
||||
- ca@valencia (Carles Ferrando)
|
||||
- es (Jorge González)
|
||||
- gl (Fran Diéguez)
|
||||
- he (Yaron Shahrabani)
|
||||
- ja (Yasumichi Akahoshi, Takayuki KUSANO)
|
||||
- ko (Changwoo Ryu)
|
||||
- nb (Kjartan Maraas)
|
||||
- pa (A S Alam)
|
||||
- sl (Andrej Žnidaršič, Matej Urbančič)
|
||||
- te (krishnababu k)
|
||||
- ug (Gheyret T.Kenji)
|
||||
|
||||
===========================
|
||||
Version 2.91.0 (2010-10-04)
|
||||
===========================
|
||||
|
||||
Common:
|
||||
- Remove unneeded dependency check for XCursor (Bastien Nocera)
|
||||
- Adapt to GtkObject removal in GTK3 (Javier Jardón)
|
||||
- Use gtk_widget_get_preferred_size() instead gtk_size_request_get_size() (Javier Jardón)
|
||||
- Use upstream gettext insstead the Glib one (Javier Jardón)
|
||||
- Update autotools configuration (Javier Jardón)
|
||||
|
||||
Background:
|
||||
- Come up with 'Wallpapers' selected and displayed (Kalev Lember) (#630417)
|
||||
|
||||
Datetime:
|
||||
- Add required includes to tz.h (Bastien Nocera)
|
||||
- Add test application for missing TZ pixmaps (Bastien Nocera) (#630261)
|
||||
- Fix automake warning (Bastien Nocera)
|
||||
|
||||
Default applications:
|
||||
- Remove Opera from default browser choices (Bastien Nocera) (#627733)
|
||||
|
||||
Keyboard:
|
||||
- Updated for the latest libgnomekbd API (Sergey V. Udaltsov)
|
||||
|
||||
Mouse:
|
||||
- Rename to "Mouse and Touchpad" (Bastien Nocera)
|
||||
- Remove unneeded XCursor include (Bastien Nocera)
|
||||
|
||||
Shell:
|
||||
- Make search entry single-iconed (Bastien Nocera)
|
||||
- Show settings without a panel in Other (Bastien Nocera) (#630998)
|
||||
- Drop font viewer (William Jon McCann)
|
||||
- Wait until the toplevel is realized before using it (William Jon McCann) (#631051)
|
||||
- Update for new GTK3 drawing APIs (William Jon McCann)
|
||||
- Fix .desktop file to work correctly in gnome-shell (William Jon McCann)
|
||||
|
||||
Universal access:
|
||||
- Fix desktop file (Bastien Nocera)
|
||||
|
||||
Translations:
|
||||
- ca (Joan Duran)
|
||||
- cz (Petr Kovar)
|
||||
- eu (Inaki Larranaga Murgoitio)
|
||||
- ro (Lucian Adrian Grijincu)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.90.1 (2010-09-22)
|
||||
|
||||
- Add new background panel
|
||||
|
||||
Date and Time:
|
||||
- Draw a label on the timezone map when clicked
|
||||
- Add Region and City selection
|
||||
- Fix a number of memory leaks
|
||||
|
||||
Display:
|
||||
- Link display panel to dbus-glib
|
||||
- Add label to warn that "Same image in all monitors'
|
||||
may limit the resolution options"
|
||||
- Don't ignore errors from pkexec when using "Make default"
|
||||
|
||||
Default applications:
|
||||
- Fix possible crashers when themes are switched
|
||||
|
||||
Shell:
|
||||
- Resize shell to the size of the panel when panel is opened
|
||||
- Allow shrinking the shell, but use a fixed width
|
||||
- Use icon names as per specification
|
||||
- Free menu directory contents list
|
||||
|
||||
Font viewer:
|
||||
- Fix font preview not working
|
||||
|
||||
General:
|
||||
- Loads of GTK3 deprecation work
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.5 (2010-07-12)
|
||||
|
||||
Date and Time:
|
||||
- Add application icon (Thomas Wood, Lapo Calamandrei)
|
||||
- Remove "seconds" spin button (Thomas Wood)
|
||||
|
||||
Display:
|
||||
- Make sure the screen label is hidden when the panel is closed (Thomas Wood)
|
||||
|
||||
Shell:
|
||||
- Fix panel activation in existing running instance (Thomas Wood)
|
||||
|
||||
Universal Access:
|
||||
- Add size groups (Thomas Wood)
|
||||
|
||||
libgnome-control-center:
|
||||
- Derive CcPanel from GtkBin, rather than GtkAlignment (Thomas Wood)
|
||||
|
||||
General:
|
||||
- Don't build libwindow-settings (Thomas Wood)
|
||||
- Clean up configure.ac (Thomas Wood)
|
||||
- Remove capplets directory from build (Thomas Wood)
|
||||
- GVariant API adjustment: byte_array -> bytestring (Ryan Lortie)
|
||||
|
||||
Translations:
|
||||
- es (Jorge González)
|
||||
- gl (Fran Diéguez)
|
||||
- zh_CN (甘露(Gan Lu))
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.4.2 (2010-06-30)
|
||||
|
||||
Date and Time:
|
||||
- Work around a cairo bug that prevents the map being display correctly
|
||||
(Thomas Wood)
|
||||
- Install the UI files into the correct directory (Thomas Wood)
|
||||
|
||||
General:
|
||||
- Make build work with GSEAL (Jonh Wendell)
|
||||
- Fix compile with recent GTK versions (Richard Hughes)
|
||||
|
||||
Translations:
|
||||
- gl (Fran Diéguez)
|
||||
- he (Yaron Shahrabani)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.4.1 (2010-06-29)
|
||||
|
||||
Date and Time:
|
||||
- Fix memory leak (Thomas Wood)
|
||||
- Fix .desktop file Exec and use X-GNOME-Settings-Panel identifier (Thomas Wood)
|
||||
- Make sure DBus is included in the cflags and linked libraries (Thomas Wood)
|
||||
- Prevent crash when DBus service is not available (Thomas Wood)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.4 (2010-06-29)
|
||||
|
||||
General:
|
||||
- Updated to use GTK+ 3 (Rodrigo Moya, Richard Hughes, Bastien Nocera)
|
||||
|
||||
Date and Time:
|
||||
- New panel for configuring date and time settings (Thomas Wood)
|
||||
|
||||
Shell:
|
||||
- Switch to using GtkApplication rather than libunique (Richard Hughes)
|
||||
|
||||
libgnome-control-center:
|
||||
- Remove redundant properties from CcPanel (Thomas Wood)
|
||||
|
||||
Translations:
|
||||
- de (Mario Blättermann)
|
||||
- eo (Kristjan SCHMIDT)
|
||||
- es (Jorge González)
|
||||
- et (Ivar Smolin)
|
||||
- gl (Fran Diéguez)
|
||||
- hu (Gabor Kelemen)
|
||||
- id (Andika Triwidada)
|
||||
- nb (Kjartan Maraas)
|
||||
- pa (A S Alam)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.3 (2010-06-07)
|
||||
|
||||
About Me:
|
||||
- Catch error messages from passwd (#620135) (Bin Li)
|
||||
|
||||
Common:
|
||||
- Replace deprecated GTK+ symbols. (#572325) (Andre Klapper)
|
||||
|
||||
Display:
|
||||
- Convert to a settings panel (Thomas Wood)
|
||||
|
||||
Keyboard:
|
||||
- Change Print layout to Show layout (Sergey V. Udaltsov)
|
||||
|
||||
Shell:
|
||||
- Ensure padding around each embedded settings panel (Thomas Wood)
|
||||
- Set the window icon and title when opening a panel (Thomas Wood)
|
||||
- Improve keyboard navigation (Matthias Clasen)
|
||||
|
||||
Universal-Access:
|
||||
- Implement a new accessibility preferences panel
|
||||
(Thomas Wood, William Jon McCann)
|
||||
|
||||
General:
|
||||
- Make desktop file naming more consistent (Thomas Wood)
|
||||
- Add X-GNOME-Settings-Panel key to panel desktop files (Thomas Wood)
|
||||
- Make sure the Exec line is valid in panel desktop files (Thomas Wood)
|
||||
|
||||
Translations:
|
||||
- es (Jorge González)
|
||||
- et (Ivar Smolin)
|
||||
- gl (Fran Diéguez)
|
||||
- he (Yaron Shahrabani)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.2 (2010-05-24)
|
||||
|
||||
About Me:
|
||||
- Don't hang when new and old password are too similar (Milan Bouchet-Valat)
|
||||
(#619354)
|
||||
|
||||
Shell:
|
||||
- Add a new shell that supports embedded settings panels
|
||||
(Thomas Wood, William Jon McCann)
|
||||
|
||||
libgnome-control-center:
|
||||
- Add a new library that provides an API to create embedded settings panels for
|
||||
the new shell (Thomas Wood, William Jon McCann)
|
||||
|
||||
Mouse:
|
||||
- Convert to using the Panel API (Thomas Wood)
|
||||
|
||||
Keyboard:
|
||||
- Convert to using the Panel API (Sergey V. Udaltsov)
|
||||
|
||||
Network:
|
||||
- Convert to using the Panel API (Thomas Wood)
|
||||
|
||||
Default Applications:
|
||||
- Convert to using the Panel API (Thomas Wood)
|
||||
|
||||
Keybindings:
|
||||
- Convert to using the Panel API (Thomas Wood)
|
||||
|
||||
Windows:
|
||||
- Disable from build (Thomas Wood)
|
||||
|
||||
|
||||
Translations:
|
||||
- sl (Andrej Žnidaršič)
|
||||
- gl (Fran Diéguez)
|
||||
- or (Manoj Kumar Giri)
|
||||
- en@shaw (Thomas Thurman)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.31.1 (2010-05-05)
|
||||
|
||||
Common:
|
||||
- Use only single GTK+ includes (Javier Jardón) (#615292)
|
||||
- Remove GTK+ deprecated symbols (Javier Jardón) (#572325)
|
||||
|
||||
About me:
|
||||
- Don't hang when new and old password only differ in case (Milan Bouchet-Valat)
|
||||
- Minor string updates (Jens Granseuer) (#615283)
|
||||
- Use changes-prevent and changes-allow icons from the icon-them instead of
|
||||
the outdated lock-icons (Andreas Proschofsky) (#408585)
|
||||
- Use accessor functions instead direct access (Maxim Ermilov) (#597888)
|
||||
|
||||
Display:
|
||||
- Add a "Make Default" button in gnome-display-properties, which is used to
|
||||
set up a systemwide default RANDR configuration (Federico Mena Quintero)
|
||||
- Change icon name to preferences-desktop-display (Jens Granseuer) (#614912)
|
||||
|
||||
Keyboard:
|
||||
- Added tooltips (Sergey Udaltsov) (#615521)
|
||||
- Use new libgnomekbd function for default group switcher (Sergey Udaltsov)
|
||||
(#603806)
|
||||
- Proper response id for the help button (Sergey Udaltsov) (#616917)
|
||||
|
||||
Shell:
|
||||
- Fix issue with g-c-c shell and YaST shell having same unique identifier (Scott Reeves)
|
||||
|
||||
Typing break:
|
||||
- Add support for Ubuntu's app indicator (Travis B. Hartwell)
|
||||
|
||||
Translations:
|
||||
- ar (Khaled Hosny)
|
||||
- ast (Xandru Armesto)
|
||||
- ca@valencia (Carles Ferrando)
|
||||
- crh (Reşat SABIQ)
|
||||
- de (Mario Blättermann)
|
||||
- es (Jorge González)
|
||||
- et (Mattias Põldaru)
|
||||
- fr (Laurent Coudeur)
|
||||
- gl (Fran Diéguez)
|
||||
- gu (Sweta Kothari)
|
||||
- he (Marios Zindilis)
|
||||
- hy (Norayr Chilingaryan)
|
||||
- id (Andika Triwidada)
|
||||
- kn (Shankar Prasad)
|
||||
- lv (Peteris Krisjanis)
|
||||
- ml (Ani Peter)
|
||||
- mr (Sandeep Shedmake)
|
||||
- ms (Ahmed Noor Kader Mustajir Md Eusoff)
|
||||
- nb (Kjartan Maraas)
|
||||
- oc (Yannig Marchegay)
|
||||
- or (Manoj Kumar Giri)
|
||||
- sl (Matej Urbančič)
|
||||
- zh_CN (Funda Wang)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.30.0 (2010-03-25)
|
||||
|
||||
About me:
|
||||
- Fix global variable confusion (Michal Schmidt)
|
||||
- Fix remembering of data between runs (Michal Schmidt)
|
||||
|
||||
Appearance:
|
||||
- Mark a string for translation (Gabor Kelemen) (#612015)
|
||||
- Fix GTK+ multi-threading (Matthias Clasen) (#610003)
|
||||
|
||||
Display:
|
||||
- Don't show a tooltip while a monitor is being dragged (Federico Mena Quintero)
|
||||
|
||||
Typing break:
|
||||
- Lock all the screens (Matthias Clasen) (#492974)
|
||||
|
||||
Translations:
|
||||
- bg (Alexander Shopov)
|
||||
- bn (Jamil Ahmed)
|
||||
- ca (Joan Duran)
|
||||
- crh (Reşat SABIQ)
|
||||
- cz (Petr Kovar)
|
||||
- da (Ask H. Larsen)
|
||||
- de (Christian Kirbach)
|
||||
- en_GB (Bruce Cowan)
|
||||
- es (Jorge González)
|
||||
- et (Ivar Smolin, Mattias Põldaru)
|
||||
- eu (Inaki Larranaga Murgoitio)
|
||||
- fi (Tommi Vainikainen)
|
||||
- fr (Claude Paroz)
|
||||
- gl (Fran Diéguez)
|
||||
- gu (Sweta Kothari)
|
||||
- he (Thanos Lefteris, Kostas Papadimas)
|
||||
- hu (Gabor Kelemen)
|
||||
- it (Luca Ferretti)
|
||||
- ko (Changwoo Ryu)
|
||||
- lt (Žygimantas Beručka)
|
||||
- nn (Torstein Adolf Winterseth)
|
||||
- pa (A S Alam)
|
||||
- pl (Piotr Drąg)
|
||||
- pt (Duarte Loreto)
|
||||
- pt_BR (Og B. Maciel, Antonio Fernandes)
|
||||
- ro (Adi Roiban)
|
||||
- ru (Yuri Myasoedov, Юрий Козлов)
|
||||
- sl (Matej Urbančič)
|
||||
- sr (Miloš Popović)
|
||||
- sv (Daniel Nylander)
|
||||
- ta (vasudeven)
|
||||
- uk (Maxim V. Dziumanenko)
|
||||
- zh_HK (Chao-Hsiung Liao)
|
||||
- zh_TW (Chao-Hsiung Liao)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.29.92 (2010-03-08)
|
||||
|
||||
Translations:
|
||||
- ar (Khaled Hosny)
|
||||
- en_GB (Bruce Cowan)
|
||||
- eu (Iñaki Larranaga Murgoitio)
|
||||
- fr (Claude Paroz)
|
||||
- gl (Fran Diéguez)
|
||||
- he (Liel Fridman)
|
||||
- hu (Gabor Kelemen)
|
||||
- ja (Takayuki KUSANO)
|
||||
- ko (Changwoo Ryu)
|
||||
- nb (Kjartan Maraas)
|
||||
- nn (Torstein Adolf Winterseth)
|
||||
- pl (Piotr Drąg)
|
||||
- pt_BR (Antonio Fernandes C. Neto)
|
||||
- ru (Leonid Kanter)
|
||||
- sv (Daniel Nylander)
|
||||
- zh_HK (Chao-Hsiung Liao)
|
||||
- zh_TW (Chao-Hsiung Liao)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.29.91 (2010-02-24)
|
||||
|
||||
Appearance:
|
||||
- Add 'span' as a style for backgrounds
|
||||
|
||||
Display Properties:
|
||||
- Now fits in 640x480 and has a better layout overall.
|
||||
- Jst use "monitors" for wording, not a mixture of "monitor",
|
||||
"display", "screen".
|
||||
- Make the mouse cursor indicate when you can drag a monitor
|
||||
|
||||
Translations:
|
||||
- ar (Khaled Hosny)
|
||||
- bg (Alexander Shopov)
|
||||
- ca (Joan Duran)
|
||||
- de (Mario Blättermann)
|
||||
- es (Jorge González)
|
||||
- gl (Fran Diéguez)
|
||||
- hu (Gabor Kelemen)
|
||||
- pl (Piotr Drąg)
|
||||
- pt_BR (Vladimir Melo)
|
||||
- ro (Lucian Adrian Grijincu)
|
||||
- sl (Matej Urbančič)
|
||||
- ta (vasudeven)
|
||||
- zh_HK & zh_TW (Chao-Hsiung Liao)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.29.90 (2010-02-08)
|
||||
|
||||
About-me:
|
||||
- Fix hangs when 'passwd' outputs unexpected answers (Milan Bouchet-Valat)
|
||||
- Fix list of passwd error strings (Milan Bouchet-Valat)
|
||||
- Fix fingerprint name on 2nd page (Bastien Nocera)
|
||||
|
||||
At-properties:
|
||||
- Add AutostartCondition to gnome-at-session.desktop (Martin Pitt) (#608138)
|
||||
|
||||
Mouse:
|
||||
- Fix mnemonics conflicts on touchpad tab (Jens Granseuer) (#608057)
|
||||
|
||||
Translations:
|
||||
- de (Mario Blättermann)
|
||||
- es (Jorge González)
|
||||
- et (Ivar Smolin)
|
||||
- nb (Kjartan Maraas)
|
||||
- pa (A S Alam)
|
||||
- pt_BR (Antonio Fernandes C. Neto)
|
||||
- sl (Matej Urbančič, Andrej Žnidaršič)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.29.6 (2010-01-26)
|
||||
|
||||
About-me:
|
||||
- Add translator comments to 'Home' string (Claude Paroz) (#605944)
|
||||
|
||||
Appearance:
|
||||
- Use GtkInfoBar rather than a copy of GeditMessageArea (Thomas Wood)
|
||||
|
||||
Common:
|
||||
- Don't leak file descriptors when checking for colour schemes (Jens Granseuer) (#606155)
|
||||
|
||||
Mouse:
|
||||
- Disable tapping only for touchpads without a left mouse button (Peter Hutterer)
|
||||
|
||||
Translations:
|
||||
- bg (Alexander Shopov)
|
||||
- bn (Runa Bhattacharjee, Jamil Ahmed)
|
||||
- hu (Gabor Kelemen)
|
||||
- mr (Sandeep Shedmake)
|
||||
- nb (Kjartan Maraas)
|
||||
- sv (Daniel Nylander)
|
||||
- ta (vasudeven)
|
||||
- uk (Maxim V. Dziumanenko)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.29.4 (2009-12-24)
|
||||
|
||||
General:
|
||||
- Drop obsolete check for HAL (#595832) (Jens Granseuer)
|
||||
- Use external libslab when available (Vincent Untz)
|
||||
- Add gthread-2.0 to common modules for linking (#600589) (Jens Granseuer)
|
||||
- Enable silent build rules (Thomas Wood)
|
||||
|
||||
Common:
|
||||
- Fix all the keybindings showing up when using compiz (#600021) (Bastien
|
||||
Nocera)
|
||||
- Fix leak (Jens Granseuer)
|
||||
- Fix warning (Jens Granseuer)
|
||||
|
||||
About-me:
|
||||
- Fix crash when closing the window using the window button (#592348) (Jens
|
||||
Granseuer)
|
||||
- Add missing PNG files (Bastien Nocera)
|
||||
|
||||
Appearance:
|
||||
- Remove interface tab (#592756) (William Jon McCann)
|
||||
- Add OnlyShowIn=GNOME to the .desktop file (#594709) (Thomas Wood)
|
||||
- Update the background style option labels (#411048) (Thomas Wood)
|
||||
- Fix tooltip in the background chooser (#596369) (Matthias Clasen)
|
||||
- Add support for per-monitor backgrounds (#147808) (William Jon McCann)
|
||||
|
||||
Default applications:
|
||||
- Update the exec arg when changing terminal (#597185) (Vincent Untz)
|
||||
- Be sure to add the gconf directories for monitoring (#597186) (Thomas Wood)
|
||||
- Return an empty string for the custom web item (Thomas Wood)
|
||||
|
||||
Display:
|
||||
- Don't assert when the current output doesn't have a resolution set yet
|
||||
(#593866) (Federico Mena Quintero)
|
||||
- Automatically turn on outputs which support Mirror Screens (#590823)
|
||||
(Federico Mena Quintero)
|
||||
- Sensitize 'Mirror Screens' depending on whether mirror mode is actually
|
||||
supported (Federico Mena Quintero)
|
||||
- Desensitize the on/off radio buttons if we are in Mirror Screens mode
|
||||
(Federico Mena Quintero)
|
||||
- Show 'Mirror Screens' in the monitor label, not a random monitor's name
|
||||
(Federico Mena Quintero)
|
||||
|
||||
Font Viewer:
|
||||
- Use pango_language_get_sample_string for sample text (#595107) (Jens
|
||||
Granseuer)
|
||||
- Expand the Copyright display to get rid of unnecessary scrollbar (Jens
|
||||
Granseuer)
|
||||
- Don't use URI notation when installing fonts (#603732) (Jens Granseuer)
|
||||
|
||||
Keybindings:
|
||||
- Fix broken logic in keybinding tree model (Robert Ancell)
|
||||
- Fix zombie bindings appearing after deleting custom shortcuts (#596351) (Jens
|
||||
Granseuer)
|
||||
- Show shortcuts for the active window manager (#600531) (Wang Xin)
|
||||
- Remove sleep key entry (#170175) (Bastien Nocera)
|
||||
|
||||
Keyboard:
|
||||
- Major UI reorganization (Sergey V. Udaltsov)
|
||||
- Fix mnemonic conflict in mousekeys tab (#586433) (Jens Granseuer)
|
||||
|
||||
Mouse:
|
||||
- Disable two-finger scrolling/tapping based on touchpad capabilities. (Peter
|
||||
Hutterer)
|
||||
|
||||
Network:
|
||||
- Keep proxies in sync when "use same proxy" is selected (#589952) (Cyril
|
||||
Roelandt)
|
||||
|
||||
Typing break:
|
||||
- Increase delay for activating the postpone button to 5s (#597086) (Tim Waugh)
|
||||
- Reset timer after suspend (#430797) (Jens Granseuer)
|
||||
|
||||
Windows:
|
||||
- Don't allow Ctrl+Click as window movement modifier (#409405) (Jens Granseuer)
|
||||
|
||||
Translations:
|
||||
- ar (Khaled Hosny)
|
||||
- ca (Joan Duran)
|
||||
- ca@valencia (Carles Ferrando Garcia)
|
||||
- crh (Reşat SABIQ)
|
||||
- de (Christian Kirbach)
|
||||
- en@shaw (Thomas Thurman)
|
||||
- en_GB (Bruce Cowan)
|
||||
- es (Jorge González)
|
||||
- et (Ivar Smolin)
|
||||
- he (Yaron Shahrabani)
|
||||
- id (Andika Triwidada)
|
||||
- it (Luca Ferretti)
|
||||
- lt (Žygimantas Beručka)
|
||||
- nb (Kjartan Maraas)
|
||||
- nds (Nils-Christoph Fiedler)
|
||||
- pl (Tomasz Dominikowski)
|
||||
- ro (Adi Roiban)
|
||||
- ru (Alexandre Prokoudine)
|
||||
- sl (Matej Urbančič)
|
||||
- sv (Daniel Nylander)
|
||||
- ta (Dr.T.Vasudevan)
|
||||
- th (อาคม โชติพันธวานนท์)
|
||||
- zh_CN (Tao Wei)
|
||||
-------------------------------------------------------------------------------
|
||||
gnome-control-center 2.28.0 (2009-09-21)
|
||||
|
||||
Appearance:
|
||||
|
||||
@@ -6,7 +6,7 @@ test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="control-center"
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
(test -f $srcdir/configure.in \
|
||||
&& test -f $srcdir/autogen.sh \
|
||||
&& test -d $srcdir/shell) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
@@ -24,4 +24,4 @@ if ! which gnome-autogen.sh ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. gnome-autogen.sh
|
||||
REQUIRED_AUTOMAKE_VERSION=1.9 . gnome-autogen.sh
|
||||
|
||||
34
capplets/Makefile.am
Normal file
@@ -0,0 +1,34 @@
|
||||
SUBDIRS = \
|
||||
common \
|
||||
accessibility \
|
||||
appearance \
|
||||
default-applications \
|
||||
keybindings \
|
||||
keyboard \
|
||||
mouse \
|
||||
network \
|
||||
windows
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
common \
|
||||
accessibility \
|
||||
appearance \
|
||||
default-applications \
|
||||
keybindings \
|
||||
keyboard \
|
||||
mouse \
|
||||
network \
|
||||
windows \
|
||||
display \
|
||||
about-me
|
||||
|
||||
|
||||
if HAVE_RANDR
|
||||
SUBDIRS += display
|
||||
endif
|
||||
|
||||
if BUILD_ABOUTME
|
||||
SUBDIRS += about-me
|
||||
endif
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
2
capplets/about-me/AUTHORS
Normal file
@@ -0,0 +1,2 @@
|
||||
Diego Gonzalez Gonzalez <diego@pemas.net>
|
||||
Chris Toshok <toshok@ximian.com>
|
||||
59
capplets/about-me/Makefile.am
Normal file
@@ -0,0 +1,59 @@
|
||||
SUBDIRS = icons
|
||||
|
||||
# This is used in GNOMECC_CAPPLETS_CFLAGS
|
||||
cappletname = about-me
|
||||
|
||||
ui_files = gnome-about-me-dialog.ui gnome-about-me-password.ui gnome-about-me-fingerprint.ui
|
||||
Desktop_in_files = gnome-about-me.desktop.in
|
||||
|
||||
gnome_about_me_SOURCES = \
|
||||
eel-alert-dialog.c \
|
||||
eel-alert-dialog.h \
|
||||
eel-gtk-macros.h \
|
||||
gnome-about-me-password.c \
|
||||
gnome-about-me-password.h \
|
||||
e-image-chooser.c \
|
||||
e-image-chooser.h \
|
||||
gnome-about-me-fingerprint.c \
|
||||
gnome-about-me-fingerprint.h \
|
||||
$(MARSHALFILES) \
|
||||
fingerprint-strings.h \
|
||||
gnome-about-me.c
|
||||
|
||||
MARSHALFILES = marshal.c marshal.h
|
||||
BUILT_SOURCES = $(MARSHALFILES)
|
||||
|
||||
marshal.h: fprintd-marshal.list
|
||||
@GLIB_GENMARSHAL@ --prefix=fprintd_marshal $< --header > $@
|
||||
marshal.c: fprintd-marshal.list
|
||||
@GLIB_GENMARSHAL@ --prefix=fprintd_marshal $< --body --header > $@
|
||||
|
||||
if BUILD_ABOUTME
|
||||
bin_PROGRAMS = gnome-about-me
|
||||
|
||||
gnome_about_me_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(LIBEBOOK_LIBS)
|
||||
gnome_about_me_LDFLAGS = -export-dynamic
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
|
||||
|
||||
uidir = $(pkgdatadir)/ui
|
||||
ui_DATA = $(ui_files)
|
||||
|
||||
INCLUDES = \
|
||||
$(GNOMECC_CAPPLETS_CFLAGS) \
|
||||
$(LIBEBOOK_CFLAGS) \
|
||||
-DDATADIR="\"$(datadir)\"" \
|
||||
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
|
||||
-DGNOMECC_UI_DIR="\"$(uidir)\"" \
|
||||
-DGNOMECC_PIXMAP_DIR="\"$(pkgdatadir)/pixmaps\"" \
|
||||
-DGNOMELOCALEDIR="\"$(datadir)/locale\""
|
||||
|
||||
endif # BUILD_ABOUTME
|
||||
|
||||
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) $(desktop_DATA) $(MARSHALFILES)
|
||||
EXTRA_DIST = $(ui_files) fprintd-marshal.list
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
455
capplets/about-me/e-image-chooser.c
Normal file
@@ -0,0 +1,455 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* e-image-chooser.c
|
||||
* Copyright (C) 2004 Novell, Inc.
|
||||
* Author: Chris Toshok <toshok@ximian.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "e-image-chooser.h"
|
||||
|
||||
struct _EImageChooserPrivate {
|
||||
|
||||
GtkWidget *image;
|
||||
GtkWidget *browse_button;
|
||||
|
||||
char *image_buf;
|
||||
int image_buf_size;
|
||||
int image_width;
|
||||
int image_height;
|
||||
|
||||
gboolean editable;
|
||||
};
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
static gint image_chooser_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void e_image_chooser_init (EImageChooser *chooser);
|
||||
static void e_image_chooser_class_init (EImageChooserClass *klass);
|
||||
static void e_image_chooser_dispose (GObject *object);
|
||||
|
||||
static gboolean image_drag_motion_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y, guint time, EImageChooser *chooser);
|
||||
static gboolean image_drag_drop_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y, guint time, EImageChooser *chooser);
|
||||
static void image_drag_data_received_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info, guint time, EImageChooser *chooser);
|
||||
|
||||
static GtkObjectClass *parent_class = NULL;
|
||||
#define PARENT_TYPE GTK_TYPE_VBOX
|
||||
|
||||
enum DndTargetType {
|
||||
DND_TARGET_TYPE_URI_LIST
|
||||
};
|
||||
#define URI_LIST_TYPE "text/uri-list"
|
||||
|
||||
static GtkTargetEntry image_drag_types[] = {
|
||||
{ URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST },
|
||||
};
|
||||
static const int num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]);
|
||||
|
||||
GtkWidget *
|
||||
e_image_chooser_new (void)
|
||||
{
|
||||
return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL);
|
||||
}
|
||||
|
||||
GType
|
||||
e_image_chooser_get_type (void)
|
||||
{
|
||||
static GType eic_type = 0;
|
||||
|
||||
if (!eic_type) {
|
||||
static const GTypeInfo eic_info = {
|
||||
sizeof (EImageChooserClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) e_image_chooser_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (EImageChooser),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) e_image_chooser_init,
|
||||
};
|
||||
|
||||
eic_type = g_type_register_static (PARENT_TYPE, "EImageChooser", &eic_info, 0);
|
||||
}
|
||||
|
||||
return eic_type;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_image_chooser_class_init (EImageChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_ref (PARENT_TYPE);
|
||||
|
||||
image_chooser_signals [CHANGED] =
|
||||
g_signal_new ("changed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (EImageChooserClass, changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
object_class->dispose = e_image_chooser_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
e_image_chooser_init (EImageChooser *chooser)
|
||||
{
|
||||
EImageChooserPrivate *priv;
|
||||
|
||||
priv = chooser->priv = g_new0 (EImageChooserPrivate, 1);
|
||||
|
||||
priv->image = gtk_image_new ();
|
||||
|
||||
gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (chooser), priv->image, TRUE, TRUE, 0);
|
||||
|
||||
gtk_drag_dest_set (priv->image, 0, image_drag_types, num_image_drag_types, GDK_ACTION_COPY);
|
||||
g_signal_connect (priv->image,
|
||||
"drag_motion", G_CALLBACK (image_drag_motion_cb), chooser);
|
||||
g_signal_connect (priv->image,
|
||||
"drag_drop", G_CALLBACK (image_drag_drop_cb), chooser);
|
||||
g_signal_connect (priv->image,
|
||||
"drag_data_received", G_CALLBACK (image_drag_data_received_cb), chooser);
|
||||
|
||||
gtk_widget_show_all (priv->image);
|
||||
|
||||
/* we default to being editable */
|
||||
priv->editable = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
e_image_chooser_dispose (GObject *object)
|
||||
{
|
||||
EImageChooser *eic = E_IMAGE_CHOOSER (object);
|
||||
|
||||
if (eic->priv) {
|
||||
EImageChooserPrivate *priv = eic->priv;
|
||||
|
||||
if (priv->image_buf) {
|
||||
g_free (priv->image_buf);
|
||||
priv->image_buf = NULL;
|
||||
}
|
||||
|
||||
g_free (eic->priv);
|
||||
eic->priv = NULL;
|
||||
}
|
||||
|
||||
if (G_OBJECT_CLASS (parent_class)->dispose)
|
||||
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
set_image_from_data (EImageChooser *chooser,
|
||||
char *data, int length)
|
||||
{
|
||||
gboolean rv = FALSE;
|
||||
GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
gdk_pixbuf_loader_write (loader, data, length, NULL);
|
||||
gdk_pixbuf_loader_close (loader, NULL);
|
||||
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||
if (pixbuf)
|
||||
g_object_ref (pixbuf);
|
||||
g_object_unref (loader);
|
||||
|
||||
if (pixbuf) {
|
||||
GdkPixbuf *scaled;
|
||||
GtkRequisition chooser_size;
|
||||
|
||||
float scale;
|
||||
int new_height, new_width;
|
||||
|
||||
gtk_widget_size_request (gtk_widget_get_parent (GTK_WIDGET (chooser)),
|
||||
&chooser_size);
|
||||
chooser_size.width -= 5;
|
||||
chooser_size.height -= 5;
|
||||
|
||||
new_height = gdk_pixbuf_get_height (pixbuf);
|
||||
new_width = gdk_pixbuf_get_width (pixbuf);
|
||||
|
||||
if (chooser->priv->image_height == 0
|
||||
&& chooser->priv->image_width == 0) {
|
||||
scale = 1.0;
|
||||
}
|
||||
else if (chooser->priv->image_height < new_height
|
||||
|| chooser->priv->image_width < new_width) {
|
||||
/* we need to scale down */
|
||||
if (new_height > new_width)
|
||||
scale = (float)chooser_size.height / new_height;
|
||||
else
|
||||
scale = (float)chooser_size.width / new_width;
|
||||
}
|
||||
else {
|
||||
/* we need to scale up */
|
||||
if (new_height > new_width)
|
||||
scale = (float)new_height / chooser_size.height;
|
||||
else
|
||||
scale = (float)new_width / chooser_size.width;
|
||||
}
|
||||
|
||||
if (scale == 1.0) {
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), pixbuf);
|
||||
|
||||
chooser->priv->image_width = new_width;
|
||||
chooser->priv->image_height = new_height;
|
||||
}
|
||||
else {
|
||||
new_width *= scale;
|
||||
new_height *= scale;
|
||||
new_width = MIN (new_width, chooser_size.width);
|
||||
new_height = MIN (new_height, chooser_size.height);
|
||||
|
||||
scaled = gdk_pixbuf_scale_simple (pixbuf,
|
||||
new_width, new_height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), scaled);
|
||||
g_object_unref (scaled);
|
||||
}
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_free (chooser->priv->image_buf);
|
||||
chooser->priv->image_buf = data;
|
||||
chooser->priv->image_buf_size = length;
|
||||
|
||||
g_signal_emit (chooser,
|
||||
image_chooser_signals [CHANGED], 0);
|
||||
|
||||
rv = TRUE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
image_drag_motion_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y, guint time, EImageChooser *chooser)
|
||||
{
|
||||
GList *p;
|
||||
|
||||
if (!chooser->priv->editable)
|
||||
return FALSE;
|
||||
|
||||
for (p = context->targets; p != NULL; p = p->next) {
|
||||
char *possible_type;
|
||||
|
||||
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
|
||||
if (!strcmp (possible_type, URI_LIST_TYPE)) {
|
||||
g_free (possible_type);
|
||||
gdk_drag_status (context, GDK_ACTION_COPY, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_free (possible_type);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
image_drag_drop_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y, guint time, EImageChooser *chooser)
|
||||
{
|
||||
GList *p;
|
||||
|
||||
if (!chooser->priv->editable)
|
||||
return FALSE;
|
||||
|
||||
if (context->targets == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (p = context->targets; p != NULL; p = p->next) {
|
||||
char *possible_type;
|
||||
|
||||
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
|
||||
if (!strcmp (possible_type, URI_LIST_TYPE)) {
|
||||
g_free (possible_type);
|
||||
gtk_drag_get_data (widget, context,
|
||||
GDK_POINTER_TO_ATOM (p->data),
|
||||
time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_free (possible_type);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
image_drag_data_received_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x, gint y,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info, guint time, EImageChooser *chooser)
|
||||
{
|
||||
|
||||
char *target_type;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
target_type = gdk_atom_name (selection_data->target);
|
||||
|
||||
if (!strcmp (target_type, URI_LIST_TYPE)) {
|
||||
char *uri;
|
||||
GFile *file;
|
||||
GInputStream *istream;
|
||||
char *nl = strstr (selection_data->data, "\r\n");
|
||||
|
||||
if (nl)
|
||||
uri = g_strndup (selection_data->data, nl - (char *) selection_data->data);
|
||||
else
|
||||
uri = g_strdup (selection_data->data);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
istream = G_INPUT_STREAM (g_file_read (file, NULL, NULL));
|
||||
|
||||
if (istream != NULL) {
|
||||
GFileInfo *info;
|
||||
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL, NULL);
|
||||
|
||||
if (info != NULL) {
|
||||
gsize size;
|
||||
gboolean success;
|
||||
gchar *buf;
|
||||
|
||||
size = g_file_info_get_size (info);
|
||||
g_object_unref (info);
|
||||
|
||||
buf = g_malloc (size);
|
||||
|
||||
success = g_input_stream_read_all (istream,
|
||||
buf,
|
||||
size,
|
||||
&size,
|
||||
NULL,
|
||||
NULL);
|
||||
g_input_stream_close (istream, NULL, NULL);
|
||||
|
||||
if (success &&
|
||||
set_image_from_data (chooser, buf, size))
|
||||
handled = TRUE;
|
||||
else
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
g_object_unref (istream);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
gtk_drag_finish (context, handled, FALSE, time);
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename)
|
||||
{
|
||||
gchar *data;
|
||||
gsize data_length;
|
||||
|
||||
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
|
||||
g_return_val_if_fail (filename, FALSE);
|
||||
|
||||
if (!g_file_get_contents (filename, &data, &data_length, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!set_image_from_data (chooser, data, data_length))
|
||||
g_free (data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable)
|
||||
{
|
||||
g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser));
|
||||
|
||||
chooser->priv->editable = editable;
|
||||
|
||||
gtk_widget_set_sensitive (chooser->priv->browse_button, editable);
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
g_return_val_if_fail (data_length != NULL, FALSE);
|
||||
|
||||
*data_length = chooser->priv->image_buf_size;
|
||||
*data = g_malloc (*data_length);
|
||||
memcpy (*data, chooser->priv->image_buf, *data_length);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
/* yuck, a copy... */
|
||||
buf = g_malloc (data_length);
|
||||
memcpy (buf, data, data_length);
|
||||
|
||||
if (!set_image_from_data (chooser, buf, data_length)) {
|
||||
g_free (buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
64
capplets/about-me/e-image-chooser.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* e-image-chooser.c
|
||||
* Copyright (C) 2004 Novell, Inc.
|
||||
* Author: Chris Toshok <toshok@ximian.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _E_IMAGE_CHOOSER_H_
|
||||
#define _E_IMAGE_CHOOSER_H_
|
||||
|
||||
#include <gtk/gtkvbox.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ())
|
||||
#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser))
|
||||
#define E_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_IMAGE_CHOOSER, EImageChooserClass))
|
||||
#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
|
||||
#define E_IS_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
|
||||
|
||||
typedef struct _EImageChooser EImageChooser;
|
||||
typedef struct _EImageChooserClass EImageChooserClass;
|
||||
typedef struct _EImageChooserPrivate EImageChooserPrivate;
|
||||
|
||||
struct _EImageChooser
|
||||
{
|
||||
GtkVBox parent;
|
||||
|
||||
EImageChooserPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EImageChooserClass
|
||||
{
|
||||
GtkVBoxClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*changed) (EImageChooser *chooser);
|
||||
|
||||
|
||||
};
|
||||
|
||||
GtkWidget *e_image_chooser_new (void);
|
||||
GType e_image_chooser_get_type (void);
|
||||
|
||||
gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename);
|
||||
gboolean e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length);
|
||||
void e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable);
|
||||
|
||||
gboolean e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length);
|
||||
|
||||
#endif /* _E_IMAGE_CHOOSER_H_ */
|
||||
3
capplets/about-me/e-util-marshal.list
Normal file
@@ -0,0 +1,3 @@
|
||||
NONE:NONE
|
||||
NONE:INT
|
||||
NONE:POINTER
|
||||
470
capplets/about-me/eel-alert-dialog.c
Normal file
@@ -0,0 +1,470 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* eel-alert-dialog.c: An HIG compliant alert dialog.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "eel-alert-dialog.h"
|
||||
#include "eel-gtk-macros.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtklabel.h>
|
||||
#include <gtk/gtkhbox.h>
|
||||
#include <gtk/gtkvbox.h>
|
||||
#include <gtk/gtkimage.h>
|
||||
#include <gtk/gtkstock.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
#include <gtk/gtkexpander.h>
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ALERT_TYPE,
|
||||
PROP_BUTTONS
|
||||
};
|
||||
|
||||
struct _EelAlertDialogDetails {
|
||||
GtkWidget *image;
|
||||
GtkWidget *primary_label;
|
||||
GtkWidget *secondary_label;
|
||||
GtkWidget *details_expander;
|
||||
GtkWidget *details_label;
|
||||
GtkMessageType type;
|
||||
};
|
||||
|
||||
|
||||
static gpointer parent_class;
|
||||
|
||||
static void eel_alert_dialog_finalize (GObject *object);
|
||||
static void eel_alert_dialog_class_init (EelAlertDialogClass *klass);
|
||||
static void eel_alert_dialog_init (EelAlertDialog *dialog);
|
||||
static void eel_alert_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style);
|
||||
static void eel_alert_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void eel_alert_dialog_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void eel_alert_dialog_add_buttons (EelAlertDialog *alert_dialog,
|
||||
GtkButtonsType buttons);
|
||||
|
||||
GType
|
||||
eel_alert_dialog_get_type (void)
|
||||
{
|
||||
static GType dialog_type = 0;
|
||||
|
||||
if (!dialog_type) {
|
||||
|
||||
static const GTypeInfo dialog_info =
|
||||
{
|
||||
sizeof (EelAlertDialogClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) eel_alert_dialog_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (EelAlertDialog),
|
||||
0,
|
||||
(GInstanceInitFunc) eel_alert_dialog_init,
|
||||
};
|
||||
|
||||
dialog_type = g_type_register_static (GTK_TYPE_DIALOG, "EelAlertDialog",
|
||||
&dialog_info, 0);
|
||||
}
|
||||
return dialog_type;
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_class_init (EelAlertDialogClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
G_OBJECT_CLASS (class)->finalize = eel_alert_dialog_finalize;
|
||||
|
||||
widget_class->style_set = eel_alert_dialog_style_set;
|
||||
|
||||
gobject_class->set_property = eel_alert_dialog_set_property;
|
||||
gobject_class->get_property = eel_alert_dialog_get_property;
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("alert_border",
|
||||
_("Image/label border"),
|
||||
_("Width of border around the label and image in the alert dialog"),
|
||||
0,
|
||||
G_MAXINT,
|
||||
5,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ALERT_TYPE,
|
||||
g_param_spec_enum ("alert_type",
|
||||
_("Alert Type"),
|
||||
_("The type of alert"),
|
||||
GTK_TYPE_MESSAGE_TYPE,
|
||||
GTK_MESSAGE_INFO,
|
||||
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUTTONS,
|
||||
g_param_spec_enum ("buttons",
|
||||
_("Alert Buttons"),
|
||||
_("The buttons shown in the alert dialog"),
|
||||
GTK_TYPE_BUTTONS_TYPE,
|
||||
GTK_BUTTONS_NONE,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_finalize (GObject *object)
|
||||
{
|
||||
EelAlertDialog *dialog;
|
||||
|
||||
dialog = EEL_ALERT_DIALOG (object);
|
||||
|
||||
g_free (dialog->details);
|
||||
|
||||
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
eel_alert_dialog_init (EelAlertDialog *dialog)
|
||||
{
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *expander;
|
||||
|
||||
dialog->details = g_new0 (EelAlertDialogDetails, 1);
|
||||
|
||||
dialog->details->primary_label = gtk_label_new (NULL);
|
||||
dialog->details->secondary_label = gtk_label_new (NULL);
|
||||
dialog->details->details_label = gtk_label_new (NULL);
|
||||
dialog->details->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
|
||||
gtk_misc_set_alignment (GTK_MISC (dialog->details->image), 0.5, 0.0);
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (dialog->details->primary_label), TRUE);
|
||||
gtk_label_set_selectable (GTK_LABEL (dialog->details->primary_label), TRUE);
|
||||
gtk_label_set_use_markup (GTK_LABEL (dialog->details->primary_label), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (dialog->details->primary_label), 0.0, 0.5);
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (dialog->details->secondary_label), TRUE);
|
||||
gtk_label_set_selectable (GTK_LABEL (dialog->details->secondary_label), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (dialog->details->secondary_label), 0.0, 0.5);
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (dialog->details->details_label), TRUE);
|
||||
gtk_label_set_selectable (GTK_LABEL (dialog->details->details_label), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (dialog->details->details_label), 0.0, 0.5);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 12);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), dialog->details->image,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 12);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), dialog->details->primary_label,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), dialog->details->secondary_label,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
expander = gtk_expander_new_with_mnemonic (_("Show more _details"));
|
||||
dialog->details->details_expander = expander;
|
||||
gtk_expander_set_spacing (GTK_EXPANDER (expander), 6);
|
||||
gtk_container_add (GTK_CONTAINER (expander), dialog->details->details_label);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), expander,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (hbox);
|
||||
gtk_widget_hide (expander);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
setup_type (EelAlertDialog *dialog,
|
||||
GtkMessageType type)
|
||||
{
|
||||
const gchar *stock_id = NULL;
|
||||
GtkStockItem item;
|
||||
|
||||
switch (type) {
|
||||
case GTK_MESSAGE_INFO:
|
||||
stock_id = GTK_STOCK_DIALOG_INFO;
|
||||
break;
|
||||
case GTK_MESSAGE_QUESTION:
|
||||
stock_id = GTK_STOCK_DIALOG_QUESTION;
|
||||
break;
|
||||
case GTK_MESSAGE_WARNING:
|
||||
stock_id = GTK_STOCK_DIALOG_WARNING;
|
||||
break;
|
||||
case GTK_MESSAGE_ERROR:
|
||||
stock_id = GTK_STOCK_DIALOG_ERROR;
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown GtkMessageType %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stock_id == NULL) {
|
||||
stock_id = GTK_STOCK_DIALOG_INFO;
|
||||
}
|
||||
|
||||
if (gtk_stock_lookup (stock_id, &item)) {
|
||||
gtk_image_set_from_stock (GTK_IMAGE (dialog->details->image), stock_id,
|
||||
GTK_ICON_SIZE_DIALOG);
|
||||
} else {
|
||||
g_warning ("Stock dialog ID doesn't exist?");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EelAlertDialog *dialog;
|
||||
|
||||
dialog = EEL_ALERT_DIALOG (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ALERT_TYPE:
|
||||
dialog->details->type = g_value_get_enum (value);
|
||||
setup_type (dialog, dialog->details->type);
|
||||
break;
|
||||
case PROP_BUTTONS:
|
||||
eel_alert_dialog_add_buttons (dialog, g_value_get_enum (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EelAlertDialog *dialog;
|
||||
|
||||
dialog = EEL_ALERT_DIALOG (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ALERT_TYPE:
|
||||
g_value_set_enum (value, dialog->details->type);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
eel_alert_dialog_set_primary_label (EelAlertDialog *dialog,
|
||||
const gchar *message)
|
||||
{
|
||||
gchar *markup_str;
|
||||
char *escaped_message;
|
||||
|
||||
if (message != NULL) {
|
||||
escaped_message = g_markup_escape_text (message, -1);
|
||||
markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", escaped_message, "</span>", NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (EEL_ALERT_DIALOG (dialog)->details->primary_label),
|
||||
markup_str);
|
||||
g_free (markup_str);
|
||||
g_free (escaped_message);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
eel_alert_dialog_set_secondary_label (EelAlertDialog *dialog,
|
||||
const gchar *message)
|
||||
{
|
||||
if (message != NULL) {
|
||||
gtk_label_set_text (GTK_LABEL (EEL_ALERT_DIALOG (dialog)->details->secondary_label),
|
||||
message);
|
||||
} else {
|
||||
gtk_widget_hide (EEL_ALERT_DIALOG (dialog)->details->secondary_label);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
eel_alert_dialog_set_details_label (EelAlertDialog *dialog,
|
||||
const gchar *message)
|
||||
{
|
||||
if (message != NULL) {
|
||||
gtk_widget_show (dialog->details->details_expander);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->details->details_label), message);
|
||||
} else {
|
||||
gtk_widget_hide (dialog->details->details_expander);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GtkWidget*
|
||||
eel_alert_dialog_new (GtkWindow *parent,
|
||||
GtkDialogFlags flags,
|
||||
GtkMessageType type,
|
||||
GtkButtonsType buttons,
|
||||
const gchar *primary_message,
|
||||
const gchar *secondary_message,
|
||||
const gchar *title)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkDialog *dialog;
|
||||
|
||||
g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
|
||||
|
||||
widget = g_object_new (EEL_TYPE_ALERT_DIALOG,
|
||||
"alert_type", type,
|
||||
"buttons", buttons,
|
||||
NULL);
|
||||
atk_object_set_role (gtk_widget_get_accessible (widget), ATK_ROLE_ALERT);
|
||||
|
||||
dialog = GTK_DIALOG (widget);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
||||
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14);
|
||||
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
|
||||
gtk_dialog_set_has_separator (dialog, FALSE);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (dialog),
|
||||
(title != NULL) ? title : "");
|
||||
|
||||
eel_alert_dialog_set_primary_label (EEL_ALERT_DIALOG (dialog),
|
||||
primary_message);
|
||||
|
||||
eel_alert_dialog_set_secondary_label (EEL_ALERT_DIALOG (dialog),
|
||||
secondary_message);
|
||||
|
||||
if (parent != NULL) {
|
||||
gtk_window_set_transient_for (GTK_WINDOW (widget),
|
||||
GTK_WINDOW (parent));
|
||||
}
|
||||
|
||||
if (flags & GTK_DIALOG_MODAL) {
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
}
|
||||
|
||||
if (flags & GTK_DIALOG_DESTROY_WITH_PARENT) {
|
||||
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_add_buttons (EelAlertDialog* alert_dialog,
|
||||
GtkButtonsType buttons)
|
||||
{
|
||||
GtkDialog* dialog;
|
||||
|
||||
dialog = GTK_DIALOG (alert_dialog);
|
||||
|
||||
switch (buttons) {
|
||||
case GTK_BUTTONS_NONE:
|
||||
break;
|
||||
case GTK_BUTTONS_OK:
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_OK,
|
||||
GTK_RESPONSE_OK);
|
||||
gtk_dialog_set_default_response (dialog,
|
||||
GTK_RESPONSE_OK);
|
||||
break;
|
||||
case GTK_BUTTONS_CLOSE:
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_CLOSE,
|
||||
GTK_RESPONSE_CLOSE);
|
||||
gtk_dialog_set_default_response (dialog,
|
||||
GTK_RESPONSE_CLOSE);
|
||||
break;
|
||||
case GTK_BUTTONS_CANCEL:
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_set_default_response (dialog,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
break;
|
||||
case GTK_BUTTONS_YES_NO:
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_NO,
|
||||
GTK_RESPONSE_NO);
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_YES,
|
||||
GTK_RESPONSE_YES);
|
||||
gtk_dialog_set_default_response (dialog,
|
||||
GTK_RESPONSE_YES);
|
||||
break;
|
||||
case GTK_BUTTONS_OK_CANCEL:
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (dialog,
|
||||
GTK_STOCK_OK,
|
||||
GTK_RESPONSE_OK);
|
||||
gtk_dialog_set_default_response (dialog,
|
||||
GTK_RESPONSE_OK);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown GtkButtonsType");
|
||||
break;
|
||||
}
|
||||
g_object_notify (G_OBJECT (alert_dialog), "buttons");
|
||||
}
|
||||
|
||||
static void
|
||||
eel_alert_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
gint border_width;
|
||||
|
||||
border_width = 0;
|
||||
|
||||
parent = GTK_WIDGET (EEL_ALERT_DIALOG (widget)->details->image->parent);
|
||||
|
||||
if (parent != NULL) {
|
||||
gtk_widget_style_get (widget, "alert_border",
|
||||
&border_width, NULL);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (parent),
|
||||
border_width);
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_CLASS (parent_class)->style_set) {
|
||||
(GTK_WIDGET_CLASS (parent_class)->style_set) (widget, prev_style);
|
||||
}
|
||||
}
|
||||
61
capplets/about-me/eel-alert-dialog.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* eel-alert-dialog.h: An HIG compliant alert dialog.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef EEL_ALERT_DIALOG_H
|
||||
#define EEL_ALERT_DIALOG_H
|
||||
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
|
||||
#define EEL_TYPE_ALERT_DIALOG (eel_alert_dialog_get_type ())
|
||||
#define EEL_ALERT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_ALERT_DIALOG, EelAlertDialog))
|
||||
|
||||
typedef struct _EelAlertDialog EelAlertDialog;
|
||||
typedef struct _EelAlertDialogClass EelAlertDialogClass;
|
||||
typedef struct _EelAlertDialogDetails EelAlertDialogDetails;
|
||||
|
||||
struct _EelAlertDialog
|
||||
{
|
||||
GtkDialog parent_instance;
|
||||
EelAlertDialogDetails *details;
|
||||
};
|
||||
|
||||
struct _EelAlertDialogClass
|
||||
{
|
||||
GtkDialogClass parent_class;
|
||||
};
|
||||
|
||||
GType eel_alert_dialog_get_type (void);
|
||||
|
||||
GtkWidget* eel_alert_dialog_new (GtkWindow *parent,
|
||||
GtkDialogFlags flags,
|
||||
GtkMessageType type,
|
||||
GtkButtonsType buttons,
|
||||
const gchar *primary_message,
|
||||
const gchar *secondary_message,
|
||||
const gchar *title);
|
||||
void eel_alert_dialog_set_primary_label (EelAlertDialog *dialog,
|
||||
const gchar *message);
|
||||
void eel_alert_dialog_set_secondary_label (EelAlertDialog *dialog,
|
||||
const gchar *message);
|
||||
void eel_alert_dialog_set_details_label (EelAlertDialog *dialog,
|
||||
const gchar *message);
|
||||
|
||||
#endif /* EEL_ALERT_DIALOG_H */
|
||||
178
capplets/about-me/eel-gtk-macros.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
|
||||
|
||||
eel-gtk-macros.h: Macros to reduce boilerplate when using GTK.
|
||||
|
||||
Copyright (C) 1999, 2000, 2001 Eazel, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Darin Adler <darin@bentspoon.com>
|
||||
Ramiro Estrugo <ramiro@eazel.com>
|
||||
*/
|
||||
|
||||
#ifndef EEL_GTK_MACROS_H
|
||||
#define EEL_GTK_MACROS_H
|
||||
|
||||
#ifndef EEL_DISABLE_DEPRECATED
|
||||
|
||||
/* Define a parent_class global and a get_type function for a GTK class.
|
||||
Since this is boilerplate, it's better not to repeat it over and over again.
|
||||
Called like this:
|
||||
|
||||
EEL_CLASS_BOILERPLATE (EelBookmark, eel_bookmark, GTK_TYPE_OBJECT)
|
||||
|
||||
The parent_class_type parameter is guaranteed to be evaluated only once
|
||||
so it can be an expression, even an expression that contains a function call.
|
||||
*/
|
||||
|
||||
#define EEL_CLASS_BOILERPLATE(class_name, prefix, parent_class_type) \
|
||||
EEL_BOILERPLATE (class_name, class_name, prefix, parent_class_type, \
|
||||
EEL_REGISTER_TYPE)
|
||||
#define EEL_REGISTER_TYPE(class_name, corba_name) \
|
||||
g_type_register_static (parent_type, #class_name, &info, 0)
|
||||
|
||||
#define EEL_BOILERPLATE(class_name, corba_name, prefix, parent_class_type, \
|
||||
register_type) \
|
||||
\
|
||||
static gpointer parent_class; \
|
||||
\
|
||||
GType \
|
||||
prefix##_get_type (void) \
|
||||
{ \
|
||||
GType parent_type; \
|
||||
static GType type; \
|
||||
\
|
||||
if (type == 0) { \
|
||||
static GTypeInfo info = { \
|
||||
sizeof (class_name##Class), \
|
||||
NULL, NULL, \
|
||||
(GClassInitFunc) prefix##_class_init, \
|
||||
NULL, NULL, \
|
||||
sizeof (class_name), 0, \
|
||||
(GInstanceInitFunc) prefix##_init, \
|
||||
NULL \
|
||||
}; \
|
||||
\
|
||||
parent_type = (parent_class_type); \
|
||||
type = register_type (class_name, corba_name); \
|
||||
parent_class = g_type_class_ref (parent_type); \
|
||||
} \
|
||||
\
|
||||
return type; \
|
||||
}
|
||||
|
||||
/* Call a parent class version of a virtual function (or default
|
||||
* signal handler since that's the same thing). Nice because it
|
||||
* documents what it's doing and there is less chance for a
|
||||
* typo. Depends on the parent class pointer having the conventional
|
||||
* name "parent_class" as the boilerplate macro above does it.
|
||||
*/
|
||||
#define EEL_CALL_PARENT(parent_class_cast_macro, signal, parameters) \
|
||||
\
|
||||
G_STMT_START { \
|
||||
if (parent_class_cast_macro (parent_class)->signal != NULL) { \
|
||||
(* parent_class_cast_macro (parent_class)->signal) parameters;\
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
/* Same thing, for functions with a return value. */
|
||||
#define EEL_CALL_PARENT_WITH_RETURN_VALUE(parent_class_cast_macro, signal, \
|
||||
parameters) \
|
||||
\
|
||||
(parent_class_cast_macro (parent_class)->signal == NULL) \
|
||||
? 0 \
|
||||
: ((* parent_class_cast_macro (parent_class)->signal) parameters)
|
||||
|
||||
#endif /* EEL_DISABLE_DEPRECATED */
|
||||
|
||||
/* Call a virtual function. Useful when the virtual function is not a
|
||||
* signal, otherwise you want to gtk_signal emit. Nice because it
|
||||
* documents what it's doing and there is less chance for a typo.
|
||||
*/
|
||||
#define EEL_CALL_METHOD(class_cast_macro, object, signal, parameters) \
|
||||
\
|
||||
G_STMT_START { \
|
||||
if (class_cast_macro (G_OBJECT_GET_CLASS (object))->signal != NULL) { \
|
||||
(* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \
|
||||
parameters; \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
/* Same thing, for functions with a return value. */
|
||||
#define EEL_CALL_METHOD_WITH_RETURN_VALUE(class_cast_macro, object, signal, \
|
||||
parameters) \
|
||||
\
|
||||
(class_cast_macro (G_OBJECT_GET_CLASS (object))->signal == NULL) \
|
||||
? 0 \
|
||||
: ((* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \
|
||||
parameters) \
|
||||
|
||||
#ifndef G_DISABLE_ASSERT
|
||||
|
||||
/* Define a signal that is not implemented by this class but must be
|
||||
* implemented by subclasses. This macro should be used inside the
|
||||
* class initialization function. The companion macro EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL
|
||||
* must be used earlier in the file. Called like this:
|
||||
*
|
||||
* EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass,
|
||||
* fm_directory_view,
|
||||
* clear);
|
||||
*/
|
||||
#define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal) \
|
||||
\
|
||||
* (void (**)(void)) & (class_pointer)->signal = prefix##_unimplemented_##signal
|
||||
|
||||
/* Provide a debug-only implementation of a signal that must be implemented
|
||||
* by subclasses. The debug-only implementation fires a warning if it is called.
|
||||
* This macro should be placed as if it were a function, earlier in the file
|
||||
* than the class initialization function. Called like this:
|
||||
*
|
||||
* EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, clear);
|
||||
*/
|
||||
#define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal) \
|
||||
\
|
||||
static void \
|
||||
prefix##_unimplemented_##signal (void) \
|
||||
{ \
|
||||
g_warning ("failed to override signal " #prefix "->" #signal); \
|
||||
}
|
||||
|
||||
#else /* G_DISABLE_ASSERT */
|
||||
|
||||
#define EEL_DEFINE_MUST_OVERRIDE_SIGNAL(class_cast_macro, class_pointer, prefix, signal)
|
||||
#define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal)
|
||||
#define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal)
|
||||
|
||||
#endif /* G_DISABLE_ASSERT */
|
||||
|
||||
/* Access a method. */
|
||||
#define EEL_ACCESS_METHOD(class_cast_macro, object, method) \
|
||||
(class_cast_macro (G_OBJECT_GET_CLASS (object))->method)
|
||||
|
||||
/* Invoke a method for a given object. */
|
||||
#define EEL_INVOKE_METHOD(class_cast_macro, object, method, parameters) \
|
||||
((* EEL_ACCESS_METHOD (class_cast_macro, object, method)) parameters)
|
||||
|
||||
/* Assert the non-nullness of a method for a given object. */
|
||||
#define EEL_ASSERT_METHOD(class_cast_macro, object, method) \
|
||||
g_assert (EEL_ACCESS_METHOD (class_cast_macro, object, method) != NULL)
|
||||
|
||||
/* Invoke a method if it ain't null. */
|
||||
#define EEL_INVOKE_METHOD_IF(class_cast_macro, object, method, parameters) \
|
||||
(EEL_ACCESS_METHOD (class_cast_macro, object, method) ? 0 : \
|
||||
EEL_INVOKE_METHOD (class_cast_macro, object, method, parameters))
|
||||
|
||||
#endif /* EEL_GTK_MACROS_H */
|
||||
@@ -74,11 +74,11 @@ static const char *verify_result_str_to_msg(const char *result, gboolean is_swip
|
||||
return N_("Swipe your finger again");
|
||||
}
|
||||
if (strcmp (result, "verify-swipe-too-short") == 0)
|
||||
return N_("Swipe was too short; try again");
|
||||
return N_("Swipe was too short, try again");
|
||||
if (strcmp (result, "verify-finger-not-centered") == 0)
|
||||
return N_("Your finger was not centered; try swiping your finger again");
|
||||
return N_("Your finger was not centered, try swiping your finger again");
|
||||
if (strcmp (result, "verify-remove-and-retry") == 0)
|
||||
return N_("Remove your finger and try swiping it again");
|
||||
return N_("Remove your finger, and try swiping your finger again");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
1622
capplets/about-me/gnome-about-me-dialog.ui
Normal file
604
capplets/about-me/gnome-about-me-fingerprint.c
Normal file
@@ -0,0 +1,604 @@
|
||||
/* gnome-about-me-fingerprint.h
|
||||
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <dbus/dbus-glib-bindings.h>
|
||||
|
||||
#include "fingerprint-strings.h"
|
||||
#include "capplet-util.h"
|
||||
|
||||
/* This must match the number of images on the 2nd page in the UI file */
|
||||
#define MAX_ENROLL_STAGES 3
|
||||
|
||||
static DBusGProxy *manager = NULL;
|
||||
static DBusGConnection *connection = NULL;
|
||||
static gboolean is_disable = FALSE;
|
||||
|
||||
enum {
|
||||
STATE_NONE,
|
||||
STATE_CLAIMED,
|
||||
STATE_ENROLLING
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *enable;
|
||||
GtkWidget *disable;
|
||||
|
||||
GtkWidget *ass;
|
||||
GtkBuilder *dialog;
|
||||
|
||||
DBusGProxy *device;
|
||||
gboolean is_swipe;
|
||||
int num_enroll_stages;
|
||||
int num_stages_done;
|
||||
char *name;
|
||||
const char *finger;
|
||||
gint state;
|
||||
} EnrollData;
|
||||
|
||||
static void create_manager (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if (connection == NULL) {
|
||||
g_warning ("Failed to connect to session bus: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
manager = dbus_g_proxy_new_for_name (connection,
|
||||
"net.reactivated.Fprint",
|
||||
"/net/reactivated/Fprint/Manager",
|
||||
"net.reactivated.Fprint.Manager");
|
||||
}
|
||||
|
||||
static DBusGProxy *
|
||||
get_first_device (void)
|
||||
{
|
||||
DBusGProxy *device;
|
||||
char *device_str;
|
||||
|
||||
if (!dbus_g_proxy_call (manager, "GetDefaultDevice", NULL, G_TYPE_INVALID,
|
||||
DBUS_TYPE_G_OBJECT_PATH, &device_str, G_TYPE_INVALID)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device = dbus_g_proxy_new_for_name(connection,
|
||||
"net.reactivated.Fprint",
|
||||
device_str,
|
||||
"net.reactivated.Fprint.Device");
|
||||
|
||||
g_free (device_str);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_reason_for_error (const char *dbus_error)
|
||||
{
|
||||
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.PermissionDenied"))
|
||||
return N_("You are not allowed to access the device. Contact your system administrator.");
|
||||
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.AlreadyInUse"))
|
||||
return N_("The device is already in use.");
|
||||
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.Internal"))
|
||||
return N_("An internal error occured");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
get_error_dialog (const char *title,
|
||||
const char *dbus_error,
|
||||
GtkWindow *parent)
|
||||
{
|
||||
GtkWidget *error_dialog;
|
||||
const char *reason;
|
||||
|
||||
if (dbus_error == NULL)
|
||||
g_warning ("get_error_dialog called with reason == NULL");
|
||||
|
||||
error_dialog =
|
||||
gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s", title);
|
||||
reason = get_reason_for_error (dbus_error);
|
||||
gtk_message_dialog_format_secondary_text
|
||||
(GTK_MESSAGE_DIALOG (error_dialog), "%s", reason ? _(reason) : _(dbus_error));
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (error_dialog), ""); /* as per HIG */
|
||||
gtk_container_set_border_width (GTK_CONTAINER (error_dialog), 5);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (error_dialog),
|
||||
GTK_RESPONSE_OK);
|
||||
gtk_window_set_modal (GTK_WINDOW (error_dialog), TRUE);
|
||||
gtk_window_set_position (GTK_WINDOW (error_dialog), GTK_WIN_POS_CENTER_ON_PARENT);
|
||||
|
||||
return error_dialog;
|
||||
}
|
||||
|
||||
void
|
||||
set_fingerprint_label (GtkWidget *enable, GtkWidget *disable)
|
||||
{
|
||||
char **fingers;
|
||||
DBusGProxy *device;
|
||||
GError *error = NULL;
|
||||
|
||||
gtk_widget_set_no_show_all (enable, TRUE);
|
||||
gtk_widget_set_no_show_all (disable, TRUE);
|
||||
|
||||
if (manager == NULL) {
|
||||
create_manager ();
|
||||
if (manager == NULL) {
|
||||
gtk_widget_hide (enable);
|
||||
gtk_widget_hide (disable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
device = get_first_device ();
|
||||
if (device == NULL) {
|
||||
gtk_widget_hide (enable);
|
||||
gtk_widget_hide (disable);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dbus_g_proxy_call (device, "ListEnrolledFingers", &error, G_TYPE_STRING, "", G_TYPE_INVALID,
|
||||
G_TYPE_STRV, &fingers, G_TYPE_INVALID)) {
|
||||
if (dbus_g_error_has_name (error, "net.reactivated.Fprint.Error.NoEnrolledPrints") == FALSE) {
|
||||
gtk_widget_hide (enable);
|
||||
gtk_widget_hide (disable);
|
||||
g_object_unref (device);
|
||||
return;
|
||||
}
|
||||
fingers = NULL;
|
||||
}
|
||||
|
||||
if (fingers == NULL || g_strv_length (fingers) == 0) {
|
||||
gtk_widget_hide (disable);
|
||||
gtk_widget_show (enable);
|
||||
is_disable = FALSE;
|
||||
} else {
|
||||
gtk_widget_hide (enable);
|
||||
gtk_widget_show (disable);
|
||||
is_disable = TRUE;
|
||||
}
|
||||
|
||||
g_strfreev (fingers);
|
||||
g_object_unref (device);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_fingerprints (void)
|
||||
{
|
||||
DBusGProxy *device;
|
||||
|
||||
if (manager == NULL) {
|
||||
create_manager ();
|
||||
if (manager == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
device = get_first_device ();
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
dbus_g_proxy_call (device, "DeleteEnrolledFingers", NULL, G_TYPE_STRING, "", G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
|
||||
g_object_unref (device);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_fingerprints_question (GtkBuilder *dialog, GtkWidget *enable, GtkWidget *disable)
|
||||
{
|
||||
GtkWidget *question;
|
||||
GtkWidget *button;
|
||||
|
||||
question = gtk_message_dialog_new (GTK_WINDOW (WID ("about-me-dialog")),
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
_("Delete registered fingerprints?"));
|
||||
gtk_dialog_add_button (GTK_DIALOG (question), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
||||
|
||||
button = gtk_button_new_with_mnemonic (_("_Delete Fingerprints"));
|
||||
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_widget_show (button);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (question), button, GTK_RESPONSE_OK);
|
||||
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (question),
|
||||
_("Do you want to delete your registered fingerprints so fingerprint login is disabled?"));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (question), 5);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (question), GTK_RESPONSE_OK);
|
||||
gtk_window_set_position (GTK_WINDOW (question), GTK_WIN_POS_CENTER_ON_PARENT);
|
||||
gtk_window_set_modal (GTK_WINDOW (question), TRUE);
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (question)) == GTK_RESPONSE_OK) {
|
||||
delete_fingerprints ();
|
||||
set_fingerprint_label (enable, disable);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (question);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_data_destroy (EnrollData *data)
|
||||
{
|
||||
switch (data->state) {
|
||||
case STATE_ENROLLING:
|
||||
dbus_g_proxy_call(data->device, "EnrollStop", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
/* fall-through */
|
||||
case STATE_CLAIMED:
|
||||
dbus_g_proxy_call(data->device, "Release", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
/* fall-through */
|
||||
case STATE_NONE:
|
||||
g_free (data->name);
|
||||
g_object_unref (data->device);
|
||||
g_object_unref (data->dialog);
|
||||
gtk_widget_destroy (data->ass);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
selected_finger (GtkBuilder *dialog)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("radiobutton1")))) {
|
||||
gtk_widget_set_sensitive (WID ("finger_combobox"), FALSE);
|
||||
return "right-index-finger";
|
||||
}
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("radiobutton2")))) {
|
||||
gtk_widget_set_sensitive (WID ("finger_combobox"), FALSE);
|
||||
return "left-index-finger";
|
||||
}
|
||||
gtk_widget_set_sensitive (WID ("finger_combobox"), TRUE);
|
||||
index = gtk_combo_box_get_active (GTK_COMBO_BOX (WID ("finger_combobox")));
|
||||
switch (index) {
|
||||
case 0:
|
||||
return "left-thumb";
|
||||
case 1:
|
||||
return "left-middle-finger";
|
||||
case 2:
|
||||
return "left-ring-finger";
|
||||
case 3:
|
||||
return "left-little-finger";
|
||||
case 4:
|
||||
return "right-thumb";
|
||||
case 5:
|
||||
return "right-middle-finger";
|
||||
case 6:
|
||||
return "right-ring-finger";
|
||||
case 7:
|
||||
return "right-little-finger";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
finger_radio_button_toggled (GtkToggleButton *button, EnrollData *data)
|
||||
{
|
||||
data->finger = selected_finger (data->dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
finger_combobox_changed (GtkComboBox *combobox, EnrollData *data)
|
||||
{
|
||||
data->finger = selected_finger (data->dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
assistant_cancelled (GtkAssistant *ass, EnrollData *data)
|
||||
{
|
||||
GtkWidget *enable, *disable;
|
||||
|
||||
enable = data->enable;
|
||||
disable = data->disable;
|
||||
|
||||
enroll_data_destroy (data);
|
||||
set_fingerprint_label (enable, disable);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_result (GObject *object, const char *result, gboolean done, EnrollData *data)
|
||||
{
|
||||
GtkBuilder *dialog = data->dialog;
|
||||
char *msg;
|
||||
|
||||
if (g_str_equal (result, "enroll-completed") || g_str_equal (result, "enroll-stage-passed")) {
|
||||
char *name, *path;
|
||||
|
||||
data->num_stages_done++;
|
||||
name = g_strdup_printf ("image%d", data->num_stages_done);
|
||||
path = g_build_filename (GNOMECC_PIXMAP_DIR, "print_ok.png", NULL);
|
||||
gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
|
||||
g_free (name);
|
||||
g_free (path);
|
||||
}
|
||||
if (g_str_equal (result, "enroll-completed")) {
|
||||
gtk_label_set_text (GTK_LABEL (WID ("status-label")), _("Done!"));
|
||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (data->ass), WID ("page2"), TRUE);
|
||||
}
|
||||
|
||||
if (done != FALSE) {
|
||||
dbus_g_proxy_call(data->device, "EnrollStop", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
data->state = STATE_CLAIMED;
|
||||
if (g_str_equal (result, "enroll-completed") == FALSE) {
|
||||
/* The enrollment failed, restart it */
|
||||
dbus_g_proxy_call(data->device, "EnrollStart", NULL, G_TYPE_STRING, data->finger, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
data->state = STATE_ENROLLING;
|
||||
result = "enroll-retry-scan";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
msg = g_strdup_printf (enroll_result_str_to_msg (result, data->is_swipe), data->name);
|
||||
gtk_label_set_text (GTK_LABEL (WID ("status-label")), msg);
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
static void
|
||||
assistant_prepare (GtkAssistant *ass, GtkWidget *page, EnrollData *data)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = g_object_get_data (G_OBJECT (page), "name");
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
if (g_str_equal (name, "enroll")) {
|
||||
DBusGProxy *p;
|
||||
GError *error = NULL;
|
||||
GtkBuilder *dialog = data->dialog;
|
||||
char *path;
|
||||
guint i;
|
||||
GValue value = { 0, };
|
||||
|
||||
if (!dbus_g_proxy_call (data->device, "Claim", &error, G_TYPE_STRING, "", G_TYPE_INVALID, G_TYPE_INVALID)) {
|
||||
GtkWidget *d;
|
||||
char *msg;
|
||||
|
||||
/* translators:
|
||||
* The variable is the name of the device, for example:
|
||||
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
||||
msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
|
||||
d = get_error_dialog (msg, dbus_g_error_get_name (error), GTK_WINDOW (data->ass));
|
||||
g_error_free (error);
|
||||
gtk_dialog_run (GTK_DIALOG (d));
|
||||
gtk_widget_destroy (d);
|
||||
g_free (msg);
|
||||
|
||||
enroll_data_destroy (data);
|
||||
|
||||
return;
|
||||
}
|
||||
data->state = STATE_CLAIMED;
|
||||
|
||||
p = dbus_g_proxy_new_from_proxy (data->device, "org.freedesktop.DBus.Properties", NULL);
|
||||
if (!dbus_g_proxy_call (p, "Get", NULL, G_TYPE_STRING, "net.reactivated.Fprint.Device", G_TYPE_STRING, "num-enroll-stages", G_TYPE_INVALID,
|
||||
G_TYPE_VALUE, &value, G_TYPE_INVALID) || g_value_get_int (&value) < 1) {
|
||||
GtkWidget *d;
|
||||
char *msg;
|
||||
|
||||
/* translators:
|
||||
* The variable is the name of the device, for example:
|
||||
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
||||
msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
|
||||
d = get_error_dialog (msg, "net.reactivated.Fprint.Error.Internal", GTK_WINDOW (data->ass));
|
||||
gtk_dialog_run (GTK_DIALOG (d));
|
||||
gtk_widget_destroy (d);
|
||||
g_free (msg);
|
||||
|
||||
enroll_data_destroy (data);
|
||||
|
||||
g_object_unref (p);
|
||||
return;
|
||||
}
|
||||
g_object_unref (p);
|
||||
|
||||
data->num_enroll_stages = g_value_get_int (&value);
|
||||
|
||||
/* Hide the extra "bulbs" if not needed */
|
||||
for (i = MAX_ENROLL_STAGES; i > data->num_enroll_stages; i--) {
|
||||
char *name;
|
||||
|
||||
name = g_strdup_printf ("image%d", i);
|
||||
gtk_widget_hide (WID (name));
|
||||
g_free (name);
|
||||
}
|
||||
/* And set the right image */
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = g_strdup_printf ("%s.png", data->finger);
|
||||
path = g_build_filename (GNOMECC_PIXMAP_DIR, filename, NULL);
|
||||
g_free (filename);
|
||||
}
|
||||
for (i = 1; i <= data->num_enroll_stages; i++) {
|
||||
char *name;
|
||||
name = g_strdup_printf ("image%d", i);
|
||||
gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
|
||||
g_free (name);
|
||||
}
|
||||
g_free (path);
|
||||
|
||||
dbus_g_proxy_add_signal(data->device, "EnrollStatus", G_TYPE_STRING, G_TYPE_BOOLEAN, NULL);
|
||||
dbus_g_proxy_connect_signal(data->device, "EnrollStatus", G_CALLBACK(enroll_result), data, NULL);
|
||||
|
||||
if (!dbus_g_proxy_call(data->device, "EnrollStart", &error, G_TYPE_STRING, data->finger, G_TYPE_INVALID, G_TYPE_INVALID)) {
|
||||
GtkWidget *d;
|
||||
char *msg;
|
||||
|
||||
/* translators:
|
||||
* The variable is the name of the device, for example:
|
||||
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
||||
msg = g_strdup_printf (_("Could not start finger capture on '%s' device"), data->name);
|
||||
d = get_error_dialog (msg, dbus_g_error_get_name (error), GTK_WINDOW (data->ass));
|
||||
g_error_free (error);
|
||||
gtk_dialog_run (GTK_DIALOG (d));
|
||||
gtk_widget_destroy (d);
|
||||
g_free (msg);
|
||||
|
||||
enroll_data_destroy (data);
|
||||
|
||||
return;
|
||||
}
|
||||
data->state = STATE_ENROLLING;;
|
||||
} else {
|
||||
if (data->state == STATE_ENROLLING) {
|
||||
dbus_g_proxy_call(data->device, "EnrollStop", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
data->state = STATE_CLAIMED;
|
||||
}
|
||||
if (data->state == STATE_CLAIMED) {
|
||||
dbus_g_proxy_call(data->device, "Release", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
data->state = STATE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_fingerprints (GtkWindow *parent, GtkWidget *enable, GtkWidget *disable)
|
||||
{
|
||||
DBusGProxy *device, *p;
|
||||
GHashTable *props;
|
||||
GtkBuilder *dialog;
|
||||
EnrollData *data;
|
||||
GtkWidget *ass;
|
||||
char *msg;
|
||||
|
||||
device = NULL;
|
||||
|
||||
if (manager == NULL) {
|
||||
create_manager ();
|
||||
if (manager != NULL)
|
||||
device = get_first_device ();
|
||||
} else {
|
||||
device = get_first_device ();
|
||||
}
|
||||
|
||||
if (manager == NULL || device == NULL) {
|
||||
GtkWidget *d;
|
||||
|
||||
d = get_error_dialog (_("Could not access any fingerprint readers"),
|
||||
_("Please contact your system administrator for help."),
|
||||
parent);
|
||||
gtk_dialog_run (GTK_DIALOG (d));
|
||||
gtk_widget_destroy (d);
|
||||
return;
|
||||
}
|
||||
|
||||
data = g_new0 (EnrollData, 1);
|
||||
data->device = device;
|
||||
data->enable = enable;
|
||||
data->disable = disable;
|
||||
|
||||
/* Get some details about the device */
|
||||
p = dbus_g_proxy_new_from_proxy (device, "org.freedesktop.DBus.Properties", NULL);
|
||||
if (dbus_g_proxy_call (p, "GetAll", NULL, G_TYPE_STRING, "net.reactivated.Fprint.Device", G_TYPE_INVALID,
|
||||
dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props, G_TYPE_INVALID)) {
|
||||
const char *scan_type;
|
||||
data->name = g_value_dup_string (g_hash_table_lookup (props, "name"));
|
||||
scan_type = g_value_dup_string (g_hash_table_lookup (props, "scan-type"));
|
||||
if (g_str_equal (scan_type, "swipe"))
|
||||
data->is_swipe = TRUE;
|
||||
g_hash_table_destroy (props);
|
||||
}
|
||||
g_object_unref (p);
|
||||
|
||||
dialog = gtk_builder_new ();
|
||||
gtk_builder_add_from_file (dialog, GNOMECC_UI_DIR "/gnome-about-me-fingerprint.ui", NULL);
|
||||
data->dialog = dialog;
|
||||
|
||||
ass = WID ("assistant");
|
||||
gtk_window_set_title (GTK_WINDOW (ass), _("Enable Fingerprint Login"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (ass), parent);
|
||||
gtk_window_set_position (GTK_WINDOW (ass), GTK_WIN_POS_CENTER_ON_PARENT);
|
||||
g_signal_connect (G_OBJECT (ass), "cancel",
|
||||
G_CALLBACK (assistant_cancelled), data);
|
||||
g_signal_connect (G_OBJECT (ass), "close",
|
||||
G_CALLBACK (assistant_cancelled), data);
|
||||
g_signal_connect (G_OBJECT (ass), "prepare",
|
||||
G_CALLBACK (assistant_prepare), data);
|
||||
|
||||
/* Page 1 */
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("finger_combobox")), 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (WID ("radiobutton1")), "toggled",
|
||||
G_CALLBACK (finger_radio_button_toggled), data);
|
||||
g_signal_connect (G_OBJECT (WID ("radiobutton2")), "toggled",
|
||||
G_CALLBACK (finger_radio_button_toggled), data);
|
||||
g_signal_connect (G_OBJECT (WID ("radiobutton3")), "toggled",
|
||||
G_CALLBACK (finger_radio_button_toggled), data);
|
||||
g_signal_connect (G_OBJECT (WID ("finger_combobox")), "changed",
|
||||
G_CALLBACK (finger_combobox_changed), data);
|
||||
|
||||
data->finger = selected_finger (dialog);
|
||||
|
||||
g_object_set_data (G_OBJECT (WID("page1")), "name", "intro");
|
||||
|
||||
/* translators:
|
||||
* The variable is the name of the device, for example:
|
||||
* "To enable fingerprint login, you need to save one of your fingerprints, using the
|
||||
* 'Digital Persona U.are.U 4000/4000B' device." */
|
||||
msg = g_strdup_printf (_("To enable fingerprint login, you need to save one of your fingerprints, using the '%s' device."),
|
||||
data->name);
|
||||
gtk_label_set_text (GTK_LABEL (WID("intro-label")), msg);
|
||||
g_free (msg);
|
||||
|
||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (ass), WID("page1"), TRUE);
|
||||
|
||||
/* Page 2 */
|
||||
if (data->is_swipe != FALSE)
|
||||
gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page2"), _("Swipe finger on reader"));
|
||||
else
|
||||
gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page2"), _("Place finger on reader"));
|
||||
|
||||
g_object_set_data (G_OBJECT (WID("page2")), "name", "enroll");
|
||||
|
||||
msg = g_strdup_printf (finger_str_to_msg (data->finger, data->is_swipe), data->name);
|
||||
gtk_label_set_text (GTK_LABEL (WID("enroll-label")), msg);
|
||||
g_free (msg);
|
||||
|
||||
/* Page 3 */
|
||||
g_object_set_data (G_OBJECT (WID("page3")), "name", "summary");
|
||||
|
||||
data->ass = ass;
|
||||
gtk_widget_show_all (ass);
|
||||
}
|
||||
|
||||
void
|
||||
fingerprint_button_clicked (GtkBuilder *dialog,
|
||||
GtkWidget *enable,
|
||||
GtkWidget *disable)
|
||||
{
|
||||
if (is_disable != FALSE) {
|
||||
delete_fingerprints_question (dialog, enable, disable);
|
||||
} else {
|
||||
enroll_fingerprints (GTK_WINDOW (WID ("about-me-dialog")), enable, disable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Bastien Nocera
|
||||
*
|
||||
* Written by: Bastien Nocera <hadess@hadess.net>
|
||||
/* gnome-about-me-fingerprint.h
|
||||
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,14 +17,11 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GNOME_KEYBOARD_PROPERTY_LANG_H
|
||||
#define __GNOME_KEYBOARD_PROPERTY_LANG_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
void set_fingerprint_label (GtkWidget *enable,
|
||||
GtkWidget *disable);
|
||||
void fingerprint_button_clicked (GtkBuilder *dialog,
|
||||
GtkWidget *enable,
|
||||
GtkWidget *disable);
|
||||
|
||||
void setup_language (GtkBuilder *builder);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GNOME_KEYBOARD_PROPERTY_LANG_H */
|
||||
@@ -37,7 +37,6 @@
|
||||
<object class="GtkAssistant" id="assistant">
|
||||
<property name="border_width">12</property>
|
||||
<property name="title" translatable="yes">Enable Fingerprint Login</property>
|
||||
<property name="icon_name">system-users</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
@@ -116,13 +115,12 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="radiobutton3-hbox">
|
||||
<object class="GtkHBox" id="hbox77">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radiobutton3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Other finger: </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
@@ -132,6 +130,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -148,7 +147,7 @@
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
@@ -163,6 +162,9 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="title" translatable="yes">Select finger</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="page2">
|
||||
@@ -216,26 +218,6 @@
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
@@ -255,6 +237,9 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="title">Swipe finger on reader</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="page3">
|
||||
@@ -264,15 +249,8 @@
|
||||
</object>
|
||||
<packing>
|
||||
<property name="page_type">summary</property>
|
||||
<property name="title" translatable="yes">Done!</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="sizegroup">
|
||||
<property name="mode">both</property>
|
||||
<widgets>
|
||||
<widget name="radiobutton1"/>
|
||||
<widget name="radiobutton2"/>
|
||||
<widget name="radiobutton3-hbox"/>
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
||||
1127
capplets/about-me/gnome-about-me-password.c
Normal file
9
capplets/about-me/gnome-about-me-password.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __GNOME_ABOUT_ME_PASSWORD_H__
|
||||
#define __GNOME_ABOUT_ME_PASSWORD_H__
|
||||
|
||||
#include <gtk/gtkwindow.h>
|
||||
|
||||
void
|
||||
gnome_about_me_password (GtkWindow *parent);
|
||||
|
||||
#endif /* __GNOME_ABOUT_ME_PASSWORD_H__ */
|
||||
319
capplets/about-me/gnome-about-me-password.ui
Normal file
@@ -0,0 +1,319 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="change-password">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes">Change password</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="container-hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="dialog-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="icon_name">gtk-dialog-authentication</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="main-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="header-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Change your password</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label" translatable="yes">To change your password, enter your current password in the field below and click <b>Authenticate</b>.
|
||||
After you have authenticated, enter your new password, retype it for verification and click <b>Change password</b>.</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="entry-hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="entry-labels-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current-password-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Current _password:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">current-password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="new-password-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_New password:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">new-password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="retyped-password-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Retype new password:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">retyped-password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="entry-vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="auth-hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="current-password">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="authenticate-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox73">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-apply</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1070">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Authenticate</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="new-password">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="retyped-password">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="activates_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="status-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Please type your password again in the <b>Retype new password</b> field.</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action-area">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel-button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="change-password-button">
|
||||
<property name="label" translatable="yes">Change pa_ssword</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">cancel-button</action-widget>
|
||||
<action-widget response="-5">change-password-button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
1005
capplets/about-me/gnome-about-me.c
Normal file
14
capplets/about-me/gnome-about-me.desktop.in.in
Normal file
@@ -0,0 +1,14 @@
|
||||
[Desktop Entry]
|
||||
_Name=About Me
|
||||
_Comment=Set your personal information
|
||||
Exec=gnome-about-me
|
||||
Icon=user-info
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;X-GNOME-PersonalSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=about-me
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
@@ -29,3 +29,4 @@ pixmaps_DATA = \
|
||||
|
||||
EXTRA_DIST = $(pixmaps_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
@@ -1,4 +1,3 @@
|
||||
SUBDIRS = status apps
|
||||
|
||||
SUBDIRS = at-properties
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
31
capplets/accessibility/at-properties/Makefile.am
Normal file
@@ -0,0 +1,31 @@
|
||||
bin_PROGRAMS = gnome-at-properties
|
||||
|
||||
gnome_at_properties_LDADD = $(AT_CAPPLET_LIBS) $(GNOMECC_CAPPLETS_LIBS) $(top_builddir)/capplets/common/libcommon.la
|
||||
gnome_at_properties_SOURCES = \
|
||||
main.c
|
||||
gnome_at_properties_LDFLAGS = -export-dynamic
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
Desktop_in_files = at-properties.desktop.in
|
||||
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
|
||||
|
||||
pixmapdir = $(pkgdatadir)/pixmaps
|
||||
pixmap_DATA = \
|
||||
at-startup.png \
|
||||
at-support.png
|
||||
|
||||
uidir = $(pkgdatadir)/ui
|
||||
ui_DATA = at-enable-dialog.ui
|
||||
|
||||
INCLUDES = $(AT_CAPPLET_CFLAGS) \
|
||||
$(GNOMECC_CAPPLETS_CFLAGS) \
|
||||
-DUIDIR=\""$(uidir)"\" \
|
||||
-DPIXMAPDIR=\""$(pixmapdir)"\" \
|
||||
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
|
||||
-DGNOMELOCALEDIR="\"$(datadir)/locale\""
|
||||
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) $(Desktop_in_files) $(desktop_DATA)
|
||||
EXTRA_DIST = $(ui_DATA) $(pixmap_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
BIN
capplets/accessibility/at-properties/at-enable-capplet.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
351
capplets/accessibility/at-properties/at-enable-dialog.ui
Normal file
@@ -0,0 +1,351 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="at_properties_dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Assistive Technologies Preferences</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="at_support_frame">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Assistive Technologies</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="at_enable_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="at_pref_button">
|
||||
<property name="label" translatable="yes">_Preferred Applications</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">pref_button_img</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="at_pref_button-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes">Jump to Preferred Applications dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="at_enable_toggle">
|
||||
<property name="label" translatable="yes">_Enable assistive technologies</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="at_enable_toggle-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes">Changes to enable assistive technologies will not take effect until your next log in.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="at_applications_frame">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="pref_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Preferences</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="at_applications_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox8">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="keyboard_button">
|
||||
<property name="label" translatable="yes">_Keyboard Accessibility</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">keyboard_button_img</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="keyboard_button-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes">Jump to the Keyboard Accessibility dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="mouse_button">
|
||||
<property name="label" translatable="yes">_Mouse Accessibility</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">mouse_button_img</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="mouse_button-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes">Jump to the Mouse Accessibility dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="login_button">
|
||||
<property name="label" translatable="yes">Accessible Lo_gin</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">login_button_img</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="login_button-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes">Jump to the Accessible Login dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="at_help_button">
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="at_close_logout_button">
|
||||
<property name="label" translatable="yes">Close and _Log Out</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">close_logout_button_img</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="at_close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-11">at_help_button</action-widget>
|
||||
<action-widget response="0">at_close_logout_button</action-widget>
|
||||
<action-widget response="-7">at_close_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkImage" id="close_logout_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-quit</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="pref_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="keyboard_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="mouse_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="login_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -0,0 +1,14 @@
|
||||
[Desktop Entry]
|
||||
_Name=Assistive Technologies
|
||||
_Comment=Choose which accessibility features to enable when you log in
|
||||
Exec=gnome-at-properties
|
||||
Icon=preferences-desktop-accessibility
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;X-GNOME-PersonalSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=Assistive Technology Preferences
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
BIN
capplets/accessibility/at-properties/at-startup.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
capplets/accessibility/at-properties/at-support.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
293
capplets/accessibility/at-properties/main.c
Normal file
@@ -0,0 +1,293 @@
|
||||
#include <config.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
#define GSM_SERVICE_DBUS "org.gnome.SessionManager"
|
||||
#define GSM_PATH_DBUS "/org/gnome/SessionManager"
|
||||
#define GSM_INTERFACE_DBUS "org.gnome.SessionManager"
|
||||
|
||||
enum {
|
||||
GSM_LOGOUT_MODE_NORMAL = 0,
|
||||
GSM_LOGOUT_MODE_NO_CONFIRMATION,
|
||||
GSM_LOGOUT_MODE_FORCE
|
||||
};
|
||||
|
||||
#include "capplet-util.h"
|
||||
#include "gconf-property-editor.h"
|
||||
#include "activate-settings-daemon.h"
|
||||
|
||||
#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
|
||||
#define ACCESSIBILITY_KEY_DIR "/desktop/gnome/interface"
|
||||
|
||||
static gboolean initial_state;
|
||||
|
||||
static GtkBuilder *
|
||||
create_builder (void)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GError *error = NULL;
|
||||
static const gchar *uifile = UIDIR "/at-enable-dialog.ui";
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
|
||||
if (gtk_builder_add_from_file (builder, uifile, &error)) {
|
||||
GObject *object;
|
||||
gchar *prog;
|
||||
|
||||
object = gtk_builder_get_object (builder, "at_enable_image");
|
||||
gtk_image_set_from_file (GTK_IMAGE (object),
|
||||
PIXMAPDIR "/at-startup.png");
|
||||
|
||||
object = gtk_builder_get_object (builder,
|
||||
"at_applications_image");
|
||||
gtk_image_set_from_file (GTK_IMAGE (object),
|
||||
PIXMAPDIR "/at-support.png");
|
||||
|
||||
prog = g_find_program_in_path ("gdmsetup");
|
||||
if (prog == NULL) {
|
||||
object = gtk_builder_get_object (builder,
|
||||
"login_button");
|
||||
gtk_widget_hide (GTK_WIDGET (object));
|
||||
}
|
||||
|
||||
g_free (prog);
|
||||
} else {
|
||||
g_warning ("Could not load UI: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (builder);
|
||||
builder = NULL;
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_at_preferences (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
g_spawn_command_line_async ("gnome-default-applications-properties --show-page=a11y", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cb_keyboard_preferences (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
g_spawn_command_line_async ("gnome-keyboard-properties --a11y", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cb_mouse_preferences (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
g_spawn_command_line_async ("gnome-mouse-properties --show-page=accessibility", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cb_login_preferences (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
g_spawn_command_line_async ("gdmsetup", NULL);
|
||||
}
|
||||
|
||||
/* get_session_bus(), get_sm_proxy(), and do_logout() are all
|
||||
* based on code from gnome-session-save.c from gnome-session.
|
||||
*/
|
||||
static DBusGConnection *
|
||||
get_session_bus (void)
|
||||
{
|
||||
DBusGConnection *bus;
|
||||
GError *error = NULL;
|
||||
|
||||
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
|
||||
|
||||
if (bus == NULL) {
|
||||
g_warning ("Couldn't connect to session bus: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
static DBusGProxy *
|
||||
get_sm_proxy (void)
|
||||
{
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *sm_proxy;
|
||||
|
||||
if (!(connection = get_session_bus ()))
|
||||
return NULL;
|
||||
|
||||
sm_proxy = dbus_g_proxy_new_for_name (connection,
|
||||
GSM_SERVICE_DBUS,
|
||||
GSM_PATH_DBUS,
|
||||
GSM_INTERFACE_DBUS);
|
||||
|
||||
return sm_proxy;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_logout (GError **err)
|
||||
{
|
||||
DBusGProxy *sm_proxy;
|
||||
GError *error;
|
||||
gboolean res;
|
||||
|
||||
sm_proxy = get_sm_proxy ();
|
||||
if (sm_proxy == NULL)
|
||||
return FALSE;
|
||||
|
||||
res = dbus_g_proxy_call (sm_proxy,
|
||||
"Logout",
|
||||
&error,
|
||||
G_TYPE_UINT, 0, /* '0' means 'log out normally' */
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
if (sm_proxy)
|
||||
g_object_unref (sm_proxy);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_dialog_response (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_HELP)
|
||||
capplet_help (GTK_WINDOW (dialog),
|
||||
"goscustaccess-11");
|
||||
else if (response_id == GTK_RESPONSE_CLOSE || response_id == GTK_RESPONSE_DELETE_EVENT)
|
||||
gtk_main_quit ();
|
||||
else {
|
||||
g_message ("CLOSE AND LOGOUT!");
|
||||
|
||||
if (!do_logout (NULL))
|
||||
gtk_main_quit ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
close_logout_update (GtkBuilder *builder)
|
||||
{
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
gboolean curr_state = gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
|
||||
GObject *btn = gtk_builder_get_object (builder,
|
||||
"at_close_logout_button");
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (btn), initial_state != curr_state);
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_toggled (GtkToggleButton *toggle_button,
|
||||
GtkBuilder *builder)
|
||||
{
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
gboolean is_enabled = gtk_toggle_button_get_active (toggle_button);
|
||||
|
||||
gconf_client_set_bool (client, ACCESSIBILITY_KEY,
|
||||
is_enabled,
|
||||
NULL);
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_update (GConfClient *client,
|
||||
GtkBuilder *builder)
|
||||
{
|
||||
gboolean is_enabled = gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
|
||||
GObject *btn = gtk_builder_get_object (builder, "at_enable_toggle");
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (btn),
|
||||
is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
at_enable_update (client, user_data);
|
||||
close_logout_update (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_dialog (GtkBuilder *builder)
|
||||
{
|
||||
GConfClient *client;
|
||||
GtkWidget *widget;
|
||||
GObject *object;
|
||||
GObject *peditor;
|
||||
|
||||
client = gconf_client_get_default ();
|
||||
|
||||
gconf_client_add_dir (client, ACCESSIBILITY_KEY_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
|
||||
object = gtk_builder_get_object (builder, "at_enable_toggle");
|
||||
g_signal_connect (object, "toggled",
|
||||
G_CALLBACK (at_enable_toggled),
|
||||
builder);
|
||||
|
||||
peditor = gconf_peditor_new_boolean (NULL, ACCESSIBILITY_KEY,
|
||||
GTK_WIDGET (object),
|
||||
NULL);
|
||||
|
||||
initial_state = gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
|
||||
|
||||
at_enable_update (client, builder);
|
||||
|
||||
gconf_client_notify_add (client, ACCESSIBILITY_KEY_DIR,
|
||||
at_enable_changed,
|
||||
builder, NULL, NULL);
|
||||
|
||||
object = gtk_builder_get_object (builder, "at_pref_button");
|
||||
g_signal_connect (object, "clicked",
|
||||
G_CALLBACK (cb_at_preferences), NULL);
|
||||
|
||||
object = gtk_builder_get_object (builder, "keyboard_button");
|
||||
g_signal_connect (object, "clicked",
|
||||
G_CALLBACK (cb_keyboard_preferences), NULL);
|
||||
|
||||
object = gtk_builder_get_object (builder, "mouse_button");
|
||||
g_signal_connect (object, "clicked",
|
||||
G_CALLBACK (cb_mouse_preferences), NULL);
|
||||
|
||||
object = gtk_builder_get_object (builder, "login_button");
|
||||
g_signal_connect (object, "clicked",
|
||||
G_CALLBACK (cb_login_preferences), NULL);
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (builder,
|
||||
"at_properties_dialog"));
|
||||
capplet_set_icon (widget, "preferences-desktop-accessibility");
|
||||
|
||||
g_signal_connect (G_OBJECT (widget),
|
||||
"response",
|
||||
G_CALLBACK (cb_dialog_response), NULL);
|
||||
|
||||
gtk_widget_show (widget);
|
||||
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
capplet_init (NULL, &argc, &argv);
|
||||
|
||||
activate_settings_daemon ();
|
||||
|
||||
builder = create_builder ();
|
||||
|
||||
if (builder) {
|
||||
|
||||
setup_dialog (builder);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
capplets/appearance/Makefile.am
Normal file
@@ -0,0 +1,60 @@
|
||||
SUBDIRS = data
|
||||
|
||||
# This is used in GNOMECC_CAPPLETS_CFLAGS
|
||||
cappletname = appearance
|
||||
|
||||
bin_PROGRAMS = gnome-appearance-properties
|
||||
|
||||
gnome_appearance_properties_SOURCES = \
|
||||
appearance.h \
|
||||
appearance-desktop.c \
|
||||
appearance-desktop.h \
|
||||
appearance-font.c \
|
||||
appearance-font.h \
|
||||
appearance-main.c \
|
||||
appearance-themes.c \
|
||||
appearance-themes.h \
|
||||
appearance-style.c \
|
||||
appearance-style.h \
|
||||
gedit-message-area.c \
|
||||
gedit-message-area.h \
|
||||
gnome-wp-info.c \
|
||||
gnome-wp-info.h \
|
||||
gnome-wp-item.c \
|
||||
gnome-wp-item.h \
|
||||
gnome-wp-xml.c \
|
||||
gnome-wp-xml.h \
|
||||
theme-installer.c \
|
||||
theme-installer.h \
|
||||
theme-save.c \
|
||||
theme-save.h \
|
||||
theme-util.c \
|
||||
theme-util.h
|
||||
|
||||
AM_CFLAGS = -DGNOME_DESKTOP_USE_UNSTABLE_API
|
||||
|
||||
gnome_appearance_properties_LDADD = \
|
||||
$(top_builddir)/libwindow-settings/libgnome-window-settings.la \
|
||||
$(top_builddir)/capplets/common/libcommon.la \
|
||||
$(GNOMECC_CAPPLETS_LIBS) \
|
||||
$(FONT_CAPPLET_LIBS) \
|
||||
$(METACITY_LIBS)
|
||||
gnome_appearance_properties_LDFLAGS = -export-dynamic
|
||||
|
||||
gtkbuilderdir = $(pkgdatadir)/ui
|
||||
pixmapdir = $(pkgdatadir)/pixmaps
|
||||
wallpaperdir = $(datadir)/gnome-background-properties
|
||||
|
||||
INCLUDES = \
|
||||
$(METACITY_CFLAGS) \
|
||||
$(GNOMECC_CAPPLETS_CFLAGS) \
|
||||
$(FONT_CAPPLET_CFLAGS) \
|
||||
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
|
||||
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
|
||||
-DGNOMECC_GTKBUILDER_DIR="\"$(gtkbuilderdir)\"" \
|
||||
-DGNOMECC_PIXMAP_DIR="\"$(pixmapdir)\"" \
|
||||
-DWALLPAPER_DATADIR="\"$(wallpaperdir)\""
|
||||
|
||||
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
1310
capplets/appearance/appearance-desktop.c
Normal file
@@ -1,6 +1,7 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Denis Washington <denisw@svn.gnome.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -12,24 +13,10 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __GVC_LOG_H
|
||||
#define __GVC_LOG_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void gvc_log_init (void);
|
||||
void gvc_log_set_debug (gboolean debug);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GVC_LOG_H */
|
||||
void desktop_init (AppearanceData *data, const gchar **uris);
|
||||
void desktop_shutdown (AppearanceData *data);
|
||||
984
capplets/appearance/appearance-font.c
Normal file
@@ -0,0 +1,984 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Jonathan Blandford <jrb@gnome.org>
|
||||
* Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "appearance.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_XFT2
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
#endif /* HAVE_XFT2 */
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "capplet-util.h"
|
||||
#include "gconf-property-editor.h"
|
||||
|
||||
#define GTK_FONT_KEY "/desktop/gnome/interface/font_name"
|
||||
#define DESKTOP_FONT_KEY "/apps/nautilus/preferences/desktop_font"
|
||||
|
||||
#define METACITY_DIR "/apps/metacity/general"
|
||||
#define WINDOW_TITLE_FONT_KEY METACITY_DIR "/titlebar_font"
|
||||
#define WINDOW_TITLE_USES_SYSTEM_KEY METACITY_DIR "/titlebar_uses_system_font"
|
||||
#define MONOSPACE_FONT_KEY "/desktop/gnome/interface/monospace_font_name"
|
||||
#define DOCUMENT_FONT_KEY "/desktop/gnome/interface/document_font_name"
|
||||
|
||||
#ifdef HAVE_XFT2
|
||||
#define FONT_RENDER_DIR "/desktop/gnome/font_rendering"
|
||||
#define FONT_ANTIALIASING_KEY FONT_RENDER_DIR "/antialiasing"
|
||||
#define FONT_HINTING_KEY FONT_RENDER_DIR "/hinting"
|
||||
#define FONT_RGBA_ORDER_KEY FONT_RENDER_DIR "/rgba_order"
|
||||
#define FONT_DPI_KEY FONT_RENDER_DIR "/dpi"
|
||||
|
||||
/* X servers sometimes lie about the screen's physical dimensions, so we cannot
|
||||
* compute an accurate DPI value. When this happens, the user gets fonts that
|
||||
* are too huge or too tiny. So, we see what the server returns: if it reports
|
||||
* something outside of the range [DPI_LOW_REASONABLE_VALUE,
|
||||
* DPI_HIGH_REASONABLE_VALUE], then we assume that it is lying and we use
|
||||
* DPI_FALLBACK instead.
|
||||
*
|
||||
* See get_dpi_from_gconf_or_server() below, and also
|
||||
* https://bugzilla.novell.com/show_bug.cgi?id=217790
|
||||
*/
|
||||
#define DPI_FALLBACK 96
|
||||
#define DPI_LOW_REASONABLE_VALUE 50
|
||||
#define DPI_HIGH_REASONABLE_VALUE 500
|
||||
#endif /* HAVE_XFT2 */
|
||||
|
||||
static gboolean in_change = FALSE;
|
||||
static gchar *old_font = NULL;
|
||||
|
||||
#define MAX_FONT_POINT_WITHOUT_WARNING 32
|
||||
#define MAX_FONT_SIZE_WITHOUT_WARNING MAX_FONT_POINT_WITHOUT_WARNING*1024
|
||||
|
||||
#ifdef HAVE_XFT2
|
||||
|
||||
/*
|
||||
* Code for displaying previews of font rendering with various Xft options
|
||||
*/
|
||||
|
||||
static void
|
||||
sample_size_request (GtkWidget *darea,
|
||||
GtkRequisition *requisition)
|
||||
{
|
||||
GdkPixbuf *pixbuf = g_object_get_data (G_OBJECT (darea), "sample-pixbuf");
|
||||
|
||||
requisition->width = gdk_pixbuf_get_width (pixbuf) + 2;
|
||||
requisition->height = gdk_pixbuf_get_height (pixbuf) + 2;
|
||||
}
|
||||
|
||||
static void
|
||||
sample_expose (GtkWidget *darea,
|
||||
GdkEventExpose *expose)
|
||||
{
|
||||
GdkPixbuf *pixbuf = g_object_get_data (G_OBJECT (darea), "sample-pixbuf");
|
||||
int width = gdk_pixbuf_get_width (pixbuf);
|
||||
int height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
int x = (darea->allocation.width - width) / 2;
|
||||
int y = (darea->allocation.height - height) / 2;
|
||||
|
||||
gdk_draw_rectangle (darea->window, darea->style->white_gc, TRUE,
|
||||
0, 0,
|
||||
darea->allocation.width, darea->allocation.height);
|
||||
gdk_draw_rectangle (darea->window, darea->style->black_gc, FALSE,
|
||||
0, 0,
|
||||
darea->allocation.width - 1, darea->allocation.height - 1);
|
||||
|
||||
gdk_draw_pixbuf (darea->window, NULL, pixbuf, 0, 0, x, y, width, height,
|
||||
GDK_RGB_DITHER_NORMAL, 0, 0);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
ANTIALIAS_NONE,
|
||||
ANTIALIAS_GRAYSCALE,
|
||||
ANTIALIAS_RGBA
|
||||
} Antialiasing;
|
||||
|
||||
static GConfEnumStringPair antialias_enums[] = {
|
||||
{ ANTIALIAS_NONE, "none" },
|
||||
{ ANTIALIAS_GRAYSCALE, "grayscale" },
|
||||
{ ANTIALIAS_RGBA, "rgba" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
HINT_NONE,
|
||||
HINT_SLIGHT,
|
||||
HINT_MEDIUM,
|
||||
HINT_FULL
|
||||
} Hinting;
|
||||
|
||||
static GConfEnumStringPair hint_enums[] = {
|
||||
{ HINT_NONE, "none" },
|
||||
{ HINT_SLIGHT, "slight" },
|
||||
{ HINT_MEDIUM, "medium" },
|
||||
{ HINT_FULL, "full" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
RGBA_RGB,
|
||||
RGBA_BGR,
|
||||
RGBA_VRGB,
|
||||
RGBA_VBGR
|
||||
} RgbaOrder;
|
||||
|
||||
static GConfEnumStringPair rgba_order_enums[] = {
|
||||
{ RGBA_RGB, "rgb" },
|
||||
{ RGBA_BGR, "bgr" },
|
||||
{ RGBA_VRGB, "vrgb" },
|
||||
{ RGBA_VBGR, "vbgr" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static XftFont *
|
||||
open_pattern (FcPattern *pattern,
|
||||
Antialiasing antialiasing,
|
||||
Hinting hinting)
|
||||
{
|
||||
#ifdef FC_HINT_STYLE
|
||||
static const int hintstyles[] = {
|
||||
FC_HINT_NONE, FC_HINT_SLIGHT, FC_HINT_MEDIUM, FC_HINT_FULL
|
||||
};
|
||||
#endif /* FC_HINT_STYLE */
|
||||
|
||||
FcPattern *res_pattern;
|
||||
FcResult result;
|
||||
XftFont *font;
|
||||
|
||||
Display *xdisplay = gdk_x11_get_default_xdisplay ();
|
||||
int screen = gdk_x11_get_default_screen ();
|
||||
|
||||
res_pattern = XftFontMatch (xdisplay, screen, pattern, &result);
|
||||
if (res_pattern == NULL)
|
||||
return NULL;
|
||||
|
||||
FcPatternDel (res_pattern, FC_HINTING);
|
||||
FcPatternAddBool (res_pattern, FC_HINTING, hinting != HINT_NONE);
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
FcPatternDel (res_pattern, FC_HINT_STYLE);
|
||||
FcPatternAddInteger (res_pattern, FC_HINT_STYLE, hintstyles[hinting]);
|
||||
#endif /* FC_HINT_STYLE */
|
||||
|
||||
FcPatternDel (res_pattern, FC_ANTIALIAS);
|
||||
FcPatternAddBool (res_pattern, FC_ANTIALIAS, antialiasing != ANTIALIAS_NONE);
|
||||
|
||||
FcPatternDel (res_pattern, FC_RGBA);
|
||||
FcPatternAddInteger (res_pattern, FC_RGBA,
|
||||
antialiasing == ANTIALIAS_RGBA ? FC_RGBA_RGB : FC_RGBA_NONE);
|
||||
|
||||
FcPatternDel (res_pattern, FC_DPI);
|
||||
FcPatternAddInteger (res_pattern, FC_DPI, 96);
|
||||
|
||||
font = XftFontOpenPattern (xdisplay, res_pattern);
|
||||
if (!font)
|
||||
FcPatternDestroy (res_pattern);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_font_sample (GtkWidget *darea,
|
||||
Antialiasing antialiasing,
|
||||
Hinting hinting)
|
||||
{
|
||||
const char *string1 = "abcfgop AO ";
|
||||
const char *string2 = "abcfgop";
|
||||
|
||||
XftColor black, white;
|
||||
XRenderColor rendcolor;
|
||||
|
||||
Display *xdisplay = gdk_x11_get_default_xdisplay ();
|
||||
|
||||
GdkColormap *colormap = gdk_rgb_get_colormap ();
|
||||
Colormap xcolormap = GDK_COLORMAP_XCOLORMAP (colormap);
|
||||
|
||||
GdkVisual *visual = gdk_colormap_get_visual (colormap);
|
||||
Visual *xvisual = GDK_VISUAL_XVISUAL (visual);
|
||||
|
||||
FcPattern *pattern;
|
||||
XftFont *font1, *font2;
|
||||
XGlyphInfo extents1 = { 0 };
|
||||
XGlyphInfo extents2 = { 0 };
|
||||
GdkPixmap *pixmap;
|
||||
XftDraw *draw;
|
||||
GdkPixbuf *tmp_pixbuf, *pixbuf;
|
||||
|
||||
int width, height;
|
||||
int ascent, descent;
|
||||
|
||||
pattern = FcPatternBuild (NULL,
|
||||
FC_FAMILY, FcTypeString, "Serif",
|
||||
FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN,
|
||||
FC_SIZE, FcTypeDouble, 18.,
|
||||
NULL);
|
||||
font1 = open_pattern (pattern, antialiasing, hinting);
|
||||
FcPatternDestroy (pattern);
|
||||
|
||||
pattern = FcPatternBuild (NULL,
|
||||
FC_FAMILY, FcTypeString, "Serif",
|
||||
FC_SLANT, FcTypeInteger, FC_SLANT_ITALIC,
|
||||
FC_SIZE, FcTypeDouble, 20.,
|
||||
NULL);
|
||||
font2 = open_pattern (pattern, antialiasing, hinting);
|
||||
FcPatternDestroy (pattern);
|
||||
|
||||
ascent = 0;
|
||||
descent = 0;
|
||||
if (font1) {
|
||||
XftTextExtentsUtf8 (xdisplay, font1, (unsigned char *) string1,
|
||||
strlen (string1), &extents1);
|
||||
ascent = MAX (ascent, font1->ascent);
|
||||
descent = MAX (descent, font1->descent);
|
||||
}
|
||||
|
||||
if (font2) {
|
||||
XftTextExtentsUtf8 (xdisplay, font2, (unsigned char *) string2,
|
||||
strlen (string2), &extents2);
|
||||
ascent = MAX (ascent, font2->ascent);
|
||||
descent = MAX (descent, font2->descent);
|
||||
}
|
||||
|
||||
width = extents1.xOff + extents2.xOff + 4;
|
||||
height = ascent + descent + 2;
|
||||
|
||||
pixmap = gdk_pixmap_new (NULL, width, height, visual->depth);
|
||||
|
||||
draw = XftDrawCreate (xdisplay, GDK_DRAWABLE_XID (pixmap), xvisual, xcolormap);
|
||||
|
||||
rendcolor.red = 0;
|
||||
rendcolor.green = 0;
|
||||
rendcolor.blue = 0;
|
||||
rendcolor.alpha = 0xffff;
|
||||
XftColorAllocValue (xdisplay, xvisual, xcolormap, &rendcolor, &black);
|
||||
|
||||
rendcolor.red = 0xffff;
|
||||
rendcolor.green = 0xffff;
|
||||
rendcolor.blue = 0xffff;
|
||||
rendcolor.alpha = 0xffff;
|
||||
XftColorAllocValue (xdisplay, xvisual, xcolormap, &rendcolor, &white);
|
||||
XftDrawRect (draw, &white, 0, 0, width, height);
|
||||
if (font1)
|
||||
XftDrawStringUtf8 (draw, &black, font1,
|
||||
2, 2 + ascent,
|
||||
(unsigned char *) string1, strlen (string1));
|
||||
if (font2)
|
||||
XftDrawStringUtf8 (draw, &black, font2,
|
||||
2 + extents1.xOff, 2 + ascent,
|
||||
(unsigned char *) string2, strlen (string2));
|
||||
|
||||
XftDrawDestroy (draw);
|
||||
|
||||
if (font1)
|
||||
XftFontClose (xdisplay, font1);
|
||||
if (font2)
|
||||
XftFontClose (xdisplay, font2);
|
||||
|
||||
tmp_pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, colormap, 0, 0, 0, 0, width, height);
|
||||
pixbuf = gdk_pixbuf_scale_simple (tmp_pixbuf, 1 * width, 1 * height, GDK_INTERP_TILES);
|
||||
|
||||
g_object_unref (pixmap);
|
||||
g_object_unref (tmp_pixbuf);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (darea), "sample-pixbuf",
|
||||
pixbuf, (GDestroyNotify) g_object_unref);
|
||||
|
||||
g_signal_connect (darea, "size_request", G_CALLBACK (sample_size_request), NULL);
|
||||
g_signal_connect (darea, "expose_event", G_CALLBACK (sample_expose), NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Code implementing a group of radio buttons with different Xft option combinations.
|
||||
* If one of the buttons is matched by the GConf key, we pick it. Otherwise we
|
||||
* show the group as inconsistent.
|
||||
*/
|
||||
static void
|
||||
font_render_get_gconf (GConfClient *client,
|
||||
Antialiasing *antialiasing,
|
||||
Hinting *hinting)
|
||||
{
|
||||
gchar *antialias_str = gconf_client_get_string (client, FONT_ANTIALIASING_KEY, NULL);
|
||||
gchar *hint_str = gconf_client_get_string (client, FONT_HINTING_KEY, NULL);
|
||||
gint val;
|
||||
|
||||
val = ANTIALIAS_GRAYSCALE;
|
||||
if (antialias_str) {
|
||||
gconf_string_to_enum (antialias_enums, antialias_str, &val);
|
||||
g_free (antialias_str);
|
||||
}
|
||||
*antialiasing = val;
|
||||
|
||||
val = HINT_FULL;
|
||||
if (hint_str) {
|
||||
gconf_string_to_enum (hint_enums, hint_str, &val);
|
||||
g_free (hint_str);
|
||||
}
|
||||
*hinting = val;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Antialiasing antialiasing;
|
||||
Hinting hinting;
|
||||
GtkToggleButton *radio;
|
||||
} FontPair;
|
||||
|
||||
static GSList *font_pairs = NULL;
|
||||
|
||||
static void
|
||||
font_render_load (GConfClient *client)
|
||||
{
|
||||
Antialiasing antialiasing;
|
||||
Hinting hinting;
|
||||
gboolean inconsistent = TRUE;
|
||||
GSList *tmp_list;
|
||||
|
||||
font_render_get_gconf (client, &antialiasing, &hinting);
|
||||
|
||||
in_change = TRUE;
|
||||
|
||||
for (tmp_list = font_pairs; tmp_list; tmp_list = tmp_list->next) {
|
||||
FontPair *pair = tmp_list->data;
|
||||
|
||||
if (antialiasing == pair->antialiasing && hinting == pair->hinting) {
|
||||
gtk_toggle_button_set_active (pair->radio, TRUE);
|
||||
inconsistent = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (tmp_list = font_pairs; tmp_list; tmp_list = tmp_list->next) {
|
||||
FontPair *pair = tmp_list->data;
|
||||
|
||||
gtk_toggle_button_set_inconsistent (pair->radio, inconsistent);
|
||||
}
|
||||
|
||||
in_change = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
font_render_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
font_render_load (client);
|
||||
}
|
||||
|
||||
static void
|
||||
font_radio_toggled (GtkToggleButton *toggle_button,
|
||||
FontPair *pair)
|
||||
{
|
||||
if (!in_change) {
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
|
||||
gconf_client_set_string (client, FONT_ANTIALIASING_KEY,
|
||||
gconf_enum_to_string (antialias_enums, pair->antialiasing),
|
||||
NULL);
|
||||
gconf_client_set_string (client, FONT_HINTING_KEY,
|
||||
gconf_enum_to_string (hint_enums, pair->hinting),
|
||||
NULL);
|
||||
|
||||
/* Restore back to the previous state until we get notification */
|
||||
font_render_load (client);
|
||||
g_object_unref (client);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_font_pair (GtkWidget *radio,
|
||||
GtkWidget *darea,
|
||||
Antialiasing antialiasing,
|
||||
Hinting hinting)
|
||||
{
|
||||
FontPair *pair = g_new (FontPair, 1);
|
||||
|
||||
pair->antialiasing = antialiasing;
|
||||
pair->hinting = hinting;
|
||||
pair->radio = GTK_TOGGLE_BUTTON (radio);
|
||||
|
||||
setup_font_sample (darea, antialiasing, hinting);
|
||||
font_pairs = g_slist_prepend (font_pairs, pair);
|
||||
|
||||
g_signal_connect (radio, "toggled",
|
||||
G_CALLBACK (font_radio_toggled), pair);
|
||||
}
|
||||
#endif /* HAVE_XFT2 */
|
||||
|
||||
static void
|
||||
metacity_titlebar_load_sensitivity (AppearanceData *data)
|
||||
{
|
||||
gtk_widget_set_sensitive (appearance_capplet_get_widget (data, "window_title_font"),
|
||||
!gconf_client_get_bool (data->client,
|
||||
WINDOW_TITLE_USES_SYSTEM_KEY,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
metacity_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
metacity_titlebar_load_sensitivity (user_data);
|
||||
}
|
||||
|
||||
/* returns 0 if the font is safe, otherwise returns the size in points. */
|
||||
static gint
|
||||
font_dangerous (const char *font)
|
||||
{
|
||||
PangoFontDescription *pfd;
|
||||
gboolean retval = 0;
|
||||
|
||||
pfd = pango_font_description_from_string (font);
|
||||
if (pfd == NULL)
|
||||
/* an invalid font was passed in. This isn't our problem. */
|
||||
return 0;
|
||||
|
||||
if ((pango_font_description_get_set_fields (pfd) & PANGO_FONT_MASK_SIZE) &&
|
||||
(pango_font_description_get_size (pfd) >= MAX_FONT_SIZE_WITHOUT_WARNING)) {
|
||||
retval = pango_font_description_get_size (pfd)/1024;
|
||||
}
|
||||
pango_font_description_free (pfd);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static GConfValue *
|
||||
application_font_to_gconf (GConfPropertyEditor *peditor,
|
||||
GConfValue *value)
|
||||
{
|
||||
GConfValue *new_value;
|
||||
const char *new_font;
|
||||
GtkWidget *font_button;
|
||||
gint danger_level;
|
||||
|
||||
font_button = GTK_WIDGET (gconf_property_editor_get_ui_control (peditor));
|
||||
g_return_val_if_fail (font_button != NULL, NULL);
|
||||
|
||||
new_value = gconf_value_new (GCONF_VALUE_STRING);
|
||||
new_font = gconf_value_get_string (value);
|
||||
if (font_dangerous (old_font)) {
|
||||
/* If we're already too large, we don't warn again. */
|
||||
gconf_value_set_string (new_value, new_font);
|
||||
return new_value;
|
||||
}
|
||||
|
||||
danger_level = font_dangerous (new_font);
|
||||
if (danger_level) {
|
||||
GtkWidget *warning_dialog, *apply_button;
|
||||
const gchar *warning_label;
|
||||
gchar *warning_label2;
|
||||
|
||||
warning_label = _("Font may be too large");
|
||||
|
||||
if (danger_level > MAX_FONT_POINT_WITHOUT_WARNING) {
|
||||
warning_label2 = g_strdup_printf (ngettext (
|
||||
"The font selected is %d point large, "
|
||||
"and may make it difficult to effectively "
|
||||
"use the computer. It is recommended that "
|
||||
"you select a size smaller than %d.",
|
||||
"The font selected is %d points large, "
|
||||
"and may make it difficult to effectively "
|
||||
"use the computer. It is recommended that "
|
||||
"you select a size smaller than %d.",
|
||||
danger_level),
|
||||
danger_level,
|
||||
MAX_FONT_POINT_WITHOUT_WARNING);
|
||||
} else {
|
||||
warning_label2 = g_strdup_printf (ngettext (
|
||||
"The font selected is %d point large, "
|
||||
"and may make it difficult to effectively "
|
||||
"use the computer. It is recommended that "
|
||||
"you select a smaller sized font.",
|
||||
"The font selected is %d points large, "
|
||||
"and may make it difficult to effectively "
|
||||
"use the computer. It is recommended that "
|
||||
"you select a smaller sized font.",
|
||||
danger_level),
|
||||
danger_level);
|
||||
}
|
||||
|
||||
warning_dialog = gtk_message_dialog_new (NULL,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_BUTTONS_NONE,
|
||||
"%s",
|
||||
warning_label);
|
||||
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (warning_dialog),
|
||||
"%s", warning_label2);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (warning_dialog),
|
||||
_("Use previous font"), GTK_RESPONSE_CLOSE);
|
||||
|
||||
apply_button = gtk_button_new_with_label (_("Use selected font"));
|
||||
|
||||
gtk_button_set_image (GTK_BUTTON (apply_button), gtk_image_new_from_stock (GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON));
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (warning_dialog), apply_button, GTK_RESPONSE_APPLY);
|
||||
GTK_WIDGET_SET_FLAGS (apply_button, GTK_CAN_DEFAULT);
|
||||
gtk_widget_show (apply_button);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (warning_dialog), GTK_RESPONSE_CLOSE);
|
||||
|
||||
g_free (warning_label2);
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (warning_dialog)) == GTK_RESPONSE_APPLY) {
|
||||
gconf_value_set_string (new_value, new_font);
|
||||
} else {
|
||||
gconf_value_set_string (new_value, old_font);
|
||||
gtk_font_button_set_font_name (GTK_FONT_BUTTON (font_button), old_font);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (warning_dialog);
|
||||
} else {
|
||||
gconf_value_set_string (new_value, new_font);
|
||||
}
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
static void
|
||||
application_font_changed (GtkWidget *font_button)
|
||||
{
|
||||
const gchar *font;
|
||||
|
||||
font = gtk_font_button_get_font_name (GTK_FONT_BUTTON (font_button));
|
||||
g_free (old_font);
|
||||
old_font = g_strdup (font);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XFT2
|
||||
/*
|
||||
* EnumGroup - a group of radio buttons tied to a string enumeration
|
||||
* value. We add this here because the gconf peditor
|
||||
* equivalent of this is both painful to use (you have
|
||||
* to supply functions to convert from enums to indices)
|
||||
* and conceptually broken (the order of radio buttons
|
||||
* in a group when using Glade is not predictable.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GConfClient *client;
|
||||
GSList *items;
|
||||
gchar *gconf_key;
|
||||
GConfEnumStringPair *enums;
|
||||
int default_value;
|
||||
} EnumGroup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EnumGroup *group;
|
||||
GtkToggleButton *widget;
|
||||
int value;
|
||||
} EnumItem;
|
||||
|
||||
static void
|
||||
enum_group_load (EnumGroup *group)
|
||||
{
|
||||
gchar *str = gconf_client_get_string (group->client, group->gconf_key, NULL);
|
||||
gint val = group->default_value;
|
||||
GSList *tmp_list;
|
||||
|
||||
if (str)
|
||||
gconf_string_to_enum (group->enums, str, &val);
|
||||
|
||||
g_free (str);
|
||||
|
||||
in_change = TRUE;
|
||||
|
||||
for (tmp_list = group->items; tmp_list; tmp_list = tmp_list->next) {
|
||||
EnumItem *item = tmp_list->data;
|
||||
|
||||
if (val == item->value)
|
||||
gtk_toggle_button_set_active (item->widget, TRUE);
|
||||
}
|
||||
|
||||
in_change = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
enum_group_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
enum_group_load (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
enum_item_toggled (GtkToggleButton *toggle_button,
|
||||
EnumItem *item)
|
||||
{
|
||||
EnumGroup *group = item->group;
|
||||
|
||||
if (!in_change) {
|
||||
gconf_client_set_string (group->client, group->gconf_key,
|
||||
gconf_enum_to_string (group->enums, item->value),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Restore back to the previous state until we get notification */
|
||||
enum_group_load (group);
|
||||
}
|
||||
|
||||
static EnumGroup *
|
||||
enum_group_create (const gchar *gconf_key,
|
||||
GConfEnumStringPair *enums,
|
||||
int default_value,
|
||||
GtkWidget *first_widget,
|
||||
...)
|
||||
{
|
||||
EnumGroup *group;
|
||||
GtkWidget *widget;
|
||||
va_list args;
|
||||
|
||||
group = g_new (EnumGroup, 1);
|
||||
|
||||
group->client = gconf_client_get_default ();
|
||||
group->gconf_key = g_strdup (gconf_key);
|
||||
group->enums = enums;
|
||||
group->default_value = default_value;
|
||||
group->items = NULL;
|
||||
|
||||
va_start (args, first_widget);
|
||||
|
||||
widget = first_widget;
|
||||
while (widget) {
|
||||
EnumItem *item;
|
||||
|
||||
item = g_new (EnumItem, 1);
|
||||
item->group = group;
|
||||
item->widget = GTK_TOGGLE_BUTTON (widget);
|
||||
item->value = va_arg (args, int);
|
||||
|
||||
g_signal_connect (item->widget, "toggled",
|
||||
G_CALLBACK (enum_item_toggled), item);
|
||||
|
||||
group->items = g_slist_prepend (group->items, item);
|
||||
|
||||
widget = va_arg (args, GtkWidget *);
|
||||
}
|
||||
|
||||
va_end (args);
|
||||
|
||||
enum_group_load (group);
|
||||
|
||||
gconf_client_notify_add (group->client, gconf_key,
|
||||
enum_group_changed,
|
||||
group, NULL, NULL);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static void
|
||||
enum_group_destroy (EnumGroup *group)
|
||||
{
|
||||
g_object_unref (group->client);
|
||||
g_free (group->gconf_key);
|
||||
|
||||
g_slist_foreach (group->items, (GFunc) g_free, NULL);
|
||||
g_slist_free (group->items);
|
||||
|
||||
g_free (group);
|
||||
}
|
||||
|
||||
static double
|
||||
dpi_from_pixels_and_mm (int pixels, int mm)
|
||||
{
|
||||
double dpi;
|
||||
|
||||
if (mm >= 1)
|
||||
dpi = pixels / (mm / 25.4);
|
||||
else
|
||||
dpi = 0;
|
||||
|
||||
return dpi;
|
||||
}
|
||||
|
||||
static double
|
||||
get_dpi_from_x_server (void)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
double dpi;
|
||||
|
||||
screen = gdk_screen_get_default ();
|
||||
if (screen) {
|
||||
double width_dpi, height_dpi;
|
||||
|
||||
width_dpi = dpi_from_pixels_and_mm (gdk_screen_get_width (screen),
|
||||
gdk_screen_get_width_mm (screen));
|
||||
height_dpi = dpi_from_pixels_and_mm (gdk_screen_get_height (screen),
|
||||
gdk_screen_get_height_mm (screen));
|
||||
|
||||
if (width_dpi < DPI_LOW_REASONABLE_VALUE || width_dpi > DPI_HIGH_REASONABLE_VALUE ||
|
||||
height_dpi < DPI_LOW_REASONABLE_VALUE || height_dpi > DPI_HIGH_REASONABLE_VALUE)
|
||||
dpi = DPI_FALLBACK;
|
||||
else
|
||||
dpi = (width_dpi + height_dpi) / 2.0;
|
||||
} else {
|
||||
/* Huh!? No screen? */
|
||||
dpi = DPI_FALLBACK;
|
||||
}
|
||||
|
||||
return dpi;
|
||||
}
|
||||
|
||||
/*
|
||||
* The font rendering details dialog
|
||||
*/
|
||||
static void
|
||||
dpi_load (GConfClient *client,
|
||||
GtkSpinButton *spinner)
|
||||
{
|
||||
GConfValue *value;
|
||||
gdouble dpi;
|
||||
|
||||
value = gconf_client_get_without_default (client, FONT_DPI_KEY, NULL);
|
||||
|
||||
if (value) {
|
||||
dpi = gconf_value_get_float (value);
|
||||
gconf_value_free (value);
|
||||
} else
|
||||
dpi = get_dpi_from_x_server ();
|
||||
|
||||
if (dpi < DPI_LOW_REASONABLE_VALUE)
|
||||
dpi = DPI_LOW_REASONABLE_VALUE;
|
||||
|
||||
in_change = TRUE;
|
||||
gtk_spin_button_set_value (spinner, dpi);
|
||||
in_change = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
dpi_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
dpi_load (client, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
dpi_value_changed (GtkSpinButton *spinner,
|
||||
GConfClient *client)
|
||||
{
|
||||
/* Like any time when using a spin button with GConf, there is
|
||||
* a race condition here. When we change, we send the new
|
||||
* value to GConf, then restore to the old value until
|
||||
* we get a response to emulate the proper model/view behavior.
|
||||
*
|
||||
* If the user changes the value faster than responses are
|
||||
* received from GConf, this may cause mildly strange effects.
|
||||
*/
|
||||
if (!in_change) {
|
||||
gdouble new_dpi = gtk_spin_button_get_value (spinner);
|
||||
|
||||
gconf_client_set_float (client, FONT_DPI_KEY, new_dpi, NULL);
|
||||
|
||||
dpi_load (client, spinner);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_details_response (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_HELP) {
|
||||
capplet_help (GTK_WINDOW (dialog),
|
||||
"goscustdesk-38");
|
||||
} else
|
||||
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
cb_show_details (GtkWidget *button,
|
||||
AppearanceData *data)
|
||||
{
|
||||
if (!data->font_details) {
|
||||
GtkAdjustment *adjustment;
|
||||
GtkWidget *widget;
|
||||
EnumGroup *group;
|
||||
|
||||
data->font_details = appearance_capplet_get_widget (data, "render_details");
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (data->font_details),
|
||||
GTK_WINDOW (appearance_capplet_get_widget (data, "appearance_window")));
|
||||
|
||||
widget = appearance_capplet_get_widget (data, "dpi_spinner");
|
||||
|
||||
/* pick a sensible maximum dpi */
|
||||
adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));
|
||||
adjustment->upper = DPI_HIGH_REASONABLE_VALUE;
|
||||
adjustment->lower = DPI_LOW_REASONABLE_VALUE;
|
||||
adjustment->step_increment = 1;
|
||||
|
||||
dpi_load (data->client, GTK_SPIN_BUTTON (widget));
|
||||
g_signal_connect (widget, "value_changed",
|
||||
G_CALLBACK (dpi_value_changed), data->client);
|
||||
|
||||
gconf_client_notify_add (data->client, FONT_DPI_KEY,
|
||||
dpi_changed, widget, NULL, NULL);
|
||||
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "antialias_none_sample"), ANTIALIAS_NONE, HINT_FULL);
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "antialias_grayscale_sample"), ANTIALIAS_GRAYSCALE, HINT_FULL);
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "antialias_subpixel_sample"), ANTIALIAS_RGBA, HINT_FULL);
|
||||
|
||||
group = enum_group_create (
|
||||
FONT_ANTIALIASING_KEY, antialias_enums, ANTIALIAS_GRAYSCALE,
|
||||
appearance_capplet_get_widget (data, "antialias_none_radio"), ANTIALIAS_NONE,
|
||||
appearance_capplet_get_widget (data, "antialias_grayscale_radio"), ANTIALIAS_GRAYSCALE,
|
||||
appearance_capplet_get_widget (data, "antialias_subpixel_radio"), ANTIALIAS_RGBA,
|
||||
NULL);
|
||||
data->font_groups = g_slist_prepend (data->font_groups, group);
|
||||
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "hint_none_sample"), ANTIALIAS_GRAYSCALE, HINT_NONE);
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "hint_slight_sample"), ANTIALIAS_GRAYSCALE, HINT_SLIGHT);
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "hint_medium_sample"), ANTIALIAS_GRAYSCALE, HINT_MEDIUM);
|
||||
setup_font_sample (appearance_capplet_get_widget (data, "hint_full_sample"), ANTIALIAS_GRAYSCALE, HINT_FULL);
|
||||
|
||||
group = enum_group_create (FONT_HINTING_KEY, hint_enums, HINT_FULL,
|
||||
appearance_capplet_get_widget (data, "hint_none_radio"), HINT_NONE,
|
||||
appearance_capplet_get_widget (data, "hint_slight_radio"), HINT_SLIGHT,
|
||||
appearance_capplet_get_widget (data, "hint_medium_radio"), HINT_MEDIUM,
|
||||
appearance_capplet_get_widget (data, "hint_full_radio"), HINT_FULL,
|
||||
NULL);
|
||||
data->font_groups = g_slist_prepend (data->font_groups, group);
|
||||
|
||||
gtk_image_set_from_file (GTK_IMAGE (appearance_capplet_get_widget (data, "subpixel_rgb_image")),
|
||||
GNOMECC_PIXMAP_DIR "/subpixel-rgb.png");
|
||||
gtk_image_set_from_file (GTK_IMAGE (appearance_capplet_get_widget (data, "subpixel_bgr_image")),
|
||||
GNOMECC_PIXMAP_DIR "/subpixel-bgr.png");
|
||||
gtk_image_set_from_file (GTK_IMAGE (appearance_capplet_get_widget (data, "subpixel_vrgb_image")),
|
||||
GNOMECC_PIXMAP_DIR "/subpixel-vrgb.png");
|
||||
gtk_image_set_from_file (GTK_IMAGE (appearance_capplet_get_widget (data, "subpixel_vbgr_image")),
|
||||
GNOMECC_PIXMAP_DIR "/subpixel-vbgr.png");
|
||||
|
||||
group = enum_group_create (FONT_RGBA_ORDER_KEY, rgba_order_enums, RGBA_RGB,
|
||||
appearance_capplet_get_widget (data, "subpixel_rgb_radio"), RGBA_RGB,
|
||||
appearance_capplet_get_widget (data, "subpixel_bgr_radio"), RGBA_BGR,
|
||||
appearance_capplet_get_widget (data, "subpixel_vrgb_radio"), RGBA_VRGB,
|
||||
appearance_capplet_get_widget (data, "subpixel_vbgr_radio"), RGBA_VBGR,
|
||||
NULL);
|
||||
data->font_groups = g_slist_prepend (data->font_groups, group);
|
||||
|
||||
g_signal_connect (G_OBJECT (data->font_details),
|
||||
"response",
|
||||
G_CALLBACK (cb_details_response), NULL);
|
||||
g_signal_connect (G_OBJECT (data->font_details),
|
||||
"delete_event",
|
||||
G_CALLBACK (gtk_true), NULL);
|
||||
}
|
||||
|
||||
gtk_window_present (GTK_WINDOW (data->font_details));
|
||||
}
|
||||
#endif /* HAVE_XFT2 */
|
||||
|
||||
void
|
||||
font_init (AppearanceData *data)
|
||||
{
|
||||
GObject *peditor;
|
||||
GtkWidget *widget;
|
||||
|
||||
data->font_details = NULL;
|
||||
data->font_groups = NULL;
|
||||
|
||||
gconf_client_add_dir (data->client, "/desktop/gnome/interface",
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
gconf_client_add_dir (data->client, "/apps/nautilus/preferences",
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
gconf_client_add_dir (data->client, METACITY_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
#ifdef HAVE_XFT2
|
||||
gconf_client_add_dir (data->client, FONT_RENDER_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
#endif /* HAVE_XFT2 */
|
||||
|
||||
widget = appearance_capplet_get_widget (data, "application_font");
|
||||
peditor = gconf_peditor_new_font (NULL, GTK_FONT_KEY,
|
||||
widget,
|
||||
"conv-from-widget-cb", application_font_to_gconf,
|
||||
NULL);
|
||||
g_signal_connect_swapped (peditor, "value-changed",
|
||||
G_CALLBACK (application_font_changed),
|
||||
widget);
|
||||
application_font_changed (widget);
|
||||
|
||||
peditor = gconf_peditor_new_font (NULL, DOCUMENT_FONT_KEY,
|
||||
appearance_capplet_get_widget (data, "document_font"),
|
||||
NULL);
|
||||
|
||||
peditor = gconf_peditor_new_font (NULL, DESKTOP_FONT_KEY,
|
||||
appearance_capplet_get_widget (data, "desktop_font"),
|
||||
NULL);
|
||||
|
||||
peditor = gconf_peditor_new_font (NULL, WINDOW_TITLE_FONT_KEY,
|
||||
appearance_capplet_get_widget (data, "window_title_font"),
|
||||
NULL);
|
||||
|
||||
peditor = gconf_peditor_new_font (NULL, MONOSPACE_FONT_KEY,
|
||||
appearance_capplet_get_widget (data, "monospace_font"),
|
||||
NULL);
|
||||
|
||||
gconf_client_notify_add (data->client, WINDOW_TITLE_USES_SYSTEM_KEY,
|
||||
metacity_changed,
|
||||
data, NULL, NULL);
|
||||
|
||||
metacity_titlebar_load_sensitivity (data);
|
||||
|
||||
#ifdef HAVE_XFT2
|
||||
setup_font_pair (appearance_capplet_get_widget (data, "monochrome_radio"),
|
||||
appearance_capplet_get_widget (data, "monochrome_sample"),
|
||||
ANTIALIAS_NONE, HINT_FULL);
|
||||
setup_font_pair (appearance_capplet_get_widget (data, "best_shapes_radio"),
|
||||
appearance_capplet_get_widget (data, "best_shapes_sample"),
|
||||
ANTIALIAS_GRAYSCALE, HINT_MEDIUM);
|
||||
setup_font_pair (appearance_capplet_get_widget (data, "best_contrast_radio"),
|
||||
appearance_capplet_get_widget (data, "best_contrast_sample"),
|
||||
ANTIALIAS_GRAYSCALE, HINT_FULL);
|
||||
setup_font_pair (appearance_capplet_get_widget (data, "subpixel_radio"),
|
||||
appearance_capplet_get_widget (data, "subpixel_sample"),
|
||||
ANTIALIAS_RGBA, HINT_FULL);
|
||||
|
||||
font_render_load (data->client);
|
||||
|
||||
gconf_client_notify_add (data->client, FONT_RENDER_DIR,
|
||||
font_render_changed,
|
||||
data->client, NULL, NULL);
|
||||
|
||||
g_signal_connect (appearance_capplet_get_widget (data, "details_button"),
|
||||
"clicked", G_CALLBACK (cb_show_details), data);
|
||||
#else /* !HAVE_XFT2 */
|
||||
gtk_widget_hide (appearance_capplet_get_widget (data, "font_render_frame"));
|
||||
#endif /* HAVE_XFT2 */
|
||||
}
|
||||
|
||||
void
|
||||
font_shutdown (AppearanceData *data)
|
||||
{
|
||||
g_slist_foreach (data->font_groups, (GFunc) enum_group_destroy, NULL);
|
||||
g_slist_free (data->font_groups);
|
||||
g_slist_foreach (font_pairs, (GFunc) g_free, NULL);
|
||||
g_slist_free (font_pairs);
|
||||
g_free (old_font);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -11,16 +13,10 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Authors: Thomas Wood <thomas.wood@intel.com>
|
||||
* Rodrigo Moya <rodrigo@gnome.org>
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnome-control-center/cc-panel.h>
|
||||
|
||||
void keyboard_general_init (CcPanel *panel, GtkBuilder *builder);
|
||||
void keyboard_general_dispose (CcPanel *panel);
|
||||
void font_init (AppearanceData *data);
|
||||
void font_shutdown (AppearanceData *data);
|
||||
215
capplets/appearance/appearance-main.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include "appearance.h"
|
||||
#include "appearance-desktop.h"
|
||||
#include "appearance-font.h"
|
||||
#include "appearance-themes.h"
|
||||
#include "appearance-style.h"
|
||||
#include "theme-installer.h"
|
||||
#include "theme-thumbnail.h"
|
||||
#include "activate-settings-daemon.h"
|
||||
#include "capplet-util.h"
|
||||
|
||||
static AppearanceData *
|
||||
init_appearance_data (int *argc, char ***argv, GOptionContext *context)
|
||||
{
|
||||
AppearanceData *data = NULL;
|
||||
gchar *uifile;
|
||||
GtkBuilder *ui;
|
||||
GError *err = NULL;
|
||||
|
||||
g_thread_init (NULL);
|
||||
theme_thumbnail_factory_init (*argc, *argv);
|
||||
capplet_init (context, argc, argv);
|
||||
activate_settings_daemon ();
|
||||
|
||||
/* set up the data */
|
||||
uifile = g_build_filename (GNOMECC_GTKBUILDER_DIR, "appearance.ui",
|
||||
NULL);
|
||||
ui = gtk_builder_new ();
|
||||
gtk_builder_add_from_file (ui, uifile, &err);
|
||||
g_free (uifile);
|
||||
|
||||
if (err)
|
||||
{
|
||||
g_warning (_("Could not load user interface file: %s"), err->message);
|
||||
g_error_free (err);
|
||||
g_object_unref (ui);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = g_new (AppearanceData, 1);
|
||||
data->client = gconf_client_get_default ();
|
||||
data->ui = ui;
|
||||
data->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
main_window_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
AppearanceData *data)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_CLOSE ||
|
||||
response_id == GTK_RESPONSE_DELETE_EVENT)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
|
||||
themes_shutdown (data);
|
||||
style_shutdown (data);
|
||||
desktop_shutdown (data);
|
||||
font_shutdown (data);
|
||||
|
||||
g_object_unref (data->thumb_factory);
|
||||
g_object_unref (data->client);
|
||||
g_object_unref (data->ui);
|
||||
}
|
||||
else if (response_id == GTK_RESPONSE_HELP)
|
||||
{
|
||||
GtkNotebook *nb;
|
||||
gint pindex;
|
||||
|
||||
nb = GTK_NOTEBOOK (appearance_capplet_get_widget (data, "main_notebook"));
|
||||
pindex = gtk_notebook_get_current_page (nb);
|
||||
|
||||
switch (pindex)
|
||||
{
|
||||
case 0: /* theme */
|
||||
capplet_help (GTK_WINDOW (widget), "goscustdesk-12");
|
||||
break;
|
||||
case 1: /* background */
|
||||
capplet_help (GTK_WINDOW (widget), "goscustdesk-7");
|
||||
break;
|
||||
case 2: /* fonts */
|
||||
capplet_help (GTK_WINDOW (widget), "goscustdesk-38");
|
||||
break;
|
||||
case 3: /* interface */
|
||||
capplet_help (GTK_WINDOW (widget), "goscustuserinter-2");
|
||||
break;
|
||||
default:
|
||||
capplet_help (GTK_WINDOW (widget), "prefs-look-and-feel");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
AppearanceData *data;
|
||||
GtkWidget *w;
|
||||
|
||||
gchar *install_filename = NULL;
|
||||
gchar *start_page = NULL;
|
||||
gchar **wallpaper_files = NULL;
|
||||
GOptionContext *option_context;
|
||||
GOptionEntry option_entries[] = {
|
||||
{ "install-theme",
|
||||
'i',
|
||||
G_OPTION_FLAG_IN_MAIN,
|
||||
G_OPTION_ARG_FILENAME,
|
||||
&install_filename,
|
||||
N_("Specify the filename of a theme to install"),
|
||||
N_("filename") },
|
||||
{ "show-page",
|
||||
'p',
|
||||
G_OPTION_FLAG_IN_MAIN,
|
||||
G_OPTION_ARG_STRING,
|
||||
&start_page,
|
||||
/* TRANSLATORS: don't translate the terms in brackets */
|
||||
N_("Specify the name of the page to show (theme|background|fonts|interface)"),
|
||||
N_("page") },
|
||||
{ G_OPTION_REMAINING,
|
||||
0,
|
||||
G_OPTION_FLAG_IN_MAIN,
|
||||
G_OPTION_ARG_FILENAME_ARRAY,
|
||||
&wallpaper_files,
|
||||
NULL,
|
||||
N_("[WALLPAPER...]") },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
option_context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (option_context, option_entries, GETTEXT_PACKAGE);
|
||||
|
||||
/* init */
|
||||
data = init_appearance_data (&argc, &argv, option_context);
|
||||
if (!data)
|
||||
return 1;
|
||||
|
||||
/* init tabs */
|
||||
themes_init (data);
|
||||
style_init (data);
|
||||
desktop_init (data, (const gchar **) wallpaper_files);
|
||||
g_strfreev (wallpaper_files);
|
||||
font_init (data);
|
||||
|
||||
/* prepare the main window */
|
||||
w = appearance_capplet_get_widget (data, "appearance_window");
|
||||
capplet_set_icon (w, "preferences-desktop-theme");
|
||||
gtk_widget_show_all (w);
|
||||
|
||||
g_signal_connect_after (w, "response",
|
||||
(GCallback) main_window_response, data);
|
||||
|
||||
/* default to background page if files were given on the command line */
|
||||
if (wallpaper_files && !install_filename && !start_page)
|
||||
start_page = g_strdup ("background");
|
||||
|
||||
if (start_page != NULL) {
|
||||
gchar *page_name;
|
||||
|
||||
page_name = g_strconcat (start_page, "_vbox", NULL);
|
||||
g_free (start_page);
|
||||
|
||||
w = appearance_capplet_get_widget (data, page_name);
|
||||
if (w != NULL) {
|
||||
GtkNotebook *nb;
|
||||
gint pindex;
|
||||
|
||||
nb = GTK_NOTEBOOK (appearance_capplet_get_widget (data, "main_notebook"));
|
||||
pindex = gtk_notebook_page_num (nb, w);
|
||||
if (pindex != -1)
|
||||
gtk_notebook_set_current_page (nb, pindex);
|
||||
}
|
||||
g_free (page_name);
|
||||
}
|
||||
|
||||
if (install_filename != NULL) {
|
||||
GFile *inst = g_file_new_for_commandline_arg (install_filename);
|
||||
g_free (install_filename);
|
||||
gnome_theme_install (inst, GTK_WINDOW (w));
|
||||
g_object_unref (inst);
|
||||
}
|
||||
|
||||
g_option_context_free (option_context);
|
||||
|
||||
/* start the mainloop */
|
||||
gtk_main ();
|
||||
|
||||
/* free stuff */
|
||||
g_free (data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1067
capplets/appearance/appearance-style.c
Normal file
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -11,16 +13,10 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Authors: Thomas Wood <thomas.wood@intel.com>
|
||||
* Rodrigo Moya <rodrigo@gnome.org>
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnome-control-center/cc-panel.h>
|
||||
|
||||
void keyboard_shortcuts_init (CcPanel *panel, GtkBuilder *builder);
|
||||
void keyboard_shortcuts_dispose (CcPanel *panel);
|
||||
void style_init (AppearanceData *data);
|
||||
void style_shutdown (AppearanceData *data);
|
||||
1189
capplets/appearance/appearance-themes.c
Normal file
22
capplets/appearance/appearance-themes.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
void themes_init (AppearanceData *data);
|
||||
void themes_shutdown (AppearanceData *data);
|
||||
87
capplets/appearance/appearance.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <libgnomeui/gnome-desktop-thumbnail.h>
|
||||
|
||||
#include "gnome-theme-info.h"
|
||||
|
||||
#define APPEARANCE_KEY_DIR "/apps/control-center/appearance"
|
||||
#define MORE_THEMES_URL_KEY APPEARANCE_KEY_DIR "/more_themes_url"
|
||||
#define MORE_BACKGROUNDS_URL_KEY APPEARANCE_KEY_DIR "/more_backgrounds_url"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GConfClient *client;
|
||||
GtkBuilder *ui;
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
|
||||
/* desktop */
|
||||
GHashTable *wp_hash;
|
||||
gboolean wp_update_gconf;
|
||||
GtkIconView *wp_view;
|
||||
GtkTreeModel *wp_model;
|
||||
GtkWidget *wp_scpicker;
|
||||
GtkWidget *wp_pcpicker;
|
||||
GtkWidget *wp_style_menu;
|
||||
GtkWidget *wp_color_menu;
|
||||
GtkWidget *wp_rem_button;
|
||||
GtkFileChooser *wp_filesel;
|
||||
GtkWidget *wp_image;
|
||||
GSList *wp_uris;
|
||||
gint frame;
|
||||
|
||||
/* font */
|
||||
GtkWidget *font_details;
|
||||
GSList *font_groups;
|
||||
|
||||
/* themes */
|
||||
GtkListStore *theme_store;
|
||||
GnomeThemeMetaInfo *theme_custom;
|
||||
GdkPixbuf *theme_icon;
|
||||
GtkWidget *theme_save_dialog;
|
||||
GtkWidget *theme_message_area;
|
||||
GtkWidget *theme_message_label;
|
||||
GtkWidget *apply_background_button;
|
||||
GtkWidget *revert_font_button;
|
||||
GtkWidget *apply_font_button;
|
||||
GtkWidget *install_button;
|
||||
GtkWidget *theme_info_icon;
|
||||
GtkWidget *theme_error_icon;
|
||||
gchar *revert_application_font;
|
||||
gchar *revert_documents_font;
|
||||
gchar *revert_desktop_font;
|
||||
gchar *revert_windowtitle_font;
|
||||
gchar *revert_monospace_font;
|
||||
|
||||
/* style */
|
||||
GdkPixbuf *gtk_theme_icon;
|
||||
GdkPixbuf *window_theme_icon;
|
||||
GdkPixbuf *icon_theme_icon;
|
||||
GtkWidget *style_message_area;
|
||||
GtkWidget *style_message_label;
|
||||
GtkWidget *style_install_button;
|
||||
} AppearanceData;
|
||||
|
||||
#define appearance_capplet_get_widget(x, y) (GtkWidget *) gtk_builder_get_object (x->ui, y)
|
||||
62
capplets/appearance/data/Makefile.am
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
gtkbuilderdir = $(pkgdatadir)/ui
|
||||
dist_gtkbuilder_DATA = appearance.ui
|
||||
|
||||
pixmapdir = $(pkgdatadir)/pixmaps
|
||||
dist_pixmap_DATA = \
|
||||
subpixel-bgr.png \
|
||||
subpixel-rgb.png \
|
||||
subpixel-vbgr.png \
|
||||
subpixel-vrgb.png \
|
||||
theme-thumbnailing.png \
|
||||
gtk-theme-thumbnailing.png \
|
||||
window-theme-thumbnailing.png \
|
||||
icon-theme-thumbnailing.png \
|
||||
mouse-cursor-normal.png \
|
||||
mouse-cursor-normal-large.png \
|
||||
mouse-cursor-white.png \
|
||||
mouse-cursor-white-large.png
|
||||
|
||||
cursorfontdir = $(datadir)/gnome/cursor-fonts
|
||||
dist_cursorfont_DATA = \
|
||||
cursor-large.pcf \
|
||||
cursor-white.pcf \
|
||||
cursor-large-white.pcf
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
desktop_in_files = \
|
||||
gnome-appearance-properties.desktop.in \
|
||||
gnome-theme-installer.desktop.in
|
||||
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
|
||||
|
||||
|
||||
|
||||
|
||||
@INTLTOOL_XML_RULE@
|
||||
|
||||
xml_in_files = \
|
||||
gnome-theme-package.xml.in
|
||||
|
||||
mimedir = $(datadir)/mime/packages
|
||||
mime_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
|
||||
install-data-hook:
|
||||
if ENABLE_UPDATE_MIMEDB
|
||||
$(UPDATE_MIME_DATABASE) "$(DESTDIR)$(datadir)/mime"
|
||||
endif
|
||||
|
||||
uninstall-hook:
|
||||
if ENABLE_UPDATE_MIMEDB
|
||||
$(UPDATE_MIME_DATABASE) "$(DESTDIR)$(datadir)/mime"
|
||||
endif
|
||||
|
||||
|
||||
EXTRA_DIST = $(xml_in_files)
|
||||
|
||||
|
||||
CLEANFILES = $(desktop_in_files) $(desktop_DATA) $(mime_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
2600
capplets/appearance/data/appearance.ui
Normal file
BIN
capplets/appearance/data/cursor-large-white.pcf
Normal file
BIN
capplets/appearance/data/cursor-large.pcf
Normal file
BIN
capplets/appearance/data/cursor-white.pcf
Normal file
@@ -0,0 +1,14 @@
|
||||
[Desktop Entry]
|
||||
_Name=Appearance
|
||||
_Comment=Customize the look of the desktop
|
||||
Exec=gnome-appearance-properties %F
|
||||
Icon=preferences-desktop-theme
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=Appearance
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
16
capplets/appearance/data/gnome-theme-installer.desktop.in.in
Normal file
@@ -0,0 +1,16 @@
|
||||
[Desktop Entry]
|
||||
_Name=Theme Installer
|
||||
_Comment=Installs themes packages for various parts of the desktop
|
||||
Exec=gnome-appearance-properties -i %u
|
||||
Icon=preferences-desktop-theme
|
||||
Terminal=false
|
||||
Type=Application
|
||||
MimeType=application/x-gnome-theme-package;
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;
|
||||
NoDisplay=true
|
||||
OnlyShowIn=GNOME;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=Appearance
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
9
capplets/appearance/data/gnome-theme-package.xml.in
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/x-gnome-theme-package">
|
||||
<sub-class-of type="application/x-compressed-tar"/>
|
||||
<_comment>Gnome Theme Package</_comment>
|
||||
<glob pattern="*.gtp"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
||||
|
||||
BIN
capplets/appearance/data/gtk-theme-thumbnailing.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
capplets/appearance/data/icon-theme-thumbnailing.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
capplets/appearance/data/mouse-cursor-normal-large.png
Normal file
|
After Width: | Height: | Size: 251 B |
BIN
capplets/appearance/data/mouse-cursor-normal.png
Normal file
|
After Width: | Height: | Size: 241 B |
BIN
capplets/appearance/data/mouse-cursor-white-large.png
Normal file
|
After Width: | Height: | Size: 268 B |
BIN
capplets/appearance/data/mouse-cursor-white.png
Normal file
|
After Width: | Height: | Size: 221 B |
BIN
capplets/appearance/data/subpixel-bgr.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
capplets/appearance/data/subpixel-rgb.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
capplets/appearance/data/subpixel-vbgr.png
Normal file
|
After Width: | Height: | Size: 138 B |
BIN
capplets/appearance/data/subpixel-vrgb.png
Normal file
|
After Width: | Height: | Size: 138 B |
BIN
capplets/appearance/data/theme-thumbnailing.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
capplets/appearance/data/window-theme-thumbnailing.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
626
capplets/appearance/gedit-message-area.c
Normal file
@@ -0,0 +1,626 @@
|
||||
/*
|
||||
* gedit-message-area.c
|
||||
* This file is part of gedit
|
||||
*
|
||||
* Copyright (C) 2005 - Paolo Maggi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the gedit Team, 2005. See the AUTHORS file for a
|
||||
* list of people on the gedit Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/* TODO: Style properties */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "gedit-message-area.h"
|
||||
|
||||
#define GEDIT_MESSAGE_AREA_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
|
||||
GEDIT_TYPE_MESSAGE_AREA, \
|
||||
GeditMessageAreaPrivate))
|
||||
|
||||
struct _GeditMessageAreaPrivate
|
||||
{
|
||||
GtkWidget *main_hbox;
|
||||
|
||||
GtkWidget *contents;
|
||||
GtkWidget *action_area;
|
||||
|
||||
gboolean changing_style;
|
||||
};
|
||||
|
||||
typedef struct _ResponseData ResponseData;
|
||||
|
||||
struct _ResponseData
|
||||
{
|
||||
gint response_id;
|
||||
};
|
||||
|
||||
enum {
|
||||
RESPONSE,
|
||||
CLOSE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(GeditMessageArea, gedit_message_area, GTK_TYPE_HBOX)
|
||||
|
||||
|
||||
static void
|
||||
gedit_message_area_finalize (GObject *object)
|
||||
{
|
||||
/*
|
||||
GeditMessageArea *message_area = GEDIT_MESSAGE_AREA (object);
|
||||
*/
|
||||
|
||||
G_OBJECT_CLASS (gedit_message_area_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static ResponseData *
|
||||
get_response_data (GtkWidget *widget,
|
||||
gboolean create)
|
||||
{
|
||||
ResponseData *ad = g_object_get_data (G_OBJECT (widget),
|
||||
"gedit-message-area-response-data");
|
||||
|
||||
if (ad == NULL && create)
|
||||
{
|
||||
ad = g_new (ResponseData, 1);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (widget),
|
||||
"gedit-message-area-response-data",
|
||||
ad,
|
||||
g_free);
|
||||
}
|
||||
|
||||
return ad;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
find_button (GeditMessageArea *message_area,
|
||||
gint response_id)
|
||||
{
|
||||
GList *children, *tmp_list;
|
||||
GtkWidget *child = NULL;
|
||||
|
||||
children = gtk_container_get_children (
|
||||
GTK_CONTAINER (message_area->priv->action_area));
|
||||
|
||||
for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
ResponseData *rd = get_response_data (tmp_list->data, FALSE);
|
||||
|
||||
if (rd && rd->response_id == response_id)
|
||||
{
|
||||
child = tmp_list->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_message_area_close (GeditMessageArea *message_area)
|
||||
{
|
||||
if (!find_button (message_area, GTK_RESPONSE_CANCEL))
|
||||
return;
|
||||
|
||||
/* emit response signal */
|
||||
gedit_message_area_response (GEDIT_MESSAGE_AREA (message_area),
|
||||
GTK_RESPONSE_CANCEL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
paint_message_area (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_paint_flat_box (widget->style,
|
||||
widget->window,
|
||||
GTK_STATE_NORMAL,
|
||||
GTK_SHADOW_OUT,
|
||||
NULL,
|
||||
widget,
|
||||
"tooltip",
|
||||
widget->allocation.x + 1,
|
||||
widget->allocation.y + 1,
|
||||
widget->allocation.width - 2,
|
||||
widget->allocation.height - 2);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_message_area_class_init (GeditMessageAreaClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GtkBindingSet *binding_set;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->finalize = gedit_message_area_finalize;
|
||||
|
||||
klass->close = gedit_message_area_close;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof(GeditMessageAreaPrivate));
|
||||
|
||||
signals[RESPONSE] = g_signal_new ("response",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GeditMessageAreaClass, response),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_INT);
|
||||
|
||||
signals[CLOSE] = g_signal_new ("close",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GeditMessageAreaClass, close),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
binding_set = gtk_binding_set_by_class (klass);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style,
|
||||
GeditMessageArea *message_area)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkStyle *style;
|
||||
|
||||
if (message_area->priv->changing_style)
|
||||
return;
|
||||
|
||||
/* This is a hack needed to use the tooltip background color */
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_widget_set_name (window, "gtk-tooltip");
|
||||
gtk_widget_ensure_style (window);
|
||||
style = gtk_widget_get_style (window);
|
||||
|
||||
message_area->priv->changing_style = TRUE;
|
||||
gtk_widget_set_style (GTK_WIDGET (message_area), style);
|
||||
message_area->priv->changing_style = FALSE;
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (message_area));
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_message_area_init (GeditMessageArea *message_area)
|
||||
{
|
||||
message_area->priv = GEDIT_MESSAGE_AREA_GET_PRIVATE (message_area);
|
||||
|
||||
message_area->priv->main_hbox = gtk_hbox_new (FALSE, 16); /* FIXME: use style properties */
|
||||
gtk_widget_show (message_area->priv->main_hbox);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (message_area->priv->main_hbox),
|
||||
8); /* FIXME: use style properties */
|
||||
|
||||
message_area->priv->action_area = gtk_vbox_new (TRUE, 10); /* FIXME: use style properties */
|
||||
gtk_widget_show (message_area->priv->action_area);
|
||||
gtk_box_pack_end (GTK_BOX (message_area->priv->main_hbox),
|
||||
message_area->priv->action_area,
|
||||
FALSE,
|
||||
TRUE,
|
||||
0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (message_area),
|
||||
message_area->priv->main_hbox,
|
||||
TRUE,
|
||||
TRUE,
|
||||
0);
|
||||
|
||||
gtk_widget_set_app_paintable (GTK_WIDGET (message_area), TRUE);
|
||||
|
||||
g_signal_connect (message_area,
|
||||
"expose-event",
|
||||
G_CALLBACK (paint_message_area),
|
||||
NULL);
|
||||
|
||||
/* Note that we connect to style-set on one of the internal
|
||||
* widgets, not on the message area itself, since gtk does
|
||||
* not deliver any further style-set signals for a widget on
|
||||
* which the style has been forced with gtk_widget_set_style() */
|
||||
g_signal_connect (message_area->priv->main_hbox,
|
||||
"style-set",
|
||||
G_CALLBACK (style_set),
|
||||
message_area);
|
||||
}
|
||||
|
||||
static gint
|
||||
get_response_for_widget (GeditMessageArea *message_area,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
ResponseData *rd;
|
||||
|
||||
rd = get_response_data (widget, FALSE);
|
||||
if (!rd)
|
||||
return GTK_RESPONSE_NONE;
|
||||
else
|
||||
return rd->response_id;
|
||||
}
|
||||
|
||||
static void
|
||||
action_widget_activated (GtkWidget *widget, GeditMessageArea *message_area)
|
||||
{
|
||||
gint response_id;
|
||||
|
||||
response_id = get_response_for_widget (message_area, widget);
|
||||
|
||||
gedit_message_area_response (message_area, response_id);
|
||||
}
|
||||
|
||||
void
|
||||
gedit_message_area_add_action_widget (GeditMessageArea *message_area,
|
||||
GtkWidget *child,
|
||||
gint response_id)
|
||||
{
|
||||
ResponseData *ad;
|
||||
guint signal_id;
|
||||
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
ad = get_response_data (child, TRUE);
|
||||
|
||||
ad->response_id = response_id;
|
||||
|
||||
if (GTK_IS_BUTTON (child))
|
||||
signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
|
||||
else
|
||||
signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
|
||||
|
||||
if (signal_id)
|
||||
{
|
||||
GClosure *closure;
|
||||
|
||||
closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
|
||||
G_OBJECT (message_area));
|
||||
|
||||
g_signal_connect_closure_by_id (child,
|
||||
signal_id,
|
||||
0,
|
||||
closure,
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
g_warning ("Only 'activatable' widgets can be packed into the action area of a GeditMessageArea");
|
||||
|
||||
if (response_id != GTK_RESPONSE_HELP)
|
||||
gtk_box_pack_start (GTK_BOX (message_area->priv->action_area),
|
||||
child,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0);
|
||||
else
|
||||
gtk_box_pack_end (GTK_BOX (message_area->priv->action_area),
|
||||
child,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_set_contents:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @contents: widget you want to add to the contents area
|
||||
*
|
||||
* Adds the @contents widget to the contents area of #GeditMessageArea.
|
||||
*/
|
||||
void
|
||||
gedit_message_area_set_contents (GeditMessageArea *message_area,
|
||||
GtkWidget *contents)
|
||||
{
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
g_return_if_fail (GTK_IS_WIDGET (contents));
|
||||
|
||||
message_area->priv->contents = contents;
|
||||
gtk_box_pack_start (GTK_BOX (message_area->priv->main_hbox),
|
||||
message_area->priv->contents,
|
||||
TRUE,
|
||||
TRUE,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_add_button:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @button_text: text of button, or stock ID
|
||||
* @response_id: response ID for the button
|
||||
*
|
||||
* Adds a button with the given text (or a stock button, if button_text is a stock ID)
|
||||
* and sets things up so that clicking the button will emit the "response" signal
|
||||
* with the given response_id. The button is appended to the end of the message area's
|
||||
* action area. The button widget is returned, but usually you don't need it.
|
||||
*
|
||||
* Returns: the button widget that was added
|
||||
*/
|
||||
GtkWidget*
|
||||
gedit_message_area_add_button (GeditMessageArea *message_area,
|
||||
const gchar *button_text,
|
||||
gint response_id)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
|
||||
g_return_val_if_fail (button_text != NULL, NULL);
|
||||
|
||||
button = gtk_button_new_from_stock (button_text);
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
gedit_message_area_add_action_widget (message_area,
|
||||
button,
|
||||
response_id);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static void
|
||||
add_buttons_valist (GeditMessageArea *message_area,
|
||||
const gchar *first_button_text,
|
||||
va_list args)
|
||||
{
|
||||
const gchar* text;
|
||||
gint response_id;
|
||||
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
|
||||
if (first_button_text == NULL)
|
||||
return;
|
||||
|
||||
text = first_button_text;
|
||||
response_id = va_arg (args, gint);
|
||||
|
||||
while (text != NULL)
|
||||
{
|
||||
gedit_message_area_add_button (message_area,
|
||||
text,
|
||||
response_id);
|
||||
|
||||
text = va_arg (args, gchar*);
|
||||
if (text == NULL)
|
||||
break;
|
||||
|
||||
response_id = va_arg (args, int);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_add_buttons:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @first_button_text: button text or stock ID
|
||||
* @...: response ID for first button, then more text-response_id pairs
|
||||
*
|
||||
* Adds more buttons, same as calling gedit_message_area_add_button() repeatedly.
|
||||
* The variable argument list should be NULL-terminated as with
|
||||
* gedit_message_area_new_with_buttons(). Each button must have both text and response ID.
|
||||
*/
|
||||
void
|
||||
gedit_message_area_add_buttons (GeditMessageArea *message_area,
|
||||
const gchar *first_button_text,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, first_button_text);
|
||||
|
||||
add_buttons_valist (message_area,
|
||||
first_button_text,
|
||||
args);
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_new:
|
||||
*
|
||||
* Creates a new #GeditMessageArea object.
|
||||
*
|
||||
* Returns: a new #GeditMessageArea object
|
||||
*/
|
||||
GtkWidget *
|
||||
gedit_message_area_new (void)
|
||||
{
|
||||
return g_object_new (GEDIT_TYPE_MESSAGE_AREA, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_new_with_buttons:
|
||||
* @first_button_text: stock ID or text to go in first button, or NULL
|
||||
* @...: response ID for first button, then additional buttons, ending with NULL
|
||||
*
|
||||
* Creates a new #GeditMessageArea with buttons. Button text/response ID pairs
|
||||
* should be listed, with a NULL pointer ending the list. Button text can be either
|
||||
* a stock ID such as GTK_STOCK_OK, or some arbitrary text. A response ID can be any
|
||||
* positive number, or one of the values in the GtkResponseType enumeration. If
|
||||
* the user clicks one of these dialog buttons, GeditMessageArea will emit the "response"
|
||||
* signal with the corresponding response ID.
|
||||
*
|
||||
* Returns: a new #GeditMessageArea
|
||||
*/
|
||||
GtkWidget *
|
||||
gedit_message_area_new_with_buttons (const gchar *first_button_text,
|
||||
...)
|
||||
{
|
||||
GeditMessageArea *message_area;
|
||||
va_list args;
|
||||
|
||||
message_area = GEDIT_MESSAGE_AREA (gedit_message_area_new ());
|
||||
|
||||
va_start (args, first_button_text);
|
||||
|
||||
add_buttons_valist (message_area,
|
||||
first_button_text,
|
||||
args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
return GTK_WIDGET (message_area);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_set_response_sensitive:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @response_id: a response ID
|
||||
* @setting: TRUE for sensitive
|
||||
*
|
||||
* Calls gtk_widget_set_sensitive (widget, setting) for each widget in the dialog's
|
||||
* action area with the given response_id. A convenient way to sensitize/desensitize
|
||||
* dialog buttons.
|
||||
*/
|
||||
void
|
||||
gedit_message_area_set_response_sensitive (GeditMessageArea *message_area,
|
||||
gint response_id,
|
||||
gboolean setting)
|
||||
{
|
||||
GList *children;
|
||||
GList *tmp_list;
|
||||
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
|
||||
|
||||
tmp_list = children;
|
||||
while (tmp_list != NULL)
|
||||
{
|
||||
GtkWidget *widget = tmp_list->data;
|
||||
ResponseData *rd = get_response_data (widget, FALSE);
|
||||
|
||||
if (rd && rd->response_id == response_id)
|
||||
gtk_widget_set_sensitive (widget, setting);
|
||||
|
||||
tmp_list = g_list_next (tmp_list);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_set_default_response:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @response_id: a response ID
|
||||
*
|
||||
* Sets the last widget in the message area's action area with the given response_id
|
||||
* as the default widget for the dialog. Pressing "Enter" normally activates the
|
||||
* default widget.
|
||||
*/
|
||||
void
|
||||
gedit_message_area_set_default_response (GeditMessageArea *message_area,
|
||||
gint response_id)
|
||||
{
|
||||
GList *children;
|
||||
GList *tmp_list;
|
||||
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
|
||||
|
||||
tmp_list = children;
|
||||
while (tmp_list != NULL)
|
||||
{
|
||||
GtkWidget *widget = tmp_list->data;
|
||||
ResponseData *rd = get_response_data (widget, FALSE);
|
||||
|
||||
if (rd && rd->response_id == response_id)
|
||||
gtk_widget_grab_default (widget);
|
||||
|
||||
tmp_list = g_list_next (tmp_list);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_set_default_response:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @response_id: a response ID
|
||||
*
|
||||
* Emits the 'response' signal with the given @response_id.
|
||||
*/
|
||||
void
|
||||
gedit_message_area_response (GeditMessageArea *message_area,
|
||||
gint response_id)
|
||||
{
|
||||
g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
|
||||
|
||||
g_signal_emit (message_area,
|
||||
signals[RESPONSE],
|
||||
0,
|
||||
response_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gedit_message_area_add_stock_button_with_text:
|
||||
* @message_area: a #GeditMessageArea
|
||||
* @text: the text to visualize in the button
|
||||
* @stock_id: the stock ID of the button
|
||||
* @response_id: a response ID
|
||||
*
|
||||
* Same as gedit_message_area_add_button() but with a specific text.
|
||||
*/
|
||||
GtkWidget *
|
||||
gedit_message_area_add_stock_button_with_text (GeditMessageArea *message_area,
|
||||
const gchar *text,
|
||||
const gchar *stock_id,
|
||||
gint response_id)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
|
||||
g_return_val_if_fail (text != NULL, NULL);
|
||||
g_return_val_if_fail (stock_id != NULL, NULL);
|
||||
|
||||
button = gtk_button_new_with_mnemonic (text);
|
||||
gtk_button_set_image (GTK_BUTTON (button),
|
||||
gtk_image_new_from_stock (stock_id,
|
||||
GTK_ICON_SIZE_BUTTON));
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
gedit_message_area_add_action_widget (message_area,
|
||||
button,
|
||||
response_id);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
129
capplets/appearance/gedit-message-area.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* gedit-message-area.h
|
||||
* This file is part of gedit
|
||||
*
|
||||
* Copyright (C) 2005 - Paolo Maggi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the gedit Team, 2005. See the AUTHORS file for a
|
||||
* list of people on the gedit Team.
|
||||
* See the ChangeLog files for a list of changes.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __GEDIT_MESSAGE_AREA_H__
|
||||
#define __GEDIT_MESSAGE_AREA_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Type checking and casting macros
|
||||
*/
|
||||
#define GEDIT_TYPE_MESSAGE_AREA (gedit_message_area_get_type())
|
||||
#define GEDIT_MESSAGE_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_MESSAGE_AREA, GeditMessageArea))
|
||||
#define GEDIT_MESSAGE_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_MESSAGE_AREA, GeditMessageAreaClass))
|
||||
#define GEDIT_IS_MESSAGE_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_MESSAGE_AREA))
|
||||
#define GEDIT_IS_MESSAGE_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_MESSAGE_AREA))
|
||||
#define GEDIT_MESSAGE_AREA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_MESSAGE_AREA, GeditMessageAreaClass))
|
||||
|
||||
/* Private structure type */
|
||||
typedef struct _GeditMessageAreaPrivate GeditMessageAreaPrivate;
|
||||
|
||||
/*
|
||||
* Main object structure
|
||||
*/
|
||||
typedef struct _GeditMessageArea GeditMessageArea;
|
||||
|
||||
struct _GeditMessageArea
|
||||
{
|
||||
GtkHBox parent;
|
||||
|
||||
/*< private > */
|
||||
GeditMessageAreaPrivate *priv;
|
||||
};
|
||||
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
typedef struct _GeditMessageAreaClass GeditMessageAreaClass;
|
||||
|
||||
struct _GeditMessageAreaClass
|
||||
{
|
||||
GtkHBoxClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* response) (GeditMessageArea *message_area, gint response_id);
|
||||
|
||||
/* Keybinding signals */
|
||||
void (* close) (GeditMessageArea *message_area);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gedit_reserved1) (void);
|
||||
void (*_gedit_reserved2) (void);
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
GType gedit_message_area_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget *gedit_message_area_new (void);
|
||||
|
||||
GtkWidget *gedit_message_area_new_with_buttons (const gchar *first_button_text,
|
||||
...);
|
||||
|
||||
void gedit_message_area_set_contents (GeditMessageArea *message_area,
|
||||
GtkWidget *contents);
|
||||
|
||||
void gedit_message_area_add_action_widget (GeditMessageArea *message_area,
|
||||
GtkWidget *child,
|
||||
gint response_id);
|
||||
|
||||
GtkWidget *gedit_message_area_add_button (GeditMessageArea *message_area,
|
||||
const gchar *button_text,
|
||||
gint response_id);
|
||||
|
||||
GtkWidget *gedit_message_area_add_stock_button_with_text
|
||||
(GeditMessageArea *message_area,
|
||||
const gchar *text,
|
||||
const gchar *stock_id,
|
||||
gint response_id);
|
||||
|
||||
void gedit_message_area_add_buttons (GeditMessageArea *message_area,
|
||||
const gchar *first_button_text,
|
||||
...);
|
||||
|
||||
void gedit_message_area_set_response_sensitive
|
||||
(GeditMessageArea *message_area,
|
||||
gint response_id,
|
||||
gboolean setting);
|
||||
void gedit_message_area_set_default_response
|
||||
(GeditMessageArea *message_area,
|
||||
gint response_id);
|
||||
|
||||
/* Emit response signal */
|
||||
void gedit_message_area_response (GeditMessageArea *message_area,
|
||||
gint response_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_MESSAGE_AREA_H__ */
|
||||
@@ -25,30 +25,21 @@
|
||||
#include "gnome-wp-info.h"
|
||||
|
||||
GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
|
||||
GFileInfo * file_info,
|
||||
GnomeDesktopThumbnailFactory * thumbs) {
|
||||
GnomeWPInfo *wp;
|
||||
GFile *file;
|
||||
GFileInfo *info;
|
||||
|
||||
if (file_info == NULL)
|
||||
{
|
||||
GFile *file;
|
||||
file = g_file_new_for_commandline_arg (uri);
|
||||
|
||||
file = g_file_new_for_commandline_arg (uri);
|
||||
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_NAME ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL, NULL);
|
||||
g_object_unref (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_object_ref (file_info);
|
||||
}
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_NAME ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL, NULL);
|
||||
g_object_unref (file);
|
||||
|
||||
if (info == NULL || g_file_info_get_content_type (info) == NULL) {
|
||||
if (!strcmp (uri, "(none)")) {
|
||||
@@ -93,6 +84,4 @@ void gnome_wp_info_free (GnomeWPInfo * info) {
|
||||
g_free (info->thumburi);
|
||||
g_free (info->name);
|
||||
g_free (info->mime_type);
|
||||
|
||||
g_free (info);
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
#define _GNOME_WP_INFO_H_
|
||||
|
||||
#include <glib.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <libgnomeui/gnome-desktop-thumbnail.h>
|
||||
|
||||
typedef struct _GnomeWPInfo GnomeWPInfo;
|
||||
|
||||
@@ -38,7 +38,6 @@ struct _GnomeWPInfo {
|
||||
};
|
||||
|
||||
GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
|
||||
GFileInfo * file_info,
|
||||
GnomeDesktopThumbnailFactory * thumbs);
|
||||
void gnome_wp_info_free (GnomeWPInfo * info);
|
||||
|
||||
289
capplets/appearance/gnome-wp-item.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Authors: Rodney Dawes <dobey@ximian.com>
|
||||
*
|
||||
* Copyright 2003-2006 Novell, Inc. (www.novell.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <string.h>
|
||||
#include "gnome-wp-item.h"
|
||||
|
||||
static GConfEnumStringPair options_lookup[] = {
|
||||
{ GNOME_BG_PLACEMENT_CENTERED, "centered" },
|
||||
{ GNOME_BG_PLACEMENT_FILL_SCREEN, "stretched" },
|
||||
{ GNOME_BG_PLACEMENT_SCALED, "scaled" },
|
||||
{ GNOME_BG_PLACEMENT_ZOOMED, "zoom" },
|
||||
{ GNOME_BG_PLACEMENT_TILED, "wallpaper" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static GConfEnumStringPair shade_lookup[] = {
|
||||
{ GNOME_BG_COLOR_SOLID, "solid" },
|
||||
{ GNOME_BG_COLOR_H_GRADIENT, "horizontal-gradient" },
|
||||
{ GNOME_BG_COLOR_V_GRADIENT, "vertical-gradient" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const gchar *wp_item_option_to_string (GnomeBGPlacement type)
|
||||
{
|
||||
return gconf_enum_to_string (options_lookup, type);
|
||||
}
|
||||
|
||||
const gchar *wp_item_shading_to_string (GnomeBGColorType type)
|
||||
{
|
||||
return gconf_enum_to_string (shade_lookup, type);
|
||||
}
|
||||
|
||||
GnomeBGPlacement wp_item_string_to_option (const gchar *option)
|
||||
{
|
||||
int i = GNOME_BG_PLACEMENT_SCALED;
|
||||
gconf_string_to_enum (options_lookup, option, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
GnomeBGColorType wp_item_string_to_shading (const gchar *shade_type)
|
||||
{
|
||||
int i = GNOME_BG_COLOR_SOLID;
|
||||
gconf_string_to_enum (shade_lookup, shade_type, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void set_bg_properties (GnomeWPItem *item)
|
||||
{
|
||||
if (item->filename)
|
||||
gnome_bg_set_filename (item->bg, item->filename);
|
||||
|
||||
gnome_bg_set_color (item->bg, item->shade_type, item->pcolor, item->scolor);
|
||||
gnome_bg_set_placement (item->bg, item->options);
|
||||
}
|
||||
|
||||
void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item)
|
||||
{
|
||||
if (!item->bg) {
|
||||
item->bg = gnome_bg_new ();
|
||||
|
||||
set_bg_properties (item);
|
||||
}
|
||||
}
|
||||
|
||||
void gnome_wp_item_update (GnomeWPItem *item) {
|
||||
GConfClient *client;
|
||||
GdkColor color1 = { 0, 0, 0, 0 }, color2 = { 0, 0, 0, 0 };
|
||||
gchar *s;
|
||||
|
||||
client = gconf_client_get_default ();
|
||||
|
||||
s = gconf_client_get_string (client, WP_OPTIONS_KEY, NULL);
|
||||
item->options = wp_item_string_to_option (s);
|
||||
g_free (s);
|
||||
|
||||
s = gconf_client_get_string (client, WP_SHADING_KEY, NULL);
|
||||
item->shade_type = wp_item_string_to_shading (s);
|
||||
g_free (s);
|
||||
|
||||
s = gconf_client_get_string (client, WP_PCOLOR_KEY, NULL);
|
||||
if (s != NULL) {
|
||||
gdk_color_parse (s, &color1);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
s = gconf_client_get_string (client, WP_SCOLOR_KEY, NULL);
|
||||
if (s != NULL) {
|
||||
gdk_color_parse (s, &color2);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
g_object_unref (client);
|
||||
|
||||
if (item->pcolor != NULL)
|
||||
gdk_color_free (item->pcolor);
|
||||
|
||||
if (item->scolor != NULL)
|
||||
gdk_color_free (item->scolor);
|
||||
|
||||
item->pcolor = gdk_color_copy (&color1);
|
||||
item->scolor = gdk_color_copy (&color2);
|
||||
}
|
||||
|
||||
GnomeWPItem * gnome_wp_item_new (const gchar * filename,
|
||||
GHashTable * wallpapers,
|
||||
GnomeDesktopThumbnailFactory * thumbnails) {
|
||||
GnomeWPItem *item = g_new0 (GnomeWPItem, 1);
|
||||
|
||||
item->filename = g_strdup (filename);
|
||||
item->fileinfo = gnome_wp_info_new (filename, thumbnails);
|
||||
|
||||
if (item->fileinfo != NULL && item->fileinfo->mime_type != NULL &&
|
||||
(g_str_has_prefix (item->fileinfo->mime_type, "image/") ||
|
||||
strcmp (item->fileinfo->mime_type, "application/xml") == 0)) {
|
||||
|
||||
if (g_utf8_validate (item->fileinfo->name, -1, NULL))
|
||||
item->name = g_strdup (item->fileinfo->name);
|
||||
else
|
||||
item->name = g_filename_to_utf8 (item->fileinfo->name, -1, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
gnome_wp_item_update (item);
|
||||
gnome_wp_item_ensure_gnome_bg (item);
|
||||
gnome_wp_item_update_description (item);
|
||||
|
||||
g_hash_table_insert (wallpapers, item->filename, item);
|
||||
} else {
|
||||
gnome_wp_item_free (item);
|
||||
item = NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void gnome_wp_item_free (GnomeWPItem * item) {
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_free (item->name);
|
||||
g_free (item->filename);
|
||||
g_free (item->description);
|
||||
|
||||
if (item->pcolor != NULL)
|
||||
gdk_color_free (item->pcolor);
|
||||
|
||||
if (item->scolor != NULL)
|
||||
gdk_color_free (item->scolor);
|
||||
|
||||
gnome_wp_info_free (item->fileinfo);
|
||||
if (item->bg)
|
||||
g_object_unref (item->bg);
|
||||
|
||||
gtk_tree_row_reference_free (item->rowref);
|
||||
|
||||
g_free (item);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
add_slideshow_frame (GdkPixbuf *pixbuf)
|
||||
{
|
||||
GdkPixbuf *sheet, *sheet2;
|
||||
GdkPixbuf *tmp;
|
||||
gint w, h;
|
||||
|
||||
w = gdk_pixbuf_get_width (pixbuf);
|
||||
h = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
sheet = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h);
|
||||
gdk_pixbuf_fill (sheet, 0x00000000);
|
||||
sheet2 = gdk_pixbuf_new_subpixbuf (sheet, 1, 1, w - 2, h - 2);
|
||||
gdk_pixbuf_fill (sheet2, 0xffffffff);
|
||||
g_object_unref (sheet2);
|
||||
|
||||
tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w + 6, h + 6);
|
||||
|
||||
gdk_pixbuf_fill (tmp, 0x00000000);
|
||||
gdk_pixbuf_composite (sheet, tmp, 6, 6, w, h, 6.0, 6.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
|
||||
gdk_pixbuf_composite (sheet, tmp, 3, 3, w, h, 3.0, 3.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
|
||||
gdk_pixbuf_composite (pixbuf, tmp, 0, 0, w, h, 0.0, 0.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
|
||||
|
||||
g_object_unref (sheet);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#define LIST_IMAGE_WIDTH 108
|
||||
|
||||
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
|
||||
GnomeDesktopThumbnailFactory * thumbs,
|
||||
gint frame) {
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
double aspect =
|
||||
(double)gdk_screen_get_height (gdk_screen_get_default()) /
|
||||
gdk_screen_get_width (gdk_screen_get_default());
|
||||
|
||||
set_bg_properties (item);
|
||||
|
||||
if (frame != -1)
|
||||
pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect, frame);
|
||||
else
|
||||
pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect);
|
||||
|
||||
if (pixbuf && gnome_bg_changes_with_time (item->bg))
|
||||
{
|
||||
GdkPixbuf *tmp;
|
||||
|
||||
tmp = add_slideshow_frame (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
pixbuf = tmp;
|
||||
}
|
||||
|
||||
gnome_bg_get_image_size (item->bg, thumbs, &item->width, &item->height);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
||||
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
|
||||
GnomeDesktopThumbnailFactory * thumbs) {
|
||||
return gnome_wp_item_get_frame_thumbnail (item, thumbs, -1);
|
||||
}
|
||||
|
||||
void gnome_wp_item_update_description (GnomeWPItem * item) {
|
||||
g_free (item->description);
|
||||
|
||||
if (!strcmp (item->filename, "(none)")) {
|
||||
item->description = g_strdup (item->name);
|
||||
} else {
|
||||
const gchar *description;
|
||||
gchar *size;
|
||||
gchar *dirname = g_path_get_dirname (item->filename);
|
||||
|
||||
if (strcmp (item->fileinfo->mime_type, "application/xml") == 0)
|
||||
{
|
||||
if (gnome_bg_changes_with_time (item->bg))
|
||||
description = _("Slide Show");
|
||||
else
|
||||
description = _("Image");
|
||||
}
|
||||
else
|
||||
description = g_content_type_get_description (item->fileinfo->mime_type);
|
||||
|
||||
if (gnome_bg_changes_with_size (item->bg))
|
||||
size = g_strdup (_("multiple sizes"));
|
||||
else
|
||||
/* translators: x pixel(s) by y pixel(s) */
|
||||
size = g_strdup_printf ("%d %s by %d %s",
|
||||
item->width,
|
||||
ngettext ("pixel", "pixels", item->width),
|
||||
item->height,
|
||||
ngettext ("pixel", "pixels", item->height));
|
||||
|
||||
/* translators: <b>wallpaper name</b>
|
||||
* mime type, size
|
||||
* Folder: /path/to/file
|
||||
*/
|
||||
item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
|
||||
"%s, %s\n"
|
||||
"Folder: %s"),
|
||||
item->name,
|
||||
description,
|
||||
size,
|
||||
dirname);
|
||||
g_free (size);
|
||||
g_free (dirname);
|
||||
}
|
||||
}
|
||||
@@ -17,25 +17,25 @@
|
||||
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
#include <libgnome-desktop/gnome-bg.h>
|
||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||
#include <libgnomeui/gnome-desktop-thumbnail.h>
|
||||
#include <libgnomeui/gnome-bg.h>
|
||||
|
||||
#include "gnome-wp-info.h"
|
||||
|
||||
#ifndef _GNOME_WP_ITEM_H_
|
||||
#define _GNOME_WP_ITEM_H_
|
||||
|
||||
#define WP_PATH_ID "org.gnome.desktop.background"
|
||||
#define WP_FILE_KEY "picture-filename"
|
||||
#define WP_OPTIONS_KEY "picture-options"
|
||||
#define WP_SHADING_KEY "color-shading-type"
|
||||
#define WP_PCOLOR_KEY "primary-color"
|
||||
#define WP_SCOLOR_KEY "secondary-color"
|
||||
#define WP_PATH_KEY "/desktop/gnome/background"
|
||||
#define WP_FILE_KEY WP_PATH_KEY "/picture_filename"
|
||||
#define WP_OPTIONS_KEY WP_PATH_KEY "/picture_options"
|
||||
#define WP_SHADING_KEY WP_PATH_KEY "/color_shading_type"
|
||||
#define WP_PCOLOR_KEY WP_PATH_KEY "/primary_color"
|
||||
#define WP_SCOLOR_KEY WP_PATH_KEY "/secondary_color"
|
||||
|
||||
typedef struct _GnomeWPItem GnomeWPItem;
|
||||
|
||||
@@ -44,11 +44,9 @@ struct _GnomeWPItem {
|
||||
|
||||
gchar * name;
|
||||
gchar * filename;
|
||||
gchar * size;
|
||||
GDesktopBackgroundStyle options;
|
||||
GDesktopBackgroundShading shade_type;
|
||||
|
||||
gchar * source_url;
|
||||
gchar * description;
|
||||
GnomeBGPlacement options;
|
||||
GnomeBGColorType shade_type;
|
||||
|
||||
/* Where the Item is in the List */
|
||||
GtkTreeRowReference * rowref;
|
||||
@@ -69,26 +67,21 @@ struct _GnomeWPItem {
|
||||
|
||||
GnomeWPItem * gnome_wp_item_new (const gchar *filename,
|
||||
GHashTable *wallpapers,
|
||||
GFileInfo *file_info,
|
||||
GnomeDesktopThumbnailFactory *thumbnails);
|
||||
|
||||
void gnome_wp_item_free (GnomeWPItem *item);
|
||||
GIcon * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
gint width,
|
||||
gint height);
|
||||
GIcon * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
gint width,
|
||||
gint height,
|
||||
gint frame);
|
||||
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs);
|
||||
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
|
||||
GnomeDesktopThumbnailFactory *thumbs,
|
||||
gint frame);
|
||||
void gnome_wp_item_update (GnomeWPItem *item);
|
||||
void gnome_wp_item_update_size (GnomeWPItem *item, GnomeDesktopThumbnailFactory *thumbs);
|
||||
void gnome_wp_item_update_description (GnomeWPItem *item);
|
||||
void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item);
|
||||
|
||||
const gchar *wp_item_option_to_string (GDesktopBackgroundStyle type);
|
||||
const gchar *wp_item_shading_to_string (GDesktopBackgroundShading type);
|
||||
GDesktopBackgroundStyle wp_item_string_to_option (const gchar *option);
|
||||
GDesktopBackgroundShading wp_item_string_to_shading (const gchar *shade_type);
|
||||
const gchar *wp_item_option_to_string (GnomeBGPlacement type);
|
||||
const gchar *wp_item_shading_to_string (GnomeBGColorType type);
|
||||
GnomeBGPlacement wp_item_string_to_option (const gchar *option);
|
||||
GnomeBGColorType wp_item_string_to_shading (const gchar *shade_type);
|
||||
|
||||
#endif
|
||||
@@ -18,8 +18,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "appearance.h"
|
||||
#include "gnome-wp-item.h"
|
||||
#include "gnome-wp-xml.h"
|
||||
#include <gio/gio.h>
|
||||
#include <string.h>
|
||||
#include <libxml/parser.h>
|
||||
@@ -57,7 +57,7 @@ static void gnome_wp_xml_set_bool (const xmlNode * parent,
|
||||
}
|
||||
}
|
||||
|
||||
static void gnome_wp_load_legacy (GnomeWpXml *data) {
|
||||
static void gnome_wp_load_legacy (AppearanceData *data) {
|
||||
FILE * fp;
|
||||
gchar * foo, * filename;
|
||||
|
||||
@@ -83,7 +83,7 @@ static void gnome_wp_load_legacy (GnomeWpXml *data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item = gnome_wp_item_new (foo, data->wp_hash, NULL, data->thumb_factory);
|
||||
item = gnome_wp_item_new (foo, data->wp_hash, data->thumb_factory);
|
||||
if (item != NULL && item->fileinfo == NULL) {
|
||||
gnome_wp_item_free (item);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ static void gnome_wp_load_legacy (GnomeWpXml *data) {
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static void gnome_wp_xml_load_xml (GnomeWpXml *data,
|
||||
static void gnome_wp_xml_load_xml (AppearanceData *data,
|
||||
const gchar * filename) {
|
||||
xmlDoc * wplist;
|
||||
xmlNode * root, * list, * wpa;
|
||||
@@ -118,6 +118,7 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
|
||||
if (!strcmp ((gchar *)list->name, "wallpaper")) {
|
||||
GnomeWPItem * wp;
|
||||
gchar *pcolor = NULL, *scolor = NULL;
|
||||
gchar *s;
|
||||
gboolean have_scale = FALSE, have_shade = FALSE;
|
||||
|
||||
wp = g_new0 (GnomeWPItem, 1);
|
||||
@@ -199,18 +200,24 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
|
||||
|
||||
/* Verify the colors and alloc some GdkColors here */
|
||||
if (!have_scale) {
|
||||
wp->options = g_settings_get_enum (data->settings, WP_OPTIONS_KEY);
|
||||
s = gconf_client_get_string (data->client, WP_OPTIONS_KEY, NULL);
|
||||
wp->options = wp_item_string_to_option (s);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
if (!have_shade) {
|
||||
wp->shade_type = g_settings_get_enum (data->settings, WP_SHADING_KEY);
|
||||
s = gconf_client_get_string (data->client, WP_SHADING_KEY, NULL);
|
||||
wp->shade_type = wp_item_string_to_shading (s);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
if (pcolor == NULL) {
|
||||
pcolor = g_settings_get_string (data->settings, WP_PCOLOR_KEY);
|
||||
pcolor = gconf_client_get_string (data->client,
|
||||
WP_PCOLOR_KEY, NULL);
|
||||
}
|
||||
if (scolor == NULL) {
|
||||
scolor = g_settings_get_string (data->settings, WP_SCOLOR_KEY);
|
||||
scolor = gconf_client_get_string (data->client,
|
||||
WP_SCOLOR_KEY, NULL);
|
||||
}
|
||||
gdk_color_parse (pcolor, &color1);
|
||||
gdk_color_parse (scolor, &color2);
|
||||
@@ -223,7 +230,7 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
|
||||
if ((wp->filename != NULL &&
|
||||
g_file_test (wp->filename, G_FILE_TEST_EXISTS)) ||
|
||||
!strcmp (wp->filename, "(none)")) {
|
||||
wp->fileinfo = gnome_wp_info_new (wp->filename, NULL, data->thumb_factory);
|
||||
wp->fileinfo = gnome_wp_info_new (wp->filename, data->thumb_factory);
|
||||
|
||||
if (wp->name == NULL || !strcmp (wp->filename, "(none)")) {
|
||||
g_free (wp->name);
|
||||
@@ -231,7 +238,7 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
|
||||
}
|
||||
|
||||
gnome_wp_item_ensure_gnome_bg (wp);
|
||||
gnome_wp_item_update_size (wp, NULL);
|
||||
gnome_wp_item_update_description (wp);
|
||||
g_hash_table_insert (data->wp_hash, wp->filename, wp);
|
||||
} else {
|
||||
gnome_wp_item_free (wp);
|
||||
@@ -246,7 +253,7 @@ static void gnome_wp_file_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
GnomeWpXml *data) {
|
||||
AppearanceData *data) {
|
||||
gchar * filename;
|
||||
|
||||
switch (event_type) {
|
||||
@@ -261,8 +268,8 @@ static void gnome_wp_file_changed (GFileMonitor *monitor,
|
||||
}
|
||||
}
|
||||
|
||||
static void gnome_wp_xml_add_monitor (GFile *directory,
|
||||
GnomeWpXml *data) {
|
||||
static void gnome_wp_xml_add_monitor (GFile *directory,
|
||||
AppearanceData *data) {
|
||||
GFileMonitor *monitor;
|
||||
GError *error = NULL;
|
||||
|
||||
@@ -287,7 +294,7 @@ static void gnome_wp_xml_add_monitor (GFile *directory,
|
||||
}
|
||||
|
||||
static void gnome_wp_xml_load_from_dir (const gchar *path,
|
||||
GnomeWpXml *data) {
|
||||
AppearanceData *data) {
|
||||
GFile *directory;
|
||||
GFileEnumerator *enumerator;
|
||||
GError *error = NULL;
|
||||
@@ -326,10 +333,9 @@ static void gnome_wp_xml_load_from_dir (const gchar *path,
|
||||
gnome_wp_xml_add_monitor (directory, data);
|
||||
|
||||
g_object_unref (directory);
|
||||
g_object_unref (enumerator);
|
||||
}
|
||||
|
||||
void gnome_wp_xml_load_list (GnomeWpXml *data) {
|
||||
void gnome_wp_xml_load_list (AppearanceData *data) {
|
||||
const char * const *system_data_dirs;
|
||||
gchar * datadir;
|
||||
gchar * wpdbfile;
|
||||
@@ -369,6 +375,8 @@ void gnome_wp_xml_load_list (GnomeWpXml *data) {
|
||||
g_free (datadir);
|
||||
}
|
||||
|
||||
gnome_wp_xml_load_from_dir (WALLPAPER_DATADIR, data);
|
||||
|
||||
gnome_wp_load_legacy (data);
|
||||
}
|
||||
|
||||
@@ -380,7 +388,7 @@ static void gnome_wp_list_flatten (const gchar * key, GnomeWPItem * item,
|
||||
*list = g_slist_prepend (*list, item);
|
||||
}
|
||||
|
||||
void gnome_wp_xml_save_list (GnomeWpXml *data) {
|
||||
void gnome_wp_xml_save_list (AppearanceData *data) {
|
||||
xmlDoc * wplist;
|
||||
xmlNode * root, * wallpaper, * item;
|
||||
GSList * list = NULL;
|
||||
@@ -21,22 +21,8 @@
|
||||
#ifndef _GNOME_WP_XML_H_
|
||||
#define _GNOME_WP_XML_H_
|
||||
|
||||
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
|
||||
|
||||
typedef struct _GnomeWpXml GnomeWpXml;
|
||||
|
||||
struct _GnomeWpXml
|
||||
{
|
||||
GHashTable *wp_hash;
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
GSettings *settings;
|
||||
gint thumb_height;
|
||||
gint thumb_width;
|
||||
GtkListStore *wp_model;
|
||||
};
|
||||
|
||||
void gnome_wp_xml_load_list (GnomeWpXml *data);
|
||||
void gnome_wp_xml_save_list (GnomeWpXml *data);
|
||||
void gnome_wp_xml_load_list (AppearanceData *data);
|
||||
void gnome_wp_xml_save_list (AppearanceData *data);
|
||||
|
||||
#endif
|
||||
|
||||
798
capplets/appearance/theme-installer.c
Normal file
@@ -0,0 +1,798 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "appearance.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "capplet-util.h"
|
||||
#include "file-transfer-dialog.h"
|
||||
#include "theme-installer.h"
|
||||
#include "theme-util.h"
|
||||
|
||||
enum {
|
||||
THEME_INVALID,
|
||||
THEME_ICON,
|
||||
THEME_GNOME,
|
||||
THEME_GTK,
|
||||
THEME_ENGINE,
|
||||
THEME_METACITY,
|
||||
THEME_CURSOR,
|
||||
THEME_ICON_CURSOR
|
||||
};
|
||||
|
||||
enum {
|
||||
TARGZ,
|
||||
TARBZ,
|
||||
DIRECTORY
|
||||
};
|
||||
|
||||
static gboolean
|
||||
cleanup_tmp_dir (GIOSchedulerJob *job,
|
||||
GCancellable *cancellable,
|
||||
const gchar *tmp_dir)
|
||||
{
|
||||
GFile *directory;
|
||||
|
||||
directory = g_file_new_for_path (tmp_dir);
|
||||
capplet_file_delete_recursive (directory, NULL);
|
||||
g_object_unref (directory);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
file_theme_type (const gchar *dir)
|
||||
{
|
||||
gchar *filename = NULL;
|
||||
gboolean exists;
|
||||
|
||||
if (!dir)
|
||||
return THEME_INVALID;
|
||||
|
||||
filename = g_build_filename (dir, "index.theme", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
|
||||
|
||||
if (exists) {
|
||||
GPatternSpec *pattern;
|
||||
gchar *file_contents = NULL;
|
||||
gsize file_size;
|
||||
gboolean match;
|
||||
|
||||
g_file_get_contents (filename, &file_contents, &file_size, NULL);
|
||||
g_free (filename);
|
||||
|
||||
pattern = g_pattern_spec_new ("*[Icon Theme]*");
|
||||
match = g_pattern_match_string (pattern, file_contents);
|
||||
g_pattern_spec_free (pattern);
|
||||
|
||||
if (match) {
|
||||
pattern = g_pattern_spec_new ("*Directories=*");
|
||||
match = g_pattern_match_string (pattern, file_contents);
|
||||
g_pattern_spec_free (pattern);
|
||||
g_free (file_contents);
|
||||
|
||||
if (match) {
|
||||
/* check if we have a cursor, too */
|
||||
filename = g_build_filename (dir, "cursors", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_DIR);
|
||||
g_free (filename);
|
||||
|
||||
if (exists)
|
||||
return THEME_ICON_CURSOR;
|
||||
else
|
||||
return THEME_ICON;
|
||||
}
|
||||
return THEME_CURSOR;
|
||||
}
|
||||
|
||||
pattern = g_pattern_spec_new ("*[X-GNOME-Metatheme]*");
|
||||
match = g_pattern_match_string (pattern, file_contents);
|
||||
g_pattern_spec_free (pattern);
|
||||
g_free (file_contents);
|
||||
|
||||
if (match)
|
||||
return THEME_GNOME;
|
||||
} else {
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
filename = g_build_filename (dir, "gtk-2.0", "gtkrc", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
|
||||
g_free (filename);
|
||||
|
||||
if (exists)
|
||||
return THEME_GTK;
|
||||
|
||||
filename = g_build_filename (dir, "metacity-1", "metacity-theme-1.xml", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
|
||||
g_free (filename);
|
||||
|
||||
if (exists)
|
||||
return THEME_METACITY;
|
||||
|
||||
/* cursor themes don't necessarily have an index.theme */
|
||||
filename = g_build_filename (dir, "cursors", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_DIR);
|
||||
g_free (filename);
|
||||
|
||||
if (exists)
|
||||
return THEME_CURSOR;
|
||||
|
||||
filename = g_build_filename (dir, "configure", NULL);
|
||||
exists = g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
|
||||
g_free (filename);
|
||||
|
||||
if (exists)
|
||||
return THEME_ENGINE;
|
||||
|
||||
return THEME_INVALID;
|
||||
}
|
||||
|
||||
static void
|
||||
transfer_cancel_cb (GtkWidget *dialog,
|
||||
gchar *path)
|
||||
{
|
||||
GFile *todelete;
|
||||
|
||||
todelete = g_file_new_for_path (path);
|
||||
capplet_file_delete_recursive (todelete, NULL);
|
||||
|
||||
g_object_unref (todelete);
|
||||
g_free (path);
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
missing_utility_message_dialog (GtkWindow *parent,
|
||||
const gchar *utility)
|
||||
{
|
||||
GtkWidget *dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
_("Cannot install theme"));
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
_("The %s utility is not installed."), utility);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/* this works around problems when doing fork/exec in a threaded app
|
||||
* with some locks being held/waited on in different threads.
|
||||
*
|
||||
* we do the idle callback so that the async xfer has finished and
|
||||
* cleaned up its vfs job. otherwise it seems the slave thread gets
|
||||
* woken up and it removes itself from the job queue before it is
|
||||
* supposed to. very strange.
|
||||
*
|
||||
* see bugzilla.gnome.org #86141 for details
|
||||
*/
|
||||
static gboolean
|
||||
process_local_theme_tgz_tbz (GtkWindow *parent,
|
||||
const gchar *util,
|
||||
const gchar *tmp_dir,
|
||||
const gchar *archive)
|
||||
{
|
||||
gboolean rc;
|
||||
int status;
|
||||
gchar *command, *filename, *zip, *tar;
|
||||
|
||||
if (!(zip = g_find_program_in_path (util))) {
|
||||
missing_utility_message_dialog (parent, util);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(tar = g_find_program_in_path ("tar"))) {
|
||||
missing_utility_message_dialog (parent, "tar");
|
||||
g_free (zip);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
filename = g_shell_quote (archive);
|
||||
|
||||
/* this should be something more clever and nonblocking */
|
||||
command = g_strdup_printf ("sh -c 'cd \"%s\"; %s -d -c < \"%s\" | %s xf - '",
|
||||
tmp_dir, zip, filename, tar);
|
||||
g_free (zip);
|
||||
g_free (tar);
|
||||
g_free (filename);
|
||||
|
||||
rc = (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && status == 0);
|
||||
g_free (command);
|
||||
|
||||
if (rc == FALSE) {
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
_("Cannot install theme"));
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
_("There was a problem while extracting the theme."));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_local_theme_archive (GtkWindow *parent,
|
||||
gint filetype,
|
||||
const gchar *tmp_dir,
|
||||
const gchar *archive)
|
||||
{
|
||||
if (filetype == TARGZ)
|
||||
return process_local_theme_tgz_tbz (parent, "gzip", tmp_dir, archive);
|
||||
else if (filetype == TARBZ)
|
||||
return process_local_theme_tgz_tbz (parent, "bzip2", tmp_dir, archive);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
invalid_theme_dialog (GtkWindow *parent,
|
||||
const gchar *filename,
|
||||
gboolean maybe_theme_engine)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
const gchar *primary = _("There was an error installing the selected file");
|
||||
const gchar *secondary = _("\"%s\" does not appear to be a valid theme.");
|
||||
const gchar *engine = _("\"%s\" does not appear to be a valid theme. It may be a theme engine which you need to compile.");
|
||||
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s", primary);
|
||||
if (maybe_theme_engine)
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), engine, filename);
|
||||
else
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, filename);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnome_theme_install_real (GtkWindow *parent,
|
||||
gint filetype,
|
||||
const gchar *tmp_dir,
|
||||
const gchar *theme_name,
|
||||
gboolean ask_user)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GtkWidget *dialog, *apply_button;
|
||||
GFile *theme_source_dir, *theme_dest_dir;
|
||||
GError *error = NULL;
|
||||
gint theme_type;
|
||||
gchar *target_dir = NULL;
|
||||
|
||||
/* What type of theme is it? */
|
||||
theme_type = file_theme_type (tmp_dir);
|
||||
switch (theme_type) {
|
||||
case THEME_ICON:
|
||||
case THEME_CURSOR:
|
||||
case THEME_ICON_CURSOR:
|
||||
target_dir = g_build_path (G_DIR_SEPARATOR_S,
|
||||
g_get_home_dir (), ".icons",
|
||||
theme_name, NULL);
|
||||
break;
|
||||
case THEME_GNOME:
|
||||
target_dir = g_build_path (G_DIR_SEPARATOR_S,
|
||||
g_get_home_dir (), ".themes",
|
||||
theme_name, NULL);
|
||||
break;
|
||||
case THEME_METACITY:
|
||||
case THEME_GTK:
|
||||
target_dir = g_build_path (G_DIR_SEPARATOR_S,
|
||||
g_get_home_dir (), ".themes",
|
||||
theme_name, NULL);
|
||||
break;
|
||||
case THEME_ENGINE:
|
||||
invalid_theme_dialog (parent, theme_name, TRUE);
|
||||
return FALSE;
|
||||
default:
|
||||
invalid_theme_dialog (parent, theme_name, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* see if there is an icon theme lurking in this package */
|
||||
if (theme_type == THEME_GNOME) {
|
||||
gchar *path;
|
||||
|
||||
path = g_build_path (G_DIR_SEPARATOR_S,
|
||||
tmp_dir, "icons", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_IS_DIR)
|
||||
&& (file_theme_type (path) == THEME_ICON)) {
|
||||
gchar *new_path, *update_icon_cache;
|
||||
GFile *new_file;
|
||||
GFile *src_file;
|
||||
|
||||
src_file = g_file_new_for_path (path);
|
||||
new_path = g_build_path (G_DIR_SEPARATOR_S,
|
||||
g_get_home_dir (),
|
||||
".icons",
|
||||
theme_name, NULL);
|
||||
new_file = g_file_new_for_path (new_path);
|
||||
|
||||
if (!g_file_move (src_file, new_file, G_FILE_COPY_NONE,
|
||||
NULL, NULL, NULL, &error)) {
|
||||
g_warning ("Error while moving from `%s' to `%s': %s",
|
||||
path, new_path, error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
g_object_unref (new_file);
|
||||
g_object_unref (src_file);
|
||||
|
||||
/* update icon cache - shouldn't really matter if this fails */
|
||||
update_icon_cache = g_strdup_printf ("gtk-update-icon-cache %s", new_path);
|
||||
g_spawn_command_line_async (update_icon_cache, NULL);
|
||||
g_free (update_icon_cache);
|
||||
|
||||
g_free (new_path);
|
||||
}
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
/* Move the dir to the target dir */
|
||||
theme_source_dir = g_file_new_for_path (tmp_dir);
|
||||
theme_dest_dir = g_file_new_for_path (target_dir);
|
||||
|
||||
if (!g_file_move (theme_source_dir, theme_dest_dir,
|
||||
G_FILE_COPY_OVERWRITE, NULL, NULL,
|
||||
NULL, &error)) {
|
||||
gchar *str;
|
||||
|
||||
str = g_strdup_printf (_("Installation for theme \"%s\" failed."), theme_name);
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s",
|
||||
str);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", error->message);
|
||||
|
||||
g_free (str);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
success = FALSE;
|
||||
} else {
|
||||
if (theme_type == THEME_ICON || theme_type == THEME_ICON_CURSOR)
|
||||
{
|
||||
gchar *update_icon_cache;
|
||||
|
||||
/* update icon cache - shouldn't really matter if this fails */
|
||||
update_icon_cache = g_strdup_printf ("gtk-update-icon-cache %s", target_dir);
|
||||
g_spawn_command_line_async (update_icon_cache, NULL);
|
||||
|
||||
g_free (update_icon_cache);
|
||||
}
|
||||
|
||||
if (ask_user) {
|
||||
/* Ask to apply theme (if we can) */
|
||||
if (theme_type == THEME_GTK
|
||||
|| theme_type == THEME_METACITY
|
||||
|| theme_type == THEME_ICON
|
||||
|| theme_type == THEME_CURSOR
|
||||
|| theme_type == THEME_ICON_CURSOR) {
|
||||
/* TODO: currently cannot apply "gnome themes" */
|
||||
gchar *str;
|
||||
|
||||
str = g_strdup_printf (_("The theme \"%s\" has been installed."), theme_name);
|
||||
dialog = gtk_message_dialog_new_with_markup (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_NONE,
|
||||
"<span weight=\"bold\" size=\"larger\">%s</span>",
|
||||
str);
|
||||
g_free (str);
|
||||
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
_("Would you like to apply it now, or keep your current theme?"));
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog),
|
||||
_("Keep Current Theme"),
|
||||
GTK_RESPONSE_CLOSE);
|
||||
|
||||
apply_button = gtk_button_new_with_label (_("Apply New Theme"));
|
||||
gtk_button_set_image (GTK_BUTTON (apply_button),
|
||||
gtk_image_new_from_stock (GTK_STOCK_APPLY,
|
||||
GTK_ICON_SIZE_BUTTON));
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (dialog), apply_button, GTK_RESPONSE_APPLY);
|
||||
GTK_WIDGET_SET_FLAGS (apply_button, GTK_CAN_DEFAULT);
|
||||
gtk_widget_show (apply_button);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY);
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_APPLY) {
|
||||
/* apply theme here! */
|
||||
GConfClient *gconf_client;
|
||||
|
||||
gconf_client = gconf_client_get_default ();
|
||||
|
||||
switch (theme_type) {
|
||||
case THEME_GTK:
|
||||
gconf_client_set_string (gconf_client, GTK_THEME_KEY, theme_name, NULL);
|
||||
break;
|
||||
case THEME_METACITY:
|
||||
gconf_client_set_string (gconf_client, METACITY_THEME_KEY, theme_name, NULL);
|
||||
break;
|
||||
case THEME_ICON:
|
||||
gconf_client_set_string (gconf_client, ICON_THEME_KEY, theme_name, NULL);
|
||||
break;
|
||||
case THEME_CURSOR:
|
||||
gconf_client_set_string (gconf_client, CURSOR_THEME_KEY, theme_name, NULL);
|
||||
break;
|
||||
case THEME_ICON_CURSOR:
|
||||
gconf_client_set_string (gconf_client, ICON_THEME_KEY, theme_name, NULL);
|
||||
gconf_client_set_string (gconf_client, CURSOR_THEME_KEY, theme_name, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_unref (gconf_client);
|
||||
}
|
||||
} else {
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
_("GNOME Theme %s correctly installed"),
|
||||
theme_name);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (target_dir);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
process_local_theme (GtkWindow *parent,
|
||||
const char *path)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
gint filetype;
|
||||
|
||||
if (g_str_has_suffix (path, ".tar.gz")
|
||||
|| g_str_has_suffix (path, ".tgz")
|
||||
|| g_str_has_suffix(path, ".gtp")) {
|
||||
filetype = TARGZ;
|
||||
} else if (g_str_has_suffix (path, ".tar.bz2")) {
|
||||
filetype = TARBZ;
|
||||
} else if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
|
||||
filetype = DIRECTORY;
|
||||
} else {
|
||||
gchar *filename;
|
||||
filename = g_path_get_basename (path);
|
||||
invalid_theme_dialog (parent, filename, FALSE);
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filetype == DIRECTORY) {
|
||||
gchar *name = g_path_get_basename (path);
|
||||
gnome_theme_install_real (parent,
|
||||
filetype,
|
||||
path,
|
||||
name,
|
||||
TRUE);
|
||||
g_free (name);
|
||||
} else {
|
||||
/* Create a temp directory and uncompress file there */
|
||||
GDir *dir;
|
||||
const gchar *name;
|
||||
gchar *tmp_dir;
|
||||
gboolean ok;
|
||||
gint n_themes;
|
||||
GFile *todelete;
|
||||
|
||||
tmp_dir = g_strdup_printf ("%s/.themes/.theme-%u",
|
||||
g_get_home_dir (),
|
||||
g_random_int ());
|
||||
|
||||
if ((g_mkdir (tmp_dir, 0700)) != 0) {
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
_("Failed to create temporary directory"));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
g_free (tmp_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!process_local_theme_archive (parent, filetype, tmp_dir, path)
|
||||
|| ((dir = g_dir_open (tmp_dir, 0, NULL)) == NULL)) {
|
||||
g_io_scheduler_push_job ((GIOSchedulerJobFunc) cleanup_tmp_dir,
|
||||
g_strdup (tmp_dir),
|
||||
g_free,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL);
|
||||
g_free (tmp_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
todelete = g_file_new_for_path (path);
|
||||
g_file_delete (todelete, NULL, NULL);
|
||||
g_object_unref (todelete);
|
||||
|
||||
/* See whether we have multiple themes to install. If so,
|
||||
* we won't ask the user whether to apply the new theme
|
||||
* after installation. */
|
||||
n_themes = 0;
|
||||
for (name = g_dir_read_name (dir);
|
||||
name && n_themes <= 1;
|
||||
name = g_dir_read_name (dir)) {
|
||||
gchar *theme_dir;
|
||||
|
||||
theme_dir = g_build_filename (tmp_dir, name, NULL);
|
||||
|
||||
if (g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
|
||||
++n_themes;
|
||||
|
||||
g_free (theme_dir);
|
||||
}
|
||||
g_dir_rewind (dir);
|
||||
|
||||
ok = TRUE;
|
||||
for (name = g_dir_read_name (dir); name && ok;
|
||||
name = g_dir_read_name (dir)) {
|
||||
gchar *theme_dir;
|
||||
|
||||
theme_dir = g_build_filename (tmp_dir, name, NULL);
|
||||
|
||||
if (g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
|
||||
ok = gnome_theme_install_real (parent,
|
||||
filetype,
|
||||
theme_dir,
|
||||
name,
|
||||
n_themes == 1);
|
||||
|
||||
g_free (theme_dir);
|
||||
}
|
||||
g_dir_close (dir);
|
||||
|
||||
if (ok && n_themes > 1) {
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
_("New themes have been successfully installed."));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
g_io_scheduler_push_job ((GIOSchedulerJobFunc) cleanup_tmp_dir,
|
||||
tmp_dir, g_free,
|
||||
G_PRIORITY_DEFAULT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWindow *parent;
|
||||
char *path;
|
||||
} TransferData;
|
||||
|
||||
static void
|
||||
transfer_done_cb (GtkWidget *dialog,
|
||||
TransferData *tdata)
|
||||
{
|
||||
/* XXX: path should be on the local filesystem by now? */
|
||||
|
||||
if (dialog != NULL) {
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
process_local_theme (tdata->parent, tdata->path);
|
||||
|
||||
g_free (tdata->path);
|
||||
g_free (tdata);
|
||||
}
|
||||
|
||||
void
|
||||
gnome_theme_install (GFile *file,
|
||||
GtkWindow *parent)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
gchar *path, *base;
|
||||
GList *src, *target;
|
||||
const gchar *template;
|
||||
TransferData *tdata;
|
||||
|
||||
if (file == NULL) {
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
_("No theme file location specified to install"));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
return;
|
||||
}
|
||||
|
||||
/* see if someone dropped a local directory */
|
||||
if (g_file_is_native (file)
|
||||
&& g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY) {
|
||||
path = g_file_get_path (file);
|
||||
process_local_theme (parent, path);
|
||||
g_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
/* we can't tell if this is an icon theme yet, so just make a
|
||||
* temporary copy in .themes */
|
||||
path = g_build_filename (g_get_home_dir (), ".themes", NULL);
|
||||
|
||||
if (access (path, X_OK | W_OK) != 0) {
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
_("Insufficient permissions to install the theme in:\n%s"), path);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
g_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
base = g_file_get_basename (file);
|
||||
|
||||
if (g_str_has_suffix (base, ".tar.gz")
|
||||
|| g_str_has_suffix (base, ".tgz")
|
||||
|| g_str_has_suffix (base, ".gtp"))
|
||||
template = "gnome-theme-%d.gtp";
|
||||
else if (g_str_has_suffix (base, ".tar.bz2"))
|
||||
template = "gnome-theme-%d.tar.bz2";
|
||||
else {
|
||||
invalid_theme_dialog (parent, base, FALSE);
|
||||
g_free (base);
|
||||
return;
|
||||
}
|
||||
g_free (base);
|
||||
|
||||
src = g_list_append (NULL, g_object_ref (file));
|
||||
|
||||
path = NULL;
|
||||
do {
|
||||
gchar *file_tmp;
|
||||
|
||||
g_free (path);
|
||||
file_tmp = g_strdup_printf (template, g_random_int ());
|
||||
path = g_build_filename (g_get_home_dir (), ".themes", file_tmp, NULL);
|
||||
g_free (file_tmp);
|
||||
} while (g_file_test (path, G_FILE_TEST_EXISTS));
|
||||
|
||||
tdata = g_new0 (TransferData, 1);
|
||||
tdata->parent = parent;
|
||||
tdata->path = path;
|
||||
|
||||
dialog = file_transfer_dialog_new_with_parent (parent);
|
||||
g_signal_connect (dialog,
|
||||
"cancel",
|
||||
(GCallback) transfer_cancel_cb, path);
|
||||
g_signal_connect (dialog,
|
||||
"done",
|
||||
(GCallback) transfer_done_cb, tdata);
|
||||
|
||||
target = g_list_append (NULL, g_file_new_for_path (path));
|
||||
file_transfer_dialog_copy_async (FILE_TRANSFER_DIALOG (dialog),
|
||||
src,
|
||||
target,
|
||||
FILE_TRANSFER_DIALOG_DEFAULT,
|
||||
G_PRIORITY_DEFAULT);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
/* don't free the path since we're using that for the signals */
|
||||
g_list_foreach (src, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (src);
|
||||
g_list_foreach (target, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (target);
|
||||
}
|
||||
|
||||
void
|
||||
gnome_theme_installer_run (GtkWindow *parent,
|
||||
const gchar *filename)
|
||||
{
|
||||
static gboolean running_theme_install = FALSE;
|
||||
static gchar old_folder[512] = "";
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
|
||||
if (running_theme_install)
|
||||
return;
|
||||
|
||||
running_theme_install = TRUE;
|
||||
|
||||
if (filename == NULL)
|
||||
filename = old_folder;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new (_("Select Theme"),
|
||||
parent,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_REJECT,
|
||||
GTK_STOCK_OPEN,
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, _("Theme Packages"));
|
||||
gtk_file_filter_add_mime_type (filter, "application/x-bzip-compressed-tar");
|
||||
gtk_file_filter_add_mime_type (filter, "application/x-compressed-tar");
|
||||
gtk_file_filter_add_mime_type (filter, "application/x-gnome-theme-package");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, _("All Files"));
|
||||
gtk_file_filter_add_pattern(filter, "*");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
if (strcmp (old_folder, ""))
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), old_folder);
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
gchar *uri_selected, *folder;
|
||||
|
||||
uri_selected = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
|
||||
|
||||
folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
|
||||
g_strlcpy (old_folder, folder, 255);
|
||||
g_free (folder);
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
if (uri_selected != NULL) {
|
||||
GFile *file = g_file_new_for_uri (uri_selected);
|
||||
g_free (uri_selected);
|
||||
|
||||
gnome_theme_install (file, parent);
|
||||
g_object_unref (file);
|
||||
}
|
||||
} else {
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/*
|
||||
* we're relying on the gnome theme info module to pick up changes
|
||||
* to the themes so we don't need to update the model here
|
||||
*/
|
||||
|
||||
running_theme_install = FALSE;
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Red Hat, Inc
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -11,29 +14,15 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#ifndef THEME_INSTALLER_H
|
||||
#define THEME_INSTALLER_H
|
||||
|
||||
#include "cc-printers-panel.h"
|
||||
void gnome_theme_install (GFile *file, GtkWindow *parent);
|
||||
void gnome_theme_installer_run (GtkWindow *parent, const gchar *filename);
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
void
|
||||
g_io_module_load (GIOModule *module)
|
||||
{
|
||||
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
/* register the panel */
|
||||
cc_printers_panel_register (module);
|
||||
}
|
||||
|
||||
void
|
||||
g_io_module_unload (GIOModule *module)
|
||||
{
|
||||
}
|
||||
#endif /* THEME_INSTALLER_H */
|
||||
381
capplets/appearance/theme-save.c
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "appearance.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "theme-save.h"
|
||||
#include "theme-util.h"
|
||||
#include "capplet-util.h"
|
||||
|
||||
static GQuark error_quark;
|
||||
enum {
|
||||
INVALID_THEME_NAME
|
||||
};
|
||||
|
||||
/* taken from gnome-desktop-item.c */
|
||||
static gchar *
|
||||
escape_string_and_dup (const gchar *s)
|
||||
{
|
||||
gchar *return_value, *p;
|
||||
const gchar *q;
|
||||
int len = 0;
|
||||
|
||||
if (s == NULL)
|
||||
return g_strdup("");
|
||||
|
||||
q = s;
|
||||
while (*q)
|
||||
{
|
||||
len++;
|
||||
if (strchr ("\n\r\t\\", *q) != NULL)
|
||||
len++;
|
||||
q++;
|
||||
}
|
||||
return_value = p = (gchar *) g_malloc (len + 1);
|
||||
do
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
case '\t':
|
||||
*p++ = '\\';
|
||||
*p++ = 't';
|
||||
break;
|
||||
case '\n':
|
||||
*p++ = '\\';
|
||||
*p++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*p++ = '\\';
|
||||
*p++ = 'r';
|
||||
break;
|
||||
case '\\':
|
||||
*p++ = '\\';
|
||||
*p++ = '\\';
|
||||
break;
|
||||
default:
|
||||
*p++ = *s;
|
||||
}
|
||||
}
|
||||
while (*s++);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_theme_name (const gchar *theme_name,
|
||||
GError **error)
|
||||
{
|
||||
if (theme_name == NULL) {
|
||||
g_set_error (error,
|
||||
error_quark,
|
||||
INVALID_THEME_NAME,
|
||||
_("Theme name must be present"));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
str_remove_slash (const gchar *src)
|
||||
{
|
||||
const gchar *i;
|
||||
gchar *rtn;
|
||||
gint len = 0;
|
||||
i = src;
|
||||
|
||||
while (*i) {
|
||||
if (*i != '/')
|
||||
len++;
|
||||
i++;
|
||||
}
|
||||
|
||||
rtn = (gchar *) g_malloc (len + 1);
|
||||
while (*src) {
|
||||
if (*src != '/') {
|
||||
*rtn = *src;
|
||||
rtn++;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*rtn = '\0';
|
||||
return rtn - len;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
setup_directory_structure (const gchar *theme_name,
|
||||
GError **error)
|
||||
{
|
||||
gchar *dir, *theme_name_dir;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
theme_name_dir = str_remove_slash (theme_name);
|
||||
|
||||
dir = g_build_filename (g_get_home_dir (), ".themes", NULL);
|
||||
if (!g_file_test (dir, G_FILE_TEST_EXISTS))
|
||||
g_mkdir (dir, 0775);
|
||||
g_free (dir);
|
||||
|
||||
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, NULL);
|
||||
if (!g_file_test (dir, G_FILE_TEST_EXISTS))
|
||||
g_mkdir (dir, 0775);
|
||||
g_free (dir);
|
||||
|
||||
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, "index.theme", NULL);
|
||||
g_free (theme_name_dir);
|
||||
|
||||
if (g_file_test (dir, G_FILE_TEST_EXISTS)) {
|
||||
GtkDialog *dialog;
|
||||
GtkWidget *button;
|
||||
gint response;
|
||||
|
||||
dialog = (GtkDialog *) gtk_message_dialog_new (NULL,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_CANCEL,
|
||||
_("The theme already exists. Would you like to replace it?"));
|
||||
button = gtk_dialog_add_button (dialog, _("_Overwrite"), GTK_RESPONSE_ACCEPT);
|
||||
gtk_button_set_image (GTK_BUTTON (button),
|
||||
gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON));
|
||||
response = gtk_dialog_run (dialog);
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
retval = (response != GTK_RESPONSE_CANCEL);
|
||||
}
|
||||
g_free (dir);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_theme_to_disk (GnomeThemeMetaInfo *theme_info,
|
||||
const gchar *theme_name,
|
||||
const gchar *theme_description,
|
||||
gboolean save_background,
|
||||
GError **error)
|
||||
{
|
||||
gchar *dir, *theme_name_dir;
|
||||
GFile *tmp_file;
|
||||
GFile *target_file;
|
||||
GOutputStream *output;
|
||||
|
||||
gchar *str, *current_background;
|
||||
GConfClient *client;
|
||||
const gchar *theme_header =
|
||||
"[Desktop Entry]\n"
|
||||
"Name=%s\n"
|
||||
"Type=X-GNOME-Metatheme\n"
|
||||
"Comment=%s\n"
|
||||
"\n"
|
||||
"[X-GNOME-Metatheme]\n"
|
||||
"GtkTheme=%s\n"
|
||||
"MetacityTheme=%s\n"
|
||||
"IconTheme=%s\n";
|
||||
|
||||
theme_name_dir = str_remove_slash (theme_name);
|
||||
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, "index.theme~", NULL);
|
||||
g_free (theme_name_dir);
|
||||
|
||||
tmp_file = g_file_new_for_path (dir);
|
||||
dir [strlen (dir) - 1] = '\000';
|
||||
target_file = g_file_new_for_path (dir);
|
||||
g_free (dir);
|
||||
|
||||
/* start making the theme file */
|
||||
str = g_strdup_printf (theme_header, theme_name, theme_description,
|
||||
theme_info->gtk_theme_name,
|
||||
theme_info->metacity_theme_name,
|
||||
theme_info->icon_theme_name);
|
||||
|
||||
output = G_OUTPUT_STREAM (g_file_replace (tmp_file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
|
||||
g_output_stream_write (output, str, strlen (str), NULL, NULL);
|
||||
g_free (str);
|
||||
|
||||
if (theme_info->gtk_color_scheme) {
|
||||
gchar *a, *tmp;
|
||||
tmp = g_strdup (theme_info->gtk_color_scheme);
|
||||
for (a = tmp; *a != '\0'; a++)
|
||||
if (*a == '\n')
|
||||
*a = ',';
|
||||
str = g_strdup_printf ("GtkColorScheme=%s\n", tmp);
|
||||
g_output_stream_write (output, str, strlen (str), NULL, NULL);
|
||||
|
||||
g_free (str);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
if (theme_info->cursor_theme_name) {
|
||||
#ifdef HAVE_XCURSOR
|
||||
str = g_strdup_printf ("CursorTheme=%s\n"
|
||||
"CursorSize=%i\n",
|
||||
theme_info->cursor_theme_name,
|
||||
theme_info->cursor_size);
|
||||
#else
|
||||
str = g_strdup_printf ("CursorFont=%s\n", theme_info->cursor_theme_name);
|
||||
#endif
|
||||
g_output_stream_write (output, str, strlen (str), NULL, NULL);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
if (theme_info->notification_theme_name) {
|
||||
str = g_strdup_printf ("NotificationTheme=%s\n", theme_info->notification_theme_name);
|
||||
g_output_stream_write (output, str, strlen (str), NULL, NULL);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
if (save_background) {
|
||||
client = gconf_client_get_default ();
|
||||
current_background = gconf_client_get_string (client, BACKGROUND_KEY, NULL);
|
||||
|
||||
if (current_background != NULL) {
|
||||
str = g_strdup_printf ("BackgroundImage=%s\n", current_background);
|
||||
|
||||
g_output_stream_write (output, str, strlen (str), NULL, NULL);
|
||||
|
||||
g_free (current_background);
|
||||
g_free (str);
|
||||
}
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
g_file_move (tmp_file, target_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
|
||||
g_output_stream_close (output, NULL, NULL);
|
||||
|
||||
g_object_unref (tmp_file);
|
||||
g_object_unref (target_file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
save_theme_to_disk (GnomeThemeMetaInfo *theme_info,
|
||||
const gchar *theme_name,
|
||||
const gchar *theme_description,
|
||||
gboolean save_background,
|
||||
GError **error)
|
||||
{
|
||||
if (!check_theme_name (theme_name, error))
|
||||
return FALSE;
|
||||
|
||||
if (!setup_directory_structure (theme_name, error))
|
||||
return FALSE;
|
||||
|
||||
if (!write_theme_to_disk (theme_info, theme_name, theme_description, save_background, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
save_dialog_response (GtkWidget *save_dialog,
|
||||
gint response_id,
|
||||
AppearanceData *data)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK) {
|
||||
GtkWidget *entry;
|
||||
GtkWidget *text_view;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start_iter;
|
||||
GtkTextIter end_iter;
|
||||
gchar *buffer_text;
|
||||
GnomeThemeMetaInfo *theme_info;
|
||||
gchar *theme_description = NULL;
|
||||
gchar *theme_name = NULL;
|
||||
gboolean save_background;
|
||||
GError *error = NULL;
|
||||
|
||||
entry = appearance_capplet_get_widget (data, "save_dialog_entry");
|
||||
theme_name = escape_string_and_dup (gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
|
||||
text_view = appearance_capplet_get_widget (data, "save_dialog_textview");
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
gtk_text_buffer_get_start_iter (buffer, &start_iter);
|
||||
gtk_text_buffer_get_end_iter (buffer, &end_iter);
|
||||
buffer_text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
|
||||
theme_description = escape_string_and_dup (buffer_text);
|
||||
g_free (buffer_text);
|
||||
theme_info = (GnomeThemeMetaInfo *) g_object_get_data (G_OBJECT (save_dialog), "meta-theme-info");
|
||||
save_background = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
|
||||
appearance_capplet_get_widget (data, "save_background_checkbutton")));
|
||||
|
||||
if (save_theme_to_disk (theme_info, theme_name, theme_description, save_background, &error)) {
|
||||
/* remove the custom theme */
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (theme_find_in_model (GTK_TREE_MODEL (data->theme_store), "__custom__", &iter))
|
||||
gtk_list_store_remove (data->theme_store, &iter);
|
||||
}
|
||||
|
||||
g_free (theme_name);
|
||||
g_free (theme_description);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
gtk_widget_hide (save_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_text_changed (GtkEditable *editable,
|
||||
AppearanceData *data)
|
||||
{
|
||||
const gchar *text;
|
||||
GtkWidget *button;
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (editable));
|
||||
button = appearance_capplet_get_widget (data, "save_dialog_save_button");
|
||||
|
||||
gtk_widget_set_sensitive (button, text != NULL && text[0] != '\000');
|
||||
}
|
||||
|
||||
void
|
||||
theme_save_dialog_run (GnomeThemeMetaInfo *theme_info,
|
||||
AppearanceData *data)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GtkWidget *text_view;
|
||||
GtkTextBuffer *text_buffer;
|
||||
|
||||
entry = appearance_capplet_get_widget (data, "save_dialog_entry");
|
||||
text_view = appearance_capplet_get_widget (data, "save_dialog_textview");
|
||||
|
||||
if (data->theme_save_dialog == NULL) {
|
||||
data->theme_save_dialog = appearance_capplet_get_widget (data, "theme_save_dialog");
|
||||
|
||||
g_signal_connect (data->theme_save_dialog, "response", (GCallback) save_dialog_response, data);
|
||||
g_signal_connect (data->theme_save_dialog, "delete-event", (GCallback) gtk_true, NULL);
|
||||
g_signal_connect (entry, "changed", (GCallback) entry_text_changed, data);
|
||||
|
||||
error_quark = g_quark_from_string ("gnome-theme-save");
|
||||
gtk_widget_set_size_request (text_view, 300, 100);
|
||||
}
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
||||
entry_text_changed (GTK_EDITABLE (entry), data);
|
||||
gtk_widget_grab_focus (entry);
|
||||
|
||||
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
gtk_text_buffer_set_text (text_buffer, "", 0);
|
||||
g_object_set_data (G_OBJECT (data->theme_save_dialog), "meta-theme-info", theme_info);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (data->theme_save_dialog),
|
||||
GTK_WINDOW (appearance_capplet_get_widget (data, "appearance_window")));
|
||||
gtk_widget_show (data->theme_save_dialog);
|
||||
}
|
||||