Compare commits

..

4 Commits

Author SHA1 Message Date
David Reveman
c23c92b069 Handle scaling with RANDR transformations for Clone mode 2010-01-28 12:30:30 -06:00
David Reveman
acb0b4725f Add an (invisible for now) combo box to select scaling for a display 2010-01-28 12:08:11 -06:00
Federico Mena Quintero
6677c366a8 Set the GConf key for tablet rotation when the user clicks the checkbox
The actual call to xsetwacom(1) will be handled in gnome-settings-daemon.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
2009-12-02 17:01:12 -06:00
Federico Mena Quintero
97b42a7ccf Add a checkbox to rotate a pressure-sensitive tablet as well as the monitor
For tablets, we will call xsetwacom(1) to rotate the stylus when the monitor is
rotated.  This is the corresponding option in the display capplet; it also depends
on a patch to gnome-settings-daemon to actually handle the changes.

For built-in tablets like a Tablet PC, you *want* the tablet to rotate
when you rotate the monitor.  However, this is not the case for external
tablets plugged to a desktop PC.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
2009-12-02 17:00:28 -06:00
837 changed files with 190511 additions and 472376 deletions

View File

@@ -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
View File

@@ -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:

View File

@@ -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
View 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

View File

@@ -0,0 +1,2 @@
Diego Gonzalez Gonzalez <diego@pemas.net>
Chris Toshok <toshok@ximian.com>

View 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

View 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;
}

View 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_ */

View File

@@ -0,0 +1,3 @@
NONE:NONE
NONE:INT
NONE:POINTER

View 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);
}
}

View 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 */

View 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 */

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View 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);
}
}

View File

@@ -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 */

View File

@@ -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>

File diff suppressed because it is too large Load Diff

View 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__ */

View 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 &lt;b&gt;Authenticate&lt;/b&gt;.
After you have authenticated, enter your new password, retype it for verification and click &lt;b&gt;Change password&lt;/b&gt;.</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 &lt;b&gt;Retype new password&lt;/b&gt; 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>

File diff suppressed because it is too large Load Diff

View 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@

View File

@@ -29,3 +29,4 @@ pixmaps_DATA = \
EXTRA_DIST = $(pixmaps_DATA)
-include $(top_srcdir)/git.mk

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -1,4 +1,3 @@
SUBDIRS = status apps
SUBDIRS = at-properties
-include $(top_srcdir)/git.mk

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View 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>

View File

@@ -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@

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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);

View 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);
}

View File

@@ -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);

View 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;
}

File diff suppressed because it is too large Load Diff

View 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);

File diff suppressed because it is too large Load Diff

View 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);

View 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)

View 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

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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@

View 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@

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View 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;
}

View 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__ */

View File

@@ -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);
}

View File

@@ -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);

View 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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View 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;
}

View File

@@ -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 */

View 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);
}

Some files were not shown because too many files have changed in this diff Show More