Author: rpmcruz Date: Thu Nov 29 18:22:01 2007 New Revision: 42514 URL: http://svn.opensuse.org/viewcvs/yast?rev=42514&view=rev Log: Branching. Added: trunk/gtk/unstable/integrate/ trunk/gtk/unstable/integrate/YaST2.call trunk/gtk/unstable/integrate/yast2 (with props) trunk/gtk/unstable/integrate/yast2-funcs trunk/gtk/unstable/mockups/ trunk/gtk/unstable/mockups/package-selector/ trunk/gtk/unstable/mockups/package-selector/christian-package-selector-1.png (with props) trunk/gtk/unstable/mockups/package-selector/christian-package-selector-2.png (with props) trunk/gtk/unstable/mockups/package-selector/christian-patterns.png (with props) trunk/gtk/unstable/mockups/package-selector/martin-package-selector-1.gif (with props) trunk/gtk/unstable/mockups/package-selector/packagekit-groups.png (with props) trunk/gtk/unstable/mockups/package-selector/packagekit-search.png (with props) trunk/gtk/unstable/mockups/package-selector/ricado-split-use-cases.svg trunk/gtk/unstable/mockups/package-selector/ubuntu-add-remove-applications.jpg (with props) trunk/gtk/unstable/mockups/wizard-look/ trunk/gtk/unstable/mockups/wizard-look/installer-mockup.png (with props) trunk/gtk/unstable/mockups/wizard-look/jakub-installer-mockup.jpg (with props) trunk/gtk/unstable/mockups/wizard-look/jakub-mockup.svg trunk/gtk/unstable/mockups/wizard-look/ricardo-installer-mockup.svg trunk/gtk/unstable/mockups/wizard-look/tools-mockup.png (with props) trunk/gtk/unstable/package/ trunk/gtk/unstable/package/yast2-gtk-rpmlintrc trunk/gtk/unstable/package/yast2-gtk.changes trunk/gtk/unstable/src/ trunk/gtk/unstable/src/.cvsignore trunk/gtk/unstable/src/Makefile trunk/gtk/unstable/src/Makefile.am trunk/gtk/unstable/src/Makefile.in trunk/gtk/unstable/src/Y2CCGtk.cc trunk/gtk/unstable/src/YGBarGraph.cc trunk/gtk/unstable/src/YGComboBox.cc trunk/gtk/unstable/src/YGDialog.cc trunk/gtk/unstable/src/YGDialog.h trunk/gtk/unstable/src/YGDumbTab.cc trunk/gtk/unstable/src/YGFrame.cc trunk/gtk/unstable/src/YGImage.cc trunk/gtk/unstable/src/YGIntField.cc trunk/gtk/unstable/src/YGLabel.cc trunk/gtk/unstable/src/YGLayout.cc trunk/gtk/unstable/src/YGMenuButton.cc trunk/gtk/unstable/src/YGMultiLineEdit.cc trunk/gtk/unstable/src/YGPackageSelector.cc trunk/gtk/unstable/src/YGPackageSelector.cc-ori trunk/gtk/unstable/src/YGProgressBar.cc trunk/gtk/unstable/src/YGPushButton.cc trunk/gtk/unstable/src/YGRadioButton.cc trunk/gtk/unstable/src/YGTable.cc trunk/gtk/unstable/src/YGTextEntry.cc trunk/gtk/unstable/src/YGTime.cc trunk/gtk/unstable/src/YGTree.cc trunk/gtk/unstable/src/YGUI.cc trunk/gtk/unstable/src/YGUI.h trunk/gtk/unstable/src/YGUtils.cc trunk/gtk/unstable/src/YGUtils.h trunk/gtk/unstable/src/YGWidget.cc trunk/gtk/unstable/src/YGWidget.h trunk/gtk/unstable/src/YGWizard.cc trunk/gtk/unstable/src/YGi18n.h trunk/gtk/unstable/src/dummy.cc trunk/gtk/unstable/src/icons/ trunk/gtk/unstable/src/icons/cat-development.xpm trunk/gtk/unstable/src/icons/cat-documentation.xpm trunk/gtk/unstable/src/icons/cat-emulators.xpm trunk/gtk/unstable/src/icons/cat-games.xpm trunk/gtk/unstable/src/icons/cat-hardware.xpm trunk/gtk/unstable/src/icons/cat-multimedia.xpm trunk/gtk/unstable/src/icons/cat-network.xpm trunk/gtk/unstable/src/icons/cat-office.xpm trunk/gtk/unstable/src/icons/cat-system.xpm trunk/gtk/unstable/src/icons/cat-utilities.xpm trunk/gtk/unstable/src/icons/pkg-3D.xpm trunk/gtk/unstable/src/icons/pkg-available-locked.xpm trunk/gtk/unstable/src/icons/pkg-available.xpm trunk/gtk/unstable/src/icons/pkg-install-auto.xpm trunk/gtk/unstable/src/icons/pkg-install.xpm trunk/gtk/unstable/src/icons/pkg-installed-locked.xpm trunk/gtk/unstable/src/icons/pkg-installed-upgradable-locked.xpm trunk/gtk/unstable/src/icons/pkg-installed-upgradable.xpm trunk/gtk/unstable/src/icons/pkg-installed.xpm trunk/gtk/unstable/src/icons/pkg-list-mode.xpm trunk/gtk/unstable/src/icons/pkg-locked.xpm trunk/gtk/unstable/src/icons/pkg-remove-auto.xpm trunk/gtk/unstable/src/icons/pkg-remove.xpm trunk/gtk/unstable/src/icons/pkg-tiles-mode.xpm trunk/gtk/unstable/src/icons/pkg-unlocked.xpm trunk/gtk/unstable/src/mng-loader.c trunk/gtk/unstable/src/mng-loader.h trunk/gtk/unstable/src/test.cc trunk/gtk/unstable/src/ygdkmngloader.c trunk/gtk/unstable/src/ygdkmngloader.c-old trunk/gtk/unstable/src/ygdkmngloader.h trunk/gtk/unstable/src/ygtkbargraph.c trunk/gtk/unstable/src/ygtkbargraph.h trunk/gtk/unstable/src/ygtkfieldentry.c trunk/gtk/unstable/src/ygtkfieldentry.h trunk/gtk/unstable/src/ygtkfindentry.c trunk/gtk/unstable/src/ygtkfindentry.h trunk/gtk/unstable/src/ygtkhtmlwrap.c trunk/gtk/unstable/src/ygtkhtmlwrap.h trunk/gtk/unstable/src/ygtkmenubutton.c trunk/gtk/unstable/src/ygtkmenubutton.h trunk/gtk/unstable/src/ygtkratiobox.c trunk/gtk/unstable/src/ygtkratiobox.h trunk/gtk/unstable/src/ygtkrichtext.c trunk/gtk/unstable/src/ygtkrichtext.h trunk/gtk/unstable/src/ygtksteps.c trunk/gtk/unstable/src/ygtksteps.h trunk/gtk/unstable/src/ygtkwizard.c trunk/gtk/unstable/src/ygtkwizard.h trunk/gtk/unstable/src/ygtkzyppwrapper.cc trunk/gtk/unstable/src/ygtkzyppwrapper.h trunk/gtk/unstable/src/yzyppwrapper.cc trunk/gtk/unstable/src/yzyppwrapper.h trunk/gtk/unstable/tests/ trunk/gtk/unstable/tests/Beep.ycp (with props) trunk/gtk/unstable/tests/Cursor.ycp trunk/gtk/unstable/tests/FileDialog.ycp trunk/gtk/unstable/tests/Frame.ycp trunk/gtk/unstable/tests/IconButton.ycp (with props) trunk/gtk/unstable/tests/IconItems-ComboBox.ycp (with props) trunk/gtk/unstable/tests/IconItems-MultiSelectionBox.ycp (with props) trunk/gtk/unstable/tests/IconItems-SelectionBox.ycp (with props) trunk/gtk/unstable/tests/Image.ycp trunk/gtk/unstable/tests/ImageMng.ycp trunk/gtk/unstable/tests/Layout-Align-Weight.ycp (with props) trunk/gtk/unstable/tests/Layout-AlignStretch.ycp trunk/gtk/unstable/tests/Layout-Expand.ycp (with props) trunk/gtk/unstable/tests/Layout-Frame2.ycp (with props) trunk/gtk/unstable/tests/Layout-HVCenter-Align.ycp (with props) trunk/gtk/unstable/tests/Layout-ReplacePoint.ycp (with props) trunk/gtk/unstable/tests/Layout-Split-Split.ycp (with props) trunk/gtk/unstable/tests/Layout-Truncated-Widget.ycp (with props) trunk/gtk/unstable/tests/Layout-Wizard-BackgroundWidget.ycp (with props) trunk/gtk/unstable/tests/Layout-Wizard-OneWidget.ycp (with props) trunk/gtk/unstable/tests/Layout-Wizard3.ycp (with props) trunk/gtk/unstable/tests/MainDialogs.ycp trunk/gtk/unstable/tests/MultiProgressMeterHuge.ycp trunk/gtk/unstable/tests/MultiProgressMeterVer.ycp trunk/gtk/unstable/tests/MultiSelectionBox.ycp trunk/gtk/unstable/tests/ProgressPulse.ycp trunk/gtk/unstable/tests/RichText1.ycp trunk/gtk/unstable/tests/RichText2.ycp trunk/gtk/unstable/tests/SelectionBox.ycp (with props) trunk/gtk/unstable/tests/StockIcons.ycp trunk/gtk/unstable/tests/Table3-4.ycp (with props) trunk/gtk/unstable/tests/TransientDialog.ycp trunk/gtk/unstable/tests/Tree3.ycp trunk/gtk/unstable/tests/WizardList.ycp trunk/gtk/unstable/tests/image.gif (with props) trunk/gtk/unstable/tests/movie-endless.mng-old (with props) trunk/gtk/unstable/tests/movie1.mng (with props) trunk/gtk/unstable/tests/movie2.mng (with props) trunk/gtk/unstable/tests/movie3.mng (with props) trunk/gtk/unstable/tests/movie4.mng (with props) trunk/gtk/unstable/tests/movie5.mng (with props) trunk/gtk/unstable/tests/movie6.mng (with props) trunk/gtk/unstable/tests/movie7.mng (with props) trunk/gtk/unstable/tests/movie8.mng (with props) trunk/gtk/unstable/ycc/ trunk/gtk/unstable/ycc/Makefile trunk/gtk/unstable/ycc/ycc.cpp Added: trunk/gtk/unstable/integrate/YaST2.call URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/integrate/YaST2.call... ============================================================================== --- trunk/gtk/unstable/integrate/YaST2.call (added) +++ trunk/gtk/unstable/integrate/YaST2.call Thu Nov 29 18:22:01 2007 @@ -0,0 +1,779 @@ +#!/bin/sh +#================ +# FILE : YaST2.call +#---------------- +# PROJECT : YaST (Yet another Setup Tool v2) +# COPYRIGHT : (c) 2004 SUSE Linux AG, Germany. All rights reserved +# : +# AUTHORS : Steffen Winterfeldt <snwint@suse.de> +# . Arvin Schnell <arvin@suse.de> +# : Marcus Schaefer <ms@suse.de> +# : +# BELONGS TO : System installation and Administration +# : +# DESCRIPTION : This is the main script to start the YaST2 installer +# : according to the possible installation environments +# : These are: +# : --- +# : - Standard Installation Qt/X11 or text based +# : - Via serial line ttyS0/115200 baud, 8N1, RTS/CTS +# : which is the same as the NCURSES mode +# : - VNC Installation via browser +# : +# : +# STATUS : $Id: YaST2.call 32688 2006-09-04 14:05:17Z locilka $ +#---------------- +# +#set -x + +. /etc/YaST2/XVersion + +#============================================= +# Functions... +#--------------------------------------------- +#----[ wait_for_x11 ]----# +function wait_for_x11() { +#------------------------------------------------------ +# after a X-Server has been started you can wait until +# the server is ready for requests using this function +# --- + server_running=0 + TESTX=/usr/sbin/testX + while kill -0 $xserver_pid 2>/dev/null ; do + sleep 1 + if test -e /tmp/.X11-unix/X0 && test -x $TESTX ; then + $TESTX "$YaST2color" 2>/dev/null + err=$? + # exit code 1 -> XOpenDisplay failed... + if test $err = 1;then + log "\tTestX: XOpenDisplay failed" + server_running=0 + continue + fi + # exit code 2 -> color or dimensions doesn't fit... + if test $err = 2;then + log "\tTestX: color or dimensions doesn't fit" + kill $xserver_pid + server_running=0 + break; + fi + server_running=1 + break + fi + done +} + +#----[ get_bus_id ]----# +function get_bus_id () { +#------------------------------------------------------ +# ask the PCi bus for the location of the first +# graphics card. +# --- + for line in $(/sbin/lspci -n | grep "Class 0300" | cut -f 1 -d " ");do + echo $line |\ + grep -q -E "^[0-9a-f]{2}:[0-9a-f]{2}\.[0-9a-f]" + if [ $? = 0 ];then + PCIBus=$(echo $line | cut -f1 -d:); + PCISlot=$(echo $line | cut -f2 -d: | cut -f 1 -d.); + PCIFunc=$(echo $line | cut -f2 -d.); + log "\tFound standard BusID: $PCIBus:$PCISlot:$PCIFunc" + printf "PCI:%d@0:%d:%d" \ + 0x$PCIBus 0x$PCISlot 0x$PCIFunc + break + else + echo $line |\ + grep -q -E "^[0-9a-f]{4}:[0-9a-f]{2}:[0-9a-f]{2}\.[0-9a-f]" + if [ $? = 0 ];then + PCIDomain=$(echo $line | cut -f1 -d:); + PCIBus=$(echo $line | cut -f2 -d:); + PCISlot=$(echo $line | cut -f3 -d: | cut -f 1 -d.); + PCIFunc=$(echo $line | cut -f2 -d.); + log "\tFound domain BusID: $PCIBus@$PCIDomain:$PCISlot $PCIFunc" + printf "PCI:%d@%d:%d:%d" \ + 0x$PCIBus 0x$PCIDomain 0x$PCISlot 0x$PCIFunc + break + fi + fi + done +} + +#----[ count_qt_geometry ]----# +function count_qt_geometry () { + # current X-resolution, display 0 + XRES=$(/usr/sbin/xquery -d :0 -r) + + log "\t===Qt Geometry===" + log "\tResolution: ${XRES}" + + # current X and Y resolution + XRES_X=$(echo $XRES | sed 's|[0123456789]\+ \([0123456789]\+\)x[0123456789]\+|\1|') #' + XRES_Y=$(echo $XRES | sed 's|[0123456789]\+ [0123456789]\+x\([0123456789]\+\)|\1|') #' + + log "\tX: ${XRES_X}" + log "\tY: ${XRES_Y}" + + # default values, minimal window 640x480 + WINDOW_SIZE_X=640 + WINDOW_SIZE_Y=480 + OFFSET_X=0 + OFFSET_Y=0 + BACKGROUND_IMAGE="" + + # cannot get any X-resolution + if [ "${XRES}" == "" ]; then + # cannot find out X resolution + WINDOW_SIZE_X=800 + WINDOW_SIZE_Y=600 + # reasonable + else + # FIXME: recount background image + BACKGROUND_IMAGE="/usr/lib/YaST2/startup/bkg.png" + + # must be bigger or equal to 1400x1050 + if [ "$(expr $XRES_X \>= 1400)" == "1" ] && [ "$(expr $XRES_Y \>= 1050)" == "1" ]; then + WINDOW_SIZE_X=1024 + WINDOW_SIZE_Y=786 + # must be bigger or equal to 800x600 + elif [ "$(expr $XRES_X \>= 800)" == "1" ] && [ "$(expr $XRES_Y \>= 600)" == "1" ]; then + WINDOW_SIZE_X=800 + WINDOW_SIZE_Y=600 + fi + + # X and Y offsets + OFFSET_X=$(expr ${XRES_X} - ${WINDOW_SIZE_X}) + OFFSET_X=$(expr ${OFFSET_X} / 2) + OFFSET_Y=$(expr ${XRES_Y} - ${WINDOW_SIZE_Y}) + OFFSET_Y=$(expr ${OFFSET_Y} / 2) + fi + + log "\tWindow size X: ${WINDOW_SIZE_X}" + log "\tWindow size X: ${WINDOW_SIZE_Y}" + log "\tOffset X: ${OFFSET_X}" + log "\tOffset X: ${OFFSET_Y}" + + # final window geometry, 'Window_XxWindow_Y+Offset_X+Offset_Y' + X_GEOMETRY="${WINDOW_SIZE_X}x${WINDOW_SIZE_Y}+${OFFSET_X}+${OFFSET_Y}" + + log "\tUsed geometry: ${X_GEOMETRY}" +} + +#----[ prepare_for_qt ]----# +function prepare_for_qt () { +#------------------------------------------------------ +# prepare Qt installation +# --- + export LD_LIBRARY_PATH="/opt/gnome/lib:$LD_LIBRARY_PATH" + + #============================================= + # Setup Qt environment + #--------------------------------------------- + set_inst_qt_env + set_splash 100 + + #============================================= + # patch X11 conf. if not update/continue mode + #--------------------------------------------- + if [ ! -f /var/lib/YaST2/runme_at_boot ];then + if [ ! -f /etc/X11/xorg.conf.instorig ];then + # create backup copy... + cp /etc/X11/xorg.conf /etc/X11/xorg.conf.instorig + + # Activate correct device/screen section... + sed -e "s#Screen.*Screen\[.*\]#Screen "\""Screen[$X11_CONFIG_ID]#" \ + /etc/X11/xorg.conf >/etc/X11/xorg.conf.new + mv /etc/X11/xorg.conf.new /etc/X11/xorg.conf + + # update core pointer input device section... + if [ -f "/usr/sbin/xupdate" ];then + cat /etc/X11/xorg.conf | \ + /usr/sbin/xupdate > /etc/X11/xorg.conf.new + mv /etc/X11/xorg.conf.new /etc/X11/xorg.conf + fi + + # update driver and busID if accelerated driver should be used... + if [ "$X11_CONFIG_ID" = 0 ];then + # replace BusID placeholder with real busID + XBusID=$(get_bus_id) + if [ ! -z "$XBusID" ];then + sed -e 's/#BusID/BusID/' \ + -e "s#1:0:0#$XBusID#" /etc/X11/xorg.conf \ + > /etc/X11/xorg.conf.new + mv /etc/X11/xorg.conf.new /etc/X11/xorg.conf + fi + + # replace driver placeholder with real name + sed -e "s#ChangeMe#$XServer#" /etc/X11/xorg.conf \ + > /etc/X11/xorg.conf.new + mv /etc/X11/xorg.conf.new /etc/X11/xorg.conf + fi + fi + fi + #============================================= + # start X-Server and wait until ready + #--------------------------------------------- + if [ ! -z "$NEED_XSERVER" ];then + export DISPLAY=:0 + [ -z $Xstartpath ] || ln -snf $Xbindir/XFree86 /var/X11R6/bin/X + $Xexecutable -deferglyphs 16 2>/dev/tty8 1>&2 vt07 & + xserver_pid=$! + wait_for_x11 + if [ "$server_running" = 1 ];then + log "\tX-Server is ready: $xserver_pid" + fi + fi + #============================================= + # set YaST2 Qt options for local displays + #--------------------------------------------- + if [ ! -z "$NEED_XSERVER" ];then + Y2_UI_ARGS="--noborder --auto-fonts" + count_qt_geometry + if [ "${X_GEOMETRY}" != "" ]; then + Y2_UI_ARGS="${Y2_UI_ARGS} -geometry ${X_GEOMETRY}" + fi + fi +} + +#----[ prepare_for_ncurses ]----# +function prepare_for_ncurses () { +#------------------------------------------------------ +# prepare NCURSES installation +# --- + #============================================= + # Create Braille config if not update mode + #--------------------------------------------- + if [ $INST_MODE = "normal" ];then + if [ ! -z "$Braille" ];then + log "Braille config needed, setting up braille display" + sed -e "s#brlname=.*#brlname=$Braille#" \ + -e "s#brlport=.*#brlport=$Brailledevice#" /etc/suse-blinux.conf \ + >/tmp/suse-blinux.conf + mv -f /tmp/suse-blinux.conf /etc + /etc/init.d/suse-blinux start + fi + fi + #============================================= + # Check for FbIterm + #--------------------------------------------- + check_run_fbiterm + log "\tCheck for FB-I-terminal: RUN_FBITERM = $RUN_FBITERM" +} + +#----[ prepare_for_ssh ]----# +function prepare_for_ssh () { +#------------------------------------------------------ +# prepare SSH installation +# --- +# + : +} + +#----[ prepare_for_vnc ]----# +function prepare_for_vnc () { +#------------------------------------------------------ +# prepare VNC installation +# --- +# + #============================================= + # Setup splash screen + #--------------------------------------------- + set_splash 100 + + #============================================= + # Setup y2base options + #--------------------------------------------- + # xxx + #Y2_UI_ARGS="--fullscreen --noborder --auto-fonts" + Y2_UI_ARGS="--noborder --auto-fonts" + + #============================================= + # Setup VNC server and start it + #--------------------------------------------- + setupVNCAuthentication + if [ $VNCPASS_EXCEPTION = 0 ];then + disable_splash + startVNCServer + wait_for_x11 + if [ "$server_running" = 1 ];then + log "\tXvnc-Server is ready: $xserver_pid" + fi + fi +} + +function check_gtk() +{ + echo "silly stub check_gtk" + return 0 +} + +#----[ check_Qt ]----# +function check_Qt () { +#------------------------------------------------------ +# check if the prepared medium Qt is valid +# --- + if [ ! -z "$NEED_XSERVER" ];then + if [ "$server_running" = 0 ];then + # /.../ + # X-Server couldn't be started, selecting + # NCURSES mode as fallback ? + # --- + log "\tX-Server couldn't be started, falling back to ncurses" + Y2_MODE_FLAGS='("text_fallback")' + SELECTED_MEDIUM="NCURSES" + prepare_for_ncurses + Y2_MODE=ncurses + fi + else + /usr/sbin/testX --fast 2>/dev/null + if test $? = 1;then + log "\tCannot access Display: $DISPLAY, falling back to ncurses" + SELECTED_MEDIUM="NCURSES" + prepare_for_ncurses + Y2_MODE=ncurses + fi + fi +} + +#----[ check_network ]----# +function check_network () { +#------------------------------------------------------ +# check if the prepared medium SSH is valid. It is valid +# if there is a network interface accessable and we are +# able to use ncurses or X11 +# --- + if ! found_iface ; then + # /.../ + # No network interface found for SSH or VNC installation + # this is a fatal error here + # --- + log "\tNo network interface found, fatal error" + fatalError + fi + if [ ! -z "$DISPLAY" ];then + log "\tDisplay: $DISPLAY found for network install" + Y2_MODE=gtk + fi + if ! check_gtk ; then + log "\tQt plugin check failed falling back to ncurses" + Y2_MODE=ncurses + fi +} + +#----[ check_vnc ]----# +function check_vnc () { +#------------------------------------------------------ +# check if the prepared medium VNC is valid +# --- + check_network + if [ $VNCPASS_EXCEPTION = 1 ];then + log "\tVNC access has been disabled due to a password exception" + log "\tPlease make sure the password is at least 8 characters long" + fatalError + fi + if [ "$server_running" = 0 ];then + # /.../ + # XVnc server couldn't be started, what to do now, I think + # this is a fatal error here + # --- + log "\tXVnc server couldn't be started, fatal error" + fatalError + fi +} + +#----[ start_yast ]----# +function start_yast () { +#------------------------------------------------------ +# Start YaST2 refering to the contents of the Y2_* +# startup variables +# --- + local overcommit + read overcommit < /proc/sys/vm/overcommit_memory + echo "*** Starting YaST2 ***" + log "\tAllow big memory allocation: overcommit_memory=1" + echo 1 > /proc/sys/vm/overcommit_memory + if [ "$SPLASH" = yes -a -x /sbin/splash -a -n "$SPLASHCFG" ];then + /sbin/splash -t "YaST running" + fi + export QT_IM_MODULE=xim + + if [ "$RUN_FBITERM" = "1" ]; then + OPT_FBITERM=/usr/bin/fbiterm + else + OPT_FBITERM= + fi + + # set up a background if any needed + if [ "${BACKGROUND_IMAGE}" != "" ]; then + log "\tUsing background: ${BACKGROUND_IMAGE}" + fvwm-root --dither ${BACKGROUND_IMAGE} + fi + + log "\tStarting YaST2:" + log "\tMODULE_NAME: $Y2_MODULE_NAME" + log "\tMODE_FLAGS: $Y2_MODE_FLAGS" + log "\tMODULE_ARGS: $Y2_MODULE_ARGS" + log "\tMODE: $Y2_MODE" + log "\tUI_ARGS: $Y2_UI_ARGS" + log "\tQT_IM_MODULE:$QT_IM_MODULE" + $OPT_FBITERM y2base \ + "$Y2_MODULE_NAME" \ + $Y2_MODE_FLAGS \ + $Y2_MODULE_ARGS \ + $Y2_MODE \ + $Y2_UI_ARGS + Y2_EXIT_CODE=$? + Y2_ABORT_MESSAGE="YaST seems to be aborted abnormally !" + Y2_OK_MESSAGE="YaST procedure ended successfully" + if [ -s /etc/yast.inf ];then + #============================================= + # check yast.inf contents + #--------------------------------------------- + cat /etc/yast.inf | grep -q -i "Aborted: 1" + if [ $? = 0 ];then + log "\t$Y2_ABORT_MESSAGE" + fi + else + #============================================= + # YaST ended successfully + #--------------------------------------------- + log "\t$Y2_OK_MESSAGE" + fi + if [ $SELECTED_MEDIUM = "SSH" ] && [ ! "$VNC" = 1 ];then + echo "*** Preparing SSH installation for reboot ***" + echo "*** NOTE: after reboot, you have to reconnect and call ***" + echo "*** /usr/lib/YaST2/startup/YaST2.ssh ***" + log "\tPreparing SSH installation for reboot" + echo $Y2_EXIT_CODE > /tmp/YaST2_ssh_installation_finished + fi + if [ $Y2_EXIT_CODE -eq 0 ];then + start_yast_and_reboot + start_yast_again + fi + log "\tReset memory allocation: overcommit_memory=$overcommit" + echo $overcommit > /proc/sys/vm/overcommit_memory +} + +#----[ start_yast_and_reboot ]----# +function start_yast_and_reboot () { +#------------------------------------------------------ +# This function will reboot the system and start yast +# again by touching the file /var/lib/YaST2/runme_at_boot. +# The function is triggered by the file /var/lib/YaST2/reboot +# --- + if [ -f /var/lib/YaST2/reboot ];then + rm -f /var/lib/YaST2/reboot + touch /var/lib/YaST2/runme_at_boot + /sbin/shutdown -r now + fi +} + +#----[ start_yast_again ]----# +function start_yast_again () { +#------------------------------------------------------ +# This function will restart yast again with the same +# options as used before. The function is triggered by +# the file /var/lib/YaST2/restart_yast +# --- + if [ -f /var/lib/YaST2/restart_yast ];then + rm -f /var/lib/YaST2/restart_yast + start_yast + fi +} + +#============================================= +# Start the Magic :-) +#============================================= +# 1) Source common script functions +#--------------------------------------------- +. /usr/lib/YaST2/startup/common/functions.sh +. /usr/lib/YaST2/startup/requires +. /usr/lib/YaST2/startup/arch/ia64/x11.sh + +#============================================= +# 1.1) set splash progress bar to 90% +#--------------------------------------------- +set_splash 90 +#============================================= +# 1.2) set root HOME directory +#--------------------------------------------- +export HOME=/root +#============================================= +# 1.3) set HTTP/FTP proxy and configure syslog +#--------------------------------------------- +set_syslog ; set_proxy + +#============================================= +# 2) Initialize... +#--------------------------------------------- +# 2.1) setup PATH +PATH=$ybindir:$PATH +[ -z Xstartpath ] || PATH=/var/X11R6/bin:$PATH +#============================================= +# 2.2) get X11 driver directory +#--------------------------------------------- +X11_DRIVER_DIR=$Xdriverpath +if [ -d $Xdriver64path ];then + X11_DRIVER_DIR=$Xdriver64path +fi +#============================================= +# 2.3) obtain RAM size in Kb +#--------------------------------------------- +MEM_TOTAL=`awk '/^MemTotal:/{ print $2 }' /proc/meminfo` +if [ ${#MEM_TOTAL} -gt 9 ];then + MEM_TOTAL=1000000000 +fi +#============================================= +# 2.4) check for valid framebuffer +#--------------------------------------------- +FBDEV_OK=0 +if (: < /dev/fb0) 2>/dev/null ; then + FBDEV_OK=1 +fi +#============================================= +# 2.5) setup installation mode (update y/n) +#--------------------------------------------- +INST_MODE="normal" +if [ -f /var/lib/YaST2/update_mode ];then + INST_MODE="update" +fi +#============================================= +# 2.6) import install.inf +#--------------------------------------------- +import_install_inf + +#============================================= +# 2.7) set LOG prefix +#--------------------------------------------- +LOG_PREFIX="Stage [call]" + +#============================================= +# 3) Medium prequalification +#--------------------------------------------- +# Check which installation mediums can be used. There are +# four mediums available: Qt(0) SSH(1), VNC(2) and NCURSES(3). +# The following checks will create an array which contains +# the possible mediums. An index of 1 indicates "can be used" +# an index of 0 indicated "cannot be used" +# --- +MEDIUM=(1 1 1 1) + +#============================================= +# 3.1) prequalification checks for Qt +#--------------------------------------------- +log "Starting prequalification checks..." +log "===================================" +# 3.1.1) Qt plugin check... +if ! check_gtk ; then + log "\tQt plugin check failed -> Medium Qt disabled" + MEDIUM[0]=0 +fi +# 3.1.2) X-Server module check... +# BEG IA64: use accelerated X11 driver +ia64_check_x11 +# END IA64: +XServerAccel=$XServer +if [ "$XServer" = "vmware" ];then + if [ ! -f "$X11_DRIVER_DIR/${XServer}_drv.so" ];then + log "\t$XServer driver not installed -> Medium Qt disabled" + MEDIUM[0]=0 + fi + X11_CONFIG_ID=vmware +else + XServer=fbdev + if [ $FBDEV_OK -eq 0 ];then + log "\tNo Framebuffer available: Using vesa driver" + XServer=vesa + fi + if [ ! -f "$X11_DRIVER_DIR/${XServer}_drv.so" ];then + log "\t$XServer driver not installed -> Medium Qt disabled" + MEDIUM[0]=0 + fi + X11_CONFIG_ID=$XServer +fi +if [ "$acceleratedx" = "1" ];then + if [ ! -f "$X11_DRIVER_DIR/${XServerAccel}_drv.so" ];then + log "\t$XServerAccel driver not installed -> X11 acceleration disabled" + else + log "\tUsing accelerated driver -> $XServerAccel" + MEDIUM[0]=1 + XServer=$XServerAccel + X11_CONFIG_ID=0 + fi +fi +# 3.1.3) Memory check >= 90MB for Qt/X11... +if [ $MEM_TOTAL -lt "$MEM_NEEDED" ];then + log "\tMemory requirement > 90MB not fulfilled -> Medium Qt disabled" + MEDIUM[0]=0 +fi +# 3.1.4) Check if we need to start our own X11 server... +if [ -z "$DISPLAY" ];then + NEED_XSERVER=1 +fi +# 3.1.5) Check for xorg.conf... +if [ ! -f /etc/X11/xorg.conf ];then +if [ ! -f $Xorgconftempl ];then + log "\tNo X11 configuration template found -> Medium Qt disabled" + MEDIUM[0]=0 +else + cp $Xorgconftempl /etc/X11/xorg.conf +fi +fi +# 3.1.6) Check for WindowManager configuration +if [ ! -f $Xsharedir/fvwm/fvwmrc.yast2 ];then + log "\tNo Windowmanager configuration found -> Medium Qt disabled" + MEDIUM[0]=0 +fi +# 3.1.7) Check for remote display usage +if [ ! -z $Display_IP ];then + log "\tRemote Display usage -> Medium Qt enabled" + log "\tExporting DISPLAY to host: $Display_IP:0.0" + export DISPLAY="$Display_IP:0.0" + NEED_XSERVER="" + MEDIUM[0]=1 +fi + +#============================================= +# 3.2) prequalification checks for SSH +#--------------------------------------------- +# 3.2.1) Check for SSH daemon +if [ -f /var/run/sshd.*pid ];then + ps `cat /var/run/sshd.*pid` >/dev/null || MEDIUM[2]=0 +else + log "\tNo SSH daemon running -> Medium SSH disabled" + MEDIUM[1]=0 +fi + +#============================================= +# 3.3) prequalification checks for VNC +#--------------------------------------------- +# 3.3.1) Check for WindowManager configuration +if [ ! -f $Xsharedir/fvwm/fvwmrc.yast2 ];then + log "\tNo Windowmanager configuration found -> Medium VNC disabled" + MEDIUM[2]=0 +fi +# 3.3.2) Check for VNC X-Server binary +if [ ! -x $Xbindir/Xvnc ] ; then + log "\tNo Xvnc server installed -> Medium VNC disabled" + MEDIUM[2]=0 +fi +# 3.3.3) Check for testX binary +if [ ! -x /usr/sbin/testX ] ; then + log "\tNo testX binary installed -> Medium VNC disabled" + MEDIUM[2]=0 +fi + +#============================================= +# 4) Evaluate medium selection +#--------------------------------------------- +# At this point we are evaluating the variables which have +# been imported from the install.inf file into the current +# environment. The standard method of installing the system +# should be Qt based. Refering to the variables Textmode, +# Braille, UseSSH and VNC another medium could be selected +# VNC overrides UseSSH +# --- +log "Evaluate medium selection..." +log "============================" +SELECTED_MEDIUM="QT" +if [ "$Textmode" = 1 ];then + log "\tMedium Textmode (ncurses) has been selected" + SELECTED_MEDIUM="NCURSES" +fi +if [ ! -z "$Braille" ];then + log "\tMedium Braille (ncurses) has been selected" + SELECTED_MEDIUM="NCURSES" +fi +if [ "$UseSSH" = 1 ];then + log "\tMedium SSH has been selected" + SELECTED_MEDIUM="SSH" +fi +if [ "$VNC" = 1 ];then + log "\tMedium VNC has been selected" + SELECTED_MEDIUM="VNC" +fi + +#============================================= +# 5) Check selected medium +#--------------------------------------------- +# Refering to the prequalification check results we need to +# check if the selected medium is valid according to the +# MEDIUM flag entry. If the medium is not valid we will +# fallback to NCURSES mode +# --- +log "Check selected medium..." +log "========================" +log "\tWished medium is: $SELECTED_MEDIUM" +case $SELECTED_MEDIUM in + QT) { + if [ ${MEDIUM[0]} -eq 0 ];then + log "\tMedium Qt not available, falling back to ncurses" + SELECTED_MEDIUM="NCURSES" + fi + } ;; + SSH) { + if [ ${MEDIUM[1]} -eq 0 ];then + log "\tMedium SSH not available, falling back to ncurses" + SELECTED_MEDIUM="NCURSES" + fi + } ;; + VNC) { + if [ ${MEDIUM[2]} -eq 0 ];then + log "\tMedium VNC not available, falling back to ncurses" + SELECTED_MEDIUM="NCURSES" + fi + } ;; +esac +log "\tSelected medium is: $SELECTED_MEDIUM" + +#============================================= +# 6) Prepare selected medium +#--------------------------------------------- +case $SELECTED_MEDIUM in + QT) prepare_for_qt ; Y2_MODE=gtk ;; + SSH) prepare_for_ssh ; Y2_MODE=ncurses ;; + VNC) prepare_for_vnc ; Y2_MODE=gtk ;; + NCURSES) prepare_for_ncurses ; Y2_MODE=ncurses ;; +esac + +#============================================= +# 7) Check prepared medium +#--------------------------------------------- +case $SELECTED_MEDIUM in + QT) check_Qt ;; + SSH) check_network ;; + VNC) check_vnc ;; +esac + +# The prepare_for_ncurses in step 6 is kinda useless if step 7 can +# change Y2MODE to ncurses in several ways +# Anyway, #150799 +if [ "$Y2_MODE" = "ncurses" ]; then + Y2_UI_ARGS=--nothreads +fi + +#============================================= +# 8) Call YaST2 +#--------------------------------------------- +Y2_MODULE_NAME=${1:-installation}; shift +Y2_MODULE_ARGS=\(\"$*\"\) +start_yast + +#============================================= +# 9) Clean sweep +#--------------------------------------------- +# 9.1) clear Qt environment... +clr_inst_qt_env + +# 9.2) kill X-Server... +if [ "$server_running" = 1 ];then + sleep 1 && kill $xserver_pid + while kill -0 $xserver_pid 2>/dev/null ; do + sleep 1 + done +fi + +#============================================= +# 10) exit with YaST2 exit code +#--------------------------------------------- +exit $Y2_EXIT_CODE + + Added: trunk/gtk/unstable/integrate/yast2 URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/integrate/yast2?rev=... ============================================================================== --- trunk/gtk/unstable/integrate/yast2 (added) +++ trunk/gtk/unstable/integrate/yast2 Thu Nov 29 18:22:01 2007 @@ -0,0 +1,280 @@ +#!/bin/bash + +# File: /sbin/yast2 +# Module: yast2 +# Summary: YaST2 launch script +# +# This script is responsable to start the YaST setup tools. If no arguments +# are given, a control center should be launched that will call this same script +# with the wanted setup tool as an argument. In which case, we shall detect the +# best YaST frontend to provide (eg. gtk for gnome, qt for kde, ncurses for console). +# + +export PATH=/sbin:/usr/sbin:$PATH + +# load common script functions +# (like the detection of frontend plugins) +. /usr/lib/YaST2/bin/yast2-funcs + +# allow user to over-rule the default frontend via a global file +FRONTEND="auto" +if test -f /etc/sysconfig/yast2; then + . /etc/sysconfig/yast2 +fi + +# Arguments to be passed for frontend and the control center (like the --fullscreen) +YAST_ARGS="" + +printhelp() +{ + echo "Usage: $0 [OPTIONS] [MODULE] [module specific parameters]" + echo + echo "OPTIONS:" + echo " -l, --list list all available modules" + echo " -g, --geometry default window size (graphical frontend only)" + echo " --noborder no window manager border for main window (graphical frontend only)" + echo " --fullscreen use full screen (graphical frontend only)" + echo " -s, --style widget style (qt only)" + echo " -h, --help this message" + echo + echo "exceptional case for installing packages:" + echo "$0 OPTION <package> [<package> [...]]" + echo + echo "OPTION:" + echo " -i, --install install rpm package" + echo + echo "<package> can be a single short package name (e.g. gvim)" + echo "which will be installed with dependency checking, or the full" + echo "path to an rpm package (e.g /tmp/gvim.rpm) which will be" + echo "installed without dependency checking" + echo +} + +listmodules() +{ + list=`/bin/ls -1 /usr/share/applications/YaST2/*.desktop 2>/dev/null` + + if [ -z "$list" ] ; then + echo "No modules installed" + else + echo "Available modules:" + echo + grep -h "Exec=/sbin/yast2 " $list | \ + sed 's|Exec=/sbin/yast2 \([^ ]\+\)\( .*\)\?|\1|' | \ + sort -u + fi +} + +YCP_MENU="$ybindir/y2base menu" +QT_MENU="$ybindir/y2controlcenter" +GTK_MENU="/opt/gnome/bin/control-center" +run_yast_menu() +{ + if [ $FRONTEND == "ncurses" ]; then + while true ; do + $YCP_MENU ncurses $YAST_ARGS + if [ ! -e "/var/lib/YaST2/restart_menu" ] ; then + break + fi + done + else # gtk or qt + if echo $WINDOWMANAGER | grep -qi "gnome" && + [ -e $GTK_MENU ]; then + $GTK_MENU $YAST_ARGS + elif [ -e $QT_CONTROL_CENTER ]; then + $QT_MENU $YAST_ARGS + else + # run the same YCP menu of ncurses + $YCP_MENU $FRONTEND $YAST_ARGS + fi + fi +} + +## PARSE arguments +TEMP=`/usr/bin/getopt -o hlg:s:Si --long help,list,kcontrol,geometry:,style:,strings,install,fullscreen,noborder \ + -n 'yast2' -- "$@"` + +if [ $? != 0 ] ; then + echo "Exit." >&2 + exit 1 +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + case "$1" in + -h|--help) printhelp; exit 0 ;; + -l|--list) listmodules; exit 0 ;; + -g|--geometry) YAST_ARGS="$YAST_ARGS -geometry $2"; shift 2; ;; + -i|--install) Y2_INSTALL_PACKAGES=true; shift ;; + --fullscreen) YAST_ARGS="$YAST_ARGS --fullscreen"; shift ;; + --noborder) YAST_ARGS="$YAST_ARGS --noborder" ; shift ;; + --kcontrol) YAST_ARGS="$YAST_ARGS --kcontrol_id YaST" ; shift ;; + --) shift ; break ;; + *) echo "Unrecognized option $1" ; exit 1 ;; + + # IMPORTANT: Remember to change that "getopt" call above, too + # if you change anything here! + esac +done + +if [ "$Y2_INSTALL_PACKAGES" = "true" ]; then + export module=sw_single +else + # allow module as argument, defaults to "menu" + export module="${1-menu}" + shift +fi + +case "`/usr/bin/basename $0`" in + YaST|yast|yast1|zast) + unset DISPLAY + ;; +esac + +if [ "$UID" = 0 ]; then + echo $$ > /var/run/yast.pid +fi +set_lang_from_sysconfig + +## CHECK what frontend we should use +if [ $FRONTEND != "ncurses" ] && [ $FRONTEND != "qt" ] && [ $FRONTEND != "gtk" ] && \ + [ $FRONTEND != "auto" ]; then + echo "Warning: specified frontend $FRONTEND is unknown." + FRONTEND="auto" +fi + +if [ $FRONTEND == "auto" ]; then + if [ -z "$DISPLAY" ]; then + # using the terminal + FRONTEND="ncurses" + else + # running on X11 + # TODO: maybe GTK could be the default one? ;-) + if echo $WINDOWMANAGER | grep -qi "gnome" || \ + echo $WINDOWMANAGER | grep -qi "xfce" ; then + FRONTEND="gtk" + else + FRONTEND="qt" + fi + fi +fi + +# fallbacks should go here so that an user preferred frontend also fallback +if [ $FRONTEND == "gtk" ] && ! check_gtk && check_qt ; then + FRONTEND="qt" +fi +if [ $FRONTEND == "qt" ] && ! check_qt && check_gtk ; then + FRONTEND="gtk" +fi +if [ $FRONTEND != "ncurses" ] && ! check_qt && ! check_gtk ; then + FRONTEND="ncurses" +fi +if [ $FRONTEND == "ncurses" ] && ! check_ncurses; then + echo "Error: please install yast2-ncurses to use the YaST2 text mode interface" + exit 1 +fi + +## SET frontend specific environment settings and whatever they need +if [ $FRONTEND == "ncurses" ]; then + TTY=`/usr/bin/tty` + # on console, start yast in UTF-8 locale (only on a 'local' console) + if [ "$TERM" = "linux" -a \( "$TTY" = /dev/console -o "$TTY" != "${TTY#/dev/tty[0-9]}" \) ] ; then + case "$LANG" in + # if it is known that a language doesn't yet work well with ncurses + # on console use English instead: + ja*|ko*|zh*) + export LANG=en_US.UTF-8 + export LC_CTYPE=en_US.UTF-8 + ;; + *) + # get rid of encoding and/or modifier + export LANG=${LANG%%[.@]*}.UTF-8 + export LC_CTYPE=${LANG%%[.@]*}.UTF-8 + ;; + esac + if /bin/testutf8 ; [ $? -ne 2 ] ; then + /usr/bin/test -x /bin/unicode_start && /bin/unicode_start + uc_started=1 + fi + else + case "$TERM" in + vt*|xterm*|linux|screen*) + # probe terminal and fix lang settings + UTF8TESTED=0 + # binary /bin/testutf8 is missing at least on s390x, #158001 + /usr/bin/test -x /bin/testutf8 && UTF8TESTED=1 && /bin/testutf8 + # return code of the /bin/testutf8 + # 0=utf-unknown, 1=utf-ok, 2=utf-err + UTF8STATUS=$? + + # not tested or not working UTF-8 support + if [ "$UTF8TESTED" == "1" ] && [ $UTF8STATUS -ne 2 ] ; then + /usr/bin/test -n "$LANG" && LANG=${LANG%.UTF-8} + /usr/bin/test -n "$LC_CTYPE" && LC_CTYPE=${LC_CTYPE%.UTF-8} + else + /usr/bin/test -n "$LANG" && LANG=${LANG%%[.@]*}.UTF-8 + /usr/bin/test -n "$LC_CTYPE" && LC_CTYPE=${LC_CTYPE%%[.@]*}.UTF-8 + fi + ;; + esac + fi + + # this fixes launching of interactive subprocesses, #150799 + YAST_ARGS="$YAST_ARGS --nothreads" +fi + +if [ $FRONTEND == "qt" ]; then + set_qt_home_dir + + # FIXME: why the hack was this done? full screening something that + # takes so much time to load is just annoying! + if echo $WINDOWMANAGER | grep -qi "kde" ; then + if [ $module == "sw_single" ] ; then + case "$YAST_ARGS" in + *fullscreen*) ;; + *) YAST_ARGS="$YAST_ARGS --fullscreen" ;; + esac + fi + fi +fi + +## RUN the requested module +if [ $module == "menu" ]; then + run_yast_menu +else + # we do a cycle because we want to keep the online_update module alive as long + # as there are pending patches + while true ; do + # Transform every argument into a ycp string, that is surround all + # args by ("..."). args may contain spaces. + a=("$@") + b=("${a[@]/#/(\"}") + c=("${b[@]/%/\")}") + set -- "${c[@]}" + + $ybindir/y2base $module "$@" $FRONTEND "$YAST_ARGS" + + if [ ! $module == "online_update" ] || [ ! -e "/var/lib/YaST2/selected_patches.ycp" ] ; then + break + fi + done +fi + +## LAST frontend specific changes +if [ $FRONTEND == "ncurses" ]; then + if [ "$uc_started" ] ; then + /usr/bin/test -x /bin/unicode_stop && /bin/unicode_stop + fi +fi + +## EXIT +exit_code=$? + +if [ "$UID" = 0 ]; then + rm -f /var/run/yast.pid +fi + +exit $exit_code + Added: trunk/gtk/unstable/integrate/yast2-funcs URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/integrate/yast2-func... ============================================================================== --- trunk/gtk/unstable/integrate/yast2-funcs (added) +++ trunk/gtk/unstable/integrate/yast2-funcs Thu Nov 29 18:22:01 2007 @@ -0,0 +1,141 @@ +# File: /usr/share/YaST2/bin/yast2-funcs +# Module: yast2 +# Summary: Common functions for YaST2 start scripts +# Authors: Arvin Schnell <arvin@suse.de> +# +# $Id: yast2-funcs 24861 2005-08-12 11:10:25Z locilka $ + +# some path definitions +ybindir=/usr/lib/YaST2/bin +logdir=/var/log/YaST2 + + +# font for qt +# obsolete, we should not need it anymore, adrian +# Y2_XFONT="-gnu-unifont-medium-r-normal--16-160-75-75-p-80-iso10646-1" + + +# +# check if plugins are in lib or lib64 subdir and sets the variable +# plugindir accordingly +# +function get_plugindir() +{ + plugindir=/usr/lib/YaST2/plugin + if `ldd $ybindir/y2base | egrep --quiet "/lib64/(.*/)?libc.so"` ; then + plugindir=/usr/lib64/YaST2/plugin + fi +} + +# +# check if the gtk plugin and all necessary libaries are present +# +function check_gtk() +{ + get_plugindir + Y2_GTK=$plugindir/libpy2gtk.so.2 + + if [ -e "$Y2_GTK" ] ; then + if ! `/usr/bin/ldd "$Y2_GTK" | grep --quiet "=> not found"` ; then + return 0 # success + fi + echo "warning: the gtk frontend is installed but does not work" + sleep 1 + fi + + return 1 # failure +} + +# +# check if the qt plugin and all necessary libaries are present +# +function check_qt() +{ + get_plugindir + Y2_QT=$plugindir/libpy2qt.so.2 + + if [ -e "$Y2_QT" ] ; then + if ! `/usr/bin/ldd "$Y2_QT" | grep --quiet "=> not found"` ; then + return 0 # success + fi + echo "warning: the qt frontend is installed but does not work" + sleep 1 + fi + + return 1 # failure +} + + +# +# check if the ncurses plugin and all necessary libaries are present +# +function check_ncurses() +{ + get_plugindir + Y2_NCURSES=$plugindir/libpy2ncurses.so.2 + + if [ -e "$Y2_NCURSES" ] ; then + if ! `/usr/bin/ldd "$Y2_NCURSES" | grep --quiet "=> not found"` ; then + return 0 # success + fi + echo "warning: the ncurses frontend is installed but does not work" + sleep 1 + fi + + return 1 # failure +} + + +# +# if LANG is empty set LANG to RC_LANG in /etc/sysconfig/language +# +function set_lang_from_sysconfig() +{ + # if LANG is "POSIX", unset LANG + # SL 9.3 had default LANG set to "" + # SL 10.0 has default LANG set to "POSIX" + if [ "$LANG" == "POSIX" ] ; then + LANG="" + fi + + # if LANG is not empty and /etc/sysconfig/language exists + if [ -z "$LANG" -a -r /etc/sysconfig/language ] ; then + . /etc/sysconfig/language + if [ -n "$RC_LANG" ] ; then + export LANG=$RC_LANG + fi + fi +} + + +function set_qt_home_dir() +{ + local user="$USER" + if [ "$KDESU_USER" ]; then + user="$KDESU_USER" + fi + temp_QT_HOME_DIR="`eval echo ~$user/.qt/`" + if test -r "$temp_QT_HOME_DIR/qtrc"; then + export QT_HOME_DIR="$temp_QT_HOME_DIR" + fi +} + + +function set_inst_qt_env() +{ + export XCURSOR_THEME="crystalwhite" + export QT_HOME_DIR="`eval echo /tmp/.qt/`" + mkdir -p /tmp/.qt + [ -e /usr/share/desktop-data/qtrc ] && cp /usr/share/desktop-data/qtrc /tmp/.qt/ +} + + +function clr_inst_qt_env() +{ + rm -rf /tmp/.qt/ +} + + +### Local Variables: *** +### mode: shell-script *** +### End: *** Added: trunk/gtk/unstable/mockups/package-selector/christian-package-selector-1.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/christian-package-selector-2.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/christian-patterns.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/martin-package-selector-1.gif URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/packagekit-groups.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/packagekit-search.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/package-selector/ricado-split-use-cases.svg URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== --- trunk/gtk/unstable/mockups/package-selector/ricado-split-use-cases.svg (added) +++ trunk/gtk/unstable/mockups/package-selector/ricado-split-use-cases.svg Thu Nov 29 18:22:01 2007 @@ -0,0 +1,634 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.45.1" + width="720" + height="410" + sodipodi:docbase="/home/rick2/Documents/yast/gtk/mockups/package-selector" + sodipodi:docname="ricado-split-use-cases.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.0"> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs5" /> + <sodipodi:namedview + inkscape:window-height="777" + inkscape:window-width="939" + inkscape:pageshadow="2" + inkscape:pageopacity="1" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showguides="true" + inkscape:guide-bbox="true" + inkscape:zoom="1" + inkscape:cx="372.04724" + inkscape:cy="228.70418" + inkscape:window-x="334" + inkscape:window-y="42" + inkscape:current-layer="svg2" + showgrid="false" + width="720px" + height="410px" /> + <rect + style="fill:#fff966;fill-opacity:1;stroke:none;stroke-width:1.59800005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8339" + width="718" + height="409" + x="2" + y="1" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="267" + y="41.362183" + id="text7070"><tspan + sodipodi:role="line" + id="tspan7072" + x="267" + y="41.362183">Action:</tspan></text> + <path + sodipodi:type="arc" + id="path7074" + sodipodi:cx="167" + sodipodi:cy="74.862183" + sodipodi:rx="19" + sodipodi:ry="16.5" + d="M 186 74.862183 A 19 16.5 0 1 1 148,74.862183 A 19 16.5 0 1 1 186 74.862183 z" + transform="matrix(0.6614424,0,0,0.7616609,239.03913,-22.157412)" + style="fill:#ffffff;stroke:#000000;stroke-width:2.76719594;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /> + <path + sodipodi:type="arc" + style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path8045" + sodipodi:cx="128" + sodipodi:cy="161.36218" + sodipodi:rx="10" + sodipodi:ry="9" + d="M 138 161.36218 A 10 9 0 1 1 118,161.36218 A 10 9 0 1 1 138 161.36218 z" + transform="matrix(0.85,0,0,1,240.7,-127)" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="369" + y="41.362183" + id="text8047"><tspan + sodipodi:role="line" + id="tspan8049" + x="369" + y="41.362183">Install</tspan></text> + <path + sodipodi:type="arc" + id="path8053" + sodipodi:cx="167" + sodipodi:cy="74.862183" + sodipodi:rx="19" + sodipodi:ry="16.5" + d="M 186 74.862183 A 19 16.5 0 1 1 148,74.862183 A 19 16.5 0 1 1 186 74.862183 z" + transform="matrix(0.6614424,0,0,0.7616609,339.53912,-20.657415)" + style="fill:#ffffff;stroke:#000000;stroke-width:2.76719594;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="471" + y="41.362183" + id="text8059"><tspan + sodipodi:role="line" + id="tspan8061" + x="471" + y="41.362183">Remove</tspan></text> + <path + sodipodi:type="arc" + id="path8063" + sodipodi:cx="167" + sodipodi:cy="74.862183" + sodipodi:rx="19" + sodipodi:ry="16.5" + d="M 186 74.862183 A 19 16.5 0 1 1 148,74.862183 A 19 16.5 0 1 1 186 74.862183 z" + transform="matrix(0.6614424,0,0,0.7616609,464.53912,-20.657415)" + style="fill:#ffffff;stroke:#000000;stroke-width:2.76719594;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="595" + y="42.362183" + id="text8065"><tspan + sodipodi:role="line" + id="tspan8067" + x="595" + y="42.362183">Upgrade</tspan></text> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.56370759;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8069" + width="132.43629" + height="269.43628" + x="263.78186" + y="77.144043" /> + <g + id="g8078" + transform="matrix(0.7085094,0,0,0.8192639,-8.44843,-87.77487)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8071" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8075"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8073" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <path + sodipodi:type="star" + style="fill:#cfcfff;fill-opacity:1;stroke:#000000;stroke-width:0.6525771;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="path8087" + sodipodi:sides="4" + sodipodi:cx="207" + sodipodi:cy="178.36218" + sodipodi:r1="30.413813" + sodipodi:r2="21.505814" + sodipodi:arg1="0.76214654" + sodipodi:arg2="1.5475447" + inkscape:flatsided="true" + inkscape:rounded="0.07" + inkscape:randomized="0" + d="M 229,199.36218 C 226.92111,201.54007 188.17789,202.44108 186,200.36218 C 183.82211,198.28329 182.92111,159.54007 185,157.36218 C 187.07889,155.18429 225.82211,154.28329 228,156.36218 C 230.17789,158.44108 231.07889,197.18429 229,199.36218 z " + transform="matrix(2.6971042,0,0,0.9494303,-87.80056,-41.980263)" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="422" + y="133.36218" + id="text8089"><tspan + sodipodi:role="line" + id="tspan8091" + x="422" + y="133.36218">Install</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="314" + y="103.36218" + id="text8093"><tspan + sodipodi:role="line" + id="tspan8095" + x="314" + y="103.36218">Emacs</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="323" + y="152.36218" + id="text8097"><tspan + sodipodi:role="line" + id="tspan8099" + x="323" + y="152.36218">Yast</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="322" + y="192.36218" + id="text8101"><tspan + sodipodi:role="line" + id="tspan8103" + x="322" + y="192.36218">Gnome</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="333" + y="229.36218" + id="text8105"><tspan + sodipodi:role="line" + id="tspan8107" + x="333" + y="229.36218">. . .</tspan></text> + <g + id="g8109" + transform="matrix(0.7085094,0,0,0.8192639,-7.44842,-45.774865)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8111" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8113"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8115" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <g + id="g8117" + transform="matrix(0.7085094,0,0,0.8192639,-6.44842,-4.774865)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8119" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8121"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8123" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <g + id="g8125" + transform="matrix(0.7085094,0,0,0.8192639,-6.44842,33.225135)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8127" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8129"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8131" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <g + id="g8133" + transform="matrix(0.7085094,0,0,0.8192639,-5.44842,70.225135)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8135" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8137"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8139" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <g + id="g8141" + transform="matrix(0.7085094,0,0,0.8192639,-4.44842,110.22514)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8143" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8145"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8147" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <path + sodipodi:type="star" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.59800005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="path8149" + sodipodi:sides="3" + sodipodi:cx="257" + sodipodi:cy="206.36218" + sodipodi:r1="38.897301" + sodipodi:r2="27.504545" + sodipodi:arg1="0.80357798" + sodipodi:arg2="1.8507755" + inkscape:flatsided="true" + inkscape:rounded="0.07" + inkscape:randomized="0" + d="M 284,234.36218 C 280.60518,237.63576 220.38888,220.32166 219.25129,215.74487 C 218.1137,211.16808 263.2163,167.67628 267.74871,168.9795 C 272.28112,170.28271 287.39482,231.08861 284,234.36218 z " + transform="matrix(-0.5046744,-9.1938879e-2,0.1000384,-0.2995076,614.5839,212.26209)" /> + <path + sodipodi:type="star" + style="fill:#cfcfff;fill-opacity:1;stroke:#000000;stroke-width:0.6525771;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="path8151" + sodipodi:sides="4" + sodipodi:cx="207" + sodipodi:cy="178.36218" + sodipodi:r1="30.413813" + sodipodi:r2="21.505814" + sodipodi:arg1="0.76214654" + sodipodi:arg2="1.5475447" + inkscape:flatsided="true" + inkscape:rounded="0.07" + inkscape:randomized="0" + d="M 229,199.36218 C 226.92111,201.54007 188.17789,202.44108 186,200.36218 C 183.82211,198.28329 182.92111,159.54007 185,157.36218 C 187.07889,155.18429 225.82211,154.28329 228,156.36218 C 230.17789,158.44108 231.07889,197.18429 229,199.36218 z " + transform="matrix(-2.6971042,0,0,0.9494303,1029.3006,29.019722)" /> + <path + sodipodi:type="star" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.59800005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="path8157" + sodipodi:sides="3" + sodipodi:cx="257" + sodipodi:cy="206.36218" + sodipodi:r1="38.897301" + sodipodi:r2="27.504545" + sodipodi:arg1="0.80357798" + sodipodi:arg2="1.8507755" + inkscape:flatsided="true" + inkscape:rounded="0.07" + inkscape:randomized="0" + d="M 284,234.36218 C 280.60518,237.63576 220.38888,220.32166 219.25129,215.74487 C 218.1137,211.16808 263.2163,167.67628 267.74871,168.9795 C 272.28112,170.28271 287.39482,231.08861 284,234.36218 z " + transform="matrix(0.5046744,-9.1938879e-2,-0.1000384,-0.2995076,329.17835,283.26208)" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="459" + y="203.36218" + id="text8159"><tspan + sodipodi:role="line" + id="tspan8161" + x="459" + y="203.36218">Undo</tspan></text> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.56370759;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8163" + width="132.43629" + height="269.43628" + x="552.78186" + y="76.644043" /> + <g + id="g8169" + transform="matrix(0.7085094,0,0,0.8192639,280.55158,-85.77486)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8171" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8173"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8175" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <g + id="g8177" + transform="matrix(0.7085094,0,0,0.8192639,280.55158,-45.774865)"> + <rect + y="212.26196" + x="393.89227" + height="37.200428" + width="46.215443" + id="rect8179" + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.79179287;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" /> + <a + id="a8181"> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:1.58312905;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8183" + width="44.19965" + height="13.608962" + x="395.26849" + y="213.00041" /> + </a> + </g> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="606" + y="110.36218" + id="text8189"><tspan + sodipodi:role="line" + id="tspan8191" + x="606" + y="110.36218">VIM</tspan></text> + <text + xml:space="preserve" + style="font-size:12.81681156px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="655.58746" + y="135.82359" + id="text8193" + transform="scale(0.9154865,1.0923154)"><tspan + sodipodi:role="line" + id="tspan8195" + x="655.58746" + y="135.82359">Dependency 1</tspan></text> + <path + sodipodi:type="star" + style="fill:#cfcfff;fill-opacity:1;stroke:#000000;stroke-width:0.6525771;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="path8278" + sodipodi:sides="4" + sodipodi:cx="207" + sodipodi:cy="178.36218" + sodipodi:r1="30.413813" + sodipodi:r2="21.505814" + sodipodi:arg1="0.76214654" + sodipodi:arg2="1.5475447" + inkscape:flatsided="true" + inkscape:rounded="0.07" + inkscape:randomized="0" + d="M 229,199.36218 C 226.92111,201.54007 188.17789,202.44108 186,200.36218 C 183.82211,198.28329 182.92111,159.54007 185,157.36218 C 187.07889,155.18429 225.82211,154.28329 228,156.36218 C 230.17789,158.44108 231.07889,197.18429 229,199.36218 z " + transform="matrix(-2.8494521,1.1259094e-2,4.9738035e-3,0.7992946,1200.4495,232.96761)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.59565759;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 662.75191,371.04823 L 656.66967,388.11409 L 648.24809,368.61027 L 657.13753,388.11409 L 662.75191,371.04823 z " + id="path8268" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="553" + y="385.36218" + id="text8281"><tspan + sodipodi:role="line" + id="tspan8283" + x="553" + y="385.36218">Packages</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="487.1709" + y="384.49109" + id="text8285"><tspan + sodipodi:role="line" + id="tspan8287" + x="487.1709" + y="384.49109">Type:</tspan></text> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.03835428;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8222" + width="169.29662" + height="289.12125" + x="43.576736" + y="92.37149" /> + <path + style="fill:#ffffdb;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 30,25.862183 L 138,23.862183 L 238,67.862183 L 240,397.86218 L 21,398.86218 L 20,25.862183 L 30,25.862183 z " + id="path8224" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="34" + y="52.862183" + id="text8230"><tspan + sodipodi:role="line" + id="tspan8232" + x="34" + y="52.862183">Filters</tspan></text> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.29615057;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8234" + width="182.30185" + height="24.301849" + x="35.849075" + y="68.711258" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.76469111px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 41.459552,88.95369 L 50.117654,88.95369 L 44.922793,89.96676 L 44.922793,72.744533 L 48.963241,72.744533 L 40.882346,73.7576 L 45.5,72.744533 L 46.654414,72.744533 L 44.345586,72.744533 L 44.345586,90.97983 L 41.459552,88.95369 z " + id="path8240" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.79200006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 41.759684,107.70843 L 62.153755,114.1277 L 38.846245,123.01593 L 62.153755,113.63391 L 41.759684,107.70843 z " + id="path8242" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="72" + y="120.86218" + id="text8244"><tspan + sodipodi:role="line" + id="tspan8246" + x="72" + y="120.86218">Categories</tspan></text> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.79200006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6.4;stroke-opacity:1" + id="rect8248" + width="180" + height="158" + x="39" + y="135.86218" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 52,152.86218 L 51,276.86218 L 92,275.86218 L 51,275.86218 L 52,171.86218 L 86,171.86218 L 85,253.86218 L 125,252.86218 L 84,253.86218 L 86,209.86218 L 123,209.86218 L 85,209.86218 L 86,172.86218 L 52,172.86218 L 52,152.86218 z " + id="path8250" + sodipodi:nodetypes="ccccccccccccccc" /> + <text + xml:space="preserve" + style="font-size:18px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="95" + y="179.86218" + id="text8252"><tspan + sodipodi:role="line" + id="tspan8254" + x="95" + y="179.86218">Office</tspan></text> + <text + xml:space="preserve" + style="font-size:13.26576328px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="155.67979" + y="177.31532" + id="text8256" + transform="scale(0.8291102,1.2061123)"><tspan + sodipodi:role="line" + id="tspan8258" + x="155.67979" + y="177.31532">Word Processors</tspan></text> + <text + xml:space="preserve" + style="font-size:14.71323204px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="141.53064" + y="238.04373" + id="text8260" + transform="scale(0.919577,1.0874565)"><tspan + sodipodi:role="line" + id="tspan8262" + x="141.53064" + y="238.04373">Spreedsheets</tspan></text> + <text + xml:space="preserve" + style="font-size:18px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="99" + y="280.86218" + id="text8264"><tspan + sodipodi:role="line" + id="tspan8266" + x="99" + y="280.86218">Multimedia</tspan></text> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.79200006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 60.74032,314.20843 L 40.34625,320.6277 L 63.65375,329.51593 L 40.34625,320.13391 L 60.74032,314.20843 z " + id="path8333" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="79.5625" + y="328.03308" + id="text8270"><tspan + sodipodi:role="line" + id="tspan8272" + x="79.5625" + y="328.03308">Repositories</tspan></text> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="49" + y="361.86218" + id="text8274"><tspan + sodipodi:role="line" + id="tspan8276" + x="49" + y="361.86218">. . .</tspan></text> +</svg> Added: trunk/gtk/unstable/mockups/package-selector/ubuntu-add-remove-applications.jpg URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/package-sele... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/wizard-look/installer-mockup.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/wizard-look/... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/wizard-look/jakub-installer-mockup.jpg URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/wizard-look/... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/mockups/wizard-look/jakub-mockup.svg URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/wizard-look/... ============================================================================== --- trunk/gtk/unstable/mockups/wizard-look/jakub-mockup.svg (added) +++ trunk/gtk/unstable/mockups/wizard-look/jakub-mockup.svg Thu Nov 29 18:22:01 2007 @@ -0,0 +1,348 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="512" + height="512" + id="svg3164" + sodipodi:version="0.32" + inkscape:version="0.45.1" + version="1.0" + sodipodi:docbase="/home/jimmac/gfx/suse" + sodipodi:docname="yast-face-mockup.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:export-filename="/home/jimmac/gfx/suse/yast-face-mockup.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <defs + id="defs3166"> + <linearGradient + id="linearGradient9896"> + <stop + style="stop-color:#cecece;stop-opacity:1;" + offset="0" + id="stop9898" /> + <stop + style="stop-color:#9e9e9e;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9900" /> + </linearGradient> + <linearGradient + id="linearGradient9868"> + <stop + id="stop9870" + offset="0.0000000" + style="stop-color:#4e4e4e;stop-opacity:1.0000000;" /> + <stop + id="stop9872" + offset="1.0000000" + style="stop-color:#616161;stop-opacity:0.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient9854"> + <stop + style="stop-color:#4e4e4e;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop9856" /> + <stop + style="stop-color:#ababab;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9858" /> + </linearGradient> + <linearGradient + id="linearGradient9830"> + <stop + style="stop-color:#505050;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop9832" /> + <stop + style="stop-color:#181818;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9834" /> + </linearGradient> + <linearGradient + id="linearGradient3800"> + <stop + id="stop3802" + offset="0.0000000" + style="stop-color:#f4d9b1;stop-opacity:1.0000000;" /> + <stop + id="stop3804" + offset="1.0000000" + style="stop-color:#df9725;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient4163"> + <stop + id="stop4165" + offset="0.0000000" + style="stop-color:#3b74bc;stop-opacity:1.0000000;" /> + <stop + id="stop4167" + offset="1.0000000" + style="stop-color:#2d5990;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient3824"> + <stop + id="stop3826" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3828" + offset="1.0000000" + style="stop-color:#c9c9c9;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient4338"> + <stop + style="stop-color:#e9b15e;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop4340" /> + <stop + style="stop-color:#966416;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop4342" /> + </linearGradient> + <linearGradient + id="linearGradient4344"> + <stop + id="stop4346" + offset="0" + style="stop-color:#727e0a;stop-opacity:1;" /> + <stop + id="stop4348" + offset="1.0000000" + style="stop-color:#5b6508;stop-opacity:1.0000000;" /> + </linearGradient> + <filter + inkscape:collect="always" + x="-0.016093679" + width="1.0321873" + y="-0.12716499" + height="1.25433" + id="filter6146"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.68335658" + id="feGaussianBlur6148" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5749" + id="linearGradient5212" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.560438,0,0,1,-180.35099,80.000027)" + x1="527.00006" + y1="337.49994" + x2="527.00006" + y2="349.99997" /> + <linearGradient + id="linearGradient5749"> + <stop + style="stop-color:#eeeeec;stop-opacity:1;" + offset="0" + id="stop5751" /> + <stop + style="stop-color:#dcdcd8;stop-opacity:1;" + offset="1" + id="stop5753" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5749" + id="linearGradient5218" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.736263,0,0,1,10.989174,79.000022)" + x1="527.00006" + y1="337.49994" + x2="527.00006" + y2="349.99997" /> + <linearGradient + id="linearGradient6107"> + <stop + style="stop-color:#3465a4;stop-opacity:1" + offset="0" + id="stop6109" /> + <stop + id="stop6115" + offset="0.5" + style="stop-color:#83a6d9;stop-opacity:1;" /> + <stop + style="stop-color:#3465a4;stop-opacity:1" + offset="1" + id="stop6111" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6107" + id="linearGradient6113" + x1="196.5" + y1="263" + x2="602.5" + y2="263" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.9160495,0,0,2.1052305,-103.9617,-168.61518)" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="241.72408" + inkscape:cy="244.38808" + inkscape:document-units="px" + inkscape:current-layer="layer1" + width="512px" + height="512px" + borderlayer="true" + inkscape:showpageshadow="false" + showgrid="false" + inkscape:window-width="1083" + inkscape:window-height="908" + inkscape:window-x="149" + inkscape:window-y="0" /> + <metadata + id="metadata3169"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;color:#000000;fill:url(#linearGradient6113);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5220" + width="371" + height="386.85565" + x="76.5" + y="56.644333" + rx="4.5823212" + ry="4.5823212" /> + <rect + style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5138" + width="366" + height="355" + x="79" + y="86" + rx="0" + ry="0" /> + <rect + style="color:#000000;fill:url(#linearGradient5218);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:2.99999976;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5140" + width="66.999771" + height="24.000029" + x="365.5" + y="404.49997" + rx="2.9687498" + ry="2.96875" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans" + x="385.99982" + y="421.00003" + id="text5142"><tspan + sodipodi:role="line" + id="tspan5144" + x="385.99982" + y="421.00003">Next</tspan></text> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" + d="M 386.96852,422.50002 L 392.90602,422.50002" + id="path5170" /> + <rect + ry="2.96875" + rx="2.9687474" + y="405.49997" + x="89.5" + height="24.000029" + width="50.999733" + id="rect5180" + style="color:#000000;fill:url(#linearGradient5212);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.99999958;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <text + id="text5182" + y="422.00003" + x="101.99992" + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="422.00003" + x="101.99992" + id="tspan5184" + sodipodi:role="line">Help</tspan></text> + <path + id="path5186" + d="M 103.49993,423.50002 L 108.49993,423.50002" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> + <text + sodipodi:linespacing="125%" + id="text6122" + y="56.362183" + x="203.67383" + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:0.49714284;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6146);font-family:Segoe" + xml:space="preserve" + transform="matrix(1.18725,0,0,1.18725,-40.3025,10.144894)"><tspan + y="56.362183" + x="203.67383" + id="tspan6124" + sodipodi:role="line">Hardware Setup</tspan></text> + <text + xml:space="preserve" + style="font-size:14.24700165px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Trebuchet MS" + x="201.50928" + y="75.873657" + id="text6118" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6120" + x="201.50928" + y="75.873657">Hardware Setup</tspan></text> + <g + id="g4295" + transform="translate(3.330917,-21.00005)"> + <text + id="text4287" + y="136.00006" + x="88.071426" + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="136.00006" + x="88.071426" + id="tspan4289" + sodipodi:role="line">Choose Driver:</tspan></text> + <path + id="path4291" + d="M 89.510984,137.50005 L 95.411632,137.50005" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> + </g> + <rect + style="fill:#ffffff;stroke:#babdb6;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" + id="rect4293" + width="344" + height="265.99997" + x="89.5" + y="125.50002" + rx="2.9687476" + ry="2.96875" /> + </g> +</svg> Added: trunk/gtk/unstable/mockups/wizard-look/ricardo-installer-mockup.svg URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/wizard-look/... ============================================================================== --- trunk/gtk/unstable/mockups/wizard-look/ricardo-installer-mockup.svg (added) +++ trunk/gtk/unstable/mockups/wizard-look/ricardo-installer-mockup.svg Thu Nov 29 18:22:01 2007 @@ -0,0 +1,378 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="512" + height="512" + id="svg3164" + sodipodi:version="0.32" + inkscape:version="0.44.1" + version="1.0" + sodipodi:docbase="/home/rick2" + sodipodi:docname="installer-mockup.svg" + inkscape:export-filename="/home/jimmac/gfx/suse/yast-face-mockup.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <defs + id="defs3166"> + <linearGradient + id="linearGradient9896"> + <stop + style="stop-color:#cecece;stop-opacity:1;" + offset="0" + id="stop9898" /> + <stop + style="stop-color:#9e9e9e;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9900" /> + </linearGradient> + <linearGradient + id="linearGradient9868"> + <stop + id="stop9870" + offset="0.0000000" + style="stop-color:#4e4e4e;stop-opacity:1.0000000;" /> + <stop + id="stop9872" + offset="1.0000000" + style="stop-color:#616161;stop-opacity:0.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient9854"> + <stop + style="stop-color:#4e4e4e;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop9856" /> + <stop + style="stop-color:#ababab;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9858" /> + </linearGradient> + <linearGradient + id="linearGradient9830"> + <stop + style="stop-color:#505050;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop9832" /> + <stop + style="stop-color:#181818;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop9834" /> + </linearGradient> + <linearGradient + id="linearGradient3800"> + <stop + id="stop3802" + offset="0.0000000" + style="stop-color:#f4d9b1;stop-opacity:1.0000000;" /> + <stop + id="stop3804" + offset="1.0000000" + style="stop-color:#df9725;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient4163"> + <stop + id="stop4165" + offset="0.0000000" + style="stop-color:#3b74bc;stop-opacity:1.0000000;" /> + <stop + id="stop4167" + offset="1.0000000" + style="stop-color:#2d5990;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient3824"> + <stop + id="stop3826" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3828" + offset="1.0000000" + style="stop-color:#c9c9c9;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient4338"> + <stop + style="stop-color:#e9b15e;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop4340" /> + <stop + style="stop-color:#966416;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop4342" /> + </linearGradient> + <linearGradient + id="linearGradient4344"> + <stop + id="stop4346" + offset="0" + style="stop-color:#727e0a;stop-opacity:1;" /> + <stop + id="stop4348" + offset="1.0000000" + style="stop-color:#5b6508;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5749" + id="linearGradient5212" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.560438,0,0,1,-81.05688,145.6536)" + x1="527.00006" + y1="337.49994" + x2="527.00006" + y2="349.99997" /> + <linearGradient + id="linearGradient5749"> + <stop + style="stop-color:#eeeeec;stop-opacity:1;" + offset="0" + id="stop5751" /> + <stop + style="stop-color:#dcdcd8;stop-opacity:1;" + offset="1" + id="stop5753" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5749" + id="linearGradient5218" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.736263,0,0,1,68.94996,149)" + x1="527.00006" + y1="337.49994" + x2="527.00006" + y2="349.99997" /> + <linearGradient + id="linearGradient6107"> + <stop + style="stop-color:#3465a4;stop-opacity:1" + offset="0" + id="stop6109" /> + <stop + id="stop6115" + offset="0.5" + style="stop-color:#83a6d9;stop-opacity:1;" /> + <stop + style="stop-color:#3465a4;stop-opacity:1" + offset="1" + id="stop6111" /> + </linearGradient> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.1953125" + inkscape:cx="256" + inkscape:cy="271.20829" + inkscape:document-units="px" + inkscape:current-layer="layer1" + width="512px" + height="512px" + borderlayer="true" + inkscape:showpageshadow="false" + showgrid="false" + inkscape:window-width="1440" + inkscape:window-height="828" + inkscape:window-x="0" + inkscape:window-y="26" /> + <metadata + id="metadata3169"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="color:black;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + id="rect5138" + width="513" + height="511" + x="-1" + y="1" + rx="0" + ry="0" /> + <rect + style="color:black;fill:url(#linearGradient5218);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:2.99999976;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + id="rect5140" + width="66.999771" + height="24.000029" + x="423.46078" + y="474.49997" + rx="2.9687498" + ry="2.96875" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans" + x="443.63379" + y="490.00003" + id="text5142"><tspan + sodipodi:role="line" + id="tspan5144" + x="443.63379" + y="490.00003">Next</tspan></text> + <rect + ry="2.96875" + rx="2.9687474" + y="471.15356" + x="188.79411" + height="24.000029" + width="50.999733" + id="rect5180" + style="color:black;fill:url(#linearGradient5212);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.99999958;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + <text + id="text5182" + y="485.98041" + x="200.80385" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans" + xml:space="preserve"><tspan + y="485.98041" + x="200.80385" + id="tspan5184" + sodipodi:role="line">Help</tspan></text> + <rect + style="fill:white;stroke:#babdb6;stroke-width:1.14902854;stroke-miterlimit:4;stroke-dasharray:none" + id="rect4293" + width="302.04697" + height="325.17773" + x="191.37843" + y="123.24775" + rx="3.1898239" + ry="3.6478913" /> + <path + style="fill:#87bd87;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.1111107,520.72932 C 7.1111107,520.72932 135.78292,525.54946 135.58744,471.36984 C 135.392,417.1999 135.97832,457.14761 135.97832,457.14761 L 136.85488,126.69001 C 136.85488,126.69001 135.59675,103.14234 145.82517,90.297902 C 157.15075,76.075702 173.17392,75.657432 173.17392,75.657432 C 173.17392,75.657432 365.17061,79.723792 464.44254,78.167232 C 518.57963,77.330632 519.94771,8.7293224 519.94771,8.7293224 L 7.1111107,7.8927224 L 7.1111107,520.72932 z " + id="path4669" + sodipodi:nodetypes="czccscsccc" /> + <path + style="fill:#87d958;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M -0.41829972,512.83464 C -0.41829972,512.83464 128.25351,517.65478 128.05803,463.47516 C 127.86259,409.30522 128.44891,449.25293 128.44891,449.25293 L 129.32547,118.79533 C 129.32547,118.79533 128.06734,95.247664 138.29576,82.403217 C 149.62134,68.181022 165.64451,67.76275 165.64451,67.76275 C 165.64451,67.76275 357.6412,71.829111 456.91313,70.272551 C 511.05022,69.435951 512.4183,0.83464057 512.4183,0.83464057 L -0.41829972,-0.0019620281 L -0.41829972,512.83464 z " + id="path3730" + sodipodi:nodetypes="czccscsccc" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-weight:bold;fill:white;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="117.96078" + y="40.156864" + id="text3732"><tspan + sodipodi:role="line" + id="tspan3734" + x="117.96078" + y="40.156864">Hardware Setup</tspan></text> + <text + xml:space="preserve" + style="font-size:10px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="34.300655" + y="116.28758" + id="text3736"><tspan + sodipodi:role="line" + id="tspan3738" + x="34.300655" + y="116.28758">Welcome</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="128.78758" + id="tspan3740"></tspan><tspan + sodipodi:role="line" + x="34.300655" + y="141.28758" + id="tspan3744">Choose language</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="153.78758" + id="tspan3742" /><tspan + sodipodi:role="line" + x="34.300655" + y="166.28758" + id="tspan3746">Format disk</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="178.78758" + id="tspan3748" /><tspan + sodipodi:role="line" + x="34.300655" + y="191.28758" + id="tspan3750">Install packages</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="203.78758" + id="tspan3752" /><tspan + sodipodi:role="line" + x="34.300655" + y="216.28758" + id="tspan3754">Add users</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="228.78758" + id="tspan3756" /><tspan + sodipodi:role="line" + x="34.300655" + y="241.28758" + id="tspan3758" /><tspan + sodipodi:role="line" + x="34.300655" + y="253.78758" + id="tspan3760" /><tspan + sodipodi:role="line" + x="34.300655" + y="266.28758" + id="tspan3762">Check updates</tspan><tspan + sodipodi:role="line" + x="34.300655" + y="278.78758" + id="tspan3764" /><tspan + sodipodi:role="line" + x="34.300655" + y="291.28758" + id="tspan3766">Done</tspan></text> + <text + xml:space="preserve" + style="font-size:10px;font-style:normal;font-weight:bold;fill:white;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="30.117647" + y="238.43135" + id="text3768"><tspan + sodipodi:role="line" + id="tspan3770" + x="30.117647" + y="238.43135">Hardware setup</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="197.43791" + y="105.41177" + id="text3776"><tspan + sodipodi:role="line" + id="tspan3778" + x="197.43791" + y="105.41177">Choose driver:</tspan></text> + <path + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.73778713px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 12.231207,229.93425 L 26.90235,234.95978 L 11.581307,241.07227 L 12.231207,229.93425 z " + id="path3782" + sodipodi:nodetypes="cccc" /> + </g> +</svg> Added: trunk/gtk/unstable/mockups/wizard-look/tools-mockup.png URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/mockups/wizard-look/... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/package/yast2-gtk-rpmlintrc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/package/yast2-gtk-rp... ============================================================================== --- trunk/gtk/unstable/package/yast2-gtk-rpmlintrc (added) +++ trunk/gtk/unstable/package/yast2-gtk-rpmlintrc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,2 @@ +# yast2 likes a .so file for it's plugin that looks like a -devel pkg thing +addFilter("devel-file-in-non-devel-package") Added: trunk/gtk/unstable/package/yast2-gtk.changes URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/package/yast2-gtk.ch... ============================================================================== --- trunk/gtk/unstable/package/yast2-gtk.changes (added) +++ trunk/gtk/unstable/package/yast2-gtk.changes Thu Nov 29 18:22:01 2007 @@ -0,0 +1,107 @@ +------------------------------------------------------------------- +Wed Oct 6 15:32:01 BST 2007 - mmichael@suse.de + +- n#300750: big speedup wrt. search / sort + +------------------------------------------------------------------- +Wed Aug 26 15:32:01 BST 2007 - mmichael@suse.de + +- n#300390: warn if cancelling a non-submitted transaction. + +------------------------------------------------------------------- +Wed Aug 8 15:32:01 BST 2007 - mmichael@suse.de + +- #296945: pulse progress bar impl. + +------------------------------------------------------------------- +Fri Aug 10 18:01:20 CEST 2007 - mvidner@suse.cz + +- Finished integrating Feature #120292, UI as a namespace callable + from yast2-*-bindings. +- 2.5.9 + +------------------------------------------------------------------- +Wed Aug 8 15:32:01 BST 2007 - mmichael@suse.de + +- FaTE #302018: details on how to print the license +- 2.15.8 + +------------------------------------------------------------------- +Wed Aug 8 09:22:32 CEST 2007 - mvidner@suse.cz + +- Don't build-require yast2-devel-doc. +- 2.15.7.2 + +------------------------------------------------------------------- +Mon Aug 6 14:00:37 CEST 2007 - mvidner@suse.cz + +- Adapted to changes in yast2-core needed for making UI callable from + yast2-*-bindings. +- 2.15.7.1 + +------------------------------------------------------------------- +Thu Jul 26 07:28:31 CEST 2007 - jsrain@suse.cz + +- removed yast2-devel from BuildRequires +- 2.15.7 + +------------------------------------------------------------------- +Mon Jul 23 15:32:01 BST 2007 - mmichael@suse.de + +- fix crash-on-start n#293065 +- fix uninitialized warnings +- fix empty-partition divide by 0 case +- 2.15.6 + +------------------------------------------------------------------- +Mon Jul 16 17:07:01 CEST 2007 - jsrain@suse.cz + +- adapted to new libzypp +- added support for translations +- 2.15.5 + +------------------------------------------------------------------- +Thu Jun 21 10:24:55 CEST 2007 - mmichael@suse.de + +- upgrade to yast2-gtk-2.15.4, fixes many bugs, pwrt. + package selector, improved search, multi-select for + installations &, large scale robustness & functionality + table-sorting fix, progress bar fix, initial easter-egg, + add rpmlintrc to avoid complaints about plugin .so name + +------------------------------------------------------------------- +Fri May 11 18:19:10 CEST 2007 - mmichael@suse.de + +- upgrade to yast2-gtk-2.15.3, fixes #268146, #271716 + and improves package selector search / sort. + +------------------------------------------------------------------- +Tue Apr 17 15:58:40 CEST 2007 - mmichael@suse.de + +- upgrade to yast2-gtk-2.15.2, fixes upgrade.ycp + +------------------------------------------------------------------- +Fri Mar 16 13:36:04 CET 2007 - mmichael@suse.de + +- upgrade to yast2-gtk-2.15.1, several fixes, including #247682, #247683 + +------------------------------------------------------------------- +Wed Feb 7 11:26:07 CET 2007 - mmichael@suse.de + +- update to yast2-gtk-2.15.0, fixes build and adds new Frame type + +------------------------------------------------------------------- +Wed Aug 30 10:56:28 CEST 2006 - cthiel@suse.de + +- added yast2-gtk-autogen.patch to fix build with latests yast2-devtools + +------------------------------------------------------------------- +Mon Aug 28 11:34:13 CEST 2006 - cthiel@suse.de + +- fix build + +------------------------------------------------------------------- +Wed Aug 23 18:20:30 CEST 2006 - mmichael@suse.de + +- import yast2-gtk into autobuild. + Added: trunk/gtk/unstable/src/.cvsignore URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/.cvsignore?rev=4... ============================================================================== --- trunk/gtk/unstable/src/.cvsignore (added) +++ trunk/gtk/unstable/src/.cvsignore Thu Nov 29 18:22:01 2007 @@ -0,0 +1,7 @@ +Makefile.in +Makefile +*.lo +*.la +.libs +.deps +dummy Added: trunk/gtk/unstable/src/Makefile URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/Makefile?rev=425... ============================================================================== --- trunk/gtk/unstable/src/Makefile (added) +++ trunk/gtk/unstable/src/Makefile Thu Nov 29 18:22:01 2007 @@ -0,0 +1,754 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# src/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + + +pkgdatadir = $(datadir)/yast2-gtk +pkglibdir = $(libdir)/yast2-gtk +pkgincludedir = $(includedir)/yast2-gtk +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i686-suse-linux-gnu +host_triplet = i686-suse-linux-gnu +target_triplet = i686-suse-linux-gnu +noinst_PROGRAMS = dummy$(EXEEXT) +check_PROGRAMS = test$(EXEEXT) +subdir = src +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(plugindir)" +pluginLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libpy2gtk_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libpy2gtk_la_OBJECTS = Y2CCGtk.lo YGUtils.lo YGUI.lo YGDialog.lo \ + YGLayout.lo YGWidget.lo YGLabel.lo YGPushButton.lo \ + YGProgressBar.lo YGTextEntry.lo YGMultiLineEdit.lo \ + YGIntField.lo YGRadioButton.lo YGImage.lo YGFrame.lo \ + YGComboBox.lo YGTable.lo YGTree.lo YGMenuButton.lo \ + YGBarGraph.lo YGDumbTab.lo YGWizard.lo YGTime.lo \ + YGPackageSelector.lo ygtkratiobox.lo ygtkbargraph.lo \ + ygtksteps.lo ygtkfieldentry.lo ygtkmenubutton.lo ygtkwizard.lo \ + ygtkfindentry.lo ygdkmngloader.lo ygtkhtmlwrap.lo \ + ygtkrichtext.lo yzyppwrapper.lo ygtkzyppwrapper.lo +libpy2gtk_la_OBJECTS = $(am_libpy2gtk_la_OBJECTS) +libpy2gtk_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libpy2gtk_la_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(noinst_PROGRAMS) +am_dummy_OBJECTS = dummy.$(OBJEXT) +dummy_OBJECTS = $(am_dummy_OBJECTS) +dummy_DEPENDENCIES = libpy2gtk.la +am_test_OBJECTS = test.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_DEPENDENCIES = $(top_builddir)/src/$(plugin_LTLIBRARIES) +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libpy2gtk_la_SOURCES) $(dummy_SOURCES) $(test_SOURCES) +DIST_SOURCES = $(libpy2gtk_la_SOURCES) $(dummy_SOURCES) \ + $(test_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run aclocal-1.10 +AGENT_LIBADD = -L$(libdir) -lscr +ALLOCA = +AMTAR = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run tar +AR = ar +AUTOCONF = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run autoconf +AUTOHEADER = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run autoheader +AUTOMAKE = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run automake-1.10 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 -Wall -Wformat=2 -Wmissing-prototypes +CPP = gcc -E +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 -Wall -Wformat=2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /usr/bin/grep -E +EXEEXT = +F77 = +FFLAGS = +GREP = /usr/bin/grep +GTK_CFLAGS = -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 +GTK_LIBS = -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgmodule-2.0 -ldl -lgthread-2.0 -lrt -lgobject-2.0 -lglib-2.0 +INSTALL = /usr/bin/install -c -p +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +LTLIBOBJS = +MAINTAINER = Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> Michael Meeks <michael.meeks@novell.com> +MAKEINFO = ${SHELL} /home/rick2/Documents/yast/gtk/unstable/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +OBJEXT = o +PACKAGE = yast2-gtk +PACKAGE_BUGREPORT = http://bugs.opensuse.org/ +PACKAGE_NAME = yast2-gtk +PACKAGE_STRING = yast2-gtk 2.15.9 +PACKAGE_TARNAME = yast2-gtk +PACKAGE_VERSION = 2.15.9 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_PATH = +PYUI_LIBS = -lpy2UI +RANLIB = ranlib +RPMNAME = yast2-gtk +SED = /usr/bin/sed +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +STYLESHEET_CSS = /usr/share/YaST2/data/docbook/css/yast2docs.css +STYLESHEET_HTML = /usr/share/YaST2/data/docbook/stylesheets/customize-html.xsl +STYLESHEET_PDF = /usr/share/YaST2/data/docbook/stylesheets/customize-fo.xsl +STYLESHEET_YCPDOC = /usr/share/YaST2/data/docbook/stylesheets/ycpdoc.xsl +STYLESHEET_YDOC = /usr/share/YaST2/data/docbook/stylesheets/ydoc.xsl +VERSION = 2.15.9 +XGETTEXT = /usr/bin/xgettext +Y2DEVTOOLS_PREFIX = /usr +YDOXYGEN = /usr/lib/YaST2/bin/ydoxygen +ZYPP_CFLAGS = +ZYPP_LIBS = -lzypp +abs_builddir = /home/rick2/Documents/yast/gtk/unstable/src +abs_srcdir = /home/rick2/Documents/yast/gtk/unstable/src +abs_top_builddir = /home/rick2/Documents/yast/gtk/unstable +abs_top_srcdir = /home/rick2/Documents/yast/gtk/unstable +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_F77 = +agentdir = ${prefix}/lib/YaST2/servers_non_y2 +am__include = include +am__leading_dot = . +am__quote = +am__tar = tar --format=ustar -chf - "$$tardir" +am__untar = tar -xf - +bindir = ${exec_prefix}/bin +build = i686-suse-linux-gnu +build_alias = +build_cpu = i686 +build_os = linux-gnu +build_vendor = suse +builddir = . +clientdir = ${prefix}/share/YaST2/clients +datadir = ${datarootdir} +datarootdir = ${prefix}/share +desktopdir = ${prefix}/share/applications/YaST2 +docdir = ${prefix}/share/doc/packages/yast2-gtk +dvidir = ${docdir} +exec_prefix = ${prefix} +execcompdir = ${prefix}/lib/YaST2 +fillupdir = /var/adm/fillup-templates +host = i686-suse-linux-gnu +host_alias = +host_cpu = i686 +host_os = linux-gnu +host_vendor = suse +htmldir = ${docdir} +imagedir = ${prefix}/share/YaST2/images +includedir = ${prefix}/include/YaST2 +infodir = ${datarootdir}/info +install_sh = $(SHELL) /home/rick2/Documents/yast/gtk/unstable/install-sh +libdir = /usr/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${prefix}/share/YaST2/locale +localstatedir = ${prefix}/var +mandir = ${prefix}/share/man +mkdir_p = /bin/mkdir -p +moduledir = ${prefix}/share/YaST2/modules +oldincludedir = /usr/include +pdfdir = ${docdir} +pkgconfigdatadir = ${datadir}/pkgconfig +pkgconfigdir = ${libdir}/pkgconfig +plugindir = ${libdir}/YaST2/plugin +potdir = ${docdir}/pot +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +schemadir = ${prefix}/share/YaST2/schema +scrconfdir = ${prefix}/share/YaST2/scrconf +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target = i686-suse-linux-gnu +target_alias = +target_cpu = i686 +target_os = linux-gnu +target_vendor = suse +themedir = ${prefix}/share/YaST2/theme +top_builddir = .. +top_srcdir = .. +yast2dir = ${prefix}/share/YaST2 +ybindir = ${prefix}/lib/YaST2/bin +ydatadir = ${prefix}/share/YaST2/data +yncludedir = ${prefix}/share/YaST2/include +ystartupdir = ${prefix}/lib/YaST2 +AM_CFLAGS = $(GTK_CFLAGS) \ + -DTHEMEDIR=\"${themedir}/current\" + +AM_CXXFLAGS = $(GTK_CFLAGS) \ + -DY2LOG=\"ui-gtk\" \ + -DTHEMEDIR=\"${themedir}/current\" + +noinst_HEADERS = $(wildcard *.h) + +# plugin, libtool forces 'lib' prefix +plugin_LTLIBRARIES = libpy2gtk.la +libpy2gtk_la_LDFLAGS = -version-info 2:0 +libpy2gtk_la_LIBADD = -L$(plugindir) $(PYUI_LIBS) -L$(libdir) -lycp -ly2 \ + $(GTK_LIBS) $(ZYPP_LIBS) $(GTKHTML_LIBS) + +libpy2gtk_la_SOURCES = \ + Y2CCGtk.cc \ + YGUtils.cc \ + YGUI.cc \ + YGDialog.cc \ + YGLayout.cc \ + YGWidget.cc \ + YGLabel.cc \ + YGPushButton.cc \ + YGProgressBar.cc \ + YGTextEntry.cc \ + YGMultiLineEdit.cc \ + YGIntField.cc \ + YGRadioButton.cc \ + YGImage.cc \ + YGFrame.cc \ + YGComboBox.cc \ + YGTable.cc \ + YGTree.cc \ + YGMenuButton.cc \ + YGBarGraph.cc \ + YGDumbTab.cc \ + YGWizard.cc \ + YGTime.cc \ + YGPackageSelector.cc \ + ygtkratiobox.c \ + ygtkbargraph.c \ + ygtksteps.c \ + ygtkfieldentry.c \ + ygtkmenubutton.c \ + ygtkwizard.c \ + ygtkfindentry.c \ + ygdkmngloader.c \ + ygtkhtmlwrap.c \ + ygtkrichtext.c \ + yzyppwrapper.cc \ + ygtkzyppwrapper.cc + +# should only append ygtkrichtext.c if USE_GTKHTML is set +dummy_SOURCES = dummy.cc +dummy_LDADD = libpy2gtk.la +TESTS = $(check_PROGRAMS) +test_SOURCES = test.cc +test_LDADD = $(top_builddir)/src/$(plugin_LTLIBRARIES) +INCLUDES = -I$(srcdir)/include -I$(includedir) -I$(includedir)/yui $(ZYPP_CFLAGS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \ + else :; fi; \ + done + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libpy2gtk.la: $(libpy2gtk_la_OBJECTS) $(libpy2gtk_la_DEPENDENCIES) + $(libpy2gtk_la_LINK) -rpath $(plugindir) $(libpy2gtk_la_OBJECTS) $(libpy2gtk_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +dummy$(EXEEXT): $(dummy_OBJECTS) $(dummy_DEPENDENCIES) + @rm -f dummy$(EXEEXT) + $(CXXLINK) $(dummy_OBJECTS) $(dummy_LDADD) $(LIBS) +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/Y2CCGtk.Plo +include ./$(DEPDIR)/YGBarGraph.Plo +include ./$(DEPDIR)/YGComboBox.Plo +include ./$(DEPDIR)/YGDialog.Plo +include ./$(DEPDIR)/YGDumbTab.Plo +include ./$(DEPDIR)/YGFrame.Plo +include ./$(DEPDIR)/YGImage.Plo +include ./$(DEPDIR)/YGIntField.Plo +include ./$(DEPDIR)/YGLabel.Plo +include ./$(DEPDIR)/YGLayout.Plo +include ./$(DEPDIR)/YGMenuButton.Plo +include ./$(DEPDIR)/YGMultiLineEdit.Plo +include ./$(DEPDIR)/YGPackageSelector.Plo +include ./$(DEPDIR)/YGProgressBar.Plo +include ./$(DEPDIR)/YGPushButton.Plo +include ./$(DEPDIR)/YGRadioButton.Plo +include ./$(DEPDIR)/YGTable.Plo +include ./$(DEPDIR)/YGTextEntry.Plo +include ./$(DEPDIR)/YGTime.Plo +include ./$(DEPDIR)/YGTree.Plo +include ./$(DEPDIR)/YGUI.Plo +include ./$(DEPDIR)/YGUtils.Plo +include ./$(DEPDIR)/YGWidget.Plo +include ./$(DEPDIR)/YGWizard.Plo +include ./$(DEPDIR)/dummy.Po +include ./$(DEPDIR)/test.Po +include ./$(DEPDIR)/ygdkmngloader.Plo +include ./$(DEPDIR)/ygtkbargraph.Plo +include ./$(DEPDIR)/ygtkfieldentry.Plo +include ./$(DEPDIR)/ygtkfindentry.Plo +include ./$(DEPDIR)/ygtkhtmlwrap.Plo +include ./$(DEPDIR)/ygtkmenubutton.Plo +include ./$(DEPDIR)/ygtkratiobox.Plo +include ./$(DEPDIR)/ygtkrichtext.Plo +include ./$(DEPDIR)/ygtksteps.Plo +include ./$(DEPDIR)/ygtkwizard.Plo +include ./$(DEPDIR)/ygtkzyppwrapper.Plo +include ./$(DEPDIR)/yzyppwrapper.Plo + +.c.o: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LTCOMPILE) -c -o $@ $< + +.cc.o: + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: + $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pluginLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-pluginLTLIBRARIES + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: Added: trunk/gtk/unstable/src/Makefile.am URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/Makefile.am?rev=... ============================================================================== --- trunk/gtk/unstable/src/Makefile.am (added) +++ trunk/gtk/unstable/src/Makefile.am Thu Nov 29 18:22:01 2007 @@ -0,0 +1,69 @@ +AM_CFLAGS = $(GTK_CFLAGS) \ + -DTHEMEDIR=\"${themedir}/current\" +AM_CXXFLAGS = $(GTK_CFLAGS) \ + -DY2LOG=\"ui-gtk\" \ + -DTHEMEDIR=\"${themedir}/current\" + +noinst_HEADERS = $(wildcard *.h) + +# test linkage for missing symbols etc. +noinst_PROGRAMS = dummy + +# plugin, libtool forces 'lib' prefix +plugin_LTLIBRARIES = libpy2gtk.la + +libpy2gtk_la_LDFLAGS = -version-info 2:0 +libpy2gtk_la_LIBADD = -L$(plugindir) $(PYUI_LIBS) -L$(libdir) -lycp -ly2 \ + $(GTK_LIBS) $(ZYPP_LIBS) $(GTKHTML_LIBS) +libpy2gtk_la_SOURCES = \ + Y2CCGtk.cc \ + YGUtils.cc \ + YGUI.cc \ + YGDialog.cc \ + YGLayout.cc \ + YGWidget.cc \ + YGLabel.cc \ + YGPushButton.cc \ + YGProgressBar.cc \ + YGTextEntry.cc \ + YGMultiLineEdit.cc \ + YGIntField.cc \ + YGRadioButton.cc \ + YGImage.cc \ + YGFrame.cc \ + YGComboBox.cc \ + YGTable.cc \ + YGTree.cc \ + YGMenuButton.cc \ + YGBarGraph.cc \ + YGDumbTab.cc \ + YGWizard.cc \ + YGTime.cc \ + YGPackageSelector.cc \ + ygtkratiobox.c \ + ygtkbargraph.c \ + ygtksteps.c \ + ygtkfieldentry.c \ + ygtkmenubutton.c \ + ygtkwizard.c \ + ygtkfindentry.c \ + ygdkmngloader.c \ + ygtkhtmlwrap.c \ + ygtkrichtext.c \ + yzyppwrapper.cc \ + ygtkzyppwrapper.cc +# should only append ygtkrichtext.c if USE_GTKHTML is set + +dummy_SOURCES = dummy.cc +dummy_LDADD = libpy2gtk.la + +check_PROGRAMS = test +TESTS = $(check_PROGRAMS) + +test_SOURCES = test.cc +test_LDADD = $(top_builddir)/src/$(plugin_LTLIBRARIES) + +INCLUDES = -I$(srcdir)/include -I$(includedir) -I$(includedir)/yui $(ZYPP_CFLAGS) + +EXTRA_DIST = + Added: trunk/gtk/unstable/src/Makefile.in URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/Makefile.in?rev=... ============================================================================== --- trunk/gtk/unstable/src/Makefile.in (added) +++ trunk/gtk/unstable/src/Makefile.in Thu Nov 29 18:22:01 2007 @@ -0,0 +1,754 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +noinst_PROGRAMS = dummy$(EXEEXT) +check_PROGRAMS = test$(EXEEXT) +subdir = src +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(plugindir)" +pluginLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libpy2gtk_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libpy2gtk_la_OBJECTS = Y2CCGtk.lo YGUtils.lo YGUI.lo YGDialog.lo \ + YGLayout.lo YGWidget.lo YGLabel.lo YGPushButton.lo \ + YGProgressBar.lo YGTextEntry.lo YGMultiLineEdit.lo \ + YGIntField.lo YGRadioButton.lo YGImage.lo YGFrame.lo \ + YGComboBox.lo YGTable.lo YGTree.lo YGMenuButton.lo \ + YGBarGraph.lo YGDumbTab.lo YGWizard.lo YGTime.lo \ + YGPackageSelector.lo ygtkratiobox.lo ygtkbargraph.lo \ + ygtksteps.lo ygtkfieldentry.lo ygtkmenubutton.lo ygtkwizard.lo \ + ygtkfindentry.lo ygdkmngloader.lo ygtkhtmlwrap.lo \ + ygtkrichtext.lo yzyppwrapper.lo ygtkzyppwrapper.lo +libpy2gtk_la_OBJECTS = $(am_libpy2gtk_la_OBJECTS) +libpy2gtk_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libpy2gtk_la_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(noinst_PROGRAMS) +am_dummy_OBJECTS = dummy.$(OBJEXT) +dummy_OBJECTS = $(am_dummy_OBJECTS) +dummy_DEPENDENCIES = libpy2gtk.la +am_test_OBJECTS = test.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_DEPENDENCIES = $(top_builddir)/src/$(plugin_LTLIBRARIES) +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libpy2gtk_la_SOURCES) $(dummy_SOURCES) $(test_SOURCES) +DIST_SOURCES = $(libpy2gtk_la_SOURCES) $(dummy_SOURCES) \ + $(test_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGENT_LIBADD = @AGENT_LIBADD@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINTAINER = @MAINTAINER@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYUI_LIBS = @PYUI_LIBS@ +RANLIB = @RANLIB@ +RPMNAME = @RPMNAME@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +STYLESHEET_CSS = @STYLESHEET_CSS@ +STYLESHEET_HTML = @STYLESHEET_HTML@ +STYLESHEET_PDF = @STYLESHEET_PDF@ +STYLESHEET_YCPDOC = @STYLESHEET_YCPDOC@ +STYLESHEET_YDOC = @STYLESHEET_YDOC@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +Y2DEVTOOLS_PREFIX = @Y2DEVTOOLS_PREFIX@ +YDOXYGEN = @YDOXYGEN@ +ZYPP_CFLAGS = @ZYPP_CFLAGS@ +ZYPP_LIBS = @ZYPP_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +agentdir = @agentdir@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +clientdir = @clientdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +desktopdir = @desktopdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +execcompdir = @execcompdir@ +fillupdir = @fillupdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imagedir = @imagedir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdatadir = @pkgconfigdatadir@ +pkgconfigdir = @pkgconfigdir@ +plugindir = @plugindir@ +potdir = @potdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +schemadir = @schemadir@ +scrconfdir = @scrconfdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +themedir = @themedir@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +yast2dir = @yast2dir@ +ybindir = @ybindir@ +ydatadir = @ydatadir@ +yncludedir = @yncludedir@ +ystartupdir = @ystartupdir@ +AM_CFLAGS = $(GTK_CFLAGS) \ + -DTHEMEDIR=\"${themedir}/current\" + +AM_CXXFLAGS = $(GTK_CFLAGS) \ + -DY2LOG=\"ui-gtk\" \ + -DTHEMEDIR=\"${themedir}/current\" + +noinst_HEADERS = $(wildcard *.h) + +# plugin, libtool forces 'lib' prefix +plugin_LTLIBRARIES = libpy2gtk.la +libpy2gtk_la_LDFLAGS = -version-info 2:0 +libpy2gtk_la_LIBADD = -L$(plugindir) $(PYUI_LIBS) -L$(libdir) -lycp -ly2 \ + $(GTK_LIBS) $(ZYPP_LIBS) $(GTKHTML_LIBS) + +libpy2gtk_la_SOURCES = \ + Y2CCGtk.cc \ + YGUtils.cc \ + YGUI.cc \ + YGDialog.cc \ + YGLayout.cc \ + YGWidget.cc \ + YGLabel.cc \ + YGPushButton.cc \ + YGProgressBar.cc \ + YGTextEntry.cc \ + YGMultiLineEdit.cc \ + YGIntField.cc \ + YGRadioButton.cc \ + YGImage.cc \ + YGFrame.cc \ + YGComboBox.cc \ + YGTable.cc \ + YGTree.cc \ + YGMenuButton.cc \ + YGBarGraph.cc \ + YGDumbTab.cc \ + YGWizard.cc \ + YGTime.cc \ + YGPackageSelector.cc \ + ygtkratiobox.c \ + ygtkbargraph.c \ + ygtksteps.c \ + ygtkfieldentry.c \ + ygtkmenubutton.c \ + ygtkwizard.c \ + ygtkfindentry.c \ + ygdkmngloader.c \ + ygtkhtmlwrap.c \ + ygtkrichtext.c \ + yzyppwrapper.cc \ + ygtkzyppwrapper.cc + +# should only append ygtkrichtext.c if USE_GTKHTML is set +dummy_SOURCES = dummy.cc +dummy_LDADD = libpy2gtk.la +TESTS = $(check_PROGRAMS) +test_SOURCES = test.cc +test_LDADD = $(top_builddir)/src/$(plugin_LTLIBRARIES) +INCLUDES = -I$(srcdir)/include -I$(includedir) -I$(includedir)/yui $(ZYPP_CFLAGS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \ + else :; fi; \ + done + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libpy2gtk.la: $(libpy2gtk_la_OBJECTS) $(libpy2gtk_la_DEPENDENCIES) + $(libpy2gtk_la_LINK) -rpath $(plugindir) $(libpy2gtk_la_OBJECTS) $(libpy2gtk_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +dummy$(EXEEXT): $(dummy_OBJECTS) $(dummy_DEPENDENCIES) + @rm -f dummy$(EXEEXT) + $(CXXLINK) $(dummy_OBJECTS) $(dummy_LDADD) $(LIBS) +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Y2CCGtk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGBarGraph.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGComboBox.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGDialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGDumbTab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGFrame.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGImage.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGIntField.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGLabel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGLayout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGMenuButton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGMultiLineEdit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGPackageSelector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGProgressBar.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGPushButton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGRadioButton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGTable.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGTextEntry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGTime.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGTree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGUI.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGUtils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGWidget.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/YGWizard.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygdkmngloader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkbargraph.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkfieldentry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkfindentry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkhtmlwrap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkmenubutton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkratiobox.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkrichtext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtksteps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkwizard.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ygtkzyppwrapper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yzyppwrapper.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +.cc.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pluginLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-pluginLTLIBRARIES + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: Added: trunk/gtk/unstable/src/Y2CCGtk.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/Y2CCGtk.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/Y2CCGtk.cc (added) +++ trunk/gtk/unstable/src/Y2CCGtk.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,68 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <YGUI.h> +#include <YUIComponent.h> +#include <ycp/y2log.h> + +#if YAST2_VERSION >= 2015006 +// New UI plugin work +# include <Y2CCUI.h> +# define NEW_UI_PLUGIN +# define Y2CCUI_INIT +#else +# define Y2CCUI Y2ComponentCreator +# define Y2CCUI_INIT Y2ComponentBroker::BUILTIN +#endif + +class YGUIComponent : public YUIComponent +{ +public: + + YGUIComponent() : YUIComponent() {} + + virtual string name() const { return "gtk"; } + + virtual YUI *createUI (int argc, char **argv, + bool with_threads, const char * macro_file) + { +#ifdef IMPL_DEBUG + fprintf (stderr, "Create a gtk+ UI: %d '%s' !\n", with_threads, macro_file); +#endif + return new YGUI (argc, argv, with_threads, macro_file); + } +}; + +class Y2CCGtk : public Y2CCUI +{ +public: + Y2CCGtk () : Y2CCUI (Y2CCUI_INIT) { }; + + bool isServerCreator () const { return true; }; + + Y2Component *create (const char * name) const + { + y2milestone( "Creating %s component", name ); + if (!strcmp (name, "gtk") ) { +#ifdef NEW_UI_PLUGIN + Y2Component* ret = YUIComponent::uiComponent (); + if (!ret || ret->name () != name) { + y2debug ("UI component is %s, creating %s", ret? ret->name().c_str() : "NULL", name); + ret = new YGUIComponent(); + } + return ret; +#else + return new YGUIComponent(); +#endif + } + else + return 0; + } +}; + +// Singleton plugin registration instance. +Y2CCGtk g_y2ccgtk; + + Added: trunk/gtk/unstable/src/YGBarGraph.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGBarGraph.cc?re... ============================================================================== --- trunk/gtk/unstable/src/YGBarGraph.cc (added) +++ trunk/gtk/unstable/src/YGBarGraph.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,193 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" +#include "ygtkbargraph.h" + +#include "YBarGraph.h" + +class YGBarGraph : public YBarGraph, public YGWidget +{ +public: + YGBarGraph (const YWidgetOpt &opt, YGWidget *parent) + : YBarGraph (opt) + , YGWidget (this, parent, true, YGTK_TYPE_BAR_GRAPH, NULL) + { } + + // YBarGraph + virtual void doUpdate() + { + ygtk_bar_graph_create_entries (YGTK_BAR_GRAPH (getWidget()), segments()); + for (int i = 0; i < segments(); i++) + ygtk_bar_graph_setup_entry (YGTK_BAR_GRAPH (getWidget()), i, + label(i).c_str(), value(i)); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createBarGraph (YWidget *parent, YWidgetOpt &opt) +{ + return new YGBarGraph (opt, YGWidget::get (parent)); +} + +#include "YPartitionSplitter.h" + +class YGPartitionSplitter : public YPartitionSplitter, public YGWidget +{ +public: + YGtkBarGraph *m_barGraph; + bool m_showDelta; + GtkWidget *m_scale, *m_free_spin, *m_new_spin; + string m_freeLabel, m_newPartLabel; + + YGPartitionSplitter (const YWidgetOpt &opt, YGWidget *parent, + int _usedSize, int _totalFreeSize, int _newPartSize, + int _minNewPartSize, int _minFreeSize, + const YCPString &usedLabel, const YCPString &freeLabel, + const YCPString &newPartLabel, const YCPString &freeFieldLabel, + const YCPString &newPartFieldLabel) + : YPartitionSplitter (opt, _usedSize, _totalFreeSize, _newPartSize, + _minNewPartSize, _minFreeSize, usedLabel, + freeLabel, newPartLabel, freeFieldLabel, + newPartFieldLabel) + , YGWidget (this, parent, true, GTK_TYPE_VBOX, NULL) + { + /* Bar graph widget */ + GtkWidget *graph = ygtk_bar_graph_new(); + m_barGraph = YGTK_BAR_GRAPH (graph); + ygtk_bar_graph_create_entries (m_barGraph, 3); + ygtk_bar_graph_setup_entry (m_barGraph, 0, usedLabel->value_cstr(), + usedSize()); + m_freeLabel = freeLabel->value(); + m_newPartLabel = newPartLabel->value(); + // the others are setup-ed on SetValue() + + /* Labels over the slider */ + GtkWidget *labels_box, *free_label, *new_part_label; + labels_box = gtk_hbox_new (FALSE, 0); + free_label = gtk_label_new (freeFieldLabel->value_cstr()); + new_part_label = gtk_label_new (newPartFieldLabel->value_cstr()); + gtk_box_pack_start (GTK_BOX (labels_box), free_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (labels_box), new_part_label, FALSE, FALSE, 0); + + /* Slider and the spinners */ + m_showDelta = opt.countShowDelta.value(); + + GtkWidget *slider_box = gtk_hbox_new (FALSE, 0); + m_scale = gtk_hscale_new_with_range (minFreeSize(), maxFreeSize(), 1); + gtk_scale_set_draw_value (GTK_SCALE (m_scale), FALSE); + m_free_spin = gtk_spin_button_new_with_range + (minFreeSize(), maxFreeSize(), 1); + m_new_spin = gtk_spin_button_new_with_range + (minNewPartSize(), maxNewPartSize(), 1); + + gtk_box_pack_start (GTK_BOX (slider_box), m_free_spin, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (slider_box), m_scale, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (slider_box), m_new_spin, FALSE, FALSE, 0); + + g_signal_connect (G_OBJECT (m_scale), "value-changed", + G_CALLBACK (scale_changed_cb), this); + g_signal_connect (G_OBJECT (m_free_spin), "value-changed", + G_CALLBACK (free_spin_changed_cb), this); + g_signal_connect (G_OBJECT (m_new_spin), "value-changed", + G_CALLBACK (new_spin_changed_cb), this); + + /* Main layout */ + gtk_box_pack_start (GTK_BOX (getWidget()), graph, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (getWidget()), labels_box, FALSE, TRUE, 2); + gtk_box_pack_start (GTK_BOX (getWidget()), slider_box, FALSE, TRUE, 2); + + setValue (newPartSize()); // initialization + gtk_widget_show_all (getWidget()); + } + + // YPartitionSplitter + virtual void setValue (int newValue) + { + IMPL + YPartitionSplitter::setValue (newValue); + + ygtk_bar_graph_setup_entry (m_barGraph, 1, m_freeLabel.c_str(), + remainingFreeSize()); + ygtk_bar_graph_setup_entry (m_barGraph, 2, m_newPartLabel.c_str(), + newPartSize()); + + // block connections + g_signal_handlers_block_by_func (m_scale, + (gpointer) scale_changed_cb, this); + g_signal_handlers_block_by_func (m_free_spin, + (gpointer) free_spin_changed_cb, this); + g_signal_handlers_block_by_func (m_new_spin, + (gpointer) new_spin_changed_cb, this); + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_free_spin), + remainingFreeSize()); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_new_spin), + newPartSize()); + gtk_range_set_value (GTK_RANGE (m_scale), remainingFreeSize()); + + // unblock connections + g_signal_handlers_unblock_by_func (m_scale, + (gpointer) scale_changed_cb, this); + g_signal_handlers_unblock_by_func (m_free_spin, + (gpointer) free_spin_changed_cb, this); + g_signal_handlers_unblock_by_func (m_new_spin, + (gpointer) new_spin_changed_cb, this); + } + + static void scale_changed_cb (GtkRange *range, YGPartitionSplitter *pThis) + { + IMPL + int newFreeSize = (int) gtk_range_get_value (range); + int newPartSize = pThis->totalFreeSize() - newFreeSize; + if (pThis->m_showDelta) + newPartSize += pThis->usedSize(); + + pThis->setValue (newPartSize); + pThis->emitEvent (YEvent::ValueChanged); + } + + static void free_spin_changed_cb (GtkSpinButton *spin, YGPartitionSplitter *pThis) + { + IMPL + int newFreeSize = gtk_spin_button_get_value_as_int (spin); + int newPartSize = pThis->totalFreeSize() - newFreeSize; + if (pThis->m_showDelta) + newPartSize += pThis->usedSize(); + + pThis->setValue (newPartSize); + pThis->emitEvent (YEvent::ValueChanged); + } + + static void new_spin_changed_cb (GtkSpinButton *spin, YGPartitionSplitter *pThis) + { + IMPL + if (pThis->m_showDelta) + pThis->setValue (pThis->remainingFreeSize() - pThis->totalFreeSize()); + else + pThis->setValue (gtk_spin_button_get_value_as_int (spin)); + pThis->emitEvent (YEvent::ValueChanged); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createPartitionSplitter (YWidget *parent, YWidgetOpt &opt, + int usedSize, int totalFreeSize, int newPartSize, + int minNewPartSize, int minFreeSize, + const YCPString &usedLabel,const YCPString &freeLabel, + const YCPString &newPartLabel, + const YCPString &freeFieldLabel, + const YCPString &newPartFieldLabel) +{ + return new YGPartitionSplitter (opt, YGWidget::get (parent), usedSize, + totalFreeSize, newPartSize, minNewPartSize, minFreeSize, usedLabel, + freeLabel, newPartLabel, freeFieldLabel, newPartFieldLabel); +} Added: trunk/gtk/unstable/src/YGComboBox.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGComboBox.cc?re... ============================================================================== --- trunk/gtk/unstable/src/YGComboBox.cc (added) +++ trunk/gtk/unstable/src/YGComboBox.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,156 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YComboBox.h" +#include "YGWidget.h" + +class YGComboBox : public YComboBox, public YGLabeledWidget +{ +bool m_showingIcons; + + public: + YGComboBox (const YWidgetOpt &opt, YGWidget *parent, YCPString label) + : YComboBox (opt, label) + , YGLabeledWidget (this, parent, label, YD_HORIZ, true, + opt.isEditable.value() ? GTK_TYPE_COMBO_BOX_ENTRY : GTK_TYPE_COMBO_BOX, NULL) + { + // pixbufs will be enabled if icons are provided + m_showingIcons = false; + + GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, GDK_TYPE_PIXBUF); + gtk_combo_box_set_model (GTK_COMBO_BOX (getWidget()), GTK_TREE_MODEL (store)); + g_object_unref (store); + + if(opt.isEditable.value()) + gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (getWidget()), 0); + else { + GtkCellRenderer* cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (getWidget()), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (getWidget()), cell, + "text", 0, NULL); + } + + g_signal_connect (G_OBJECT (getWidget()), "changed", + G_CALLBACK (selected_changed_cb), this); + } + + GtkComboBox *getComboBox() const + { + return GTK_COMBO_BOX ((const_cast<YGComboBox *>(this)->getWidget())); + } + + GtkEntry *getEntry() + { + if (!GTK_IS_COMBO_BOX_ENTRY (getWidget())) { + y2error ("YGComboBox: trying to edit read-only combo box"); + return NULL; + } + + GtkWidget *entry = gtk_bin_get_child (GTK_BIN (getWidget())); + if (!GTK_IS_ENTRY (entry)) { + g_error ("YGComboBox: GtkComboBoxEntry doesn't have a GtkEntry as child"); + return NULL; + } + + return GTK_ENTRY (entry); + } + + virtual void itemAdded (const YCPString &string, int index, bool selected) + { + GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (getComboBox())); + GtkTreeIter iter; + gtk_list_store_insert (store, &iter, index); + gtk_list_store_set (store, &iter, 0, string->value_cstr(), -1); + + if(hasIcons() && !m_showingIcons) { + GtkCellRenderer* cell = gtk_cell_renderer_pixbuf_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (getWidget()), cell, FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (getWidget()), cell, + "pixbuf", 1, NULL); + m_showingIcons = true; + } + + if (hasIcons() && !itemIcon (index)->value().empty()) { + std::string path = itemIcon (index)->value(); + if (path[0] != '/') + path = ICON_DIR + path; + + GdkPixbuf *pixbuf; + GError *error = 0; + pixbuf = gdk_pixbuf_new_from_file (path.c_str(), &error); + if (!pixbuf) + y2warning ("YGComboBox: Could not load icon: %s.\n" + "Because %s", path.c_str(), error->message); + gtk_list_store_set (store, &iter, 1, pixbuf, -1); + } + + if (selected || index == 0) + setCurrentItem (index); + } + + virtual void setValue (const YCPString &value) + { + IMPL + gtk_entry_set_text (getEntry(), value->value_cstr()); + } + + virtual YCPString getValue() const + { + return YCPString (gtk_combo_box_get_active_text (getComboBox())); + } + + virtual int getCurrentItem() const + { + return gtk_combo_box_get_active (getComboBox()); + } + + virtual void setCurrentItem (int index) + { + g_signal_handlers_block_by_func (getWidget(), (gpointer) selected_changed_cb, this); + gtk_combo_box_set_active (GTK_COMBO_BOX(getWidget()), index); + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) selected_changed_cb, this); + } + + virtual void setInputMaxLength (const YCPInteger &numberOfChars) + { + gtk_entry_set_width_chars (getEntry(), numberOfChars->asInteger()->value()); + } + + // Events notifications + static void selected_changed_cb (GtkComboBox *widget, YGComboBox *pThis) + { + /* selected_changed_cb() is called when a new item was selected or the user has + typed some text on a writable ComboBox. text_changed is true for the later and + false for the former. */ + bool text_changed = GTK_IS_COMBO_BOX_ENTRY (widget) + && pThis->getCurrentItem() == -1; + + if (text_changed) { + g_signal_handlers_block_by_func (pThis->getWidget(), (gpointer) + selected_changed_cb, pThis); + YGUtils::filterText (GTK_EDITABLE (pThis->getEntry()), 0, -1, + pThis->getValidChars()->value_cstr()); + g_signal_handlers_unblock_by_func (pThis->getWidget(), (gpointer) + selected_changed_cb, pThis); + + pThis->emitEvent (YEvent::ValueChanged, true, true); + } + else + pThis->emitEvent (YEvent::SelectionChanged, true, true); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YComboBox) +}; + +YWidget * +YGUI::createComboBox (YWidget *parent, YWidgetOpt & opt, + const YCPString & label) +{ + return new YGComboBox (opt, YGWidget::get (parent), label); +} Added: trunk/gtk/unstable/src/YGDialog.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGDialog.cc?rev=... ============================================================================== --- trunk/gtk/unstable/src/YGDialog.cc (added) +++ trunk/gtk/unstable/src/YGDialog.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,379 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGDialog.h" +#include <gdk/gdkkeysyms.h> +#include <math.h> // easter + +/* In the main dialog case (when opt.hasDefaultSize is set), it doesn't + necessarly have a window of its own. If there is already a main window, it + should replace its content -- and when closed, the previous dialog restored. + + Therefore, we have a YGDialog (the YDialog implementation), and a YGWindow + that does the windowing work and has a YWidget has its children, which can + be a YGDialog and is swap-able. +*/ + +class YGWindow; +static YGWindow *main_window = NULL; + +YGWindow::~YGWindow() +{ + IMPL + setChild (NULL); + gtk_widget_destroy (m_widget); + g_object_unref (G_OBJECT (m_widget)); +} + +void YGWindow::setChild (YWidget *new_child) +{ + IMPL + GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget)); + if (child) + gtk_container_remove (GTK_CONTAINER (m_widget), child); + if (new_child) { + child = YGWidget::get (new_child)->getLayout(); + gtk_container_add (GTK_CONTAINER (m_widget), child); + } + m_child = new_child; +} + +void YGWindow::ref (YGWindow *window) +{ + window->m_refcount++; +} +void YGWindow::unref (YGWindow *window) +{ + if (--window->m_refcount == 0) { + bool is_main_window = (window == main_window); + delete window; + if (is_main_window) + main_window = NULL; + } +} + +static gboolean draw_border_cb (GtkWidget *widget, GdkEventExpose *event, + YGWindow *pThis) +{ + IMPL + // to avoid background from overlapping, we emit the expose to the containee + // ourselves + gtk_container_propagate_expose (GTK_CONTAINER (widget), + gtk_bin_get_child (GTK_BIN (widget)), + event); + + GtkAllocation *alloc = &widget->allocation; + gtk_draw_shadow (gtk_widget_get_style (widget), widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT, + alloc->x, alloc->y, alloc->width, alloc->height); + return TRUE; +} + +static gboolean expode_window_timeout_cb (gpointer data) +{ + GtkWindow *window = YGUI::ui()->currentWindow(); + if (!window) + return FALSE; + srand (time (NULL)); + gint x, y; + gtk_window_get_position (window, &x, &y); +#if 0 + // OVAL MOVE + for (int i = 180; i < 360+180; i++) { + gtk_window_move (window, x+(int)(sin((i*G_PI)/180)*50), + y+(int)(cos((i*G_PI)/180)*50)+50); + while (gtk_events_pending()) + gtk_main_iteration(); + usleep (25); + } +#else + // EXPLOSION + for (int i = 0; i < 40; i++) { + gtk_window_move (window, x+(int)((((float)(rand())/RAND_MAX)*40)-20), + y+(int)((((float)(rand())/RAND_MAX)*40)-20)); + while (gtk_events_pending()) + gtk_main_iteration(); + usleep (200); + } +#endif + gtk_window_move (window, x, y); + return TRUE; +} + +gboolean YGWindow::close_window_cb (GtkWidget *widget, GdkEvent *event, + YGWindow *pThis) +{ + IMPL + // never let GTK+ destroy the window! just inform YCP, and let it + // do its thing. + pThis->closeWindow(); + return TRUE; +} + +void YGWindow::closeWindow() +{ + if (!m_canClose || m_canClose (m_canCloseData)) + YGUI::ui()->sendEvent (new YCancelEvent()); +} + +static gboolean key_pressed_cb (GtkWidget *widget, GdkEventKey *event, + YGWindow *pThis) +{ + IMPL + // if not main dialog, close it on escape + if (event->keyval == GDK_Escape && + /* not main window */ main_window != pThis) + { + pThis->closeWindow(); + return TRUE; + + } + + if (event->state & GDK_SHIFT_MASK) { + switch (event->keyval) { + case GDK_F8: + YGUI::ui()->askSaveLogs(); + return TRUE; + default: + break; + } + } + if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK) + && (event->state & GDK_MOD1_MASK)) { + y2milestone ("Caught YaST2 magic key combination"); + switch (event->keyval) { + case GDK_S: + YGUI::ui()->makeScreenShot(""); + return TRUE; + case GDK_M: + YGUI::ui()->toggleRecordMacro(); + return TRUE; + case GDK_P: + YGUI::ui()->askPlayMacro(); + return TRUE; + case GDK_D: + YGUI::ui()->sendEvent (new YDebugEvent()); + return TRUE; + case GDK_X: + y2milestone ("Starting xterm"); + system ("/usr/bin/xterm &"); + return TRUE; + case GDK_T: + dumpYastTree (pThis->getChild()); + return TRUE; + case GDK_H: + dumpYastHtml (pThis->getChild()); + return TRUE; + case GDK_E: // easter egg + static guint explode_timeout = 0; + if (explode_timeout == 0) + explode_timeout = g_timeout_add (10000, + expode_window_timeout_cb, NULL); + else { + g_source_remove (explode_timeout); + explode_timeout = 0; + } + return TRUE; + default: + break; + } + } + return FALSE; +} + +YGWindow::YGWindow (bool main_window) +{ + m_widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_object_ref (G_OBJECT (m_widget)); + gtk_object_sink (GTK_OBJECT (m_widget)); + + m_refcount = 0; + if (main_window) + ::main_window = this; + m_child = NULL; + m_canClose = NULL; + + { + GtkWindow *parent = YGUI::ui()->currentWindow(); + GtkWindow *window = GTK_WINDOW (m_widget); + + if (parent) { + // if there is a parent, this would be a dialog + gtk_window_set_title (window, ""); + gtk_window_set_modal (window, TRUE); + gtk_window_set_transient_for (window, parent); + gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DIALOG); + //gtk_window_set_focus_on_map (window, FALSE); + } + else { + gtk_window_set_title (window, "YaST"); + if (YGUI::ui()->unsetBorder()) + gtk_window_set_decorated (window, FALSE); + } + + if (main_window) { + int w = YGUI::ui()->getDefaultSize (YD_HORIZ), + h = YGUI::ui()->getDefaultSize (YD_VERT); + gtk_window_set_default_size (window, w, h); + } + + gtk_window_set_role (window, "yast-gtk"); + if (!YGUI::ui()->hasWM()) + g_signal_connect (G_OBJECT (m_widget), "expose-event", + G_CALLBACK (draw_border_cb), this); + } + + g_signal_connect (G_OBJECT (m_widget), "delete-event", + G_CALLBACK (close_window_cb), this); + g_signal_connect_after (G_OBJECT (m_widget), "key-press-event", + G_CALLBACK (key_pressed_cb), this); +} + +void YGWindow::setCloseCallback (YGWindowCloseFn canClose, void *canCloseData) +{ + m_canClose = canClose; + m_canCloseData = canCloseData; +} + +void YGWindow::unsetCloseCallback() +{ + m_canClose = NULL; +} + +YGDialog::YGDialog (YWidgetOpt &opt) + : YDialog (opt), + YGWidget (this, NULL, FALSE, GTK_TYPE_HBOX, NULL) +{ + setBorder (0); + m_padding = 0; + m_containee = gtk_event_box_new(); + if (hasDefaultSize() && main_window) + m_window = main_window; + else + m_window = new YGWindow (hasDefaultSize()); + YGWindow::ref (m_window); + + if (hasWarnColor() || hasInfoColor()) { + // emulate a warning / info dialog + GtkWidget *icon = gtk_image_new_from_stock + (hasWarnColor() ? GTK_STOCK_DIALOG_WARNING : GTK_STOCK_DIALOG_INFO, + GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0); + gtk_misc_set_padding (GTK_MISC (icon), 0, 12); + + gtk_box_pack_start (GTK_BOX (getWidget()), icon, FALSE, FALSE, 12); + gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0); + + GtkRequisition req; + gtk_widget_size_request (icon, &req); + m_padding = req.width + 24; + } + else + gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0); + gtk_widget_show_all (getWidget()); + + // NOTE: we need to add this containter to the window right here, else + // weird stuff happens (like if we set a pango font description to a + // GtkLabel, size request would output the size without that description + // set...) + m_window->setChild (this); +} + +YGDialog::~YGDialog() +{ + YGWindow::unref (m_window); +} + +void YGDialog::showWindow() +{ + IMPL + m_window->setChild (this); + gtk_widget_show (m_window->getWidget()); + YGUI::ui()->busyCursor(); +} + +void YGDialog::hideWindow() +{ + IMPL + m_window->setChild (NULL); + gtk_widget_hide (m_window->getWidget()); +} + +YDialog * +YGUI::createDialog (YWidgetOpt &opt) +{ + IMPL + return new YGDialog (opt); +} + +static list <YGDialog *> dialogs_stack; + +void +YGUI::showDialog (YDialog *_dialog) +{ + IMPL + YGDialog *dialog = static_cast <YGDialog *> (_dialog); + if (dialog->hasDefaultSize()) + dialogs_stack.push_back (dialog); + dialog->showWindow(); +} + +void +YGUI::closeDialog (YDialog *_dialog) +{ + IMPL + YGDialog *dialog = static_cast <YGDialog *> (_dialog); + if (dialog->hasDefaultSize()) { + dialogs_stack.pop_back(); + if (!dialogs_stack.empty()) { + YGDialog *old_dialog = dialogs_stack.back(); + old_dialog->showWindow(); + } + else + dialog->hideWindow(); + } + else + dialog->hideWindow(); +} + +GtkWindow * +YGUI::currentWindow() +{ + YDialog *ydialog = YGUI::ui()->currentDialog(); + if (ydialog) + return static_cast<YGDialog *>(ydialog)->getWindow(); + else + return NULL; +} + +YGDialog * +YGUI::currentYGDialog() +{ + YDialog *ydialog = YGUI::ui()->currentDialog(); + if (ydialog) + return static_cast<YGDialog *>(ydialog); + else + return NULL; +} + +void YGDialog::busyCursor() +{ + // NOTE: GdkDisplay won't change for new dialogs, so we don't + // have to synchronize between them or something. + static GdkCursor *cursor = NULL; + if (!cursor) { + GdkDisplay *display = gtk_widget_get_display (m_window->getWidget()); + cursor = gdk_cursor_new_for_display (display, GDK_WATCH); + } + gdk_window_set_cursor (m_window->getWidget()->window, cursor); +} + +void YGDialog::normalCursor() +{ + gdk_window_set_cursor (m_window->getWidget()->window, NULL); +} + Added: trunk/gtk/unstable/src/YGDialog.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGDialog.h?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGDialog.h (added) +++ trunk/gtk/unstable/src/YGDialog.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,70 @@ +#ifndef YGDIALOG_H +#define YGDIALOG_H + +#include "YGWidget.h" +#include "YDialog.h" + +typedef bool (*YGWindowCloseFn) (void *closure); + +class YGWindow +{ + GtkWidget *m_widget; + int m_refcount; + // we keep a pointer of the child just for debugging + // (ie. dump yast tree) + YWidget *m_child; + YGWindowCloseFn m_canClose; + void *m_canCloseData; + +private: + static gboolean close_window_cb (GtkWidget *widget, GdkEvent *event, + YGWindow *pThis); +public: + YGWindow (bool main_window); + ~YGWindow(); + void setChild (YWidget *new_child); + static void ref (YGWindow *window); + static void unref (YGWindow *window); + + void normalCursor(); + void busyCursor(); + + void setCloseCallback (YGWindowCloseFn canClose, void *canCloseData); + void unsetCloseCallback(); + void closeWindow(); + + // Y(G)Widget-like methods + GtkWidget *getWidget() { return m_widget; } + YWidget *getChild() { return m_child; } +}; + +class YGDialog : public YDialog, public YGWidget +{ + int m_padding; + GtkWidget *m_containee; + + YGWindow *m_window; + +public: + YGDialog (YWidgetOpt &opt); + virtual ~YGDialog(); + void showWindow(); + void hideWindow(); + GtkWindow *getWindow() { return GTK_WINDOW (m_window->getWidget()); } + + void setCloseCallback (YGWindowCloseFn closeCallback, void *closeData) + { m_window->setCloseCallback (closeCallback, closeData); } + void unsetCloseCallback() + { m_window->unsetCloseCallback(); } + + void normalCursor(); + void busyCursor(); + + YGWIDGET_IMPL_COMMON + + YGWIDGET_IMPL_CHILD_ADDED (m_containee) + YGWIDGET_IMPL_CHILD_REMOVED (m_containee) +}; + +#endif // YGDIALOG_H + Added: trunk/gtk/unstable/src/YGDumbTab.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGDumbTab.cc?rev... ============================================================================== --- trunk/gtk/unstable/src/YGDumbTab.cc (added) +++ trunk/gtk/unstable/src/YGDumbTab.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,118 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" +#include "YGUtils.h" +#include "YDumbTab.h" + +#include "ygtkratiobox.h" + +class YGDumbTab : public YDumbTab, public YGWidget +{ + GtkWidget *m_containee; + GtkWidget *m_last_tab; + vector <GtkWidget *> m_tab_widgets; + +public: + YGDumbTab (const YWidgetOpt &opt, YGWidget *parent) + : YDumbTab (opt), + YGWidget (this, parent, true, GTK_TYPE_NOTEBOOK, NULL) + { + IMPL + m_containee = gtk_event_box_new(); + gtk_widget_show (m_containee); + g_object_ref (G_OBJECT (m_containee)); + gtk_object_sink (GTK_OBJECT (m_containee)); + + m_last_tab = 0; + // GTK+ keeps the notebook size set to the biggset page. We can't + // do this since this is dynamic, but at least don't let the notebook + // reduce its size. + ygtk_adj_size_set_only_expand (YGTK_ADJ_SIZE (m_adj_size), TRUE); + + g_signal_connect (G_OBJECT (getWidget()), "switch-page", + G_CALLBACK (changed_tab_cb), this); + } + + ~YGDumbTab() + { + IMPL + gtk_widget_destroy (m_containee); + g_object_unref (G_OBJECT (m_containee)); + } + + virtual void addTab (const YCPString &label_text) + { + IMPL + // the tab label + string str = YGUtils::mapKBAccel (label_text->value_cstr()); + GtkWidget *label = gtk_label_new (str.c_str()); + gtk_widget_show (label); + + GtkNotebook *notebook = GTK_NOTEBOOK (getWidget()); + g_signal_handlers_block_by_func (notebook, (gpointer) changed_tab_cb, this); + + GtkWidget *empty = gtk_event_box_new(); + gtk_widget_show (empty); + + gtk_notebook_append_page (notebook, empty, label); + m_tab_widgets.push_back (empty); + + if (!m_last_tab) + change_tab (0); + + g_signal_handlers_unblock_by_func (notebook, (gpointer) changed_tab_cb, this); + } + + // to re-use the same widget in all tabs (m_fixed), we will remove and + // add to the tabs' child as tabs are changed + void change_tab (int tab_nb) + { + if (m_last_tab) + gtk_container_remove (GTK_CONTAINER (m_last_tab), m_containee); + + GtkWidget *tab = m_tab_widgets [tab_nb]; + gtk_container_add (GTK_CONTAINER (tab), m_containee); + m_last_tab = tab; + } + + virtual int getSelectedTabIndex() + { + IMPL + return gtk_notebook_get_current_page (GTK_NOTEBOOK (getWidget())); + } + + virtual void setSelectedTab (int index) + { + IMPL + change_tab (index); + + g_signal_handlers_block_by_func (getWidget(), (gpointer) changed_tab_cb, this); + gtk_notebook_set_current_page (GTK_NOTEBOOK (getWidget()), index); + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) changed_tab_cb, this); + } + + static void changed_tab_cb (GtkNotebook *notebook, GtkNotebookPage *page, + gint tab_nb, YGDumbTab *pThis) + { + YCPValue id = pThis->_tabs[tab_nb].id(); + YGUI::ui()->sendEvent (new YMenuEvent (id)); + + pThis->change_tab (tab_nb); + } + + YGWIDGET_IMPL_COMMON + YGWIDGET_IMPL_CHILD_ADDED (m_containee) + YGWIDGET_IMPL_CHILD_REMOVED (m_containee) +}; + +YWidget * +YGUI::createDumbTab (YWidget *parent, YWidgetOpt &opt) +{ + IMPL + return new YGDumbTab (opt, YGWidget::get (parent)); +} Added: trunk/gtk/unstable/src/YGFrame.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGFrame.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGFrame.cc (added) +++ trunk/gtk/unstable/src/YGFrame.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,171 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include "YGUI.h" +#include "YGWidget.h" +#include "YGUtils.h" + +// Instead of traditional looking frames, we use Gnome convention for the +// frame's look. That is: don't draw a frame, use bold header and pad the child. +#define CHILD_INDENTATION 15 + +class YGBaseFrame : public YGWidget +{ +protected: +// a GtkAlignment to set some indentation on the child +GtkWidget *m_containee; + +public: + YGBaseFrame (YWidget *y_widget, YGWidget *parent) + : YGWidget (y_widget, parent, true, GTK_TYPE_FRAME, + "shadow-type", GTK_SHADOW_NONE, NULL) + { + IMPL + m_containee = gtk_alignment_new (0, 0, 1, 1); + gtk_alignment_set_padding (GTK_ALIGNMENT (m_containee), 0, 0, 15, 0); + gtk_widget_show (m_containee); + gtk_container_add (GTK_CONTAINER (getWidget()), m_containee); + } + virtual ~YGBaseFrame() {} +}; + +#include "YFrame.h" + +class YGFrame : public YFrame, public YGBaseFrame +{ +public: + YGFrame (const YWidgetOpt &opt, YGWidget *parent, const YCPString &label) + : YFrame (opt, label), + YGBaseFrame (this, parent) + { + GtkWidget *label_widget = gtk_label_new (""); + YGUtils::setWidgetFont (GTK_WIDGET (label_widget), PANGO_WEIGHT_BOLD, + PANGO_SCALE_MEDIUM); + gtk_widget_show (label_widget); + gtk_frame_set_label_widget (GTK_FRAME (getWidget()), label_widget); + setLabel (label); + } + + virtual ~YGFrame() {} + + // YFrame + virtual void setLabel (const YCPString &_str) + { + IMPL + /* Get rid of mnemonics; make no sense here. */ + const char *_cstr = _str->value_cstr(); + size_t _clen = strlen (_cstr); + + string str; + str.reserve (_clen); + for (size_t i = 0; i < _clen; i++) + if (_cstr[i] != '&') + str += _cstr[i]; + + GtkWidget *label = gtk_frame_get_label_widget (GTK_FRAME (getWidget())); + gtk_label_set_text (GTK_LABEL (label), str.c_str()); + + YFrame::setLabel (_str); + } + + YGWIDGET_IMPL_COMMON + YGWIDGET_IMPL_CHILD_ADDED (m_containee) + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) +}; + +YContainerWidget * +YGUI::createFrame (YWidget *parent, YWidgetOpt &opt, + const YCPString &label) +{ + IMPL + return new YGFrame (opt, YGWidget::get (parent), label); +} + +#if YAST2_YGUI_CHECKBOX_FRAME +#include "YCheckBoxFrame.h" + +class YGCheckBoxFrame : public YCheckBoxFrame, public YGBaseFrame +{ +public: + YGCheckBoxFrame (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, bool checked) + : YCheckBoxFrame (opt, label), + YGBaseFrame (this, parent) + { + IMPL + GtkWidget *button = gtk_check_button_new_with_mnemonic(""); + YGUtils::setWidgetFont (GTK_WIDGET (button), PANGO_WEIGHT_BOLD, + PANGO_SCALE_MEDIUM); + gtk_widget_show_all (button); + gtk_frame_set_label_widget (GTK_FRAME (getWidget()), button); + + setLabel (label); + setValue (checked); + g_signal_connect (G_OBJECT (button), "toggled", + G_CALLBACK (toggled_cb), this); + } + virtual ~YGCheckBoxFrame() {} + + // YCheckBoxFrame + virtual void setLabel (const YCPString &_str) + { + GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget())); + GtkLabel *label = GTK_LABEL (GTK_BIN (button)->child); + + string str (YGUtils::mapKBAccel (_str->value_cstr())); + gtk_label_set_text_with_mnemonic (label, str.c_str()); + YCheckBoxFrame::setLabel (_str); + } + + bool getValue() + { + GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget())); + return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + } + + void setValue (bool newValue) + { + GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget())); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), newValue); + } + + virtual void setEnabling (bool enabled) + { + GtkWidget *frame = getWidget(); + if (enabled) + { + gtk_widget_set_sensitive (frame, TRUE); + handleChildrenEnablement (getValue()); + } + else + { + setChildrenEnabling( false ); + gtk_widget_set_sensitive (frame, FALSE); + } + } + + YGWIDGET_IMPL_CHILD_ADDED (m_containee) + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) + +private: + static void toggled_cb (GtkWidget *widget, YGCheckBoxFrame *pThis) + { + pThis->setEnabling (true); + if (pThis->getNotify()) + YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::ValueChanged)); + } +}; + +YContainerWidget * +YGUI::createCheckBoxFrame (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, bool checked) +{ + IMPL + return new YGCheckBoxFrame (opt, YGWidget::get (parent), label, checked); +} + +#else +# warning "Not compiling CheckBoxFrame..." +#endif /*YAST2_YGUI_CHECKBOX_FRAME*/ Added: trunk/gtk/unstable/src/YGImage.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGImage.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGImage.cc (added) +++ trunk/gtk/unstable/src/YGImage.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,287 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include "ygdkmngloader.h" +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YEvent.h" +#include "YGWidget.h" +#include "YImage.h" + +class YGImage : public YImage, public YGWidget +{ + bool m_hasZeroWidth, m_hasZeroHeight, m_isScaled, m_isTiled, m_isAnimation; + bool m_imageLoaded; + + struct Animation { + GdkPixbufAnimation *pixbuf; + GdkPixbufAnimationIter *frame; + guint timeout_id; + }; + union { + GdkPixbuf *m_pixbuf; + Animation *m_animation; + }; + gchar *alt_text; + + void initOptions (const YWidgetOpt &opt) + { + IMPL + m_imageLoaded = false; + m_hasZeroWidth = opt.zeroWidth.value(); + m_hasZeroHeight = opt.zeroHeight.value(); + m_isAnimation = opt.animated.value(); + m_isScaled = opt.scaleToFit.value(); + m_isTiled = opt.tiled.value(); + + if (m_hasZeroWidth || m_isScaled || m_isTiled) + setStretchable (YD_HORIZ, true); + if (m_hasZeroHeight || m_isScaled || m_isTiled) + setStretchable (YD_VERT, true); + + if (m_isScaled && m_isTiled) { + y2warning ("YImage can't be scaled and tiled at the same time"); + m_isTiled = false; + } + + if (m_isAnimation) + m_animation = NULL; + else + m_pixbuf = NULL; + + g_signal_connect (G_OBJECT (getWidget()), "expose-event", + G_CALLBACK (expose_event_cb), this); + gtk_widget_queue_draw (getWidget()); + } + + void loadImage (GdkPixbuf *pixbuf, const char *error_msg) + { + IMPL + if (pixbuf == NULL) { + g_warning ("Couldn't load image - %s", error_msg); + return; + } + + m_imageLoaded = true; + m_pixbuf = pixbuf; + gtk_widget_set_size_request (getWidget(), m_hasZeroWidth ? -1 : gdk_pixbuf_get_width (pixbuf), + m_hasZeroHeight ? -1 : gdk_pixbuf_get_height (pixbuf)); + } + + void loadAnimation (GdkPixbufAnimation *pixbuf, const char *error_msg) + { + IMPL + if (pixbuf == NULL) { + g_warning ("Couldn't load animation - %s", error_msg); + return; + } + + m_imageLoaded = true; + m_animation = new Animation; + m_animation->pixbuf = pixbuf; + + m_animation->frame = NULL; + advance_frame_cb (this); + + g_signal_connect (G_OBJECT (getWidget()), "expose-event", + G_CALLBACK (expose_event_cb), this); + gtk_widget_queue_draw (getWidget()); + } + +public: + YGImage (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &filename_str, const YCPString &text) + : YImage (opt), + YGWidget (this, parent, true, GTK_TYPE_DRAWING_AREA, NULL) + { + IMPL + alt_text = g_strdup (text->value_cstr()); + initOptions (opt); + + const char *filename = filename_str->value_cstr(); + GError *error = 0; + if (m_isAnimation) { + GdkPixbufAnimation *pixbuf; + if (ygdk_mng_pixbuf_is_file_mng (filename)) + pixbuf = ygdk_mng_pixbuf_new_from_file (filename, &error); + else + pixbuf = gdk_pixbuf_animation_new_from_file (filename, &error); + loadAnimation (pixbuf, error ? error->message : "(undefined)"); + } + else { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error); + loadImage (pixbuf, error ? error->message : "(undefined)"); + } + } + + YGImage (const YWidgetOpt &opt, YGWidget *parent, + const YCPByteblock &byteblock, const YCPString &text) + : YImage (opt), + YGWidget (this, parent, true, GTK_TYPE_DRAWING_AREA, NULL) + { + IMPL + alt_text = g_strdup (text->value_cstr()); + initOptions (opt); + + GError *error = 0; + if (m_isAnimation && ygdk_mng_pixbuf_is_data_mng (byteblock->value(), byteblock->size())) + { + GdkPixbufAnimation *pixbuf; + pixbuf = ygdk_mng_pixbuf_new_from_data (byteblock->value(), byteblock->size(), &error); + loadAnimation (pixbuf, error ? error->message : "(undefined)"); + } + else + { + GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); + g_signal_connect (G_OBJECT (loader), "area-prepared", + G_CALLBACK (image_loaded_cb), this); + + if (!gdk_pixbuf_loader_write (loader, + byteblock->value(), byteblock->size(), &error)) + g_warning ("Could not load image from data blocks: %s", error->message); + gdk_pixbuf_loader_close (loader, &error); + } + } + + virtual ~YGImage() + { + IMPL + if (m_imageLoaded) { + if (m_isAnimation) { + g_object_unref (G_OBJECT (m_animation->pixbuf)); + if (m_animation->timeout_id) + g_source_remove (m_animation->timeout_id); + delete m_animation; + } + else + g_object_unref (G_OBJECT (m_pixbuf)); + } + g_free (alt_text); + } + + // callback for image loading + static void image_loaded_cb (GdkPixbufLoader *loader, YGImage *pThis) + { + IMPL + if (pThis->m_isAnimation) { + if (pThis->m_animation) { + // a new frame loaded -- just redraw the widget + if (gdk_pixbuf_animation_iter_on_currently_loading_frame + (pThis->m_animation->frame)) + gtk_widget_queue_draw (pThis->getWidget()); + } + else { + GdkPixbufAnimation *pixbuf = gdk_pixbuf_loader_get_animation (loader); + g_object_ref (G_OBJECT (pixbuf)); + pThis->loadAnimation (pixbuf, " on block data reading callback"); + } + } + else { + GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + g_object_ref (G_OBJECT (pixbuf)); + pThis->loadImage (pixbuf, " on block data reading callback"); + } + } + + // callback for image displaying + static gboolean advance_frame_cb (void *pData) + { + IMPL + YGImage *pThis = (YGImage *) pData; + Animation *animation = pThis->m_animation; + + if (!animation->frame) // no frame yet loaded + animation->frame = gdk_pixbuf_animation_get_iter (animation->pixbuf, NULL); + else + if (gdk_pixbuf_animation_iter_advance (animation->frame, NULL)) + gtk_widget_queue_draw (pThis->getWidget()); + + // shedule next frame + int delay = gdk_pixbuf_animation_iter_get_delay_time (animation->frame); + if (delay != -1) + animation->timeout_id = g_timeout_add (delay, advance_frame_cb, pThis); + + GdkPixbuf *pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (pThis->m_animation->frame); + gtk_widget_set_size_request (pThis->getWidget(), gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + return FALSE; + } + + static gboolean expose_event_cb (GtkWidget *widget, GdkEventExpose *event, + YGImage *pThis) + { + IMPL + int x, y, width, height; + x = widget->allocation.x + 6; + y = widget->allocation.y + 6; + width = widget->allocation.width; + height = widget->allocation.height; + + cairo_t *cr = gdk_cairo_create (widget->window); + + if (!pThis->m_imageLoaded) { + // show default text if no image was loaded + PangoLayout *layout; + layout = gtk_widget_create_pango_layout (widget, pThis->alt_text); + + int text_width, text_height; + pango_layout_get_size (layout, &text_width, &text_height); + text_width /= PANGO_SCALE; + text_height /= PANGO_SCALE; + + x += (width - text_width) / 2; + y += (height - text_height) / 2; + + cairo_move_to (cr, x, y); + pango_cairo_show_layout (cr, layout); + + g_object_unref (layout); + cairo_destroy (cr); + return TRUE; + } + + GdkPixbuf *pixbuf; + if (pThis->m_isAnimation) + pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (pThis->m_animation->frame); + else + pixbuf = pThis->m_pixbuf; + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); + + if (pThis->m_isTiled) + cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); + + if (pThis->m_isScaled) { + double scale_x = (double) gdk_pixbuf_get_width (pixbuf) / width; + double scale_y = (double) gdk_pixbuf_get_height (pixbuf) / height; + cairo_matrix_t matrix; + cairo_matrix_init_scale (&matrix, scale_x, scale_y); + cairo_pattern_set_matrix (cairo_get_source (cr), &matrix); + } + + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_destroy (cr); + return TRUE; + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createImage (YWidget *parent, YWidgetOpt &opt, + YCPByteblock image_data, YCPString default_text) +{ + IMPL + return new YGImage (opt, YGWidget::get (parent), image_data, default_text); +} + +YWidget * +YGUI::createImage (YWidget *parent, YWidgetOpt &opt, + YCPString file_name, YCPString default_text) +{ + IMPL + return new YGImage (opt, YGWidget::get (parent), file_name, default_text); +} Added: trunk/gtk/unstable/src/YGIntField.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGIntField.cc?re... ============================================================================== --- trunk/gtk/unstable/src/YGIntField.cc (added) +++ trunk/gtk/unstable/src/YGIntField.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,152 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YGWidget.h" + +#define SLIDER_NICESIZE_IN_CHARS 15 + +class YGSpinBox : public YGLabeledWidget +{ + GtkWidget *m_spiner, *m_slider; + +public: + YGSpinBox (YWidget *y_widget, YGWidget *parent, + const YWidgetOpt &opt, const YCPString &label, + int minValue, int maxValue, int initialValue, + bool show_slider) + : YGLabeledWidget (y_widget, parent, label, YD_HORIZ, true, + GTK_TYPE_HBOX, NULL) + { + m_spiner = gtk_spin_button_new_with_range (minValue, maxValue, 1); + + if (show_slider) { + m_slider = gtk_hscale_new_with_range (minValue, maxValue, 1); + if (maxValue - minValue < 20) + // GtkScale by default uses a step of 10 -- use a lower for low values + gtk_range_set_increments (GTK_RANGE (m_slider), 1, 2); + gtk_scale_set_draw_value (GTK_SCALE (m_slider), TRUE); + YGLabeledWidget::setBuddy (m_slider); + gtk_widget_set_size_request (m_slider, + YGUtils::getCharsWidth (m_slider, SLIDER_NICESIZE_IN_CHARS), -1); + + gtk_box_pack_start (GTK_BOX (getWidget()), m_slider, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (getWidget()), m_spiner, FALSE, FALSE, 5); + gtk_widget_show (m_slider); + } + else { + m_slider = NULL; + YGLabeledWidget::setBuddy (m_spiner); + + gtk_container_add (GTK_CONTAINER (getWidget()), m_spiner); + } + gtk_widget_show (m_spiner); + + doSetValue (initialValue); + g_signal_connect (G_OBJECT (m_spiner), "value-changed", + G_CALLBACK (spiner_changed_cb), this); + if (m_slider) + g_signal_connect (G_OBJECT (m_slider), "value-changed", + G_CALLBACK (slider_changed_cb), this); + } + + GtkSpinButton *getSpiner() + { return GTK_SPIN_BUTTON (m_spiner); } + + bool useSlider() + { return m_slider != NULL; } + GtkHScale *getSlider() + { return GTK_HSCALE (m_slider); } + + virtual void reportValue (int newValue) {} + + void doSetValue (int newValue) + { + gtk_spin_button_set_value (getSpiner(), newValue); + if (useSlider()) + gtk_range_set_value (GTK_RANGE (getSlider()), newValue); + } + + // Events callbacks + static void spiner_changed_cb (GtkSpinButton *widget, YGSpinBox *pThis) + { + int newValue = gtk_spin_button_get_value_as_int (pThis->getSpiner()); + pThis->reportValue (newValue); + if (pThis->useSlider()) + gtk_range_set_value (GTK_RANGE (pThis->getSlider()), newValue); + pThis->emitEvent (YEvent::ValueChanged); + } + + static void slider_changed_cb (GtkRange *range, YGSpinBox *pThis) + { + int value = (int) gtk_range_get_value (range); + gtk_spin_button_set_value (pThis->getSpiner(), value); + pThis->reportValue (value); + pThis->emitEvent (YEvent::ValueChanged); + } +}; + +#define YGSPIN_BOX_IMPL_SET_VALUE_CHAIN(ParentClass) \ + virtual void reportValue (int newValue) { \ + ParentClass::setValue (newValue); \ + } \ + virtual void setValue (int newValue) { \ + doSetValue (newValue); \ + reportValue (newValue); \ + } + +#include "YIntField.h" + +class YGIntField : public YIntField, public YGSpinBox +{ +public: + YGIntField (const YWidgetOpt &opt, YGWidget *parent, const YCPString &label, + int minValue, int maxValue, int initialValue) + : YIntField (opt, label, minValue, maxValue, initialValue) + , YGSpinBox (this, parent, opt, label, minValue, maxValue, initialValue, false) + { } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN (YIntField) + YGSPIN_BOX_IMPL_SET_VALUE_CHAIN (YIntField) +}; + +YWidget * +YGUI::createIntField (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + int minValue, int maxValue, int initialValue) +{ + IMPL + return new YGIntField (opt, YGWidget::get (parent), label, + minValue, maxValue, initialValue); +} + +#include "YSlider.h" + +class YGSlider : public YSlider, public YGSpinBox +{ +public: + YGSlider (const YWidgetOpt &opt, YGWidget *parent, const YCPString &label, + int minValue, int maxValue, int initialValue) + : YSlider (opt, label, minValue, maxValue, initialValue) + , YGSpinBox (this, parent, opt, label, minValue, maxValue, initialValue, true) + { } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN (YSlider) + YGSPIN_BOX_IMPL_SET_VALUE_CHAIN (YSlider) +}; + +YWidget * +YGUI::createSlider (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + int minValue, int maxValue, int initialValue) +{ + IMPL + return new YGSlider (opt, YGWidget::get (parent), label, + minValue, maxValue, initialValue); +} Added: trunk/gtk/unstable/src/YGLabel.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGLabel.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGLabel.cc (added) +++ trunk/gtk/unstable/src/YGLabel.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,97 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YGWidget.h" + +#include "YLabel.h" + +class YGLabel : public YLabel, public YGWidget +{ +public: + YGLabel (const YWidgetOpt &opt, YGWidget *parent, YCPString text) + : YLabel (opt, text), + YGWidget (this, parent, true, GTK_TYPE_LABEL, NULL) + { + IMPL + gtk_misc_set_alignment (GTK_MISC (getWidget()), 0.0, 0.5); + if (opt.isOutputField.value()) + gtk_label_set_selectable (GTK_LABEL (getWidget()), TRUE); + + if (opt.boldFont.value()) + YGUtils::setWidgetFont (getWidget(), PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); + if (opt.isHeading.value()) + YGUtils::setWidgetFont (getWidget(), PANGO_WEIGHT_ULTRABOLD, PANGO_SCALE_XX_LARGE); + setLabel (text); + } + + virtual void setLabel (const YCPString &label) + { + gtk_label_set_label (GTK_LABEL (getWidget()), label->value_cstr()); + YLabel::setLabel (label); + + // Some YCP progs have no labeled labels cluttering the layout + label->value().empty() ? gtk_widget_hide (getWidget()) + : gtk_widget_show (getWidget()); + } + + // YWidget + virtual bool doSetKeyboardFocus() + { return false; } + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createLabel (YWidget *parent, YWidgetOpt &opt, + const YCPString &text) +{ + return new YGLabel (opt, YGWidget::get (parent), text); +} + +#include "YColoredLabel.h" +#include "ygtkbargraph.h" + +class YGColoredLabel : public YColoredLabel, public YGWidget +{ +public: + YGColoredLabel (const YWidgetOpt &opt, YGWidget *parent, YCPString text, + const YColor &fgColor, const YColor &bgColor, int margin) + : YColoredLabel (opt, text), + YGWidget (this, parent, true, YGTK_TYPE_COLORED_LABEL, NULL) + { + IMPL + gtk_misc_set_alignment (GTK_MISC (getWidget()), 0.0, 0.5); + gtk_misc_set_padding (GTK_MISC (getWidget()), margin, margin); + + if (opt.boldFont.value()) + YGUtils::setWidgetFont (getWidget(), PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); + if (opt.isHeading.value()) + YGUtils::setWidgetFont (getWidget(), PANGO_WEIGHT_ULTRABOLD, PANGO_SCALE_XX_LARGE); + setLabel (text); + + YGtkColoredLabel *color_label = YGTK_COLORED_LABEL (getWidget()); + ygtk_colored_label_set_shadow_type (color_label, GTK_SHADOW_OUT); + ygtk_colored_label_set_foreground (color_label, fgColor.red, fgColor.green, fgColor.blue); + ygtk_colored_label_set_background (color_label, bgColor.red, bgColor.green, bgColor.blue); + } + + virtual void setLabel (const YCPString &label) + { + gtk_label_set_label (GTK_LABEL (getWidget()), label->value_cstr()); + YColoredLabel::setLabel (label); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createColoredLabel (YWidget *parent, YWidgetOpt &opt, YCPString label, + YColor fgColor, YColor bgColor, int margin) +{ + return new YGColoredLabel (opt, YGWidget::get (parent), label, + fgColor, bgColor, margin); +} Added: trunk/gtk/unstable/src/YGLayout.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGLayout.cc?rev=... ============================================================================== --- trunk/gtk/unstable/src/YGLayout.cc (added) +++ trunk/gtk/unstable/src/YGLayout.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,371 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" +#include "YGUtils.h" + +#include "YSplit.h" +#include "ygtkratiobox.h" +#include "YSpacing.h" + +// GtkBox-like container (actually, more like our YGtkRatioBox) +class YGSplit : public YSplit, public YGWidget +{ + // This group is meant to set all YGLabeledWidget with horizontal label + // to share the same width (if they belong to the same YSplit), so they + // look right + GtkSizeGroup *m_labels_group; + +public: + YGSplit (const YWidgetOpt &opt, YGWidget *parent, YUIDimension dim) + : YSplit (opt, dim), + YGWidget (this, parent, true, + dim == YD_HORIZ ? YGTK_TYPE_RATIO_HBOX + : YGTK_TYPE_RATIO_VBOX, NULL) + { + setBorder (0); + m_labels_group = NULL; + } + + ~YGSplit() + { + if (m_labels_group) + g_object_unref (G_OBJECT (m_labels_group)); + } + + virtual void childAdded (YWidget *ychild) + { + IMPL + YGWidget *ygchild = YGWidget::get (ychild); + + gtk_container_add (GTK_CONTAINER (getWidget()), ygchild->getLayout()); + sync_stretchable (ychild); + + // set labels of YGLabeledWidgets to the same width + // we have to do quite some work due to over-clutter on YCP progs + while (ychild) { + if (ychild->isContainer()) { + // try to see if there is a YGLabeledWidget at start + // (and ignore YSpacings) + YContainerWidget *container = (YContainerWidget *) ychild; + if (container->numChildren()) + for (int i = 0; i < container->numChildren(); i++) { + ychild = container->child (i); + if (!dynamic_cast <YSpacing *> (ychild)) + break; + } + else // no kids + break; + } + else { + ygchild = YGWidget::get (ychild); + YGLabeledWidget *labeled_child = dynamic_cast <YGLabeledWidget *> (ygchild); + if (labeled_child && labeled_child->orientation() == YD_HORIZ) { + if (!m_labels_group) + m_labels_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (m_labels_group, + labeled_child->getLabelWidget()); + } + break; + } + } + } + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) + + virtual void sync_stretchable (YWidget *ychild) + { + IMPL + YGtkRatioBox *box = YGTK_RATIO_BOX (getWidget()); + YGWidget *child = YGWidget::get (ychild); + + YUIDimension dim = dimension(); + bool horiz_fill = child->isStretchable (YD_HORIZ) + || ychild->hasWeight (YD_HORIZ); + bool vert_fill = child->isStretchable (YD_VERT) + || ychild->hasWeight (YD_VERT); + + ygtk_ratio_box_set_child_packing (box, child->getLayout(), ychild->weight (dim), + horiz_fill, vert_fill, 0); + ygtk_ratio_box_set_child_expand (box, child->getLayout(), + child->isStretchable (dim), + ychild->isLayoutStretch (dim)); + YGWidget::sync_stretchable(); + } + + virtual void moveChild (YWidget *, long, long) {}; // ignore +}; + +YContainerWidget * +YGUI::createSplit (YWidget *parent, YWidgetOpt &opt, YUIDimension dimension) +{ + IMPL + return new YGSplit (opt, YGWidget::get (parent), dimension); +} + +#include "YAlignment.h" + +class YGAlignment : public YAlignment, public YGWidget +{ + GdkPixbuf *m_background_pixbuf; + +public: + YGAlignment (const YWidgetOpt &opt, YGWidget *parent, + YAlignmentType halign, YAlignmentType valign) + : YAlignment (opt, halign, valign), + YGWidget (this, parent, true, GTK_TYPE_ALIGNMENT, NULL) + { + setBorder (0); + m_background_pixbuf = 0; + } + + virtual ~YGAlignment() + { + if (m_background_pixbuf) + g_object_unref (G_OBJECT (m_background_pixbuf)); + } + + virtual void childAdded (YWidget *ychild) + { + YGWidget *child = YGWidget::get (ychild); + gtk_container_add (GTK_CONTAINER (getWidget()), child->getLayout()); + + /* The padding is used for stuff like making YCP progs nicer for + yast-qt wizard, so it hurts us -- it's disabled. */ + //child->setPadding (topMargin(), bottomMargin(), + // leftMargin(), rightMargin()); + setMinSize (minWidth(), minHeight()); + + sync_stretchable (ychild); // alignment will be set here + } + YGWIDGET_IMPL_CHILD_REMOVED (m_widget) + + virtual void sync_stretchable (YWidget *child) + { + IMPL + setAlignment (align [YD_HORIZ], align [YD_VERT]); + YGWidget::sync_stretchable (m_y_widget); + } + + void setAlignment (YAlignmentType halign, YAlignmentType valign) + { + // special case (which YAlignment.cc also uses); let stretchable + // children stretch if opt.stretch is set (exploitable by the wizard) + GValue hstretch, vstretch; + hstretch = YGUtils::floatToGValue (0); + if (_stretch [YD_HORIZ] && YGWidget::get (child (0))->isStretchable (YD_HORIZ)) + hstretch = YGUtils::floatToGValue (1); + vstretch = YGUtils::floatToGValue (0); + if (_stretch [YD_VERT] && YGWidget::get (child (0))->isStretchable (YD_VERT)) + vstretch = YGUtils::floatToGValue (1); + + if (halign != YAlignUnchanged) { + GValue xalign = YGUtils::floatToGValue (yToGtkAlign (halign)); + g_object_set_property (G_OBJECT (getWidget()), "xalign", &xalign); + g_object_set_property (G_OBJECT (getWidget()), "xscale", &hstretch); + } + if (valign != YAlignUnchanged) { + GValue yalign = YGUtils::floatToGValue (yToGtkAlign (valign)); + g_object_set_property (G_OBJECT (getWidget()), "yalign", &yalign); + g_object_set_property (G_OBJECT (getWidget()), "yscale", &vstretch); + } + } + + void setPadding (int top, int bottom, int left, int right) + { + gtk_alignment_set_padding (GTK_ALIGNMENT (getWidget()), + top, bottom, left, right); + } + + virtual void setBackgroundPixmap (string filename) + { + // YAlignment will prepend a path to the image + YAlignment::setBackgroundPixmap (filename); + filename = YAlignment::backgroundPixmap(); + + if (m_background_pixbuf) + g_object_unref (G_OBJECT (m_background_pixbuf)); + + if (filename.empty()) { + m_background_pixbuf = 0; + g_signal_handlers_disconnect_by_func (G_OBJECT (getWidget()), + (void*) expose_event_cb, this); + } + else { + GError *error = 0; + m_background_pixbuf = gdk_pixbuf_new_from_file (filename.c_str(), &error); + if (!m_background_pixbuf) + g_warning ("Setting YAlignment background - couldn't load image '%s' - %s", + filename.c_str(), error->message); + else + g_signal_connect (G_OBJECT (getWidget()), "expose-event", + G_CALLBACK (expose_event_cb), this); + } + } + + static gboolean expose_event_cb (GtkWidget *widget, GdkEventExpose *event, + YGAlignment *pThis) + { + GtkAllocation *alloc = &widget->allocation; + cairo_t *cr = gdk_cairo_create (widget->window); + + gdk_cairo_set_source_pixbuf (cr, pThis->m_background_pixbuf, 0, 0); + cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); + + cairo_rectangle (cr, alloc->x, alloc->y, alloc->width, alloc->height); + cairo_fill (cr); + + cairo_destroy (cr); + + gtk_container_propagate_expose (GTK_CONTAINER (widget), + GTK_BIN (widget)->child, event); + return TRUE; + } + + virtual void moveChild (YWidget *, long, long) {}; // ignore + + virtual string getDebugLabel() const + { + struct inner { + static const char *alignLabel (YAlignmentType align) + { + switch (align) { + case YAlignUnchanged: + return "unchanged"; + case YAlignBegin: + return "begin"; + case YAlignEnd: + return "end"; + case YAlignCenter: + return "center"; + } + return ""; /*not run*/ + } + }; + + string str; + str += inner::alignLabel (align [YD_HORIZ]); + str += " x "; + str += inner::alignLabel (align [YD_VERT]); + return str; + } + +private: + // helper -- converts YWidget YAlignmentType to Gtk's align float + static float yToGtkAlign (YAlignmentType align) + { + switch (align) { + case YAlignBegin: return 0.0; + default: + case YAlignCenter: return 0.5; + case YAlignEnd: return 1.0; + } + } +}; + +YContainerWidget * +YGUI::createAlignment (YWidget *parent, YWidgetOpt &opt, + YAlignmentType halign, YAlignmentType valign) +{ + IMPL + return new YGAlignment (opt, YGWidget::get (parent), halign, valign); +} + +#include "YEmpty.h" + +// Just an empty space. +class YGEmpty : public YEmpty, public YGWidget +{ +public: + YGEmpty (const YWidgetOpt &opt, YGWidget *parent) + : YEmpty (opt), + YGWidget (this, parent, true, GTK_TYPE_EVENT_BOX, NULL) + { + setBorder (0); + } +}; + +YWidget * +YGUI::createEmpty (YWidget *parent, YWidgetOpt &opt) +{ + IMPL + return new YGEmpty (opt, YGWidget::get (parent)); +} + +#include "YSpacing.h" + +// Empty space, with a fixed size. +class YGSpacing : public YSpacing, public YGWidget +{ +public: + YGSpacing (const YWidgetOpt &opt, YGWidget *parent, + float size, bool horizontal, bool vertical) + : YSpacing (opt, size, horizontal, vertical), + YGWidget (this, parent, true, GTK_TYPE_EVENT_BOX, NULL) + { + setBorder (0); + gtk_widget_set_size_request (getWidget(), width(), height()); + } +}; + +YWidget * +YGUI::createSpacing (YWidget *parent, YWidgetOpt & opt, float size, + bool horiz, bool vert) +{ + IMPL + return new YGSpacing (opt, YGWidget::get (parent), size, horiz, vert); +} + +#include "YReplacePoint.h" + +// an empty space that will get replaced +class YGReplacePoint : public YReplacePoint, public YGWidget +{ +public: + YGReplacePoint (const YWidgetOpt &opt, YGWidget *parent) + : YReplacePoint (opt), + YGWidget (this, parent, true, GTK_TYPE_EVENT_BOX, NULL) + { + setBorder (0); + } + + YGWIDGET_IMPL_CHILD_ADDED (getWidget()) + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) +}; + +YContainerWidget * +YGUI::createReplacePoint( YWidget *parent, YWidgetOpt & opt ) +{ + IMPL + return new YGReplacePoint (opt, YGWidget::get (parent)); +} + +#include "YSquash.h" + +// A-like YAlignment, YSquash messes around child settings. +// In this case, it can remove the stretchable attribute. +class YGSquash : public YSquash, public YGWidget +{ +public: + YGSquash (const YWidgetOpt &opt, YGWidget *parent, + bool hsquash, bool vsquash) + : YSquash (opt, hsquash, vsquash), + YGWidget (this, parent, true, GTK_TYPE_EVENT_BOX, NULL) + { + setBorder (0); + } + + YGWIDGET_IMPL_CHILD_ADDED (getWidget()) + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) +}; + +YContainerWidget * +YGUI::createSquash (YWidget *parent, YWidgetOpt &opt, + bool hsquash, bool vsquash) +{ + IMPL + return new YGSquash (opt, YGWidget::get (parent), hsquash, vsquash); +} Added: trunk/gtk/unstable/src/YGMenuButton.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGMenuButton.cc?... ============================================================================== --- trunk/gtk/unstable/src/YGMenuButton.cc (added) +++ trunk/gtk/unstable/src/YGMenuButton.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,79 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YGWidget.h" +#include "YMenuButton.h" +#include "ygtkmenubutton.h" + +class YGMenuButton : public YMenuButton, public YGWidget +{ +public: + YGMenuButton (const YWidgetOpt &opt, + YGWidget *parent, + YCPString label) + : YMenuButton (opt, label), + YGWidget (this, parent, true, YGTK_TYPE_MENU_BUTTON, NULL) + { + IMPL + setLabel (label); + } + + virtual ~YGMenuButton() {} + + // YMenuButton + virtual void setLabel (const YCPString &label) + { + IMPL + string str = YGUtils::mapKBAccel (label->value_cstr()); + ygtk_menu_button_set_label (YGTK_MENU_BUTTON (getWidget()), str.c_str()); + YMenuButton::setLabel (label); + } + + // YMenuButton + virtual void createMenu() + { + GtkWidget *menu = doCreateMenu (getToplevelMenu()->itemList()); + gtk_widget_show_all (menu); + ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (getWidget()), menu); + } + + static GtkWidget* doCreateMenu (YMenuItemList &items) + { + GtkWidget *menu = gtk_menu_new(); + for (YMenuItemListIterator it = items.begin(); it != items.end(); it++) { + GtkWidget *entry; + string str = YGUtils::mapKBAccel ((*it)->getLabel()->value_cstr()); + entry = gtk_menu_item_new_with_mnemonic (str.c_str()); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry); + + if ((*it)->hasChildren()) + gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry), + doCreateMenu ((*it)->itemList())); + else + g_signal_connect (G_OBJECT (entry), "activate", + G_CALLBACK (selected_item_cb), *it); + } + + return menu; + } + + static void selected_item_cb (GtkMenuItem *menuitem, YMenuItem *yitem) + { + YGUI::ui()->sendEvent (new YMenuEvent (yitem->getId())); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createMenuButton (YWidget *parent, YWidgetOpt &opt, + const YCPString &label) +{ + return new YGMenuButton (opt, YGWidget::get (parent), label); +} Added: trunk/gtk/unstable/src/YGMultiLineEdit.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGMultiLineEdit.... ============================================================================== --- trunk/gtk/unstable/src/YGMultiLineEdit.cc (added) +++ trunk/gtk/unstable/src/YGMultiLineEdit.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,390 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include <string> +#include "YGUtils.h" +#include "YGWidget.h" + +class YGTextView : public YGScrolledWidget +{ +int maxChars; + +public: + YGTextView (YWidget *y_widget, YGWidget *parent, const YWidgetOpt &opt, + const YCPString &label, const YCPString &text, bool editable) + : YGScrolledWidget (y_widget, parent, label, YD_VERT, true, + GTK_TYPE_TEXT_VIEW, "wrap-mode", GTK_WRAP_WORD, NULL) + { + IMPL + if (!opt.isShrinkable.value()) + setMinSizeInChars (20, 10); + setPolicy (GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + + maxChars = -1; + setText (text); + + if (!editable) + { + gtk_text_view_set_editable (GTK_TEXT_VIEW (getWidget()), FALSE); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (getWidget()), FALSE); + } + + g_signal_connect (G_OBJECT (getBuffer()), "changed", + G_CALLBACK (text_changed_cb), this); + } + + GtkTextBuffer* getBuffer() + { return gtk_text_view_get_buffer (GTK_TEXT_VIEW (getWidget())); } + + int getCharsNb() + { + IMPL + return gtk_text_buffer_get_char_count (getBuffer()); + } + + void setCharsNb (int max_chars) + { + IMPL + maxChars = max_chars; + if (maxChars != -1 && getCharsNb() > maxChars) + truncateText (maxChars); + } + + void truncateText(int pos) + { + IMPL + GtkTextIter start_it, end_it; + gtk_text_buffer_get_iter_at_offset (getBuffer(), &start_it, pos); + gtk_text_buffer_get_end_iter (getBuffer(), &end_it); + + g_signal_handlers_block_by_func (getWidget(), (gpointer) text_changed_cb, this); + gtk_text_buffer_delete (getBuffer(), &start_it, &end_it); + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) text_changed_cb, this); + } + + void setText (const YCPString &text) + { + IMPL + gtk_text_buffer_set_text (getBuffer(), text->value_cstr(), -1); + } + + YCPString getText() + { + IMPL + GtkTextIter start_it, end_it; + gtk_text_buffer_get_bounds (getBuffer(), &start_it, &end_it); + + gchar* text = gtk_text_buffer_get_text (getBuffer(), &start_it, &end_it, FALSE); + YCPString str (text); + g_free (text); + return str; + } + + void scrollToBottom() + { + YGUtils::scrollTextViewDown (GTK_TEXT_VIEW (getWidget())); + } + + // Event callbacks + static void text_changed_cb (GtkTextBuffer *buffer, YGTextView *pThis) + { + if (pThis->maxChars != -1 && pThis->getCharsNb() > pThis->maxChars) { + pThis->truncateText (pThis->maxChars); + gdk_beep(); + } + pThis->emitEvent (YEvent::ValueChanged); + } +}; + +#include "YMultiLineEdit.h" + +class YGMultiLineEdit : public YMultiLineEdit, public YGTextView +{ +public: + YGMultiLineEdit (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, const YCPString &text) + : YMultiLineEdit (opt, label) + , YGTextView (this, parent, opt, label, text, true) + { } + + // YMultiLineEdit + virtual void setText (const YCPString &text) + { YGTextView::setText (text); } + + virtual YCPString text() + { return YGTextView::getText(); } + + virtual void setInputMaxLength (const YCPInteger &numberOfChars) + { YGTextView::setCharsNb (numberOfChars->asInteger()->value()); } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YMultiLineEdit) +}; + +YWidget * +YGUI::createMultiLineEdit (YWidget *parent, YWidgetOpt & opt, + const YCPString & label, const YCPString & text) +{ + return new YGMultiLineEdit (opt, YGWidget::get (parent), label, text); +} + +#include "YLogView.h" + +class YGLogView : public YLogView, public YGTextView +{ +public: + YGLogView (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, int visibleLines, int maxLines) + : YLogView (opt, label, visibleLines, maxLines) + , YGTextView (this, parent, opt, label, YCPString(""), false) + { + setMinSizeInChars (0, visibleLines); + } + + // YLogView + virtual void setLogText (const YCPString &text) + { + setText (text); + scrollToBottom(); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YLogView) +}; + +YWidget * +YGUI::createLogView (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, int visibleLines, + int maxLines) +{ + return new YGLogView (opt, YGWidget::get (parent), + label, visibleLines, maxLines); +} + +#include "YRichText.h" + +class YGPlainText : public YRichText, public YGTextView +{ +bool m_autoScrollDown; + +public: + YGPlainText(const YWidgetOpt &opt, YGWidget *parent, const YCPString &text) + : YRichText (opt, text) + , YGTextView (this, parent, opt, YCPString(""), text, false) + { + IMPL + m_autoScrollDown = opt.autoScrollDown.value(); + } + + // YRichText + virtual void setText (const YCPString &text) + { + IMPL + YGTextView::setText (text); + if (m_autoScrollDown) + scrollToBottom(); + YRichText::setText (text); + } + + YGWIDGET_IMPL_COMMON +}; + +#include "ygtkhtmlwrap.h" + +class YGRichText : public YRichText, public YGScrolledWidget +{ +bool m_autoScrollDown; + +public: + YGRichText(const YWidgetOpt &opt, YGWidget *parent, const YCPString &text) + : YRichText (opt, text) + , YGScrolledWidget (this, parent, true, ygtk_html_wrap_get_type(), NULL) + { + IMPL + if (!opt.isShrinkable.value()) + setMinSizeInChars (20, 8); + m_autoScrollDown = opt.autoScrollDown.value(); + + ygtk_html_wrap_init (getWidget()); + ygtk_html_wrap_connect_link_clicked (getWidget(), G_CALLBACK (link_clicked_cb), this); + + setText (text); + } + + // YRichText + virtual void setText (const YCPString &_text) + { + IMPL + string text (_text->value()); + YGUtils::replace (text, "&product;", 9, YUI::ui()->productName().c_str()); + + ygtk_html_wrap_set_text (getWidget(), text.c_str()); + if (m_autoScrollDown) + ygtk_html_wrap_scroll (getWidget(), FALSE); + YRichText::setText (_text); + } + + static void link_clicked_cb (GtkWidget *widget, const char *url, YGRichText *pThis) + { + YGUI::ui()->sendEvent (new YMenuEvent (YCPString (url))); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createRichText (YWidget *parent, YWidgetOpt &opt, const YCPString &text) +{ + if (opt.plainTextMode.value()) + return new YGPlainText (opt, YGWidget::get (parent), text); + else + return new YGRichText (opt, YGWidget::get (parent), text); +} + +#if 0 +/* Wrote this code, in order to allow the user to print a package license. + But they are written in HTML, so that was too much for me. Anyway, might + be needed in the future -- it prints text okay. Maybe we could adapt it to + YGtkRichText, so that it just iterates through its tags (its a GtkTextView + afterall), rather than doing html parsing. ugh. Maybe we could somehow re-use + GtkTextView GtkLayouts...*/ + +typedef struct { + gchar *title, *text; + PangoLayout *title_layout, *text_layout; + gint cur_line; +} PrintData; + + +static void free_print_data_cb (gpointer _data, GClosure *closure) +{ + PrintData *data = _data; +fprintf (stderr, "freeing print data '%s'\n", data->title); + g_free (data->title); + g_free (data->text); + if (data->title_layout) + g_object_unref (G_OBJECT (data->title_layout)); + if (data->text_layout) + g_object_unref (G_OBJECT (data->text_layout)); + g_free (data); +} + +static void print_begin_cb (GtkPrintOperation *print, GtkPrintContext *context, PrintData *data) +{ + int width = gtk_print_context_get_width (context); + int height = gtk_print_context_get_height (context); + + PangoFontDescription *desc; + desc = pango_font_description_from_string ("Sans 12"); + + data->text_layout = gtk_print_context_create_pango_layout (context); + pango_layout_set_font_description (data->text_layout, desc); + pango_layout_set_width (data->text_layout, width * PANGO_SCALE); + pango_layout_set_text (data->text_layout, data->text, -1); + + data->title_layout = gtk_print_context_create_pango_layout (context); + pango_layout_set_font_description (data->title_layout, desc); + pango_layout_set_width (data->title_layout, width * PANGO_SCALE); + pango_layout_set_text (data->title_layout, data->title, -1); + + pango_font_description_free (desc); + + int title_height, text_height; + pango_layout_get_pixel_size (data->title_layout, NULL, &title_height); + title_height += 10; + pango_layout_get_pixel_size (data->text_layout, NULL, &text_height); + + int pages_nb, page_height = height - title_height; + pages_nb = text_height / page_height; + if (text_height % page_height != 0) + pages_nb++; + data->cur_line = 0; +fprintf (stderr, "print begin: will use %d pages\n", pages_nb); + gtk_print_operation_set_n_pages (print, pages_nb); +} + +static void print_draw_page_cb (GtkPrintOperation *print, GtkPrintContext *context, + gint page_nb, PrintData *data) +{ + int title_height; + pango_layout_get_pixel_size (data->title_layout, NULL, &title_height); + title_height += 10; + + cairo_t *cr = gtk_print_context_get_cairo_context (context); + cairo_set_source_rgb (cr, 0, 0, 0); + + cairo_move_to (cr, 6, 3); + pango_cairo_show_layout (cr, data->title_layout); + + cairo_move_to (cr, 0, title_height-4); + cairo_line_to (cr, gtk_print_context_get_width (context), title_height-4); + cairo_stroke (cr); + + int y = title_height, page_height = 0; + for (;; data->cur_line++) { +fprintf (stderr, "printing line: %d\n", data->cur_line); + PangoLayoutLine *line = pango_layout_get_line_readonly (data->text_layout, + data->cur_line); + if (!line) +{ +fprintf (stderr, "no more lines\n"); + break; +} + PangoRectangle rect; + pango_layout_line_get_pixel_extents (line, NULL, &rect); +fprintf (stderr, "paragraph rect: %d x %d , %d x %d\n", rect.x, rect.y, rect.width, rect.height); + page_height += rect.height; + if (page_height >= gtk_print_context_get_height (context)) +{ +fprintf (stderr, "end of page: %f x %d\n", gtk_print_context_get_height (context), page_height); + break; +} + + cairo_move_to (cr, rect.x, y + rect.height); + pango_cairo_show_layout_line (cr, line); + y += rect.height; + } +} + +void ygtk_html_print_text (GtkWindow *parent_window, const gchar *title, const gchar *text) +{ + PrintData *data = g_new (PrintData, 1); + data->title = g_strdup (title); + data->text = g_strdup (text); + data->title_layout = data->text_layout = NULL; + + GtkPrintOperation *print = gtk_print_operation_new(); + + static GtkPrintSettings *print_settings = NULL; + if (print_settings) + gtk_print_operation_set_print_settings (print, print_settings); + + g_signal_connect (G_OBJECT (print), "begin-print", G_CALLBACK (print_begin_cb), data); + g_signal_connect_data (G_OBJECT (print), "draw-page", G_CALLBACK (print_draw_page_cb), + data, free_print_data_cb, 0); + + GError *error; + GtkPrintOperationResult res; + res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, + parent_window, &error); + if (res == GTK_PRINT_OPERATION_RESULT_ERROR) { + GtkWidget *dialog; + dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "<b>Print error</b>\n%s", error->message); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_error_free (error); + } + if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { + if (print_settings) + g_object_unref (print_settings); + print_settings = g_object_ref (gtk_print_operation_get_print_settings (print)); + } +} +#endif + Added: trunk/gtk/unstable/src/YGPackageSelector.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGPackageSelecto... ============================================================================== --- trunk/gtk/unstable/src/YGPackageSelector.cc (added) +++ trunk/gtk/unstable/src/YGPackageSelector.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,1764 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> + +#include "YGUI.h" +#include "YGUtils.h" +#include "YGi18n.h" +#include "YGDialog.h" + +#include "ygtkwizard.h" +#include "ygtkfindentry.h" +#include "ygtkhtmlwrap.h" +#include "ygtkzyppwrapper.h" + +// utilities +static GtkWidget *createImageFromXPM (const char **xpm) +{ + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (xpm); + GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf); + gtk_widget_show (image); + g_object_unref (pixbuf); + return image; +} + +#define FILEMANAGER_EXEC "/usr/bin/nautilus" +inline void FILEMANAGER_LAUNCH (const char *path) +{ system ((std::string (FILEMANAGER_EXEC) + " -n --no-desktop " + path + " &").c_str()); } + +#include "icons/pkg-list-mode.xpm" +#include "icons/pkg-tiles-mode.xpm" + +class PackagesView +{ +public: + struct Listener { + virtual void packagesSelected (const std::list <Ypp::Package *> &selection) = 0; + }; + void setListener (Listener *listener) + { m_listener = listener; } + +private: +Listener *m_listener; + + void packagesSelected (const std::list <Ypp::Package *> &selection) + { + if (m_listener) { + busyCursor(); + m_listener->packagesSelected (selection); + normalCursor(); + } + } + + struct View { + PackagesView *m_parent; + GtkWidget *m_widget; + View (PackagesView *parent) : m_parent (parent) + {} + virtual void setModel (GtkTreeModel *model) = 0; + + void selectedPaths (GtkTreeModel *model, GList *paths) + { + std::list <Ypp::Package *> packages; + for (GList *i = paths; i; i = i->next) { + Ypp::Package *package; + GtkTreePath *path = (GtkTreePath *) i->data; + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, YGtkZyppModel::PTR_COLUMN, &package, -1); + gtk_tree_path_free (path); + + packages.push_back (package); + } + g_list_free (paths); + m_parent->packagesSelected (packages); + } + }; + struct ListView : public View + { + ListView (PackagesView *parent) + : View (parent) + { + GtkTreeView *view = GTK_TREE_VIEW (m_widget = gtk_tree_view_new()); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), 1); + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "pixbuf", YGtkZyppModel::ICON_COLUMN, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + renderer = gtk_cell_renderer_text_new(); + g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "markup", YGtkZyppModel::NAME_DESCRIPTION_COLUMN, NULL); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "pixbuf", YGtkZyppModel::SPECIAL_ICON_COLUMN, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (packages_selected_cb), this); + gtk_widget_show (m_widget); + } + + virtual void setModel (GtkTreeModel *model) + { + gtk_tree_view_set_model (GTK_TREE_VIEW (m_widget), model); + if (GTK_WIDGET_REALIZED (m_widget)) + gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (m_widget), 0, 0); + } + + static void packages_selected_cb (GtkTreeSelection *selection, View *pThis) + { + GtkTreeModel *model; + GList *paths = gtk_tree_selection_get_selected_rows (selection, &model); + pThis->selectedPaths (model, paths); + } + }; + struct IconView : public View + { + IconView (PackagesView *parent) + : View (parent) + { + GtkIconView *view = GTK_ICON_VIEW (m_widget = gtk_icon_view_new()); + gtk_icon_view_set_text_column (view, YGtkZyppModel::NAME_COLUMN); + gtk_icon_view_set_pixbuf_column (view, YGtkZyppModel::ICON_COLUMN); + gtk_icon_view_set_selection_mode (view, GTK_SELECTION_MULTIPLE); + g_signal_connect (G_OBJECT (m_widget), "selection-changed", + G_CALLBACK (packages_selected_cb), this); + gtk_widget_show (m_widget); + } + + virtual void setModel (GtkTreeModel *model) + { + gtk_icon_view_set_model (GTK_ICON_VIEW (m_widget), model); + if (GTK_WIDGET_REALIZED (m_widget)) { + GtkTreePath *path = gtk_tree_path_new_first(); + gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (m_widget), + path, FALSE, 0, 0); + gtk_tree_path_free (path); + } + } + + static void packages_selected_cb (GtkIconView *view, View *pThis) + { + GtkTreeModel *model = gtk_icon_view_get_model (view); + GList *paths = gtk_icon_view_get_selected_items (view); + pThis->selectedPaths (model, paths); + } + }; + +GtkWidget *m_box, *m_bin, *m_list_button, *m_icon_button; +GtkTreeModel *m_model; +View *m_view; + +public: + GtkWidget *getWidget() + { return m_box; } + + PackagesView() : m_listener (NULL), m_model (NULL), m_view (NULL) + { + m_bin = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_bin), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_bin), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + + GtkWidget *buttons = gtk_vbox_new (FALSE, 0), *image; + image = createImageFromXPM (pkg_list_mode_xpm); + m_list_button = gtk_toggle_button_new(); + gtk_button_set_image (GTK_BUTTON (m_list_button), image); + image = createImageFromXPM (pkg_tiles_mode_xpm); + m_icon_button = gtk_toggle_button_new(); + gtk_button_set_image (GTK_BUTTON (m_icon_button), image); + gtk_box_pack_start (GTK_BOX (buttons), gtk_label_new(""), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (buttons), m_list_button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (buttons), m_icon_button, FALSE, FALSE, 0); + g_signal_connect (G_OBJECT (m_list_button), "toggled", + G_CALLBACK (mode_toggled_cb), this); + g_signal_connect (G_OBJECT (m_icon_button), "toggled", + G_CALLBACK (mode_toggled_cb), this); + + m_box = gtk_hbox_new (FALSE, 2); + gtk_box_pack_start (GTK_BOX (m_box), m_bin, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_box), buttons, FALSE, TRUE, 0); + + setMode (LIST_MODE); + } + + ~PackagesView() + { + if (m_model) + g_object_unref (G_OBJECT (m_model)); + delete m_view; + } + + enum ViewMode { + LIST_MODE, ICON_MODE + }; + void setMode (ViewMode mode) + { + busyCursor(); + g_signal_handlers_block_by_func (m_list_button, (gpointer) mode_toggled_cb, this); + g_signal_handlers_block_by_func (m_icon_button, (gpointer) mode_toggled_cb, this); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_list_button), mode == LIST_MODE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_icon_button), mode == ICON_MODE); + + g_signal_handlers_unblock_by_func (m_list_button, (gpointer) mode_toggled_cb, this); + g_signal_handlers_unblock_by_func (m_icon_button, (gpointer) mode_toggled_cb, this); + + if (m_view) + gtk_container_remove (GTK_CONTAINER (m_bin), m_view->m_widget); + delete m_view; + if (mode == LIST_MODE) + m_view = new ListView (this); + else + m_view = new IconView (this); +fprintf (stderr, "adding new view to container\n"); + gtk_container_add (GTK_CONTAINER (m_bin), m_view->m_widget); + if (m_model) + m_view->setModel (m_model); + packagesSelected (std::list <Ypp::Package *> ()); + normalCursor(); + } + + void query (Ypp::Query *query) + { + busyCursor(); + + if (m_model) + g_object_unref (G_OBJECT (m_model)); + + YGtkZyppModel *zmodel = ygtk_zypp_model_new (query); + m_model = GTK_TREE_MODEL (zmodel); + if (m_view) { + m_view->setModel (m_model); + packagesSelected (std::list <Ypp::Package *> ()); + } + normalCursor(); + } + +private: + static void mode_toggled_cb (GtkToggleButton *toggle, PackagesView *pThis) + { + bool active = gtk_toggle_button_get_active (toggle); + if (!active) { + // don't let the button be un-pressed + g_signal_handlers_block_by_func (toggle, (gpointer) mode_toggled_cb, pThis); + gtk_toggle_button_set_active (toggle, TRUE); + g_signal_handlers_unblock_by_func (toggle, (gpointer) mode_toggled_cb, pThis); + return; + } + ViewMode mode = GTK_WIDGET (toggle) == pThis->m_list_button ? LIST_MODE : ICON_MODE; + pThis->setMode (mode); + } + + void busyCursor() + { + if (GTK_WIDGET_REALIZED (m_bin)) { + YGUI::ui()->busyCursor(); + // so that the cursor is actually set... + while (g_main_context_iteration (NULL, FALSE)) ; + } + } + void normalCursor() + { + if (GTK_WIDGET_REALIZED (m_bin)) + YGUI::ui()->normalCursor(); + } +}; + +// TEMP: a window of modified packages +class TrashWindow : PackagesView::Listener +{ +GtkWidget *m_window, *m_undo_button; +PackagesView *m_view; + +public: + TrashWindow() + { + m_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (m_window), "Changes"); + gtk_window_set_default_size (GTK_WINDOW (m_window), 200, 250); + + m_view = new PackagesView(); + Ypp::Query *query = new Ypp::Query (Ypp::Package::PACKAGE_TYPE); + query->setIsModified (true); + m_view->query (query); + m_view->setListener (this); + + GtkWidget *vbox = gtk_vbox_new (FALSE, 6), *undo_align; + m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO); + gtk_widget_set_sensitive (m_undo_button, FALSE); + g_signal_connect (G_OBJECT (m_undo_button), "clicked", + G_CALLBACK (undo_clicked_cb), this); + undo_align = gtk_alignment_new (1, 0, 0, 0); + gtk_container_add (GTK_CONTAINER (undo_align), m_undo_button); + + gtk_box_pack_start (GTK_BOX (vbox), m_view->getWidget(), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), undo_align, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (m_window), vbox); + gtk_widget_show_all (m_window); + } + + ~TrashWindow() + { + delete m_view; + gtk_widget_destroy (m_window); + } + +private: +std::list <Ypp::Package *> m_selection; + + virtual void packagesSelected (const std::list <Ypp::Package *> &selection) + { + gtk_widget_set_sensitive (m_undo_button, !selection.empty()); + m_selection = selection; + } + + static void undo_clicked_cb (GtkButton *button, TrashWindow *pThis) + { + for (std::list <Ypp::Package *>::iterator it = pThis->m_selection.begin(); + it != pThis->m_selection.end(); it++) + (*it)->undo(); + } +}; + +#include "icons/cat-development.xpm" +#include "icons/cat-documentation.xpm" +#include "icons/cat-emulators.xpm" +#include "icons/cat-games.xpm" +#include "icons/cat-hardware.xpm" +#include "icons/cat-network.xpm" +#include "icons/cat-multimedia.xpm" +#include "icons/cat-office.xpm" +#include "icons/cat-system.xpm" +#include "icons/cat-utilities.xpm" + +class Filters +{ +public: + struct Listener { + virtual void doQuery (Ypp::Query *query) = 0; + }; + void setListener (Listener *listener) + { m_listener = listener; signalChanged(); } + +private: + GtkWidget *m_widget, *m_name, *m_status, *m_categories, *m_repos, *m_type, + *m_categories_expander, *m_repos_expander; + Listener *m_listener; + guint timeout_id; + int repoToggled; // how many repos are toggled? if 0, it can speed up query + int packageType; + +public: + GtkWidget *getWidget() + { return m_widget; } + + Filters() + : m_listener (NULL), timeout_id (0), repoToggled (0), packageType (-1) + { + GtkWidget *vbox = gtk_vbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); + GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + m_name = ygtk_find_entry_new(); + g_signal_connect_after (G_OBJECT (m_name), "changed", + G_CALLBACK (entry_changed_cb), this); + gtk_box_pack_start (GTK_BOX (vbox), + labelWidget (_("Name: "), m_name, size_group), FALSE, TRUE, 0); + + m_status = gtk_combo_box_new_text(); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("All")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Installed")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Upgradable")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Available")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Modified")); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_status), 0); + g_signal_connect_after (G_OBJECT (m_status), "changed", + G_CALLBACK (combo_changed_cb), this); + gtk_box_pack_start (GTK_BOX (vbox), + labelWidget (_("Status: "), m_status, size_group), FALSE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), buildCategories(), FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), buildRepos(), FALSE, TRUE, 0); + + m_type = gtk_combo_box_new_text(); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Packages")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Patterns")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Languages")); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_type), 0); + g_signal_connect_after (G_OBJECT (m_type), "changed", + G_CALLBACK (combo_changed_cb), this); + gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (""), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), + labelWidget (_("Type: "), m_type, size_group), FALSE, TRUE, 0); + + m_widget = gtk_notebook_new(); + gtk_notebook_append_page (GTK_NOTEBOOK (m_widget), vbox, + gtk_label_new (_("Filters"))); + g_object_unref (G_OBJECT (size_group)); + } + + ~Filters() + { + if (timeout_id) g_source_remove (timeout_id); + } + +private: + static void entry_changed_cb (GtkEditable *editable, Filters *pThis) + { pThis->signalChangedDelay(); } + static void combo_changed_cb (GtkComboBox *combo, Filters *pThis) + { pThis->signalChanged(); } + + void signalChanged() + { + if (!m_listener) return; + + Ypp::Package::Type type; + switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_type))) + { + case 0: default: type = Ypp::Package::PACKAGE_TYPE; break; + case 1: type = Ypp::Package::PATTERN_TYPE; break; + case 2: type = Ypp::Package::LANGUAGE_TYPE; break; + + } + + Ypp::Query *query = new Ypp::Query (type); + + const char *name = gtk_entry_get_text (GTK_ENTRY (m_name)); + if (*name) + query->setName (std::string (name)); + switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_status))) + { + case 1: query->setIsInstalled (true); break; + case 2: query->setHasUpgrade (true); break; + case 3: query->setIsInstalled (false); break; + case 4: query->setIsModified (true); break; + case 0: default: break; + + } + + { + GtkTreeSelection *selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_categories)); + GtkTreeModel *model; + GtkTreeIter iter; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + Ypp::Node *category; + gtk_tree_model_get (model, &iter, 1, &category, -1); + if (category) + query->setCategory (category); + } + } + + if (repoToggled) { + std::list <int> reposQuery; + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos)); + GtkTreeIter iter; + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + gboolean enabled; + gint repo; + gtk_tree_model_get (model, &iter, 0, &enabled, 2, &repo, -1); + if (enabled) + reposQuery.push_back (repo); + } while (gtk_tree_model_iter_next (model, &iter)); + } + query->setRepositories (reposQuery); + } + + m_listener->doQuery (query); + updateCategories (type); + } + + void signalChangedDelay() + { + struct inner { + static gboolean timeout_cb (gpointer data) + { + Filters *pThis = (Filters *) data; + pThis->timeout_id = 0; + pThis->signalChanged(); + return FALSE; + } + }; + if (timeout_id) g_source_remove (timeout_id); + timeout_id = g_timeout_add (500, inner::timeout_cb, this); + } + + void updateCategories (Ypp::Package::Type type) + { + if (packageType == type) + return; + packageType = type; + + GtkTreeModel *model = NULL; + + if (type == Ypp::Package::PACKAGE_TYPE) { + struct inner { + static void populate (GtkTreeStore *store, GtkTreeIter *parent, + Ypp::Node *category) + { + if (!category) + return; + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, parent); + const std::string &name = category->name; + gtk_tree_store_set (store, &iter, 0, name.c_str(), 1, category, -1); + if (!parent) { + const char **icon = 0; + if (name == "Development") + icon = cat_development_xpm; + else if (name == "Documentation") + icon = cat_documentation_xpm; + else if (name == "Emulators") + icon = cat_emulators_xpm; + else if (name == "Games") + icon = cat_games_xpm; + else if (name == "Hardware") + icon = cat_hardware_xpm; + else if (name == "Multimedia") + icon = cat_multimedia_xpm; + else if (name == "Network") + icon = cat_network_xpm; + else if (name == "Office") + icon = cat_office_xpm; + else if (name == "System") + icon = cat_system_xpm; + else if (name == "Utilities") + icon = cat_utilities_xpm; + if (icon) { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (icon); + gtk_tree_store_set (store, &iter, 2, pixbuf, -1); + } + } + populate (store, &iter, category->child()); + populate (store, parent, category->next()); + } + }; + + GtkTreeStore *store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, + GDK_TYPE_PIXBUF); + model = GTK_TREE_MODEL (store); + + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, _("All"), 1, NULL, -1); + + inner::populate (store, NULL, Ypp::get()->getFirstCategory (type)); + + } + else if (type == Ypp::Package::PATTERN_TYPE) { + GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, + GDK_TYPE_PIXBUF); + model = GTK_TREE_MODEL (store); + + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, _("All"), 1, NULL, -1); + + for (Ypp::Node *i = Ypp::get()->getFirstCategory (type); i; i = i->next()) { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, i->name.c_str(), 1, i, -1); + } + } + + GtkTreeSelection *selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_categories)); + g_signal_handlers_block_by_func (selection, + (gpointer) categories_selection_cb, this); + + gtk_tree_view_set_model (GTK_TREE_VIEW (m_categories), model); + if (model) { + g_object_unref (G_OBJECT (model)); + gtk_widget_show (m_categories_expander); + + /* we use gtk_tree_view_set_cursor(), rather than gtk_tree_selection_select_iter() + because that one is buggy in that when the user first interacts with the treeview, + a change signal is sent, even if he was just expanding one node... */ + GtkTreePath *path = gtk_tree_path_new_first(); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (m_categories), path, NULL, FALSE); + gtk_tree_path_free (path); + } + else + gtk_widget_hide (m_categories_expander); + + g_signal_handlers_unblock_by_func (selection, + (gpointer) categories_selection_cb, this); + } + + GtkWidget *buildCategories() + { + GtkWidget *scroll; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + m_categories = gtk_tree_view_new(); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_categories), FALSE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_categories), 0); + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "pixbuf", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column); + + GtkTreeSelection *selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_categories)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (categories_selection_cb), this); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (scroll, -1, 200); + gtk_container_add (GTK_CONTAINER (scroll), m_categories); + + m_categories_expander = gtk_expander_new (_("Categories")); + gtk_container_add (GTK_CONTAINER (m_categories_expander), scroll); + gtk_expander_set_expanded (GTK_EXPANDER (m_categories_expander), TRUE); + return m_categories_expander; + } + + GtkWidget *buildRepos() + { + GtkWidget *scroll; + GtkListStore *store; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + // 0 - enabled, 1 - name, 2 - ptr + store = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT); + for (int i = 0; Ypp::get()->getRepository (i); i++) { + const Ypp::Repository *repo = Ypp::get()->getRepository (i); + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, TRUE, 1, repo->name.c_str(), 2, i, -1); + } + m_repos = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_repos), FALSE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_repos), 1); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (m_repos)), + GTK_SELECTION_NONE); + g_object_unref (G_OBJECT (store)); + renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes ("", renderer, "active", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column); + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (repo_toggled_cb), this); + g_signal_connect (G_OBJECT (m_repos), "row-activated", + G_CALLBACK (repo_clicked_cb), this); + renderer = gtk_cell_renderer_text_new(); + g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (scroll, -1, 80); + gtk_container_add (GTK_CONTAINER (scroll), m_repos); + + m_repos_expander = gtk_expander_new (_("Repositories")); + gtk_container_add (GTK_CONTAINER (m_repos_expander), scroll); + return m_repos_expander; + } + + static void categories_selection_cb (GtkTreeSelection *selection, Filters *pThis) + { +fprintf (stderr, "CATEGORIES SELECTED\n"); + pThis->signalChanged(); + } + + void toggle_repo (GtkTreePath *path) + { + IMPL + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos)); + GtkListStore *store = GTK_LIST_STORE (model); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + + gboolean enabled; + gtk_tree_model_get (model, &iter, 0, &enabled, -1); + gtk_list_store_set (store, &iter, 0, !enabled, -1); + if (enabled) repoToggled--; else repoToggled++; +fprintf (stderr, "repoToggled count: %d\n", repoToggled); + signalChanged(); + } + + static void repo_toggled_cb (GtkCellRendererToggle *renderer, + gchar *path_str, Filters *pThis) + { + IMPL + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + pThis->toggle_repo (path); + gtk_tree_path_free (path); + } + + static void repo_clicked_cb (GtkTreeView *view, GtkTreePath *path, + GtkTreeViewColumn *column, Filters *pThis) + { + IMPL + pThis->toggle_repo (path); + } + + // utility + static GtkWidget *labelWidget (const char *label_str, GtkWidget *widget, + GtkSizeGroup *group) + { + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + GtkWidget *label = gtk_label_new_with_mnemonic (label_str); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); + gtk_size_group_add_widget (group, label); + return hbox; + } +}; + +#include "icons/pkg-locked.xpm" +#include "icons/pkg-unlocked.xpm" + +class PackageControl +{ +GtkWidget *m_vbox, *m_status, *m_lock_button, *m_locked_image, *m_unlocked_image, + *m_installed_box, *m_available_box, *m_remove_button, *m_install_button, + *m_undo_button, *m_versions_combo, *m_version_repo; +GtkTreeModel *m_versions_model; + +public: +std::list <Ypp::Package *> m_packages; + + GtkWidget *getWidget() + { return m_vbox; } + + PackageControl() + { + GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + m_vbox = gtk_vbox_new (FALSE, 6); + GtkWidget *hbox, *label; + + m_lock_button = gtk_toggle_button_new(); + g_signal_connect (G_OBJECT (m_lock_button), "toggled", + G_CALLBACK (locked_toggled_cb), this); + m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO); + g_signal_connect (G_OBJECT (m_undo_button), "clicked", + G_CALLBACK (undo_clicked_cb), this); + + hbox = gtk_hbox_new (FALSE, 6); + label = gtk_label_new (_("Status:")); + YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_size_group_add_widget (size_group, label); + m_status = gtk_label_new ("-"); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), m_status, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), m_undo_button, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new(0), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), m_lock_button, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_vbox), hbox, TRUE, TRUE, 0); + + m_locked_image = createImageFromXPM (pkg_locked_xpm); + m_unlocked_image = createImageFromXPM (pkg_unlocked_xpm); + g_object_ref_sink (G_OBJECT (m_locked_image)); + g_object_ref_sink (G_OBJECT (m_unlocked_image)); + + m_remove_button = createButton (_("_Remove"), GTK_STOCK_DELETE); + g_signal_connect (G_OBJECT (m_remove_button), "clicked", + G_CALLBACK (remove_clicked_cb), this); + m_install_button = createButton ("", GTK_STOCK_SAVE); + g_signal_connect (G_OBJECT (m_install_button), "clicked", + G_CALLBACK (install_clicked_cb), this); + + m_installed_box = gtk_hbox_new (FALSE, 6); + label = gtk_label_new (_("Installed: ")); + YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_size_group_add_widget (size_group, label); + gtk_box_pack_start (GTK_BOX (m_installed_box), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_installed_box), m_remove_button, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_vbox), m_installed_box, TRUE, TRUE, 0); + + m_versions_model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT)); + m_versions_combo = gtk_combo_box_new_with_model (m_versions_model); + g_signal_connect (G_OBJECT (m_versions_combo), "changed", + G_CALLBACK (version_changed_cb), this); + + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (m_versions_combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (m_versions_combo), + renderer, "text", 0, NULL); + + m_available_box = gtk_hbox_new (FALSE, 6); + label = gtk_label_new (_("Available: ")); + YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_size_group_add_widget (size_group, label); + gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_available_box), m_versions_combo, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_available_box), m_install_button, FALSE, TRUE, 0); + label = gtk_label_new (_("(Repository:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + m_version_repo = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (m_version_repo), 0, 0.5); + gtk_label_set_ellipsize (GTK_LABEL (m_version_repo), PANGO_ELLIPSIZE_END); + gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_available_box), m_version_repo, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_vbox), m_available_box, TRUE, TRUE, 0); + + g_object_unref (G_OBJECT (size_group)); + } + + ~PackageControl() + { + gtk_widget_destroy (m_locked_image); + g_object_unref (G_OBJECT (m_locked_image)); + gtk_widget_destroy (m_unlocked_image); + g_object_unref (G_OBJECT (m_unlocked_image)); + } + + void setPackages (const std::list <Ypp::Package *> &packages) + { +fprintf (stderr, "packages selected (%d)\n", packages.size()); + // FIXME: we'll probably want to re-work the controls interface + // for now, let's just handle none-one-multiple selections separatadely + m_packages = packages; + if (packages.size() == 1) { + Ypp::Package *package = packages.front(); + // status label + std::string status; + if (package->isInstalled()) + status = _("Installed ") + package->getInstalledVersion()->number; + else + status = _("Not installed"); + if (package->toInstall()) { + int nb; + const Ypp::Package::Version *version; + package->toInstall (&nb); + version = package->getAvailableVersion (nb); + status += _(" (to install"); + if (version) + status += " " + version->number; + status += ")"; + } + else if (package->toRemove()) + status += _(" (to remove)"); + gtk_label_set_text (GTK_LABEL (m_status), status.c_str()); + if (package->isModified()) + gtk_widget_show (m_undo_button); + else + gtk_widget_hide (m_undo_button); + + // install version + if (package->isInstalled()) + gtk_widget_show (m_installed_box); + else + gtk_widget_hide (m_installed_box); + + // available versions + gtk_widget_show (m_versions_combo); + if (package->getAvailableVersion (0)) { + gtk_list_store_clear (GTK_LIST_STORE (m_versions_model)); + for (int i = 0; package->getAvailableVersion (i); i++) { + const char *version = package->getAvailableVersion (i)->number.c_str(); +fprintf (stderr, "adding version: %s\n", version); + GtkTreeIter iter; + gtk_list_store_append (GTK_LIST_STORE (m_versions_model), &iter); + gtk_list_store_set (GTK_LIST_STORE (m_versions_model), &iter, + 0, version, 1, i, -1); + } + gtk_combo_box_set_active (GTK_COMBO_BOX (m_versions_combo), 0); + gtk_widget_show (m_available_box); + } + else + gtk_widget_hide (m_available_box); + + // is locked + gtk_widget_show (m_lock_button); + bool locked = package->isLocked(); + g_signal_handlers_block_by_func (m_lock_button, (gpointer) locked_toggled_cb, this); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), locked); + g_signal_handlers_unblock_by_func (m_lock_button, (gpointer) locked_toggled_cb, this); + gtk_button_set_image (GTK_BUTTON (m_lock_button), + locked ? m_locked_image : m_unlocked_image); + gtk_widget_set_sensitive (m_install_button, !locked); + gtk_widget_set_sensitive (m_remove_button, !locked); + + gtk_widget_show (m_vbox); + } + else if (packages.size()) { + bool allInstalled = true, allNotInstalled = true, allUpgradable = true, + allModified = true, allLocked = true, allUnlocked = true; + for (std::list <Ypp::Package *>::const_iterator it = packages.begin(); + it != packages.end(); it++) { + if (!(*it)->isInstalled()) { + allInstalled = false; + allUpgradable = false; + } + else { + allNotInstalled = false; + const Ypp::Package::Version *version = (*it)->getAvailableVersion(0); + if (!version || version->cmp <= 0) + allUpgradable = false; + } + if (!(*it)->isModified()) + allModified = false; + if ((*it)->isLocked()) + allUnlocked = false; + else + allLocked = false; + } + + std::string status; + if (allInstalled) + status = _("Installed"); + else if (allNotInstalled) + status = _("Not installed"); + else + status = _("--"); + + if (allModified) { + status += _(" (modified)"); + gtk_widget_show (m_undo_button); + } + else + gtk_widget_hide (m_undo_button); + gtk_label_set_text (GTK_LABEL (m_status), status.c_str()); + + // install version + if (allInstalled) + gtk_widget_show (m_installed_box); + else + gtk_widget_hide (m_installed_box); + + // available versions + gtk_widget_hide (m_versions_combo); + if (allNotInstalled || allUpgradable) { + gtk_widget_show (m_available_box); + const char *installLabel = _("Install"); + if (allUpgradable) + installLabel = _("Upgrade"); + gtk_button_set_label (GTK_BUTTON (m_install_button), installLabel); + } + else + gtk_widget_hide (m_available_box); + + // is locked + if (allLocked || allUnlocked) { + gtk_widget_show (m_lock_button); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), allLocked); + gtk_button_set_image (GTK_BUTTON (m_lock_button), + allLocked ? m_locked_image : m_unlocked_image); + gtk_widget_set_sensitive (m_install_button, !allLocked); + gtk_widget_set_sensitive (m_remove_button, !allLocked); + } + else { + gtk_widget_hide (m_lock_button); + gtk_widget_set_sensitive (m_install_button, TRUE); + gtk_widget_set_sensitive (m_remove_button, TRUE); + } + gtk_widget_show (m_vbox); + } + else + gtk_widget_hide (m_vbox); + +#if 0 + m_package = package; + if (package) { + if (package->isInstalled()) { + gtk_widget_show (m_remove_button); + gtk_widget_hide (m_install_button); + } + else { + gtk_widget_show (m_install_button); + gtk_widget_hide (m_remove_button); + } + if (package && package->hasUpgrade()) + gtk_widget_show (m_upgrade_button); + else + gtk_widget_hide (m_upgrade_button); + } + else { + gtk_widget_hide (m_install_button); + gtk_widget_hide (m_remove_button); + gtk_widget_hide (m_upgrade_button); + } +#endif + } + +private: + static void install_clicked_cb (GtkButton *button, PackageControl *pThis) + { + Ypp::get()->startTransactions(); + for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); + it != pThis->m_packages.end(); it++) { + int version; + if (GTK_WIDGET_VISIBLE (pThis->m_versions_combo)) + version = gtk_combo_box_get_active (GTK_COMBO_BOX ( + pThis->m_versions_combo)); + else + version = 0; // i.e. most recent (on multi-packages) + (*it)->install (version); + } + Ypp::get()->finishTransactions(); + } + + static void remove_clicked_cb (GtkButton *button, PackageControl *pThis) + { + Ypp::get()->startTransactions(); + for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); + it != pThis->m_packages.end(); it++) + (*it)->remove(); + Ypp::get()->finishTransactions(); + } + + static void undo_clicked_cb (GtkButton *button, PackageControl *pThis) + { + Ypp::get()->startTransactions(); + for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); + it != pThis->m_packages.end(); it++) + (*it)->undo(); + Ypp::get()->finishTransactions(); + } + + static void locked_toggled_cb (GtkToggleButton *button, PackageControl *pThis) + { + Ypp::get()->startTransactions(); + for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); + it != pThis->m_packages.end(); it++) + (*it)->lock (gtk_toggle_button_get_active (button)); + Ypp::get()->finishTransactions(); + } + + static void version_changed_cb (GtkComboBox *combo, PackageControl *pThis) + { + fprintf (stderr, "version changed\n"); + if (!pThis->m_packages.empty()) { + Ypp::Package *package = pThis->m_packages.front(); + int nb; + GtkTreeIter iter; + if (gtk_combo_box_get_active_iter (combo, &iter)) { + gtk_tree_model_get (pThis->m_versions_model, &iter, 1, &nb, -1); + const Ypp::Package::Version *version; + fprintf (stderr, "get available version %d\n", nb); + version = package->getAvailableVersion (nb); + g_assert (version != NULL); + + const Ypp::Repository *repo = Ypp::get()->getRepository (version->repo); + if (repo) { + std::string repo_str = repo->name + ")"; + gtk_label_set_text (GTK_LABEL (pThis->m_version_repo), repo_str.c_str()); + } + else + gtk_label_set_text (GTK_LABEL (pThis->m_version_repo), + "TODO: hide this for collections)"); + + const char *installLabel = _("Install"); + if (package->isInstalled()) { + if (version->cmp > 0) + installLabel = _("Upgrade"); + else if (version->cmp == 0) + installLabel = _("Re-install"); + else //if (version->cmp < 0) + installLabel = _("Downgrade"); + } + gtk_button_set_label (GTK_BUTTON (pThis->m_install_button), installLabel); + } + } + } + + // utility + static GtkWidget *createButton (const char *label_str, const gchar *stock_id) + { + GtkWidget *button, *image; + button = gtk_button_new_with_mnemonic (label_str); + if (stock_id) { + image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button), image); + } + return button; + } +}; + +class PackageInfo +{ +GtkWidget *m_widget, *m_description, *m_filelist, *m_changelog, *m_authors; + +public: + GtkWidget *getWidget() + { return m_widget; } + + PackageInfo() + { + m_widget = gtk_notebook_new(); + addPage (_("Description"), createHtmlWidget (&m_description)); + addPage (_("File List"), createHtmlWidget (&m_filelist)); + addPage (_("ChangeLog"), createHtmlWidget (&m_changelog)); + addPage (_("Authors"), createHtmlWidget (&m_authors)); + gtk_widget_set_size_request (m_widget, -1, 150); + ygtk_html_wrap_connect_link_clicked (m_filelist, + G_CALLBACK (path_pressed_cb), NULL); + } + + void setPackage (Ypp::Package *package) + { + if (package) { + setText (m_description, package->description()); + setText (m_filelist, package->filelist()); + setText (m_changelog, package->changelog()); + setText (m_authors, package->authors()); + if (!GTK_WIDGET_VISIBLE (m_widget)) { + gtk_notebook_set_current_page (GTK_NOTEBOOK (m_widget), 0); + gtk_widget_show (m_widget); + } + } + else + gtk_widget_hide (m_widget); + } + +private: + static void path_pressed_cb (GtkWidget *text, const gchar *link) + { FILEMANAGER_LAUNCH (link); } + + // utilities: + static GtkWidget *createHtmlWidget (GtkWidget **html_widget) + { + *html_widget = ygtk_html_wrap_new(); + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (scroll), *html_widget); + return scroll; + } + + void addPage (const char *title, GtkWidget *content) + { + gtk_notebook_append_page (GTK_NOTEBOOK (m_widget), content, gtk_label_new (title)); + } + + void setText (GtkWidget *rtext, const std::string &text) + { + if (text.empty()) { + const char *empty = _("<i>(only available for installed packages)</i>"); + ygtk_html_wrap_set_text (rtext, empty); + } + else + ygtk_html_wrap_set_text (rtext, text.c_str()); + ygtk_html_wrap_scroll (rtext, TRUE); + } +}; + +class DiskView : public Ypp::Disk::Listener +{ +GtkWidget *m_widget; +bool m_hasWarn; +GtkTreeModel *m_model; + +public: + GtkWidget *getWidget() + { return m_widget; } + + DiskView() + : m_hasWarn (false) + { + m_model = GTK_TREE_MODEL (gtk_list_store_new ( + // 0 - mount point, 1 - usage percent, 2 - usage string + 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING)); + m_widget = createCombo (m_model); + g_object_unref (G_OBJECT (m_model)); + + Ypp::get()->getDisk()->setListener (this); + update(); + } + +private: + #define MIN_FREE_MB_WARN (80*1024) + virtual void update() + { + GtkListStore *store = GTK_LIST_STORE (m_model); + gtk_list_store_clear (store); + + int warn_part = -1; + Ypp::Disk *disk = Ypp::get()->getDisk(); + for (int i = 0; disk->getPartition (i); i++) { + const Ypp::Disk::Partition *part = disk->getPartition (i); + long usage = (part->used * 100) / (part->total + 1); + std::string usage_str = part->used_str + " (of " + part->total_str + ")"; + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, part->path.c_str(), 1, usage, + 2, usage_str.c_str(), -1); + if (warn_part < 0 && (part->total > 1024 && part->total - part->used < MIN_FREE_MB_WARN)) + warn_part = i; + } + if (warn_part >= 0) { + warn(); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_widget), warn_part); + } + else + gtk_combo_box_set_active (GTK_COMBO_BOX (m_widget), 0); + } + + void warn() + { + if (m_hasWarn) return; + m_hasWarn = true; + + GtkWidget *dialog, *view; + dialog = gtk_message_dialog_new (YGUI::ui()->currentWindow(), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, _("Disk Almost Full !")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "One of the partitions is reaching its limit of capacity. You may " + "have to remove packages if you wish to install some."); + + view = createView (m_model); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + + // utilities +#if 1 + static GtkWidget *createView (GtkTreeModel *model) + { + GtkWidget *view = gtk_tree_view_new_with_model (model), *scroll; + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), + GTK_SELECTION_NONE); + + GtkTreeViewColumn *column; + column = gtk_tree_view_column_new_with_attributes (_("Mount Point"), + gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + column = gtk_tree_view_column_new_with_attributes (_("Usage"), + gtk_cell_renderer_progress_new(), "value", 1, "text", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_NEVER); +// gtk_widget_set_size_request (scroll, -1, 50); + gtk_container_add (GTK_CONTAINER (scroll), view); + gtk_widget_show_all (scroll); + return scroll; + } +#endif + static GtkWidget *createCombo (GtkTreeModel *model) + { + GtkWidget *combo = gtk_combo_box_new_with_model (model); + GtkCellRenderer *renderer; + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), + renderer, "text", 0, NULL); + // let's put all columns to the same width, to make it look like a table + g_object_set (G_OBJECT (renderer), "width-chars", 14, NULL); + renderer = gtk_cell_renderer_progress_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), + renderer, "value", 1, "text", 2, NULL); + return combo; + } +}; + +class PackageSelector : public Filters::Listener, public PackagesView::Listener +{ +PackagesView *m_packages; +Filters *m_filters; +PackageInfo *m_info; +PackageControl *m_control; +DiskView *m_disk; +GtkWidget *m_box; +TrashWindow *m_trashWin; + +public: + GtkWidget *getWidget() + { return m_box; } + + PackageSelector() + { + m_packages = new PackagesView(); + m_packages->setListener (this); + + m_control = new PackageControl(); + m_info = new PackageInfo(); + + GtkWidget *vbox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (vbox), m_packages->getWidget(), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), m_control->getWidget(), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), m_info->getWidget(), FALSE, TRUE, 0); + + m_filters = new Filters(); + m_filters->setListener (this); + m_disk = new DiskView(); + + GtkWidget *left_box = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (left_box), m_filters->getWidget(), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (left_box), m_disk->getWidget(), FALSE, TRUE, 0); + + m_box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (m_box), left_box, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_box), vbox, TRUE, TRUE, 0); + gtk_widget_show_all (m_box); + + m_control->setPackages (std::list <Ypp::Package*> ()); + m_info->setPackage (NULL); + + m_trashWin = new TrashWindow(); + } + + ~PackageSelector() + { + delete m_packages; + delete m_control; + delete m_info; + delete m_filters; + delete m_disk; + delete m_trashWin; + } + + virtual void doQuery (Ypp::Query *query) + { + m_packages->query (query); + } + + virtual void packagesSelected (const std::list <Ypp::Package *> &packages) + { + m_control->setPackages (packages); + if (packages.size() == 1) + m_info->setPackage (packages.front()); + else + m_info->setPackage (NULL); + } + + void packageModified (Ypp::Package *package) + { + // GTK+ doesn't fire selection change when a selected row changes, so we need + // to re-load PackageControl in that occasions. + std::list <Ypp::Package *>::iterator it; + for (it = m_control->m_packages.begin(); it != m_control->m_packages.end(); it++) + if (*it == package) + break; + if (it != m_control->m_packages.end()) + m_control->setPackages (m_control->m_packages); + } +}; + +#include "YPackageSelector.h" + +class YGPackageSelector : public YPackageSelector, public YGWidget, public Ypp::Interface +{ +PackageSelector *m_package_selector; + +public: + YGPackageSelector (const YWidgetOpt &opt, YGWidget *parent) + : YPackageSelector (opt), + YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL) + { + setBorder (0); + YGDialog *dialog = YGUI::ui()->currentYGDialog(); + dialog->setCloseCallback (confirm_cb, this); + + GtkWindow *window = dialog->getWindow(); + gtk_window_resize (window, GTK_WIDGET (window)->allocation.width, + MAX (580, GTK_WIDGET (window)->allocation.height)); + + YGtkWizard *wizard = YGTK_WIZARD (getWidget()); + ygtk_wizard_set_header_icon (wizard, window, + THEMEDIR "/icons/32x32/apps/yast-software.png"); + ygtk_wizard_set_header_text (wizard, window, _("Package Selector")); + ygtk_wizard_set_help_text (wizard, + _("TO WRITE") + ); + + ygtk_wizard_set_abort_button_label (wizard, _("_Cancel")); + ygtk_wizard_set_abort_button_id (wizard, g_strdup ("cancel"), g_free); + ygtk_wizard_set_back_button_label (wizard, ""); + ygtk_wizard_set_next_button_label (wizard, _("_Accept")); + ygtk_wizard_set_next_button_id (wizard, g_strdup ("accept"), g_free); + g_signal_connect (G_OBJECT (getWidget()), "action-triggered", + G_CALLBACK (wizard_action_cb), this); + + m_package_selector = new PackageSelector(); + gtk_container_add (GTK_CONTAINER (wizard), m_package_selector->getWidget()); + + Ypp::get()->setInterface (this); + } + + virtual ~YGPackageSelector() + { + delete m_package_selector; + ygtk_zypp_model_finish(); + } + +protected: + static void wizard_action_cb (YGtkWizard *wizard, gpointer id, + gint id_type, YGPackageSelector *pThis) + { + IMPL + const gchar *action = (gchar *) id; + + if (!strcmp (action, "accept")) { + y2milestone ("Closing PackageSelector with 'accept'"); + YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept"))); + } + else if (!strcmp (action, "cancel")) { + y2milestone ("Closing PackageSelector with 'cancel'"); + if (pThis->confirmExit()) + YGUI::ui()->sendEvent (new YCancelEvent()); + } + } + + bool confirmExit() + { + if (!Ypp::get()->isModified()) + return true; + + GtkWidget *dialog; + dialog = gtk_message_dialog_new + (YGUI::ui()->currentWindow(), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, _("Changes not saved!")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Quit anyway?")); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + GTK_STOCK_QUIT, GTK_RESPONSE_YES, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); + + bool ok = gtk_dialog_run (GTK_DIALOG (dialog)) == + GTK_RESPONSE_YES; + gtk_widget_destroy (dialog); + return ok; + } + static bool confirm_cb (void *pThis) + { return ((YGPackageSelector *)pThis)->confirmExit(); } + + virtual bool acceptLicense (Ypp::Package *package, const std::string &license) + { + std::string title = package->name() + _(" License Agreement"); + GtkWidget *dialog = gtk_dialog_new_with_buttons (title.c_str(), + YGUI::ui()->currentWindow(), GTK_DIALOG_NO_SEPARATOR, + _("_Reject"), GTK_RESPONSE_REJECT, _("_Accept"), GTK_RESPONSE_ACCEPT, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); + + GtkWidget *license_view, *license_window; + + license_view = ygtk_html_wrap_new(); + ygtk_html_wrap_set_text (license_view, license.c_str()); + + license_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (license_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (license_window), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (license_window), license_view); + + GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox); + gtk_box_pack_start (vbox, license_window, TRUE, TRUE, 6); + + gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400); + gtk_widget_show_all (dialog); + + gint ret = gtk_dialog_run (GTK_DIALOG (dialog)); + bool confirmed = (ret == GTK_RESPONSE_ACCEPT); + + gtk_widget_destroy (dialog); + return confirmed; + } + + virtual bool resolveProblems (std::list <Ypp::Problem *> problems) + { +fprintf (stderr, "resolving %d problems\n", problems.size()); + // we can't use ordinary radio buttons, as gtk+ enforces that in a group + // one must be selected... + + enum ColumnAlias { + SHOW_TOGGLE_COL, ACTIVE_TOGGLE_COL, TEXT_COL, WEIGHT_TEXT_COL, + APPLY_PTR_COL, TOOLTIP_TEXT_COL + }; + + struct inner { + static void solution_toggled (GtkTreeModel *model, GtkTreePath *path) + { + GtkTreeStore *store = GTK_TREE_STORE (model); + GtkTreeIter iter, parent; + + gboolean enabled; + bool *apply; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, ACTIVE_TOGGLE_COL, &enabled, + APPLY_PTR_COL, &apply, -1); + + // disable all the other radios on the group, setting current + gtk_tree_model_get_iter (model, &iter, path); + if (gtk_tree_model_iter_parent (model, &parent, &iter)) { + gtk_tree_model_iter_children (model, &iter, &parent); + do { + gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, FALSE, -1); + bool *apply; + gtk_tree_model_get (model, &iter, APPLY_PTR_COL, &apply, -1); + *apply = false; + } while (gtk_tree_model_iter_next (model, &iter)); + } + + enabled = !enabled; + if (apply) + *apply = enabled; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, enabled, -1); + } +#if 0 + static void renderer_toggled_cb (GtkCellRenderer *render, gchar *path_str, + GtkTreeModel *model) + { + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + solution_toggled (model, path); + gtk_tree_path_free (path); + } +#endif + static void cursor_changed_cb (GtkTreeView *view, GtkTreeModel *model) + { + GtkTreePath *path; + gtk_tree_view_get_cursor (view, &path, NULL); + solution_toggled (model, path); + gtk_tree_path_free (path); + } + static gboolean query_tooltip_cb (GtkWidget *view, gint x, gint y, + gboolean keyboard_mode, GtkTooltip *tooltip, gpointer data) + { + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (view), + &x, &y, keyboard_mode, &model, &path, &iter)) { + gchar *tooltip_str; + gtk_tree_model_get (model, &iter, TOOLTIP_TEXT_COL, + &tooltip_str, -1); + gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (view), tooltip, path); + gtk_tree_path_free (path); + if (tooltip_str) { + gtk_tooltip_set_text (tooltip, tooltip_str); + g_free (tooltip_str); + return TRUE; + } + } + return FALSE; + + +/* + GtkTreePath *path; + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x, y, + &path, NULL, NULL, NULL)) { + GtkTreeIter iter; + gchar *tooltip_text; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + gtk_tree_model_get (model, &iter, + TOOLTIP_TEXT_COL, &tooltip_text, -1); + // some strings are just " ", so we need to check that + // now, + bool empty = true; + for (int i = 0; tooltip_text[i] && empty; i++) + if (tooltip_text[i] != ' ') + empty = false; + if (empty) + gtk_tooltip_set_text (tooltip, "(no details)"); + else + gtk_tooltip_set_text (tooltip, tooltip_text); + g_free (tooltip_text); + return TRUE; + } + return FALSE; +*/ + } + }; + + // model + GtkTreeStore *store = gtk_tree_store_new (6, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_STRING); + for (std::list <Ypp::Problem *>::iterator it = problems.begin(); + it != problems.end(); it++) { + GtkTreeIter problem_iter; + gtk_tree_store_append (store, &problem_iter, NULL); + gtk_tree_store_set (store, &problem_iter, SHOW_TOGGLE_COL, FALSE, + TEXT_COL, (*it)->description.c_str(), + WEIGHT_TEXT_COL, PANGO_WEIGHT_BOLD, APPLY_PTR_COL, NULL, + TOOLTIP_TEXT_COL, (*it)->details.c_str(), -1); + + for (int i = 0; (*it)->getSolution (i); i++) { + Ypp::Problem::Solution *solution = (*it)->getSolution (i); + GtkTreeIter solution_iter; + const gchar *tooltip_text = solution->details.c_str(); + if (solution->details.empty()) + tooltip_text = NULL; + gtk_tree_store_append (store, &solution_iter, &problem_iter); + gtk_tree_store_set (store, &solution_iter, SHOW_TOGGLE_COL, TRUE, + ACTIVE_TOGGLE_COL, FALSE, TEXT_COL, solution->description.c_str(), + APPLY_PTR_COL, &solution->apply, + TOOLTIP_TEXT_COL, tooltip_text, -1); + } + } + + // interface + GtkWidget *dialog = gtk_message_dialog_new (YGUI::ui()->currentWindow(), + GtkDialogFlags (0), GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, + _("There are some conflicts on the transaction that must be " + "solved manually.")); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY); + + GtkWidget *view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + g_object_unref (G_OBJECT (store)); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (view)), GTK_SELECTION_NONE); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), TEXT_COL); + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + renderer = gtk_cell_renderer_toggle_new(); + gtk_cell_renderer_toggle_set_radio ( + GTK_CELL_RENDERER_TOGGLE (renderer), TRUE); +/* g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (inner::renderer_toggled_cb), store);*/ + // we should not connect the actual toggle button, as we toggle on row press + g_signal_connect (G_OBJECT (view), "cursor-changed", + G_CALLBACK (inner::cursor_changed_cb), store); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "visible", SHOW_TOGGLE_COL, "active", ACTIVE_TOGGLE_COL, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "text", TEXT_COL, "weight", WEIGHT_TEXT_COL, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + gtk_tree_view_expand_all (GTK_TREE_VIEW (view)); + gtk_widget_set_has_tooltip (view, TRUE); + g_signal_connect (G_OBJECT (view), "query-tooltip", + G_CALLBACK (inner::query_tooltip_cb), store); + + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), + GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (scroll), view); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll); + + +#if 0 + // version that uses viewport, labels and radio buttons -- unfortunately, + // gtk+ enforces that one radio button per group to be selected -- we don't + // want that as the user may decide to do nothing for a certain action. + // We also don't want to add a "Do nothing" radio, as that would imply would + // dismiss the conflict. No, we just want to let the user try to resolve current + // conflicts... + struct inner { + static void solution_toggled (GtkToggleButton *toggle, bool *apply) + { *apply = gtk_toggle_button_get_active (toggle); } + }; + + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Problem Resolver"), + YGUI::ui()->currentWindow(), GtkDialogFlags (0), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL); + + GtkWidget *view_port = gtk_viewport_new (NULL, NULL); + gtk_viewport_set_shadow_type (GTK_VIEWPORT (view_port), GTK_SHADOW_NONE); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), view_port, + TRUE, TRUE, 0); + GtkWidget *main_box = gtk_vbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (view_port), main_box); + +fprintf (stderr, "populating main box\n"); + for (std::list <Ypp::Problem *>::iterator it = problems.begin(); + it != problems.end(); it++) { + GtkWidget *label, *box; +fprintf (stderr, "creating label: %s\n", (*it)->description.c_str()); + label = gtk_label_new ((*it)->description.c_str()); + YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); +fprintf (stderr, "setting tooltyp: %s\n", (*it)->details.c_str()); + if (!(*it)->details.empty()) + gtk_widget_set_tooltip_text (label, (*it)->details.c_str()); + + GSList *group = NULL; + box = gtk_vbox_new (FALSE, 6); + for (int i = 0; (*it)->getSolution (i); i++) { + Ypp::Problem::Solution *solution = (*it)->getSolution (i); +fprintf (stderr, "creating radio: %s\n", solution->description.c_str()); + GtkWidget *radio = gtk_radio_button_new_with_label ( + group, solution->description.c_str()); +fprintf (stderr, "setting tooltip: %s\n", (*it)->details.c_str()); + if (!solution->details.empty()) + gtk_widget_set_tooltip_text (radio, solution->details.c_str()); + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); + gtk_box_pack_start (GTK_BOX (box), radio, FALSE, TRUE, 0); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (inner::solution_toggled), &solution->apply); + } + + gtk_box_pack_start (GTK_BOX (main_box), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0); + } +#endif + + gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); + gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 480); + gtk_widget_show_all (dialog); + + bool apply = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_APPLY); + gtk_widget_destroy (dialog); + return apply; + } + + virtual void packageModified (Ypp::Package *package) + { + m_package_selector->packageModified (package); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createPackageSelector (YWidget *parent, YWidgetOpt &opt, + const YCPString &floppyDevice) +{ +/* if (opt.youMode.value()) + return new YGPatchSelector (opt, YGWidget::get (parent)); + else*/ + return new YGPackageSelector (opt, YGWidget::get (parent)); +} + +YWidget * +YGUI::createPkgSpecial (YWidget *parent, YWidgetOpt &opt, + const YCPString &subwidget) +{ + // same as Qt's + y2error ("The GTK+ UI does not support PkgSpecial subwidgets!"); + return 0; +} + Added: trunk/gtk/unstable/src/YGPackageSelector.cc-ori URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGPackageSelecto... ============================================================================== --- trunk/gtk/unstable/src/YGPackageSelector.cc-ori (added) +++ trunk/gtk/unstable/src/YGPackageSelector.cc-ori Thu Nov 29 18:22:01 2007 @@ -0,0 +1,2680 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* + Textdomain "yast2-gtk" +*/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YGi18n.h" +#include "YGDialog.h" +#include "YPackageSelector.h" +#include "ygtkhtmlwrap.h" +#include "ygtkwizard.h" +#include "ygtkcellrendererarrow.h" +#include "ygtkratiobox.h" +#include "ygtkfindentry.h" + +#include <map> + +//#define DISABLE_PACKAGE_SELECTOR + +#ifndef DISABLE_PACKAGE_SELECTOR +#include <zypp/ZYppFactory.h> +#include <zypp/ResObject.h> +#include <zypp/ResPoolProxy.h> +#include <zypp/ui/Selectable.h> +#include <zypp/Patch.h> +#include <zypp/Selection.h> +#include <zypp/Package.h> +#include <zypp/Pattern.h> +#include <zypp/Language.h> +#include <zypp/Product.h> +#ifdef PRE_ZYPP_3 +#include <zypp/Source.h> +#include <zypp/SourceManager.h> +#else +#include <zypp/Repository.h> +#include <zypp/RepoManager.h> +#endif + +/* We should consider linking to libgnome and use gnome_url_show(url) here, + or at least do some path finding. */ +#define FILEMANAGER_EXEC "/usr/bin/nautilus" +inline bool FILEMANAGER_PRESENT() +{ return g_file_test (FILEMANAGER_EXEC, G_FILE_TEST_IS_EXECUTABLE); } +inline void FILEMANAGER_LAUNCH (const char *path) +{ system ((string (FILEMANAGER_EXEC) + " " + path + " &").c_str()); } + +// some typedefs and functions to short Zypp names +typedef zypp::ResPoolProxy ZyppPool; +inline ZyppPool zyppPool() { return zypp::getZYpp()->poolProxy(); } +typedef zypp::ui::Selectable::Ptr ZyppSelectable; +typedef zypp::ui::Selectable* ZyppSelectablePtr; +typedef zypp::ResObject::constPtr ZyppObject; +typedef zypp::Package::constPtr ZyppPackage; +typedef zypp::Patch::constPtr ZyppPatch; +typedef zypp::Pattern::constPtr ZyppPattern; +typedef zypp::Language::constPtr ZyppLanguage; +inline ZyppPackage tryCastToZyppPkg (ZyppObject obj) + { return zypp::dynamic_pointer_cast <const zypp::Package> (obj); } +inline ZyppPatch tryCastToZyppPatch (ZyppObject obj) + { return zypp::dynamic_pointer_cast <const zypp::Patch> (obj); } +inline ZyppPattern tryCastToZyppPattern (ZyppObject obj) + { return zypp::dynamic_pointer_cast <const zypp::Pattern> (obj); } +inline ZyppLanguage tryCastToZyppLanguage (ZyppObject obj) + { return zypp::dynamic_pointer_cast <const zypp::Language> (obj); } + +static zypp::Text +fastGetSummary (ZyppObject obj) +{ + static std::map<std::string, zypp::Text> name_to_summary; + std::string &summary = name_to_summary[ obj->name() ]; + if (summary.length() <= 0) + summary = obj->summary(); + return summary; +} + +// Computer icon comes from Tango, but may not be installed, or not initialized. +#include "computer.xpm" + +static bool acceptLicense (ZyppSelectablePtr sel) +{ + if (sel->hasLicenceConfirmed()) + return true; + + ZyppObject object = sel->candidateObj(); + ZyppPackage package = tryCastToZyppPkg (object); + if (!package) + return true; + + const string &license = package->licenseToConfirm(); + if (license.empty()) { + sel->setLicenceConfirmed (true); + return true; + } + + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("License Agreement"), + YGUI::ui()->currentWindow(), GTK_DIALOG_MODAL, + _("_Reject"), GTK_RESPONSE_REJECT, _("_Accept"), GTK_RESPONSE_ACCEPT, NULL); + + GtkWidget *license_view, *license_window; + + license_view = ygtk_html_wrap_new(); + ygtk_html_wrap_set_text (license_view, license.c_str()); + + license_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (license_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (license_window), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (license_window), license_view); + + GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox); + gtk_box_pack_start (vbox, license_window, TRUE, TRUE, 6); + + const char *print_text = _("If you would like to print this license, check the EULA.txt file on the first media"); + GtkLabel *print_label = GTK_LABEL (gtk_label_new (print_text)); + gtk_box_pack_start (vbox, GTK_WIDGET (print_label), FALSE, TRUE, 2); + + gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400); + gtk_widget_show_all (dialog); + + bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT; + gtk_widget_destroy (dialog); + + sel->setLicenceConfirmed (confirmed); + return confirmed; +} + +// install / remove convinience wrapper. You only need to specify an object +// if you want that particular version to be installed. +// returns true on sucess +static bool mark_selectable (ZyppSelectablePtr selectable, bool install /*or remove*/) +{ + zypp::ui::Status status = selectable->status(); + + if (install) { + if (!selectable->hasCandidateObj()) { + y2warning ("YGPackageSelector: no package on repository to install"); + return false; + } + if (!acceptLicense (selectable)) + return false; + if (status == zypp::ui::S_Del) + status = zypp::ui::S_KeepInstalled; + else { + if (status == zypp::ui::S_KeepInstalled) + status = zypp::ui::S_Update; + else + status = zypp::ui::S_Install; + } + } + else /*remove*/ { + if (status == zypp::ui::S_NoInst) + ; // do nothing + else if (status == zypp::ui::S_Install) + status = zypp::ui::S_NoInst; + else if (status == zypp::ui::S_Update) + status = zypp::ui::S_KeepInstalled; + else + status = zypp::ui::S_Del; + } + +#if 0 // debug + const char *name = selectable->name().c_str(); + switch (status) { + case zypp::ui::S_KeepInstalled: + y2milestone ("keep %s installed\n", name); + break; + case zypp::ui::S_Update: + y2milestone ("update %s\n", name); + break; + case zypp::ui::S_Install: + y2milestone ("install %s\n", name); + break; + case zypp::ui::S_Del: + y2milestone ("remove %s\n", name); + break; + case zypp::ui::S_NoInst: + y2milestone ("don't install %s\n", name); + break; + default: + y2milestone ("error: unknown action: should not happen\n"); + break; + } +#endif + + return selectable->set_status (status); +} + +// tries to solve possible dependencies problems and asks the user for +// manual resolution if needed (there is not much space for interface +// design here) +static bool solveProblems() +{ + IMPL + zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver(); + if (resolver->resolvePool()) + return true; + zypp::ResolverProblemList problems = resolver->problems(); + if (problems.empty()) + return true; + + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Resolve Problems"), + YGUI::ui()->currentWindow(), GTK_DIALOG_MODAL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("C_onfirm"), GTK_RESPONSE_ACCEPT, NULL); + + GtkWidget *problems_view; + problems_view = gtk_tree_view_new(); + + GtkWidget *problems_window; + problems_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (problems_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (problems_window), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (problems_window), problems_view); + + GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox); + gtk_box_pack_start (vbox, problems_window, TRUE, TRUE, 0); + + // create model + // the vairous columns are: radio button active (boolean), problem + // or solution description (string), is radio button (boolean: always + // true), show radio button (boolean; false for problems) + GtkTreeStore *problems_store = gtk_tree_store_new (4, + G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + // install view + GtkTreeViewColumn *column; + GtkCellRenderer *radio_renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes ("", + radio_renderer, "active", 0, "radio", 2, "visible", 3, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (problems_view), column); + g_signal_connect (G_OBJECT (radio_renderer), "toggled", + G_CALLBACK (YGUtils::tree_view_radio_toggle_cb), + GTK_TREE_MODEL (problems_store)); + + column = gtk_tree_view_column_new_with_attributes (_("Problems"), + gtk_cell_renderer_text_new(), "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (problems_view), column); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (problems_view), FALSE); + gtk_tree_view_set_model (GTK_TREE_VIEW (problems_view), + GTK_TREE_MODEL (problems_store)); + g_object_unref (G_OBJECT (problems_store)); + + // construct model + GtkTreeIter piter, siter; + map <GtkTreePath *, zypp::ProblemSolution *> users_actions; + for (zypp::ResolverProblemList::iterator it = problems.begin(); + it != problems.end(); it++) { + zypp::ProblemSolutionList solutions = (*it)->solutions(); + + gtk_tree_store_append (problems_store, &piter, NULL); + gtk_tree_store_set (problems_store, &piter, 0, FALSE, + 1, (*it)->description().c_str(), 2, TRUE, 3, FALSE, -1); + + for (zypp::ProblemSolutionList::iterator jt = solutions.begin(); + jt != solutions.end(); jt++) { + gtk_tree_store_append (problems_store, &siter, &piter); + gtk_tree_store_set (problems_store, &siter, 0, FALSE, + 1, (*jt)->description().c_str(), 2, TRUE, 3, TRUE, -1); + users_actions [gtk_tree_model_get_path (GTK_TREE_MODEL ( + problems_store), &siter)] = get_pointer (*jt); + } + } + + // set tree properties + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (problems_view)), GTK_SELECTION_NONE); + gtk_tree_view_expand_all (GTK_TREE_VIEW (problems_view)); + + gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400); + gtk_widget_show_all (dialog); + + bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT; + + if (confirmed) { + // apply user solutions + zypp::ProblemSolutionList userChoices; + + GtkTreeIter iter; + for (map <GtkTreePath *, zypp::ProblemSolution *>::iterator it + = users_actions.begin(); it != users_actions.end(); it++) { + gtk_tree_model_get_iter (GTK_TREE_MODEL (problems_store), + &iter, it->first); + gboolean state = FALSE; + gtk_tree_model_get (GTK_TREE_MODEL (problems_store), &iter, + 0, &state, -1); + if (state) + userChoices.push_back (it->second); + + gtk_tree_path_free (it->first); + } + resolver->applySolutions (userChoices); + } + + gtk_widget_destroy (dialog); + if (confirmed) + // repeate the all process as things may not yet be solved + return solveProblems(); + return false; +} + +#ifdef PRE_ZYPP_3 +static string getSourceName (zypp::Source_Ref source) +{ // based on yast-qt's singleProduct() + if (!source.enabled()) + // can't get name if disabled; strangely, source.resolvables().begin() + // hangs + return ""; + string ret; + bool found = false; + for (zypp::ResStore::iterator it = source.resolvables().begin(); + it != source.resolvables().end(); it++) { + zypp::Product::Ptr product; + product = zypp::dynamic_pointer_cast <zypp::Product> (*it); + if (product) { + if (found) { + y2milestone ("Multiple products on installation source %s", + source.alias().c_str()); + return ""; + } + found = true; + ret = fastGetSummary (product); + } + } + + if (!found) + y2milestone ("No product on installation source %s", + source.alias().c_str()); + return ret; +} +#endif + +#define PACKAGE_INFO_HEIGHT 140 +#define ADVANCED_INFO_HEIGHT 80 + +// Expander widget with the package information +class PackageInformation +{ + GtkWidget *m_widget, *m_notebook; + // Information text + GtkWidget *m_about_text, *m_authors_text, *m_filelist_text, *m_changelog_text; + bool m_use_filemanager; + +public: + PackageInformation (const char *expander_text, bool only_description) + { + m_widget = gtk_expander_new (expander_text); + gtk_widget_set_sensitive (m_widget, FALSE); + + if (only_description) { + GtkWidget *about_win = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (about_win), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + m_about_text = ygtk_html_wrap_new(); + gtk_container_add (GTK_CONTAINER (about_win), m_about_text); + gtk_container_add (GTK_CONTAINER (m_widget), about_win); + m_authors_text = m_filelist_text = m_changelog_text = NULL; + m_notebook = NULL; + } + else { + m_notebook = gtk_notebook_new(); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (m_notebook), GTK_POS_BOTTOM); + gtk_container_add (GTK_CONTAINER (m_widget), m_notebook); + + m_about_text = add_text_tab (m_notebook, _("Description")); + m_filelist_text = add_text_tab (m_notebook, _("File List")); + if ((m_use_filemanager = FILEMANAGER_PRESENT())) + ygtk_html_wrap_connect_link_clicked (m_filelist_text, + G_CALLBACK (dir_pressed_cb), NULL); + m_changelog_text = add_text_tab (m_notebook, _("Change Log")); + m_authors_text = add_text_tab (m_notebook, _("Authors")); + } + gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (m_widget)), + -1, PACKAGE_INFO_HEIGHT); + } + + GtkWidget *getWidget() + { return m_widget; } + + void setPackage (ZyppSelectablePtr selectable, ZyppObject object) + { + if (!selectable || !object) { + if (m_about_text) + set_text (m_about_text, ""); + if (m_filelist_text) + set_text (m_filelist_text, ""); + if (m_changelog_text) + set_text (m_changelog_text, ""); + if (m_authors_text) + set_text (m_authors_text, ""); + gtk_expander_set_expanded (GTK_EXPANDER (m_widget), FALSE); + gtk_widget_set_sensitive (m_widget, FALSE); + return; + } + + /* Keep notebook on first page; but only when not visible to not + annoy the user. */ + if (m_notebook && !gtk_expander_get_expanded (GTK_EXPANDER (m_widget))) + gtk_notebook_set_current_page (GTK_NOTEBOOK (m_notebook), 0); + gtk_widget_set_sensitive (m_widget, TRUE); + + ZyppPackage package = tryCastToZyppPkg (object); + if (m_about_text) { + string description = YGUtils::escape_markup (object->description(), true); + + // cut authors, since they have their own section + string::size_type pos = description.find ("Authors:"); + if (pos != string::npos) + description.erase (pos, string::npos); + + string str; + if (package) { + description += "<br>"; + str = package->url(); + if (!str.empty()) + description += _("Website: ") + str + "<br>"; + str = package->license(); + if (!str.empty()) + description += _("License: ") + str + "<br>"; + description += _("Size: ") + object->size().asString() + "b<br>"; + } + +#ifdef PRE_ZYPP_3 + zypp::Source_Ref source = object->source(); + str = getSourceName (source); + if (str.empty()) + str = source.url().asString(); + else + str = str + " (" + source.url().asString() + ")"; +#else + zypp::Repository repo = object->repository(); + str = repo.info().name(); +#endif + if (!str.empty()) + description += _("Repository: ") + str; + + set_text (m_about_text, description); + } + if (package) { + if (m_filelist_text) { + string filelist; + const std::list <string> &filenames = package->filenames(); + for (std::list <string>::const_iterator it = filenames.begin(); + it != filenames.end(); it++) { + string file (*it); + // don't show created dirs + if (g_file_test (file.c_str(), G_FILE_TEST_IS_DIR)) + continue; + // set the path as a link + if (m_use_filemanager) { + string::size_type pos = file.find_last_of ('/'); + if (pos != string::npos) { // should be always true + string dirname (file, 0, pos+1); + string basename (file, pos+1, string::npos); + file = "<a href=" + dirname + ">" + dirname + "</a>" + basename; + } + } + filelist += file + "<br>"; + } + set_text (m_filelist_text, filelist); + } + if (m_changelog_text) { + string text; + const std::list <zypp::ChangelogEntry> &changelog = package->changelog(); + for (std::list <zypp::ChangelogEntry>::const_iterator it = changelog.begin(); + it != changelog.end(); it++) { + string t = "<blockquote>" + YGUtils::escape_markup (it->text(), true) + + "</blockquote>"; + text += "<p>" + it->date().asString() + "" + + YGUtils::escape_markup (it->author()) + ":<br>" + + t + "</p>"; + } + set_text (m_changelog_text, text); + } + if (m_authors_text) { + string packager (YGUtils::escape_markup (package->packager())), authors; + + const std::list <string> &authors_list = package->authors(); + if (!authors_list.empty()) { + for (std::list <string>::const_iterator it = authors_list.begin(); + it != authors_list.end(); it++) + authors += *it; + } + else { + /* authors() should be the proper way to get authors, but it seems to + be rarely used, instead packagers list them on the description. */ + string description (object->description()); +std::cerr << "description: " << description << std::endl; + string::size_type pos = description.find ("Authors:"); + if (pos != string::npos) { + pos = description.find_first_not_of ( + '-', pos + sizeof ("Authors:") + 1); +std::cerr << "copy string from " << pos << std::endl; + authors = string (description, pos, string::npos); + authors = YGUtils::escape_markup (authors, true); +std::cerr << "authors: " << authors << std::endl; + } + } + + string text; + if (!packager.empty()) + text = _("Packaged by:") + ("<blockquote>" + packager) + + "</blockquote>"; + if (!authors.empty()) { + if (!packager.empty()) + text += "<br><br>"; + text += _("Developed by:") + ("<blockquote>" + authors) + + "</blockquote>"; + } + set_text (m_authors_text, text); + } + } + else { + if (m_filelist_text) + set_text (m_filelist_text, ""); + if (m_changelog_text) + set_text (m_changelog_text, ""); + if (m_authors_text) + set_text (m_authors_text, ""); + } + } + +private: + // auxiliaries to cut down on code + static GtkWidget *add_text_tab (GtkWidget *notebook, const char *label) + { + GtkWidget *widget, *scroll_win; + scroll_win = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + widget = ygtk_html_wrap_new(); + gtk_container_add (GTK_CONTAINER (scroll_win), widget); + + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scroll_win, + gtk_label_new (label)); + return widget; + } + + static void set_text (GtkWidget *widget, const string &text) + { + const char *str = _("<i>(not available)</i>"); + if (!text.empty()) + str = text.c_str(); + ygtk_html_wrap_set_text (widget, str); + ygtk_html_wrap_scroll (widget, TRUE); // scroll to the start + } + + /* When a directory is pressed on the file list. */ + static void dir_pressed_cb (GtkWidget *text, const gchar *link) + { FILEMANAGER_LAUNCH (link); } +}; + +// Table widget with package sources + /* I don't like this, since it differs from the rest of the code, but to + avoid declarations... */ + struct SourcesTableListener + { + virtual ~SourcesTableListener() {} + virtual void sources_changed_cb() = 0; + }; +class SourcesTable +{ + GtkWidget *m_widget; + GtkTreeModel *m_model; + SourcesTableListener *m_listener; + +public: + SourcesTable (SourcesTableListener *listener) + : m_listener (listener) + { + /* 0 - source enabled?, 1 - source name (estimation), 2 - source URL, + 3 - source id; what they call of alias. */ + GtkListStore *store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING); + m_model = GTK_TREE_MODEL (store); + +#ifdef PRE_ZYPP_3 + zypp::SourceManager_Ptr manager = zypp::SourceManager::sourceManager(); + for (zypp::SourceManager::Source_const_iterator it = manager->Source_begin(); + it != manager->Source_end(); it++) { + zypp::Source_Ref src = *it; + if (src && src.enabled()) { + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, src.enabled(), + 1, getSourceName (src).c_str(), 2, src.url().asString().c_str(), + 3, src.alias().c_str(), -1); + } + } +#else + zypp::RepoManager manager; + std::list <zypp::RepoInfo> repos = manager.knownRepositories(); + for (std::list <zypp::RepoInfo>::iterator it = repos.begin(); + it != repos.end(); it++) { + if (it->enabled()) { + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, bool(it->enabled()), + 1, it->name().c_str(), 2, it->alias().c_str(), -1); + } + } +#endif + + GtkWidget *view = gtk_tree_view_new_with_model (m_model); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), + GTK_SELECTION_NONE); + g_object_unref (G_OBJECT (m_model)); // tree view will take care of it + + // prepare the view + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "active", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (source_toggled_cb), this); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + +#ifdef PRE_ZYPP_3 + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "text", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); +#endif + + m_widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (m_widget, -1, ADVANCED_INFO_HEIGHT); + gtk_container_add (GTK_CONTAINER (m_widget), view); + } + + GtkWidget *getWidget() + { return m_widget; } + +private: + static void source_toggled_cb (GtkCellRendererToggle *renderer, + gchar *path_str, SourcesTable *pThis) + { + IMPL + GtkTreeModel *model = pThis->m_model; + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + +#ifdef PRE_ZYPP_3 + gchar *alias; + gtk_tree_model_get (model, &iter, 3, &alias, -1); + + zypp::SourceManager_Ptr manager = zypp::SourceManager::sourceManager(); + zypp::Source_Ref source = manager->findSource (alias); + g_free (alias); + + if (gtk_cell_renderer_toggle_get_active (renderer)) + source.disable(); + else + source.enable(); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + 0, source.enabled(), -1); +#else + gchar *alias; + gtk_tree_model_get (model, &iter, 2, &alias, -1); + + zypp::RepoManager manager; + zypp::RepoInfo repo = manager.getRepositoryInfo (alias); + g_free (alias); + + bool enable = !gtk_cell_renderer_toggle_get_active (renderer); + repo.setEnabled (enable); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + 0, bool (repo.enabled()), -1); +#endif + + pThis->m_listener->sources_changed_cb(); + } +}; + +// Table widget to monitor disk partitions space-usage +#define MIN_FREE_MB_WARN (80*1024) + +class DiskTable +{ + GtkWidget *m_widget; + GtkTreeModel *m_model; + bool m_has_warned; // only warn once + + // evil long names + typedef zypp::DiskUsageCounter::MountPoint ZyppDu; + typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet; + typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator; + +public: + DiskTable() + { + m_has_warned = false; + if (zypp::getZYpp()->diskUsage().empty()) + zypp::getZYpp()->setPartitions ( + zypp::DiskUsageCounter::detectMountPoints()); + + /* 0 - mount point (also used as id), 1 - percentage of disk usage + ([0, 100]), 2 - disk usage detail (i.e. "200Mb of 1Gb") */ + GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, + G_TYPE_STRING); + m_model = GTK_TREE_MODEL (store); + update(); + + GtkWidget *view = gtk_tree_view_new_with_model (m_model); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), + GTK_SELECTION_NONE); + g_object_unref (G_OBJECT (m_model)); // tree view will take care of it + + // prepare the view + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes (_("Mount Point"), + renderer, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + renderer = gtk_cell_renderer_progress_new(); + column = gtk_tree_view_column_new_with_attributes (_("Usage"), + renderer, "value", 1, "text", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + m_widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (m_widget, -1, ADVANCED_INFO_HEIGHT); + gtk_container_add (GTK_CONTAINER (m_widget), view); + } + + GtkWidget *getWidget() + { return m_widget; } + + static string sizeToString (long long size) + { + zypp::ByteCount count (size, zypp::ByteCount::K); + return count.asString(); + } + + void update() + { + GtkListStore *store = GTK_LIST_STORE (m_model); + gtk_list_store_clear (store); + + bool warning = false; + ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage(); + for (ZyppDuSetIterator it = diskUsage.begin(); it != diskUsage.end(); it++) { + const ZyppDu &partition = *it; + if (!partition.readonly) { + // partition fields: dir, used_size, total_size (size on Kb) + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + + long usage = (partition.pkg_size * 100) / (partition.total_size + 1); + string usage_str = sizeToString (partition.pkg_size) + " (of " + + sizeToString (partition.total_size) + ")"; + gtk_list_store_set (store, &iter, 0, partition.dir.c_str(), + 1, usage, 2, usage_str.c_str(), -1); + + warning = warning || + (partition.total_size > 1024 && + partition.total_size - partition.pkg_size < MIN_FREE_MB_WARN); + } + } + if (warning) + warn(); + } + + void warn() + { + if (m_has_warned) + return; + m_has_warned = true; + + GtkWidget *dialog, *view, *scroll_view; + dialog = gtk_message_dialog_new_with_markup (YGUI::ui()->currentWindow(), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, _("<b>Disk Almost Full !</b>\n\n" + "One of the partitions is reaching its limit of capacity. You may " + "have to remove packages if you wish to install some.")); + + view = gtk_tree_view_new_with_model (m_model); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), + GTK_SELECTION_NONE); + + GtkTreeViewColumn *column; + column = gtk_tree_view_column_new_with_attributes (_("Mount Point"), + gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + column = gtk_tree_view_column_new_with_attributes (_("Usage"), + gtk_cell_renderer_progress_new(), + "value", 1, "text", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + scroll_view = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_view), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (scroll_view, -1, 80); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll_view), + GTK_SHADOW_OUT); + gtk_container_add (GTK_CONTAINER (scroll_view), view); + gtk_widget_show_all (scroll_view); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll_view); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } +}; + +// YOU patch selector +class YGPatchSelector : public YPackageSelector, public YGWidget +{ + GtkWidget *m_patches_view; + GtkTreeModel *m_patches_model; // GtkListStore type + + // Package information widget + PackageInformation *m_information_widget; + +public: + YGPatchSelector (const YWidgetOpt &opt, YGWidget *parent) + : YPackageSelector (opt), + YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL) + { + setBorder (0); + GtkWidget *main_vbox = gtk_vbox_new (FALSE, 0); + + YGtkWizard *wizard = YGTK_WIZARD (getWidget()); + ygtk_wizard_set_child (YGTK_WIZARD (getWidget()), main_vbox); + GtkWindow *window = YGUI::ui()->currentWindow(); + ygtk_wizard_set_header_text (wizard, window, _("Patch Selector")); + ygtk_wizard_set_header_icon (wizard, window, + THEMEDIR "/icons/32x32/apps/yast-software.png"); + ygtk_wizard_set_help_text (wizard, + _("For information on a given patch, just press it and as well as the " + "Package Information expander to make those informations visible.<br>" + "To install a patch you just need to press the check button next to it " + "and then the button Install when you are done.") + ); + ygtk_wizard_set_next_button_label (wizard, _("_Install")); + ygtk_wizard_set_next_button_id (wizard, g_strdup ("install"), g_free); + ygtk_wizard_set_abort_button_label (wizard, _("_Cancel")); + ygtk_wizard_set_abort_button_id (wizard, g_strdup ("cancel"), g_free); + g_signal_connect (G_OBJECT (getWidget()), "action-triggered", + G_CALLBACK (wizard_action_cb), this); + + m_patches_view = gtk_tree_view_new(); + GtkWidget *patches_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (patches_window), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (patches_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (patches_window), m_patches_view); + + m_information_widget = new PackageInformation (_("Patch Information"), true); + GtkWidget *pkg_info_widget = m_information_widget->getWidget(); + + gtk_box_pack_start (GTK_BOX (main_vbox), patches_window, TRUE, TRUE, 6); + gtk_box_pack_start (GTK_BOX (main_vbox), pkg_info_widget, FALSE, FALSE, 6); + gtk_widget_show_all (main_vbox); + + // Create a model for the patches lists + // models' columns: selected radio button state (boolean), + // package name (string), patch priority (string), selectable object (pointer) + m_patches_model = GTK_TREE_MODEL (gtk_list_store_new + (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER)); + + GtkTreeViewColumn *column; + GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes ("", renderer, + "active", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column); + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (patch_toggled_cb), this); + + column = gtk_tree_view_column_new_with_attributes (_("Priority"), + gtk_cell_renderer_text_new(), "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column); + + column = gtk_tree_view_column_new_with_attributes (_("Name"), + gtk_cell_renderer_text_new(), "text", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column); + + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Patch>(); + it != zyppPool().byKindEnd <zypp::Patch>(); it++) { + ZyppSelectable selectable = *it; + ZyppPatch patch = tryCastToZyppPatch (selectable->theObj()); + if (!patch) + continue; + bool displayPatch = false; + + // These rules are taken from YQPkgPatchList::fillList() in the RelevantPatches case + if (selectable->hasInstalledObj()) { // installed? + if (selectable->installedPoolItem().status().isIncomplete()) { // patch broken? + // The patch is broken: It had been installed, but the user somehow + // downgraded individual packages belonging to the patch to older versions. + displayPatch = true; + + y2warning( "Installed patch is broken: %s - %s", + patch->name().c_str(), + patch->summary().c_str() ); + } + } else { // not installed + if (selectable->hasCandidateObj() && selectable->candidatePoolItem().status().isSatisfied()) { + // This is a pretty exotic case, but still it might happen: + // + // The patch itelf is not installed, but it is satisfied because the + // user updated all the packages belonging to the patch to the versions + // the patch requires. All that is missing now is to get the patch meta + // data onto the system. So let's display the patch to give the user + // a chance to install it (if he so chooses). + + displayPatch = true; + + y2milestone( "Patch satisfied, but not installed yet: %s - %s", + patch->name().c_str(), + patch->summary().c_str() ); + } + } + + if (selectable->hasCandidateObj()) { // candidate available? + // The most common case: There is a candidate patch, i.e. one that could be + // installed, but either no version of that patch is installed or there is a + // newer one to which the patch could be updated. + + if (selectable->candidatePoolItem().status().isNeeded()) { // patch really needed? + // Patches are needed if any of the packages that belong to the patch + // are installed on the system. + + displayPatch = true; + } else { + // None of the packages that belong to the patch is installed on the system. + + y2debug( "Patch not needed: %s - %s", + patch->name().c_str(), + patch->summary().c_str() ); + } + } + + if (displayPatch) { + // select them all + selectable->set_status (zypp::ui::S_Install); + + GtkTreeIter iter; + GtkListStore *store = GTK_LIST_STORE (m_patches_model); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, selectable->toInstall(), + 1, patch->category().c_str(), 2, selectable->name().c_str(), + 3, get_pointer (selectable), -1); + } + } + + gtk_tree_view_set_model (GTK_TREE_VIEW (m_patches_view), m_patches_model); + + // TODO: severity should be sort by severity, not alphabetically + YGUtils::tree_view_set_sortable (GTK_TREE_VIEW (m_patches_view), 1); + + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_patches_view), 2); + + g_signal_connect (G_OBJECT (m_patches_view), "cursor-changed", + G_CALLBACK (patch_clicked_cb), this); + } + + virtual ~YGPatchSelector() + { + IMPL + g_object_unref (m_patches_model); + delete m_information_widget; + } + + static ZyppSelectablePtr selectedPatch (GtkTreeView *tree_view) + { + IMPL + GtkTreePath *path; + GtkTreeViewColumn *column; + gtk_tree_view_get_cursor (tree_view, &path, &column); + if (path) { + GtkTreeModel *model = gtk_tree_view_get_model (tree_view); + + ZyppSelectablePtr selectable = 0; + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, 3, &selectable, -1); + + gtk_tree_path_free (path); + return selectable; + } + return NULL; + } + + // callbacks + static void patch_clicked_cb (GtkTreeView *tree_view, YGPatchSelector *pThis) + { + IMPL + ZyppSelectablePtr sel = selectedPatch (tree_view); + pThis->m_information_widget->setPackage (sel, sel->theObj()); + } + + static void wizard_action_cb (YGtkWizard *wizard, gpointer id, + gint id_type, YGPatchSelector *pThis) + { + const gchar *action = (gchar *) id; + if (!strcmp (action, "install")) { + y2milestone ("Closing PackageSelector with 'accept'"); + if (solveProblems()) + YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept"))); + } + else if (!strcmp (action, "cancel")) { + y2milestone ("Closing PackageSelector with 'cancel'"); + YGUI::ui()->sendEvent (new YCancelEvent()); + } + } + + static void patch_toggled_cb (GtkCellRendererToggle *renderer, + gchar *path_str, YGPatchSelector *pThis) + { + IMPL + GtkTreeModel *model = pThis->m_patches_model; + + // Toggle the box + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + gint *column = (gint*) g_object_get_data (G_OBJECT (renderer), "column"); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + gboolean state; + ZyppSelectablePtr selectable = 0; + gtk_tree_model_get (model, &iter, 0, &state, 3, &selectable, -1); + + state = !state; + if (mark_selectable (selectable, state)) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, state, -1); + } + + YGWIDGET_IMPL_COMMON +}; + +// Package selector's widget +class PackageSelector : public SourcesTableListener +{ + +enum package_columns +{ + COL_SELECTABLE = 0, // selectable object (pointer) + COL_INSTALLED_NAME, // installed name (string) + COL_AVAILABLE_NAME, // available_name (string) + COL_IS_INSTALLED, // is installed (boolean) + COL_IS_AVAILABLE, // is available (boolean) + COL_CAN_BE_UPGRADED, // can be upgraded (boolean) + COL_CAN_BE_DOWNGRADED, // can be downgraded (boolean) + COL_SHOW_UPGRADABLE_CONTROL, // show up/downgrade control (boolean) + COL_HAS_CHILDREN, // has children + COL_FONT_STYLE // font style; italic for modified (integer) = 10 +}; + +friend class YGPackageSelector; + + GtkWidget *m_widget; + + // The GtkTreeView widgets + GtkWidget *m_installed_view, *m_available_view; + // Packages backend model + GtkTreeModel *m_packages_model; + + // Package information widget + PackageInformation *m_information_widget; + SourcesTable *m_sources_table; + DiskTable *m_disk_table; + + // Search gizmos + GtkWidget *m_search_entry, *m_plain_view; + guint search_timeout_id; + bool name_opt, summary_opt, descr_opt, provides_opt, requires_opt; + list <string> m_search_queries; + + // Interface tweak + GtkWidget *m_install_label, *m_remove_label; + +public: + PackageSelector (bool patterns_mode) + { + IMPL + m_widget = gtk_vbox_new (FALSE, 0); + + GtkWidget *packages_hbox = gtk_hbox_new (FALSE, 0); + + GtkWidget *available_box, *installed_box; + /* All views share a similar model structure. There is a common model for + all packages, where filters are installed upon to split it on two, each + installed on the tree view. The common model follows the following spec: + 0 - selectable object (pointer), 1 - installed name (string), 2 - available + name (string), 3 - is installed (boolean), 4 - is available (boolean), + 5 - can be upgraded (boolean), 6 - can be downgraded (boolean), + 7 - show up/downgrade control (boolean), 8 - has children, + 9 - font style; italic for modified (integer) = 10 + + Models are created at each view mode change (and the other freed). This + allows for more than one model type be used and is also better for speed, + since the filter and tree view then installed upon don't have to keep + syncing at every item change. */ + installed_box = createListWidget (_("<b>Installed Software:</b>"), + "computer", computer_xpm, m_installed_view, + 1, false); + available_box = createListWidget (_("<b>Available Software:</b>"), + "gtk-cdrom", NULL, m_available_view, + 2, true); + + /* FIXME: it seems (due to markup or something) search, this won't work. + Not really a issue as we provide searching, but... + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_installed_view), 0); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_available_view), 0); */ + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (m_installed_view), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (m_available_view), FALSE); + + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_installed_view)), GTK_SELECTION_MULTIPLE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_available_view)), GTK_SELECTION_MULTIPLE); + + GtkWidget *buttons_minsize, *selection_buttons_vbox, *install_button, + *remove_button; + selection_buttons_vbox = gtk_vbox_new (TRUE, 80); + // to avoid re-labeling glitches, let it only grow + buttons_minsize = ygtk_adj_size_new(); + gtk_container_add (GTK_CONTAINER (buttons_minsize), selection_buttons_vbox); + ygtk_adj_size_set_only_expand (YGTK_ADJ_SIZE (buttons_minsize), TRUE); + + install_button = createArrowButton (_("_install"), GTK_ARROW_RIGHT, &m_install_label); + remove_button = createArrowButton (_("_remove"), GTK_ARROW_LEFT, &m_remove_label); + + GtkWidget *install_align = gtk_alignment_new (0, 1, 1, 0); + gtk_container_add (GTK_CONTAINER (install_align), install_button); + GtkWidget *remove_align = gtk_alignment_new (0, 0, 1, 0); + gtk_container_add (GTK_CONTAINER (remove_align), remove_button); + + gtk_box_pack_start (GTK_BOX (selection_buttons_vbox), install_align, + TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (selection_buttons_vbox), remove_align, + TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (selection_buttons_vbox), 6); + + gtk_box_pack_start (GTK_BOX (packages_hbox), available_box, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (packages_hbox), buttons_minsize, + FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (packages_hbox), installed_box, TRUE, TRUE, 0); + + GtkWidget *view_box, *view_label, *view_categories, *view_patterns, + *view_languages; + view_label = gtk_label_new (_("View Packages:")); + gtk_label_set_use_markup (GTK_LABEL (view_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (view_label), 0, 0.5); + m_plain_view = gtk_radio_button_new_with_mnemonic (NULL, _("as _plain list")); + view_categories = gtk_radio_button_new_with_mnemonic_from_widget + (GTK_RADIO_BUTTON (m_plain_view), _("in _categories")); + view_patterns = gtk_radio_button_new_with_mnemonic_from_widget + (GTK_RADIO_BUTTON (m_plain_view), _("in _patterns")); + view_languages = gtk_radio_button_new_with_mnemonic_from_widget + (GTK_RADIO_BUTTON (m_plain_view), _("in _languages")); + view_box = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (view_box), view_label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (view_box), m_plain_view, FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (view_box), view_categories, FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (view_box), view_patterns, FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (view_box), view_languages, FALSE, TRUE, 4); + g_signal_connect (G_OBJECT (m_plain_view), "toggled", + G_CALLBACK (view_plain_mode_cb), this); + g_signal_connect (G_OBJECT (view_categories), "toggled", + G_CALLBACK (view_categories_mode_cb), this); + g_signal_connect (G_OBJECT (view_patterns), "toggled", + G_CALLBACK (view_patterns_mode_cb), this); + g_signal_connect (G_OBJECT (view_languages), "toggled", + G_CALLBACK (view_languages_mode_cb), this); + + // default search fields + name_opt = summary_opt = provides_opt = true; + requires_opt = descr_opt = false; + + GtkWidget *search_hbox, *search_label; + search_hbox = gtk_hbox_new (FALSE, 0); + search_label = gtk_label_new_with_mnemonic (_("_Search:")); + gtk_label_set_use_markup (GTK_LABEL (search_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (search_label), 0, 0.5); + m_search_entry = ygtk_find_entry_new(); + gtk_label_set_mnemonic_widget (GTK_LABEL (search_label), m_search_entry); + gtk_box_pack_start (GTK_BOX (search_hbox), search_label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (search_hbox), m_search_entry, TRUE, TRUE, 4); + search_timeout_id = 0; + g_signal_connect (G_OBJECT (m_search_entry), "activate", // when Enter + G_CALLBACK (search_activate_cb), this); // is pressed + g_signal_connect_after (G_OBJECT (m_search_entry), "changed", + G_CALLBACK (search_request_cb), this); + ygtk_find_entry_attach_menu (YGTK_FIND_ENTRY (m_search_entry), + create_search_menu()); + + /* we want "View Packages" to be aligned to "Search"; we could use a + GtkTable for that, but a GtkSizeGroup does the job with less hassle. */ + GtkSizeGroup *align_labels = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (align_labels, view_label); + gtk_size_group_add_widget (align_labels, search_label); + g_object_unref (G_OBJECT (align_labels)); + + m_information_widget = new PackageInformation (_("Package Information"), false); + GtkWidget *pkg_info_widget = m_information_widget->getWidget(); + + m_sources_table = new SourcesTable (this); + m_disk_table = new DiskTable(); + + GtkWidget *advanced_expander = gtk_expander_new (_("Advanced")); + GtkWidget *advanced_notebook = gtk_notebook_new(); + GtkWidget *sources_vbox = gtk_vbox_new (FALSE, 4); + GtkWidget *sources_label = gtk_label_new ( + _("<i>Use the Installation Source tool to manage the sources.</i>")); + gtk_misc_set_alignment (GTK_MISC (sources_label), 1, 0); + gtk_label_set_use_markup (GTK_LABEL (sources_label), TRUE); + gtk_box_pack_start (GTK_BOX (sources_vbox), m_sources_table->getWidget(), + TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (sources_vbox), sources_label, TRUE, TRUE, 0); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (advanced_notebook), GTK_POS_BOTTOM); + gtk_notebook_append_page (GTK_NOTEBOOK (advanced_notebook), + sources_vbox, gtk_label_new (_("Repositories"))); + gtk_notebook_append_page (GTK_NOTEBOOK (advanced_notebook), + m_disk_table->getWidget(), gtk_label_new (_("Disk Usage"))); + gtk_container_add (GTK_CONTAINER (advanced_expander), advanced_notebook); + + gtk_box_pack_start (GTK_BOX (m_widget), packages_hbox, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_widget), view_box, FALSE, FALSE, 12); + gtk_box_pack_start (GTK_BOX (m_widget), search_hbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (m_widget), pkg_info_widget, FALSE, FALSE, 12); + gtk_box_pack_start (GTK_BOX (m_widget), advanced_expander, FALSE, FALSE, 0); + gtk_widget_show_all (m_widget); + + g_object_ref (G_OBJECT (m_widget)); + gtk_object_sink (GTK_OBJECT (m_widget)); + + // interface sugar + g_signal_connect (G_OBJECT (install_button), "clicked", + G_CALLBACK (install_button_clicked_cb), this); + g_signal_connect (G_OBJECT (remove_button), "clicked", + G_CALLBACK (remove_button_clicked_cb), this); + + g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW ( + m_installed_view))), "changed", + G_CALLBACK (package_clicked_cb), this); + g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW ( + m_available_view))), "changed", + G_CALLBACK (package_clicked_cb), this); + + // signal for default view + if (patterns_mode) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view_patterns), TRUE); + else + g_signal_emit_by_name (G_OBJECT (m_plain_view), "toggled", this); + } + + // create widgets functions to cut down on code + GtkWidget *createListWidget (const char *header, const char *stock_icon, + const char **xpm_icon, GtkWidget *&list, int package_name_col, + bool has_version_col) + { + GtkWidget *vbox, *header_hbox, *image, *label, *scrolled_window; + + vbox = gtk_vbox_new (FALSE, 0); + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + list = gtk_tree_view_new(); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE); + gtk_tree_selection_set_select_function (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (list)), dont_select_groups_cb, this, NULL); + gtk_container_add (GTK_CONTAINER (scrolled_window), list); + + header_hbox = gtk_hbox_new (FALSE, 0); + image = NULL; + if (stock_icon) + image = gtk_image_new_from_icon_name (stock_icon, GTK_ICON_SIZE_BUTTON); + if ((!stock_icon || gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY) + && xpm_icon) { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (xpm_icon); + image = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (G_OBJECT (pixbuf)); + } + label = gtk_label_new_with_mnemonic (header); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), list); + if (image) + gtk_box_pack_start (GTK_BOX (header_hbox), image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (header_hbox), label, FALSE, FALSE, 4); + + gtk_box_pack_start (GTK_BOX (vbox), header_hbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 4); + + // The treeview model will be built according to the view... Columns + // and renderers are common anyway... + GtkCellRenderer *text_renderer = gtk_cell_renderer_text_new(); + g_object_set (G_OBJECT (text_renderer), + "ellipsize", PANGO_ELLIPSIZE_END, NULL); + GtkTreeViewColumn *column; + column = gtk_tree_view_column_new_with_attributes (_("Packages"), + text_renderer, "markup", package_name_col, "style", 9, NULL); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + // versions combo column + if (has_version_col) { + GtkCellRenderer *arrow_renderer = ygtk_cell_renderer_arrow_new(); + column = gtk_tree_view_column_new_with_attributes (NULL, + arrow_renderer, "can-go-up", 5, "can-go-down", 6, "visible", 7, NULL); + gtk_tree_view_column_set_expand (column, FALSE); + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + g_signal_connect (G_OBJECT (arrow_renderer), "pressed", + G_CALLBACK (change_available_version_cb), this); + } + return vbox; + } + + GtkWidget *createArrowButton (const char *label, GtkArrowType arrow_type, + GtkWidget **label_widget) + { + GtkWidget *button, *box = gtk_hbox_new (FALSE, 0); + GtkWidget *arrow = gtk_arrow_new (arrow_type, GTK_SHADOW_OUT); + gtk_container_add (GTK_CONTAINER (box), arrow); + *label_widget = gtk_label_new_with_mnemonic (label); + gtk_container_add (GTK_CONTAINER (box), *label_widget); + gtk_box_set_child_packing (GTK_BOX (box), arrow, FALSE, TRUE, 0, + arrow_type == GTK_ARROW_LEFT ? GTK_PACK_START : GTK_PACK_END); + + button = gtk_button_new(); + gtk_container_add (GTK_CONTAINER (button), box); + return button; + } + + // Dynamic views support + void load_packages_view (GtkTreeModel *(* build_model) (GtkProgressBar *)) + { + GtkWidget *dialog, *label, *vbox, *progress = 0; + dialog = gtk_dialog_new(); + gtk_window_set_title (GTK_WINDOW (dialog), ""); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + YGUI::ui()->currentWindow()); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_default_size (GTK_WINDOW (dialog), 100, -1); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + vbox = GTK_DIALOG (dialog)->vbox; +// gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); + label = gtk_label_new (_("Loading packages list...")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0); + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 4); + progress = gtk_progress_bar_new(); + gtk_box_pack_start (GTK_BOX (vbox), progress, TRUE, FALSE, 4); + gtk_widget_show_all (dialog); + + gtk_tree_view_set_model (GTK_TREE_VIEW (m_installed_view), NULL); + gtk_tree_view_set_model (GTK_TREE_VIEW (m_available_view), NULL); + m_information_widget->setPackage (NULL, NULL); + + GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (progress); + // build it + GtkTreeModel *model = (m_packages_model = build_model (progress_bar)); + + GtkTreeModel *installed_model, *available_model; + installed_model = gtk_tree_model_filter_new (model, NULL); + available_model = gtk_tree_model_filter_new (model, NULL); + g_object_unref (G_OBJECT (model)); + + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER ( + installed_model), is_package_installed, this, NULL); + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER ( + available_model), is_package_available, this, NULL); + + gtk_tree_view_set_model (GTK_TREE_VIEW (m_installed_view), installed_model); + gtk_tree_view_set_model (GTK_TREE_VIEW (m_available_view), available_model); + g_object_unref (G_OBJECT (installed_model)); + g_object_unref (G_OBJECT (available_model)); + + // use the "available" name to do the sorting + GtkTreeSortable *sortable = GTK_TREE_SORTABLE (model); + gtk_tree_sortable_set_sort_func (sortable, COL_AVAILABLE_NAME, + YGUtils::sort_compare_cb, + GINT_TO_POINTER (COL_AVAILABLE_NAME), + NULL); + gtk_tree_sortable_set_sort_column_id (sortable, COL_AVAILABLE_NAME, + GTK_SORT_ASCENDING); + + gtk_widget_destroy (dialog); + } + + // macros to handle progress bar + #define SET_PROGRESS(_steps, _jump) int steps = _steps, step = 0, jump = _jump; + #define PROGRESS() \ + if (progress && ((step++) % jump == 0)) { \ + gdouble fraction = steps > 0 ? ((gdouble) step) / steps : 0; \ + gtk_progress_bar_set_fraction (progress, fraction); \ + while (gtk_events_pending()) gtk_main_iteration(); } + + static GtkTreeModel *loadPackagesListAsPlain (GtkProgressBar *progress) + { + GtkListStore *store = gtk_list_store_new (10, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT); + GtkTreeModel *model = GTK_TREE_MODEL (store); + g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (1)); + + SET_PROGRESS (zyppPool().size <zypp::Package>(), 200) + GtkTreeIter iter; + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) + { + ZyppSelectable selectable = *it; + gtk_list_store_append (store, &iter); + loadPackageRow (model, &iter, selectable); + PROGRESS() + } + return model; + } + + static GtkTreeModel *loadPackagesListByCategory (GtkProgressBar *progress) + { + GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT); + GtkTreeModel *model = GTK_TREE_MODEL (store); + g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (1)); + + // we need to create the categories tree as we iterate packages + map <string, GtkTreePath *> tree; + + SET_PROGRESS (zyppPool().size <zypp::Package>(), 80) + GtkTreeIter iter, parent_iter; + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) + { + ZyppSelectable selectable = *it; + ZyppObject object = selectable->theObj(); + + GtkTreePath *path = NULL; + ZyppPackage package = tryCastToZyppPkg (object); + if (package) { + // group is a string like "Productivity/Networking/Email/Utilities" + string group = package->group(); + + // We will now retrieve the hierarchy of the package's group and + // make sure a path has already been created on all nodes, as well + // as get last node's GtkTreePath + list <string> hierarchy = YGUtils::splitString (group, '/'); + while (!hierarchy.empty()) { + string node = hierarchy.front(); + hierarchy.pop_front(); + + map <string, GtkTreePath*>::iterator it = tree.find (node); + if (it == tree.end()) { + if (path) { + gtk_tree_model_get_iter (GTK_TREE_MODEL (store), + &parent_iter, path); + gtk_tree_store_append (store, &iter, &parent_iter); + } + else // create at root + gtk_tree_store_append (store, &iter, NULL); + + string name = "<big><b>" + node + "</b></big>"; + gtk_tree_store_set (store, &iter, + 0, NULL, 1, name.c_str(), 2, name.c_str(), 3, TRUE, + 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1); + + path = gtk_tree_model_get_path (model, &iter); + tree [node] = path; + } + else // exists + path = it->second; + } + } + + if (!path) // package has no group + continue; + + gtk_tree_model_get_iter (model, &parent_iter, path); + gtk_tree_store_append (store, &iter, &parent_iter); + loadPackageRow (model, &iter, selectable); + PROGRESS() + } + + // free GtkTreePaths + for (map <string, GtkTreePath*>::iterator it = tree.begin(); + it != tree.end(); it++) + gtk_tree_path_free (it->second); + return model; + } + + /* NOTE: Getting the packages under a pattern, language, etc is done + differently, so code re-use would be limited. Probably doesn't worth + the trouble and complexity of doing so. */ + + static GtkTreeModel *loadPackagesListByPattern (GtkProgressBar *progress) + { + GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT); + GtkTreeModel *model = GTK_TREE_MODEL (store); + g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (0)); + + // we need to create a categories tree for the patterns + map <string, GtkTreeIter> tree; + + SET_PROGRESS (zyppPool().size <zypp::Pattern>(), 5) + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Pattern>(); + it != zyppPool().byKindEnd <zypp::Pattern>(); it++) { + ZyppSelectable selectable = *it; + ZyppObject object = selectable->theObj(); + ZyppPattern pattern = tryCastToZyppPattern (object); + if (pattern && pattern->userVisible()) { + GtkTreeIter category_iter, pattern_iter, package_iter; + string category = pattern->category(); + map <string, GtkTreeIter>::iterator cat_it = tree.find (category); + if (cat_it == tree.end()) { + string name = "<big><b>" + category + "</b></big>"; + gtk_tree_store_append (store, &category_iter, NULL); + gtk_tree_store_set (store, &category_iter, + 0, NULL, 1, name.c_str(), 2, name.c_str(), 3, TRUE, + 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1); + tree [category] = category_iter; + } + else + category_iter = cat_it->second; + + string name = "<b>" + fastGetSummary (object) + "</b>"; + gtk_tree_store_append (store, &pattern_iter, &category_iter); + loadPackageRow (model, &pattern_iter, selectable); + +/* gtk_tree_store_set (store, &pattern_iter, + 0, get_pointer (selectable), 1, name.c_str(), 2, name.c_str(), + 3, TRUE, 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);*/ + + // adding children packages + const set <string> &packages = pattern->install_packages(); + for (ZyppPool::const_iterator pt2 = + zyppPool().byKindBegin <zypp::Package>(); + pt2 != zyppPool().byKindEnd <zypp::Package>(); pt2++) { + ZyppSelectable sel = *pt2; + for (set <string>::iterator pt1 = packages.begin(); + pt1 != packages.end(); pt1++) { + if (sel->name() == *pt1) { + gtk_tree_store_append (store, &package_iter, &pattern_iter); + loadPackageRow (model, &package_iter, sel); + } + } + } + } + PROGRESS() + } + return model; + } + + static GtkTreeModel *loadPackagesListByLanguage (GtkProgressBar *progress) + { + GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT); + GtkTreeModel *model = GTK_TREE_MODEL (store); + g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (0)); + + SET_PROGRESS (zyppPool().size <zypp::Language>(), 20) + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Language>(); + it != zyppPool().byKindEnd <zypp::Language>(); it++) { + ZyppSelectable langsel = *it; + ZyppObject langobj = langsel->theObj(); + ZyppLanguage lang = tryCastToZyppLanguage (langobj); + if (lang) { + string langname = langsel->name(); + if (langname.empty() || langname == "C") + continue; + + string descrpt = "<b>" + langobj->description() + "</b>"; + GtkTreeIter parent_iter, iter; + gtk_tree_store_append (store, &parent_iter, NULL); + loadPackageRow (model, &parent_iter, langsel); +/* gtk_tree_store_set (store, &parent_iter, + 0, get_pointer (langsel), 1, descrpt.c_str(), 2, descrpt.c_str(), + 3, TRUE, 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);*/ + + for (ZyppPool::const_iterator it = + zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) { + ZyppSelectable pkgsel = *it; + ZyppObject pkgobj = pkgsel->theObj(); + + const zypp::CapSet &capSet = pkgobj->dep (zypp::Dep::FRESHENS); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + if (it->index() == lang->name()) { + gtk_tree_store_append (store, &iter, &parent_iter); + loadPackageRow (model, &iter, pkgsel); + } + } + } + } + PROGRESS() + } + return model; + } + #undef SET_PROGRESS + #undef PROGRESS + + static void induceObjects (ZyppSelectable selectable, ZyppObject &install_obj, + ZyppObject &available_obj, bool *has_upgrade, + bool *has_downgrade) + { + available_obj = (install_obj = NULL); + if (!selectable) + return; + switch (selectable->status()) { + case zypp::ui::S_Install: + case zypp::ui::S_Update: + install_obj = selectable->candidateObj(); + break; + case zypp::ui::S_Del: + available_obj = selectable->installedObj(); + break; + default: + available_obj = selectable->candidateObj(); + install_obj = selectable->installedObj(); + break; + } + + // zypp keeps on the pool objects whose sources we disabled, so we may + // need to calculate the candidate object here. +#ifdef PRE_ZYPP_3 + if (available_obj != NULL && !available_obj->source().enabled()) { +#else + // beware lurking tribool requires bool cast here. + if (available_obj != NULL && !(bool)(available_obj->repository().info().enabled())) { +#endif + available_obj = NULL; + for (zypp::ui::Selectable::available_iterator it = selectable->availableBegin(); + it != selectable->availableEnd(); it++) { +#ifdef PRE_ZYPP_3 + if (!(*it)->source().enabled()) +#else + if (!(*it)->repository().info().enabled()) +#endif + ; + else if (!available_obj) + available_obj = *it; + else if (zypp::Edition::compare ((*it)->edition(), + available_obj->edition()) > 0) + available_obj = *it; + } + } + + bool has_up = false, has_down = false; + if (available_obj != NULL && install_obj != NULL) { + int res = zypp::Edition::compare (install_obj->edition(), + available_obj->edition()); + if (res < 0) + has_up = true; + else if (res > 0) + has_down = true; + } + + if (has_upgrade) + *has_upgrade = has_up; + if (has_downgrade) + *has_downgrade = has_down; + } + + /* Must be called for the main model. */ + static void loadPackageRow (GtkTreeModel *model, GtkTreeIter *iter, + ZyppSelectable selectable) + { + ZyppObject install_obj, available_obj; + bool has_upgrade, has_downgrade, has_children = FALSE; + induceObjects (selectable, install_obj, available_obj, + &has_upgrade, &has_downgrade); + + bool detailed = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model), + "detail-package")); + string availableName, installedName, name (YGUtils::escape_markup (selectable->name())); + if (available_obj) { + if (detailed) + availableName = "<b>" + name + "</b> (" + available_obj->edition().version() + + ")\n<small>" + YGUtils::escape_markup (fastGetSummary (available_obj)) + + "</small>"; + else { + ZyppPattern pattern = tryCastToZyppPattern (available_obj); + ZyppLanguage lang = tryCastToZyppLanguage (available_obj); + if (pattern) { + availableName = "<b>" + fastGetSummary (available_obj) + "</b>"; + has_children = TRUE; + } else if (lang) { + availableName = "<b>" + available_obj->description() + "</b>"; + has_children = TRUE; + } else + availableName = name + " (" + available_obj->edition().version() + ")"; + } + } + if (install_obj) { + if (detailed) + installedName = "<b>" + name + "</b> (" + install_obj->edition().version() + + ")\n<small>" + YGUtils::escape_markup (fastGetSummary (install_obj)) + + "</small>"; + else { + ZyppPattern pattern = tryCastToZyppPattern (install_obj); + ZyppLanguage lang = tryCastToZyppLanguage (install_obj); + if (pattern) { + installedName = "<b>" + fastGetSummary (install_obj) + "</b>"; + has_children = TRUE; + } else if (lang) { + installedName = "<b>" + install_obj->description() + "</b>"; + has_children = TRUE; + } else + installedName = name + " (" + install_obj->edition().version() + ")"; + } + } + + // Make sure that both the availableName and installedName + // are filled. Occasionally, the names are empty, so the + // following checks make sure these variable are filled. + if (availableName.empty()) + availableName = installedName; + else if (installedName.empty()) + installedName = availableName; + + PangoStyle style = PANGO_STYLE_NORMAL; + if (selectable->toModify()) + style = PANGO_STYLE_ITALIC; + + // oh, would be nice to have a common set for tree models... + if (GTK_IS_LIST_STORE (model)) + gtk_list_store_set (GTK_LIST_STORE (model), iter, + COL_SELECTABLE, get_pointer (selectable), + COL_INSTALLED_NAME, installedName.c_str(), + COL_AVAILABLE_NAME, availableName.c_str(), + COL_IS_INSTALLED, install_obj != 0, + COL_IS_AVAILABLE, available_obj != 0, + COL_CAN_BE_UPGRADED, has_upgrade, + COL_CAN_BE_DOWNGRADED, has_downgrade, + COL_SHOW_UPGRADABLE_CONTROL, detailed, + COL_HAS_CHILDREN, has_children, + COL_FONT_STYLE, style, -1); + else /*if (GTK_IS_TREE_STORE (model))*/ + gtk_tree_store_set (GTK_TREE_STORE (model), iter, + COL_SELECTABLE, get_pointer (selectable), + COL_INSTALLED_NAME, installedName.c_str(), + COL_AVAILABLE_NAME, availableName.c_str(), + COL_IS_INSTALLED, install_obj != 0, + COL_IS_AVAILABLE, available_obj != 0, + COL_CAN_BE_UPGRADED, has_upgrade, + COL_CAN_BE_DOWNGRADED, has_downgrade, + COL_SHOW_UPGRADABLE_CONTROL, detailed, + COL_HAS_CHILDREN, has_children, + COL_FONT_STYLE, style, -1); +/* y2milestone ("set %s: %d - %d\n", selectable->name().c_str(), + available_obj != 0, install_obj != 0);*/ + } + + virtual ~PackageSelector() + { + IMPL + if (search_timeout_id) + g_source_remove (search_timeout_id); + + delete m_information_widget; + delete m_sources_table; + delete m_disk_table; + gtk_widget_destroy (m_widget); + g_object_unref (G_OBJECT (m_widget)); + } + + GtkWidget *getWidget() + { return m_widget; } + + static void view_plain_mode_cb (GtkToggleButton *button, + PackageSelector *pThis) + { + if (!gtk_toggle_button_get_active (button)) return; + pThis->load_packages_view (&loadPackagesListAsPlain); + } + + static void view_categories_mode_cb (GtkToggleButton *button, + PackageSelector *pThis) + { + if (!gtk_toggle_button_get_active (button)) return; + pThis->clear_search_entry (true); + pThis->load_packages_view (&loadPackagesListByCategory); + } + + static void view_patterns_mode_cb (GtkToggleButton *button, + PackageSelector *pThis) + { + if (!gtk_toggle_button_get_active (button)) return; + pThis->clear_search_entry (true); + pThis->load_packages_view (&loadPackagesListByPattern); + } + + static void view_languages_mode_cb (GtkToggleButton *button, + PackageSelector *pThis) + { + if (!gtk_toggle_button_get_active (button)) return; + pThis->clear_search_entry (true); + pThis->load_packages_view (&loadPackagesListByLanguage); + } + + void sources_changed_cb() + { + // reload view; FIXME: re-load the current view, not necessarly + // the plain list; hacky anyway + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m_plain_view))) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_plain_view), TRUE); + else + g_signal_emit_by_name (G_OBJECT (m_plain_view), "toggled", this); + } + + void clear_search_entry (bool dont_load) + { + if (dont_load) + g_signal_handlers_block_by_func (m_search_entry, + (gpointer) search_request_cb, this); + gtk_entry_set_text (GTK_ENTRY (m_search_entry), ""); + if (dont_load) + g_signal_handlers_unblock_by_func (m_search_entry, + (gpointer) search_request_cb, this); + } + + static void search_activate_cb (GtkEntry *entry, PackageSelector *pThis) + { + IMPL + if (pThis->search_timeout_id) + g_source_remove (pThis->search_timeout_id); + search_cb (pThis); + } + + static void search_request_cb (GtkEditable *editable, PackageSelector *pThis) + { + IMPL + // we'll make a delay for the actual search to wait for the user + // to finish writting + if (pThis->search_timeout_id) + g_source_remove (pThis->search_timeout_id); + pThis->search_timeout_id = g_timeout_add (500, search_cb, pThis); + } + + struct FindClosure { + bool found; + GtkTreeView *view; + PackageSelector *pThis; + }; + static gboolean find_exact_match (GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data) + { + FindClosure *cl = (FindClosure *) data; + + ZyppSelectablePtr sel = NULL; + + gtk_tree_model_get (model, iter, COL_SELECTABLE, &sel, -1); + + if (!sel) + return FALSE; + + if (sel->name() == *cl->pThis->m_search_queries.begin()) { + cl->found = true; + gtk_tree_selection_select_iter + (gtk_tree_view_get_selection (cl->view), iter); + package_clicked_cb (gtk_tree_view_get_selection (cl->view), cl->pThis); + return TRUE; + } + return FALSE; + } + + void highlight_exact_matches () + { + if (m_search_queries.empty() || !name_opt) + return; + + FindClosure cl; + cl.found = false; + cl.pThis = this; + cl.view = GTK_TREE_VIEW (m_installed_view); + + gtk_tree_model_foreach (gtk_tree_view_get_model (cl.view), + find_exact_match, &cl); + + if (!cl.found) { + cl.view = GTK_TREE_VIEW (m_available_view); + gtk_tree_model_foreach (gtk_tree_view_get_model (cl.view), + find_exact_match, &cl); + } + } + + static gboolean search_cb (gpointer data) + { + IMPL + + // This is potentially very slow ... +#ifdef IMPL_DEBUG + fprintf (stderr, "search start...\n"); +#endif + PackageSelector *pThis = (PackageSelector *) data; + pThis->search_timeout_id = 0; + + const gchar *query = gtk_entry_get_text (GTK_ENTRY (pThis->m_search_entry)); + bool plain_view = gtk_toggle_button_get_active ( + GTK_TOGGLE_BUTTON (pThis->m_plain_view)); + if (!plain_view) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pThis->m_plain_view), TRUE); + pThis->m_search_queries = YGUtils::splitString (query, ' '); + + // just re-filter + GtkTreeModel *available_model = + gtk_tree_view_get_model (GTK_TREE_VIEW (pThis->m_available_view)); + GtkTreeModel *installed_model = + gtk_tree_view_get_model (GTK_TREE_VIEW (pThis->m_installed_view)); + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (available_model)); + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (installed_model)); + + pThis->highlight_exact_matches (); + +#ifdef IMPL_DEBUG + fprintf (stderr, "search done...\n"); +#endif + return FALSE; + } + + GtkMenu *create_search_menu() + { + GtkWidget *menu = gtk_menu_new(); + append_option_item (menu, _("Name"), &name_opt); + append_option_item (menu, _("Summary"), &summary_opt); + append_option_item (menu, _("Description"), &descr_opt); + append_option_item (menu, _("RPM Provides"), &provides_opt); + append_option_item (menu, _("RPM Requires"), &requires_opt); + gtk_widget_show_all (menu); + return GTK_MENU (menu); + } + + static void append_option_item (GtkWidget *menu, const char *label, bool *option) + { + GtkWidget *item = gtk_check_menu_item_new_with_label (label); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), *option); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + g_signal_connect (G_OBJECT (item), "toggled", + G_CALLBACK (search_option_change_cb), option); + } + + static void search_option_change_cb (GtkCheckMenuItem *item, bool *option) + { *option = item->active; } + + inline static gboolean is_package_visible (GtkTreeModel *model, GtkTreeIter *iter, + PackageSelector *pThis, int visible_col) + { + gboolean visible, has_children; + ZyppSelectablePtr selectable; + + gtk_tree_model_get (model, iter, visible_col, &visible, + COL_HAS_CHILDREN, &has_children, + COL_SELECTABLE, &selectable, -1); + +// fprintf (stderr, "is visible '%s'\n", selectable ? selectable->name().c_str() : "<noname>"); + if (has_children) + visible = TRUE; + else if (visible && !pThis->m_search_queries.empty()) + visible = pThis->does_package_match (selectable); + + return visible; + } + + static gboolean is_package_installed (GtkTreeModel *model, GtkTreeIter *iter, + gpointer data) + { return is_package_visible (model, iter, (PackageSelector *) data, 3); } + + static gboolean is_package_available (GtkTreeModel *model, GtkTreeIter *iter, + gpointer data) + { + gboolean is_installed, is_available, has_upgrade, has_children; + gboolean visible = TRUE; + ZyppSelectablePtr selectable; + PackageSelector *pThis = (PackageSelector *) data; + + // only show the packages that aren't installed + // unless there's an upgrade available + gtk_tree_model_get (model, iter, COL_SELECTABLE, &selectable, + COL_IS_INSTALLED, &is_installed, + COL_IS_AVAILABLE, &is_available, + COL_CAN_BE_UPGRADED, &has_upgrade, + COL_HAS_CHILDREN, &has_children, -1); + if (!has_children) { + if (is_available && (!is_installed || has_upgrade)) { + if (!pThis->m_search_queries.empty()) + visible = pThis->does_package_match (selectable); + } else + visible = FALSE; + } + + return visible; + } + + bool does_package_match_one (ZyppSelectablePtr sel, string key) + { + ZyppObject obj = NULL; + + if (name_opt && YGUtils::contains (sel->name(), key)) + return TRUE; + + if (summary_opt || descr_opt || provides_opt || requires_opt) + obj = sel->theObj(); + + if (summary_opt && YGUtils::contains (fastGetSummary (obj), key)) + return TRUE; + if (descr_opt && YGUtils::contains (obj->description(), key)) + return TRUE; + if (provides_opt) { + const zypp::CapSet &capSet = obj->dep (zypp::Dep::PROVIDES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) + if (YGUtils::contains (it->asString(), key)) + return TRUE; + } + if (requires_opt) { + const zypp::CapSet &capSet = obj->dep (zypp::Dep::REQUIRES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) + if (YGUtils::contains (it->asString(), key)) + return TRUE; + } + return FALSE; + } + + gboolean does_package_match (ZyppSelectablePtr sel) + { + if (m_search_queries.empty()) + return true; + + bool and_results = true; // vs. or them ... + + bool result = and_results; + for (list <string>::iterator it = m_search_queries.begin(); + it != m_search_queries.end(); it++) { + + // TODO: googlify more ... + if (*it == "OR") { + and_results = false; + continue; + } + if (*it == "AND") { + and_results = true; + continue; + } + bool match = does_package_match_one (sel, *it); + result = and_results ? result && match : result || match; + } + return result; + } + + // callbacks + static bool getSelectedPackage (GtkTreeView *tree_view, + ZyppSelectablePtr *package_sel, GtkTreePath **_path = 0) + { + IMPL + GtkTreePath *path = 0; + gtk_tree_view_get_cursor (tree_view, &path, NULL); + if (path) { + GtkTreeModel *model = gtk_tree_view_get_model (tree_view); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, COL_SELECTABLE, package_sel, -1); + if (_path) + *_path = gtk_tree_model_filter_convert_path_to_child_path + (GTK_TREE_MODEL_FILTER (model), path); + gtk_tree_path_free (path); + return true; + } + return false; + } + + // For SLED10 / older gtk+'s ... + static bool compat_gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter, + GtkTreeIter *filter_iter, + GtkTreeIter *child_iter) + { +#if GTK_CHECK_VERSION(2,10,0) + return gtk_tree_model_filter_convert_child_iter_to_iter (filter, filter_iter, child_iter); +#else // cut/paste from gtk+ HEAD... + gboolean ret; + GtkTreePath *child_path, *path; + + memset (filter_iter, 0, sizeof (GtkTreeIter)); + + GtkTreeModel *child_model; + g_object_get (G_OBJECT (filter), "child-model", &child_model, NULL); + child_path = gtk_tree_model_get_path (child_model, child_iter); + g_return_val_if_fail (child_path != NULL, FALSE); + + path = gtk_tree_model_filter_convert_child_path_to_path (filter, + child_path); + gtk_tree_path_free (child_path); + + if (!path) + return FALSE; + + ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path); + gtk_tree_path_free (path); + + return ret; +#endif + } + + static bool sync_tree_views_scroll (GtkTreeView *current_view, GtkTreeView *other_view, + GtkTreePath *current_path, bool select_it) + { + /* What we do here is to scroll the other view to the correspondent + package position. If the package isn't present in that view, we + iterate it so we get the closest package (with respect to alphabetic + sorting). */ + + // converts the path from one model to the other + GtkTreePath *_path, *other_path; + _path = gtk_tree_model_filter_convert_path_to_child_path ( + GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (current_view)), + current_path); + if (!_path) + return false; + + GtkTreeModel *base_model = gtk_tree_model_filter_get_model ( + GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (current_view))); + + GtkTreeIter iter, other_iter; + gtk_tree_model_get_iter (base_model, &iter, _path); + gtk_tree_path_free (_path); + + int timeout = 0; + // Try to find a a similar item in the other view to synchronise with + while (!compat_gtk_tree_model_filter_convert_child_iter_to_iter ( + GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (other_view)), + &other_iter, &iter)) + { + if (!gtk_tree_model_iter_next (base_model, &iter)) + return false; + // This turns into N^3 very quickly if we search too hard + if (timeout++ > 10) + return false; + select_it = false; // not the same package -- dont select it then + } + + other_path = gtk_tree_model_get_path (gtk_tree_view_get_model (other_view), + &other_iter); + + GdkRectangle cell_rect, visible_rect; + gtk_tree_view_get_cell_area (other_view, other_path, NULL, &cell_rect); + gtk_tree_view_get_visible_rect (other_view, &visible_rect); + int y = visible_rect.y + cell_rect.y; + + gtk_tree_view_get_cell_area (current_view, current_path, NULL, &cell_rect); + y -= cell_rect.y; // offset + + gtk_tree_view_expand_to_path (other_view, other_path); + YGUtils::tree_view_smooth_scroll_to_point (other_view, 0, y); + if (select_it) + gtk_tree_selection_select_path (gtk_tree_view_get_selection (other_view), + other_path); + gtk_tree_path_free (other_path); + return true; + } + + static void package_clicked_cb (GtkTreeSelection *selection, PackageSelector *pThis) + { + IMPL + int selected_rows = gtk_tree_selection_count_selected_rows (selection); + if (selected_rows == 0) + return; + + static bool safeguard = false; + if (safeguard) + return; + safeguard = true; + + GtkTreeView *tree_view = gtk_tree_selection_get_tree_view (selection); + bool install_view = tree_view == GTK_TREE_VIEW (pThis->m_installed_view); + GtkTreeView *other_view = GTK_TREE_VIEW (install_view ? + pThis->m_available_view : pThis->m_installed_view); + + // unselect the other view + gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (other_view)); + + // select and scroll to the package in the other view (if it's listed there) + GtkTreePath *path = 0; + gtk_tree_view_get_cursor (tree_view, &path, NULL); + if (path) { + // function can be called to set some package visible + gtk_tree_view_scroll_to_cell (tree_view, path, NULL, FALSE, 0, 0); + + sync_tree_views_scroll (tree_view, other_view, path, selected_rows == 1); + gtk_tree_path_free (path); + } + + // show package information + ZyppSelectablePtr sel = 0; + getSelectedPackage (tree_view, &sel); + + ZyppObject install_obj, available_obj; + induceObjects (sel, install_obj, available_obj, NULL, NULL); + + ZyppObject &obj = install_view ? install_obj : available_obj; + pThis->m_information_widget->setPackage (sel, obj); + + // change the install/remove button label to upgrade, or etc + GtkLabel *install_label = GTK_LABEL (pThis->m_install_label), + *remove_label = GTK_LABEL (pThis->m_remove_label); + if (selected_rows > 1) { + gtk_label_set_text (install_label, _("_install")); + gtk_label_set_text (remove_label, _("_remove")); + } + else { // personalize + // remove label + if (sel && sel->toInstall()) + gtk_label_set_text (remove_label, _("_undo")); + else + gtk_label_set_text (remove_label, _("_remove")); + // install label + if (sel && sel->toDelete()) + gtk_label_set_text (install_label, _("_undo")); + else if (!install_obj) + gtk_label_set_text (install_label, _("_install")); + else if (available_obj) { + int res = zypp::Edition::compare (install_obj->edition(), + available_obj->edition()); + if (res < 0) + gtk_label_set_text (install_label, _("_upgrade")); + else if (res > 0) + gtk_label_set_text (install_label, _("_downgrade")); + else + gtk_label_set_text (install_label, _("re-_install")); + } + } + gtk_label_set_use_underline (install_label, TRUE); + gtk_label_set_use_underline (remove_label, TRUE); + + safeguard = false; + } + + // install/remove/update/... selected packages + void markSelectedPackage (GtkTreeView *view, bool available, bool installed) + { + IMPL + /* Since the filter model gets changed, get paths for the base model and + then do our stuff. */ + GList *selected = gtk_tree_selection_get_selected_rows ( + gtk_tree_view_get_selection (view), NULL); + + int selected_len = g_list_length (selected); + GtkTreeIter iters [selected_len]; + + GtkTreeModel *filter_model = gtk_tree_view_get_model (view); + GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (filter_model); + GtkTreeModel *model = gtk_tree_model_filter_get_model (filter); + + int i = 0; + for (GList *it = selected; it; it = it->next, i++) { + GtkTreePath *path = (GtkTreePath *) it->data; + + GtkTreeIter filter_iter, iter; + gtk_tree_model_get_iter (filter_model, &filter_iter, path); + gtk_tree_path_free (path); + + gtk_tree_model_filter_convert_iter_to_child_iter (filter, &iter, &filter_iter); + iters[i] = iter; + } + g_list_free (selected); + for (i = 0; i < selected_len; i++) { + GtkTreeIter *iter = &iters[i]; + ZyppSelectablePtr sel = 0; + gtk_tree_model_get (model, iter, COL_SELECTABLE, &sel, -1); + if (sel && mark_selectable (sel, installed) /* install/remove */) { + loadPackageRow (model, iter, sel); // update model + + // mark also children (eg. for patterns and languages) + GtkTreeIter child; + if (gtk_tree_model_iter_children (model, &child, iter)) { + do { + gtk_tree_model_get (model, &child, COL_SELECTABLE, &sel, -1); + if (sel && mark_selectable (sel, installed)) + loadPackageRow (model, &child, sel); + } while (gtk_tree_model_iter_next (model, &child)); + + } + } + } + + m_disk_table->update(); + + // select path, so the buttons get updated and all (hacky) + GtkTreeView *other_view = GTK_TREE_VIEW ( + GTK_WIDGET (view) == m_installed_view ? m_available_view : m_installed_view); + package_clicked_cb (gtk_tree_view_get_selection (other_view), this); + } + + static void install_button_clicked_cb (GtkButton *button, PackageSelector *pThis) + { + IMPL + pThis->markSelectedPackage (GTK_TREE_VIEW (pThis->m_available_view), false, true); + gtk_widget_grab_focus (pThis->m_available_view); + } + + static void remove_button_clicked_cb (GtkButton *button, PackageSelector *pThis) + { + IMPL + pThis->markSelectedPackage (GTK_TREE_VIEW (pThis->m_installed_view), true, false); + gtk_widget_grab_focus (pThis->m_installed_view); + } + + static void change_available_version_cb (YGtkCellRendererArrow *renderer, + guint arrow_type, const gchar *_path, PackageSelector *pThis) + { + GtkTreeModel *model = gtk_tree_view_get_model ( + GTK_TREE_VIEW (pThis->m_available_view)); + GtkTreePath *path = gtk_tree_path_new_from_string (_path); + GtkTreeIter it; + gtk_tree_model_get_iter (model, &it, path); + gtk_tree_path_free (path); + + GtkTreeIter iter; + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), + &iter, &it); + model = pThis->m_packages_model; + + ZyppSelectablePtr selectable; + gtk_tree_model_get (model, &iter, COL_SELECTABLE, &selectable, -1); + + ZyppObject candidate = selectable->candidateObj(); + for (zypp::ui::Selectable::available_iterator it = selectable->availableBegin(); + it != selectable->availableEnd(); it++) { + int cmp = zypp::Edition::compare ((*it)->edition(), candidate->edition()); + if (arrow_type == GTK_ARROW_UP) { // upgrade + if (cmp > 0) + candidate = *it; + } + else /*if (arrow_type == GTK_ARROW_DOWN)*/ { // downgrade + if (cmp < 0) + candidate = *it; + } + } + if (!selectable->setCandidate (candidate)) + y2warning ("Error: Could not %sgrade\n", arrow_type == GTK_ARROW_UP ? "up" : "down"); + pThis->loadPackageRow (model, &iter, selectable); + } + + static gboolean dont_select_groups_cb (GtkTreeSelection *selection, GtkTreeModel *model, + GtkTreePath *path, gboolean selected, gpointer data) + { + GtkTreeIter iter; + if (gtk_tree_model_get_iter (model, &iter, path)) { + ZyppSelectablePtr selectable; + gtk_tree_model_get (model, &iter, COL_SELECTABLE, &selectable, -1); + return selectable != NULL; + } + return FALSE; + } +}; + +// The ordinary package selector that displays all packages +class YGPackageSelector : public YPackageSelector, public YGWidget +{ + PackageSelector *m_package_selector; + + static bool confirm_cb (void *pThis) + { + return ((YGPackageSelector *)pThis)->checkDelete(); + } + + bool checkDelete() + { + GtkWidget *dialog; + + bool changed = + zyppPool().diffState<zypp::Package >() || + zyppPool().diffState<zypp::Pattern >() || + zyppPool().diffState<zypp::Selection>() || + zyppPool().diffState<zypp::Language >() || + zyppPool().diffState<zypp::Patch >(); + + if (!changed) + return true; + + dialog = gtk_message_dialog_new_with_markup + (YGUI::ui()->currentWindow(), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, + GTK_BUTTONS_YES_NO, + _("<b>Abandon all changes?</b>")); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_NO); + bool ok = gtk_dialog_run (GTK_DIALOG (dialog)) == + GTK_RESPONSE_YES; + gtk_widget_destroy (dialog); + return ok; + } + +public: + YGPackageSelector (const YWidgetOpt &opt, YGWidget *parent) + : YPackageSelector (opt), + YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL) + { + setBorder (0); + + YGDialog *dialog = YGUI::ui()->currentYGDialog(); + + GtkWindow *window = GTK_WINDOW (dialog->getWindow()); + gtk_window_resize (window, 680, 580); + + dialog->setCloseCallback (confirm_cb, this); + + YGtkWizard *wizard = YGTK_WIZARD (getWidget()); + + ygtk_wizard_set_header_icon (wizard, window, + THEMEDIR "/icons/32x32/apps/yast-software.png"); + ygtk_wizard_set_header_text (wizard, YGUI::ui()->currentWindow(), + "Package Selector"); + ygtk_wizard_set_help_text (wizard, + _("Two pools are presented; one with the available software, the other " + "with the installed one. To install software you choose a package " + "from the install pool and press Install. Similar method for removal " + "of software. When you are done press the Accept button.<br>" + "Information on a given package is displayed on the Package Information " + "expander at the bottom which may be enlarged.<br>" + "A categories view of the software is possible, as well as searching " + "for a given package.") + ); + + ygtk_wizard_set_abort_button_label (wizard, _("_Cancel")); + ygtk_wizard_set_abort_button_id (wizard, g_strdup ("cancel"), g_free); + ygtk_wizard_set_back_button_label (wizard, ""); + ygtk_wizard_set_next_button_label (wizard, _("_Accept")); + ygtk_wizard_set_next_button_id (wizard, g_strdup ("accept"), g_free); + g_signal_connect (G_OBJECT (getWidget()), "action-triggered", + G_CALLBACK (wizard_action_cb), this); + + m_package_selector = new PackageSelector (!opt.searchMode.value()); + gtk_container_add (GTK_CONTAINER (wizard), m_package_selector->getWidget()); + } + + virtual ~YGPackageSelector() + { + delete m_package_selector; + } + +protected: + static void wizard_action_cb (YGtkWizard *wizard, gpointer id, + gint id_type, YGPackageSelector *pThis) + { + IMPL + const gchar *action = (gchar *) id; + + if (!strcmp (action, "accept")) { + if (zyppPool().diffState <zypp::Package> ()) { + // in case of changes, check problems, ask for confirmation and JFDI. + if (pThis->confirmChanges() && solveProblems()) { + y2milestone ("Closing PackageSelector with 'accept'"); + YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept"))); + } + } + else + YGUI::ui()->sendEvent (new YCancelEvent()); + } + else if (!strcmp (action, "cancel")) { + y2milestone ("Closing PackageSelector with 'cancel'"); + if (pThis->checkDelete()) + YGUI::ui()->sendEvent (new YCancelEvent()); + } + } + + // helper function for confirmChanges + static bool isInstalled (const string &package) + { + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) { + if ((*it)->hasInstalledObj() || (*it)->toInstall()) { + if (package == (*it)->name()) + return true; + ZyppObject obj = (*it)->theObj(); + const zypp::CapSet &caps = obj->dep (zypp::Dep::PROVIDES); + for (zypp::CapSet::const_iterator jt = caps.begin(); + jt != caps.end(); jt++) + if (package == jt->asString()) + return true; + } + } + return false; // doesn't even exist + } + + bool confirmChanges() + { + IMPL + if (zyppPool().empty <zypp::Package> ()) + return false; + + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Changes Summary"), + YGUI::ui()->currentWindow(), + GtkDialogFlags (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("C_onfirm"), GTK_RESPONSE_ACCEPT, NULL); + + GtkWidget *install_label, *remove_label, *install_view, *remove_view; + install_label = gtk_label_new (_("To install:")); + remove_label = gtk_label_new (_("To remove:")); + install_view = gtk_tree_view_new(); + remove_view = gtk_tree_view_new(); + + GtkWidget *install_window, *remove_window; + install_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (install_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (install_window), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (install_window), install_view); + remove_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (remove_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type + (GTK_SCROLLED_WINDOW (remove_window), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (remove_window), remove_view); + + GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox); + gtk_box_pack_start (vbox, install_label, FALSE, FALSE, 6); + gtk_box_pack_start (vbox, install_window, TRUE, TRUE, 6); + gtk_box_pack_start (vbox, remove_label, FALSE, FALSE, 6); + gtk_box_pack_start (vbox, remove_window, TRUE, TRUE, 6); + + // create model + { + GtkTreeStore *install_store = gtk_tree_store_new (1, G_TYPE_STRING); + GtkTreeStore *remove_store = gtk_tree_store_new (1, G_TYPE_STRING); + + // install view + GtkTreeViewColumn *column; + column = gtk_tree_view_column_new_with_attributes (_("Install packages"), + gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (install_view), column); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (install_view), FALSE); + gtk_tree_view_set_model (GTK_TREE_VIEW (install_view), + GTK_TREE_MODEL (install_store)); + g_object_unref (G_OBJECT (install_store)); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (install_view)), GTK_SELECTION_NONE);; + + // remove view + column = gtk_tree_view_column_new_with_attributes (_("Remove packages"), + gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (remove_view), column); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (remove_view), FALSE); + gtk_tree_view_set_model (GTK_TREE_VIEW (remove_view), + GTK_TREE_MODEL (remove_store)); + g_object_unref (G_OBJECT (remove_store)); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (remove_view)), GTK_SELECTION_NONE);; + + // construct model + for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) + { + ZyppSelectable selectable = *it; + if (!selectable) + continue; + + GtkTreeStore *store; + if (selectable->toInstall()) + store = install_store; + else if (selectable->toDelete()) + store = remove_store; + else continue; + + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, selectable->name().c_str(), -1); + + // show dependencies -- we just ask Zypp for dependencies in the form + // of a string (which is the only way to do it anyway). + if (store == install_store) { + GtkTreeIter dep_iter; + ZyppObject object = selectable->theObj(); + const zypp::CapSet &capSet = object->dep (zypp::Dep::REQUIRES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + // don't show if it is already installed + if (isInstalled (it->asString())) + continue; + + gtk_tree_store_append (store, &dep_iter, &iter); + gtk_tree_store_set (store, &dep_iter, + 0, it->asString().c_str(), -1); + } + } + + // show packages that require this -- we will need to iterate through + // all the packages... (not very accurate) + else { + GtkTreeIter req_iter; + + for (ZyppPool::const_iterator it = + zyppPool().byKindBegin <zypp::Package>(); + it != zyppPool().byKindEnd <zypp::Package>(); it++) { + // only show if it is installed + if ((*it)->hasInstalledObj() || (*it)->toInstall()) { + ZyppSelectable dep_selectable = *it; + ZyppObject dep_object = dep_selectable->theObj(); + + const zypp::CapSet &capSet = dep_object->dep (zypp::Dep::REQUIRES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + if (it->asString() == selectable->name()) { + gtk_tree_store_append (store, &req_iter, &iter); + gtk_tree_store_set (store, &req_iter, + 0, dep_selectable->name().c_str(), -1); + break; + } + } + } + } + } + } + } + + gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400); + gtk_widget_show_all (dialog); + + bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT; + gtk_widget_destroy (dialog); + + return confirmed; + } + + YGWIDGET_IMPL_COMMON +}; +#endif /*DISABLE_PACKAGE_SELECTOR*/ + +YWidget * +YGUI::createPackageSelector (YWidget *parent, YWidgetOpt &opt, + const YCPString &floppyDevice) +{ + // TODO: floppyDevice really needed? +#ifndef DISABLE_PACKAGE_SELECTOR + if (opt.youMode.value()) + return new YGPatchSelector (opt, YGWidget::get (parent)); + else + return new YGPackageSelector (opt, YGWidget::get (parent)); +#else + return NULL; +#endif +} + +YWidget * +YGUI::createPkgSpecial (YWidget *parent, YWidgetOpt &opt, + const YCPString &subwidget) +{ + // same as Qt's + y2error ("The GTK+ UI does not support PkgSpecial subwidgets!"); + return 0; +} + Added: trunk/gtk/unstable/src/YGProgressBar.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGProgressBar.cc... ============================================================================== --- trunk/gtk/unstable/src/YGProgressBar.cc (added) +++ trunk/gtk/unstable/src/YGProgressBar.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,166 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" + +#include "YProgressBar.h" + +class YGProgressBar : public YProgressBar, public YGLabeledWidget +{ + bool m_pulse; +public: + YGProgressBar (const YWidgetOpt &opt, YGWidget *parent, + const YCPString& label, + const YCPInteger& maxprogress, const YCPInteger& progress) + : YProgressBar (opt, label, maxprogress, progress) + , YGLabeledWidget (this, parent, label, YD_VERT, true, + GTK_TYPE_PROGRESS_BAR, NULL) + { + m_pulse = maxprogress->value() <= 0; + } + // NOTE: its label widget is positionated at the vertical, because its label + // may change often and so will its size, which will look odd (we may want + // to make the label widget to only grow). + + virtual ~YGProgressBar() {} + + // YProgressBar + virtual void setProgress (const YCPInteger& newProgress) + { + IMPL + if (m_pulse) + gtk_progress_bar_pulse (GTK_PROGRESS_BAR (getWidget())); + else { + float fraction = (float) newProgress->value() / maxProgress->value(); + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (getWidget()), fraction); + } + YProgressBar::setProgress (newProgress); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN (YProgressBar) +}; + +YWidget * +YGUI::createProgressBar (YWidget* parent, YWidgetOpt& opt, + const YCPString& label, const YCPInteger& maxprogress, + const YCPInteger& progress) +{ + IMPL; + return new YGProgressBar (opt, YGWidget::get (parent), + label, maxprogress, progress); +} + +#include "YDownloadProgress.h" + +class YGDownloadProgress : public YDownloadProgress, public YGLabeledWidget +{ + guint timeout_id; + +public: + YGDownloadProgress (const YWidgetOpt &opt, YGWidget *parent, + const YCPString& label, const YCPString &filename, + int expectedSize) + : YDownloadProgress (opt, label, filename, expectedSize) + , YGLabeledWidget (this, parent, label, YD_HORIZ, true, + GTK_TYPE_PROGRESS_BAR, NULL) + { + timeout_id = g_timeout_add (250, timeout_cb, this); + } + + virtual ~YGDownloadProgress() + { + g_source_remove (timeout_id); + } + + virtual void setExpectedSize (int expectedSize) + { + YDownloadProgress::setExpectedSize (expectedSize); + timeout_cb(this); // force an update + } + + static gboolean timeout_cb (void *pData) + { + YGDownloadProgress *pThis = (YGDownloadProgress*) pData; + float fraction = (float) pThis->currentFileSize() / pThis->expectedSize(); + if (fraction > 1) fraction = 1; + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pThis->getWidget()), fraction); + return TRUE; + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN (YDownloadProgress) +}; + +YWidget * +YGUI::createDownloadProgress (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &filename, + int expectedSize) +{ + IMPL + return new YGDownloadProgress (opt, YGWidget::get (parent), + label, filename, expectedSize); +} + +#include "ygtkratiobox.h" +#include "YMultiProgressMeter.h" + +class YGMultiProgressMeter : public YMultiProgressMeter, public YGWidget +{ +public: + YGMultiProgressMeter (const YWidgetOpt &opt, YGWidget *parent, + bool horizontal, const YCPList &maxValues) + : YMultiProgressMeter (opt, horizontal, maxValues) + , YGWidget (this, parent, true, + horizontal ? YGTK_TYPE_RATIO_HBOX : YGTK_TYPE_RATIO_VBOX, NULL) + { +// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (getWidget()), TRUE); + ygtk_ratio_box_set_spacing (YGTK_RATIO_BOX (getWidget()), 2); + + for (int i = segments()-1; i >= 0; i--) { + GtkWidget* bar = gtk_progress_bar_new(); + gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (bar), + horizontal ? GTK_PROGRESS_LEFT_TO_RIGHT : GTK_PROGRESS_BOTTOM_TO_TOP); + // Progress bars would ask for too much size with weight... + const int min_size = 5; + if (horizontal) + gtk_widget_set_size_request (bar, min_size, -1); + else + gtk_widget_set_size_request (bar, -1, min_size); + ygtk_ratio_box_pack (YGTK_RATIO_BOX (getWidget()), bar, + maxValue (i), TRUE, TRUE, 0); + } + + ygtk_adj_size_set_max (YGTK_ADJ_SIZE (m_adj_size), horizontal ? 200 : 0, + horizontal ? 0 : 200); + gtk_widget_show_all (getWidget()); + } + + virtual void doUpdate() + { + GList* children = gtk_container_get_children (GTK_CONTAINER (getWidget())); + int n = segments()-1; + for (GList *i = children; i && n >= 0; i = i->next, n--) { + GtkProgressBar *bar = GTK_PROGRESS_BAR (i->data); + gfloat fraction = 0; + if (currentValue (n) != -1) + fraction = 1.0 - ((gfloat) currentValue(n) / maxValue(n)); + gtk_progress_bar_set_fraction (bar, fraction); + } + g_list_free (children); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createMultiProgressMeter (YWidget *parent, YWidgetOpt &opt, + bool horizontal, const YCPList &maxValues) +{ + return new YGMultiProgressMeter (opt, YGWidget::get (parent), + horizontal, maxValues); +} Added: trunk/gtk/unstable/src/YGPushButton.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGPushButton.cc?... ============================================================================== --- trunk/gtk/unstable/src/YGPushButton.cc (added) +++ trunk/gtk/unstable/src/YGPushButton.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,79 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YPushButton.h" +#include "YGUtils.h" +#include "YGWidget.h" + +class YGPushButton : public YPushButton, public YGWidget +{ +public: + YGPushButton (const YWidgetOpt &opt, YGWidget *parent, YCPString label) + : YPushButton (opt, label), + YGWidget (this, parent, true, GTK_TYPE_BUTTON, "can-default", TRUE, NULL) + { + IMPL + if (!opt.isShrinkable.value()) + setMinSizeInChars (10, 0); + + gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE); + setLabel (label); + + g_signal_connect (G_OBJECT (getWidget ()), "clicked", + G_CALLBACK (clicked_cb), this); + if (opt.isDefaultButton.value()) + g_signal_connect (G_OBJECT (getWidget ()), "realize", + G_CALLBACK (set_default_cb), this); + } + + virtual ~YGPushButton() {} + + // YPushButton + virtual void setLabel (const YCPString &label) + { + IMPL + string str = YGUtils::mapKBAccel (label->value_cstr()); + gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str()); + YGUtils::setStockIcon (getWidget(), str); + YPushButton::setLabel (label); + } + + virtual void setIcon (const YCPString &icon_name) + { + IMPL + string path = icon_name->value(); + if (path[0] != '/') + path = ICON_DIR + path; + + GError *error = 0; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path.c_str(), &error); + if (pixbuf) { + GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf); + gtk_button_set_image (GTK_BUTTON (getWidget()), image); + g_object_unref (G_OBJECT (pixbuf)); + } + else + y2warning ("YGPushButton: Couldn't load icon image: %s.\n" + "Reason: %s", path.c_str(), error->message); + } + + static void set_default_cb (GtkButton *button, YGPushButton *pThis) + { gtk_widget_grab_default (GTK_WIDGET (button)); } + + static void clicked_cb (GtkButton *button, YGPushButton *pThis) + { pThis->emitEvent (YEvent::Activated, false); } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createPushButton (YWidget *parent, YWidgetOpt &opt, + const YCPString &label) +{ + return new YGPushButton (opt, YGWidget::get (parent), label); +} + Added: trunk/gtk/unstable/src/YGRadioButton.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGRadioButton.cc... ============================================================================== --- trunk/gtk/unstable/src/YGRadioButton.cc (added) +++ trunk/gtk/unstable/src/YGRadioButton.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,243 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YEvent.h" +#include "YGUtils.h" +#include "YGWidget.h" + +// Sub-class GtkRadioButton to get a widget that renders like +// a radio-button, but behaves like a check/toggle-button. +static GType getCheckRadioButtonType() +{ + static GType type = 0; + + if (type) + return type; + + static const GTypeInfo info = { + sizeof (GtkRadioButtonClass), NULL, NULL, + NULL, NULL, NULL, + sizeof (GtkRadioButton), 0, NULL + }; + type = g_type_register_static (GTK_TYPE_RADIO_BUTTON, "YGRadioButton", + &info, GTypeFlags(0)); + // save a class_init function + GtkButtonClass *klass_new = GTK_BUTTON_CLASS (g_type_class_ref (type)); + GtkButtonClass *klass_sane = + GTK_BUTTON_CLASS (g_type_class_ref (GTK_TYPE_TOGGLE_BUTTON)); + klass_new->clicked = klass_sane->clicked; + return type; +} + +#include "YRadioButtonGroup.h" +#include "YRadioButton.h" + +class YGRadioButton : public YRadioButton, public YGWidget +{ + bool m_isBold; + +public: + + YGRadioButton (const YWidgetOpt &opt, + YGWidget *parent, + YCPString label, + YRadioButtonGroup *rbg, + bool checked) + : YRadioButton (opt, label, rbg), + YGWidget (this, parent, true, getCheckRadioButtonType(), NULL) + { + IMPL + setBorder (0); + setValue (YCPBoolean (checked)); + + m_isBold = opt.boldFont.value(); + gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE); + setLabel (label); + + g_signal_connect (G_OBJECT (getWidget()), "toggled", + G_CALLBACK (toggled_cb), this); + } + + // YRadioButton + virtual void setLabel (const YCPString &text) + { + // NOTE: we can't just set a gtk_widget_modify() at the initialization + // because each gtk_button_set_label() creates a new label + IMPL + string str = YGUtils::mapKBAccel(text->value_cstr()); + if (m_isBold) + str = "<b>" + str + "</b>"; + gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str()); + YRadioButton::setLabel (text); + + GtkWidget *label = gtk_bin_get_child (GTK_BIN (getWidget())); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + } + + virtual void setValue (const YCPBoolean &checked) + { + IMPL + g_signal_handlers_block_by_func (getWidget(), (gpointer) toggled_cb, this); + + if (checked->value()) + buttonGroup()->uncheckOtherButtons (this); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), + checked->value()); + + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) toggled_cb, this); + } + + virtual YCPBoolean getValue() + { + IMPL + return YCPBoolean (gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON (getWidget()))); + } + + // YWidget + YGWIDGET_IMPL_COMMON + + // callbacks + static void toggled_cb (GtkButton *button, YGRadioButton *pThis) + { + IMPL + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) + pThis->buttonGroup()->uncheckOtherButtons (pThis); + else { + g_signal_handlers_block_by_func (button, (gpointer) toggled_cb, pThis); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + g_signal_handlers_unblock_by_func (button, (gpointer) toggled_cb, pThis); + } + + pThis->emitEvent (YEvent::ValueChanged); + } +}; + +YWidget * +YGUI::createRadioButton (YWidget *parent, YWidgetOpt &opt, + YRadioButtonGroup *rbg, const YCPString &label, + bool checked) +{ + IMPL; + return new YGRadioButton (opt, YGWidget::get (parent), label, rbg, checked); +} + +// YRadioButtonGroup + +class YGRadioButtonGroup : public YRadioButtonGroup, public YGWidget +{ +public: + YGRadioButtonGroup(const YWidgetOpt &opt, + YGWidget *parent) + : YRadioButtonGroup (opt), + YGWidget (this, parent, true, GTK_TYPE_EVENT_BOX, NULL) + { } + + YGWIDGET_IMPL_COMMON + YGWIDGET_IMPL_CHILD_ADDED (m_widget) + YGWIDGET_IMPL_CHILD_REMOVED (m_widget) +}; + +YContainerWidget * +YGUI::createRadioButtonGroup (YWidget *parent, YWidgetOpt &opt) +{ + IMPL; + return new YGRadioButtonGroup (opt, YGWidget::get (parent)); +} + +#include "YCheckBox.h" + +class YGCheckBox : public YCheckBox, public YGWidget +{ + bool m_isBold; + +public: + YGCheckBox(const YWidgetOpt &opt, + YGWidget *parent, + const YCPString &label_str, + bool checked) + : YCheckBox (opt, label_str), + YGWidget (this, parent, true, GTK_TYPE_CHECK_BUTTON, NULL) + { + IMPL + setBorder (0); + m_isBold = opt.boldFont.value(); + + gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE); + setLabel (label_str); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), checked); + + g_signal_connect (G_OBJECT (getWidget ()), "toggled", + G_CALLBACK (toggled_cb), this); + } + + // YCheckButton + virtual void setLabel (const YCPString &text) + { + IMPL + string str = YGUtils::mapKBAccel(text->value_cstr()); + if (m_isBold) + str = "<b>" + str + "</b>"; + gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str()); + YCheckBox::setLabel (text); + + GtkWidget *label = gtk_bin_get_child (GTK_BIN (getWidget())); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + } + + virtual void setValue (const YCPValue &val) + { + IMPL; + GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget()); + + g_signal_handlers_block_by_func (getWidget(), (gpointer) toggled_cb, this); + + if (val->isBoolean()) { + gtk_toggle_button_set_inconsistent (button, FALSE); + gtk_toggle_button_set_active (button, val->asBoolean()->value()); + } + else + gtk_toggle_button_set_inconsistent (button, TRUE); + + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) toggled_cb, this); + } + + virtual YCPValue getValue() + { + IMPL; + + GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget()); + + if (gtk_toggle_button_get_inconsistent (button)) + return YCPVoid(); + else + return YCPBoolean (gtk_toggle_button_get_active (button)); + } + + static void toggled_cb (GtkBox *box, YGCheckBox *pThis) + { + IMPL + GtkToggleButton *button = GTK_TOGGLE_BUTTON (box); + if (gtk_toggle_button_get_inconsistent (button)) { + gtk_toggle_button_set_inconsistent (button, false); + pThis->setValue (YCPBoolean (true)); + } + + pThis->emitEvent (YEvent::ValueChanged); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createCheckBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + bool checked) +{ + IMPL; + return new YGCheckBox (opt, YGWidget::get (parent), label, checked); +} Added: trunk/gtk/unstable/src/YGTable.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGTable.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGTable.cc (added) +++ trunk/gtk/unstable/src/YGTable.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,523 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGUtils.h" +#include "YGWidget.h" + +/* A generic widget for table related widgets. */ +class YGTableView : public YGScrolledWidget +{ +protected: + int m_colsNb; + +public: + YGTableView (YWidget *y_widget, YGWidget *parent, + const YWidgetOpt &opt, YCPString label) + : YGScrolledWidget (y_widget, parent, label, YD_VERT, true, + GTK_TYPE_TREE_VIEW, NULL) + { + IMPL + m_colsNb = 0; + + /* Yast tools expect the user to be unable to un-select the row. They + generally don't check to see if the returned value is -1. So, just + disallow un-selection. */ + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (getWidget())), GTK_SELECTION_BROWSE); + + // let the derivates do the event hooks. They have subtile differences. + } + + void initModel (const vector <GType> &types, bool show_headers) + { + IMPL + // turn vector into an array; last column dedicated to the row id + m_colsNb = types.size(); + GType types_array [m_colsNb+1]; + for (unsigned int i = 0; i < types.size(); i++) + types_array [i] = types[i]; + types_array[m_colsNb] = G_TYPE_INT; + + GtkListStore *list = gtk_list_store_newv (m_colsNb+1, types_array); + gtk_tree_view_set_model (GTK_TREE_VIEW (getWidget()), GTK_TREE_MODEL (list)); + g_object_unref (G_OBJECT (list)); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (getWidget()), show_headers); + } + + void insertColumn (int col_nb, string header, GType type) + { + IMPL + GtkTreeViewColumn *column = 0; + + // The allignment of the column items + gfloat xalign = 0.0; + if (header.length()) { + if (header[0] == 'R') + xalign = 1.0; + else if (header[0] == 'C') + xalign = 0.5; + // else if (header[0] == 'L') + header = header.substr(1); + } + + if (type == G_TYPE_STRING) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + g_object_set (renderer, "xalign", xalign, NULL); + // set the last column, the expandable one, as wrapable + if (col_nb == m_colsNb-1 && col_nb >= 3) + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + column = gtk_tree_view_column_new_with_attributes (header.c_str(), + renderer, "text", col_nb, NULL); + } + else if (type == G_TYPE_BOOLEAN) { // toggle button + GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new(); + g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (col_nb)); + g_object_set (renderer, "xalign", xalign, NULL); + column = gtk_tree_view_column_new_with_attributes (header.c_str(), + renderer, "active", col_nb, NULL); + + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (toggled_cb), this); + } + else if (type == GDK_TYPE_PIXBUF) { + GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); + g_object_set (renderer, "xalign", xalign, NULL); + column = gtk_tree_view_column_new_with_attributes (header.c_str(), + renderer, "pixbuf", col_nb, NULL); + } + else + g_error ("YGTable: no support for column of given type"); + + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_insert_column (GTK_TREE_VIEW (getWidget()), column, col_nb); + } + + void setSearchCol (int col) + { + gtk_tree_view_set_search_column (GTK_TREE_VIEW (getWidget()), col); + } + +protected: + inline GtkListStore *getStore() + { return GTK_LIST_STORE (getModel()); } + inline GtkTreeModel *getModel() + { return gtk_tree_view_get_model (GTK_TREE_VIEW (getWidget())); } + +protected: + /* NOTE: gtk_list_store_insert() doesn't necessarly put the row in the + requested position. For instance, if the number of rows is smaller than + the one requested, it just appends it. So, we must translate YCP rows + numbering to the ones we set. We'll call YCP rows as ids. + Besides, if we do sorting, paths will get changed. */ + + bool getRowOf (GtkTreeIter *iter, int id) { + if (!gtk_tree_model_get_iter_first (getModel(), iter)) + return false; + + int _id = -1; + do { + gtk_tree_model_get (getModel(), iter, m_colsNb, &_id, -1); + if (_id == id) + return true; + } while (gtk_tree_model_iter_next (getModel(), iter)); + return false; + } + + int getIdOf (int row) { + GtkTreeIter iter; + if (!gtk_tree_model_iter_nth_child (getModel(), &iter, NULL, row)) + return -1; + + int id; + gtk_tree_model_get (getModel(), &iter, m_colsNb, &id, -1); + return id; + } + + void addRow (int id) + { + IMPL + GtkTreeIter iter; + gtk_list_store_append (getStore(), &iter); + gtk_list_store_set (getStore(), &iter, m_colsNb, id, -1); + } + + void setItemText (string text, int id, int col) + { + IMPL + GtkTreeIter iter; + if (getRowOf (&iter, id)) + gtk_list_store_set (getStore(), &iter, col, text.c_str(), -1); + } + + void setItemBool (gboolean state, int id, int col) + { + IMPL + GtkTreeIter iter; + if (getRowOf (&iter, id)) + gtk_list_store_set (getStore(), &iter, col, state, -1); + } + + void setItemIcon (string icon, int id, int col) + { + IMPL + GtkTreeIter iter; + if (getRowOf (&iter, id)) { + GdkPixbuf *pixbuf; + if (icon[0] != '/') + icon = ICON_DIR + icon; + + GError *error = 0; + pixbuf = gdk_pixbuf_new_from_file (icon.c_str(), &error); + if (!pixbuf) + y2warning ("YGTable: Could not load icon: %s.\n" + "Because %s", icon.c_str(), error->message); + + gtk_list_store_set (getStore(), &iter, col, pixbuf, -1); + } + } + + void deleteRows() + { + IMPL + blockEvents(); + gtk_list_store_clear (getStore()); + unblockEvents(); + } + + int getCurrentRow() + { + IMPL + GtkTreePath *path; + gtk_tree_view_get_cursor (GTK_TREE_VIEW(getWidget()), &path, NULL); + if (path == NULL) + return -1; + + GtkTreeIter iter; + gtk_tree_model_get_iter (getModel(), &iter, path); + gtk_tree_path_free (path); + + int id; + gtk_tree_model_get (getModel(), &iter, m_colsNb, &id, -1); + return id; + } + + void setCurrentRow (int id) + { + IMPL + blockEvents(); + GtkTreeIter iter; + if (getRowOf (&iter, id)) { + GtkTreePath *path = gtk_tree_model_get_path (getModel(), &iter); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (getWidget()), path, NULL, false); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (getWidget()), path, NULL, + TRUE, 0.5, 0.5); + gtk_tree_path_free (path); + } + unblockEvents(); + } + + void blockEvents() + { + g_signal_handlers_block_by_func (getWidget(), (gpointer) selected_cb, this); + g_signal_handlers_block_by_func (getWidget(), (gpointer) selected_delayed_cb, this); + } + void unblockEvents() + { + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) selected_cb, this); + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) selected_delayed_cb, this); + } + + // toggled by user (through clicking on the renderer or some other action) + void toggle (GtkTreePath *path, gint column) + { + IMPL + GtkTreeIter iter; + if (!gtk_tree_model_get_iter (getModel(), &iter, path)) + return; + gboolean state; + + gtk_tree_model_get (getModel(), &iter, column, &state, -1); + gtk_list_store_set (getStore(), &iter, column, !state, -1); + + emitEvent (YEvent::ValueChanged); + } + + static void selected_cb (GtkTreeView *tree_view, YGTableView* pThis) + { + IMPL + pThis->emitEvent (YEvent::SelectionChanged); + } + + static void selected_delayed_cb (GtkTreeView *tree_view, YGTableView* pThis) + { + IMPL + pThis->emitEvent (YEvent::SelectionChanged, true, true, false); + } + + static void activated_cb (GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, YGTableView* pThis) + { + IMPL + pThis->emitEvent (YEvent::Activated); + } + + static void toggled_cb (GtkCellRendererToggle *renderer, gchar *path_str, + YGTableView *pThis) + { + IMPL + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "column")); + pThis->toggle (path, column); + gtk_tree_path_free (path); + } +}; + +#include "YTable.h" + +class YGTable : public YTable, public YGTableView +{ +public: + YGTable (const YWidgetOpt &opt, YGWidget *parent, + vector <string> headers) + : YTable (opt, headers.size()), + YGTableView (this, parent, opt, YCPString("")) + { + IMPL + vector <GType> types; + types.assign (numCols(), G_TYPE_STRING); + initModel (types, true); + for (int i = 0; i < numCols(); i++) + insertColumn (i, headers[i], types[i]); + + setLabelVisible (false); + + if (!opt.keepSorting.value()) + YGUtils::tree_view_set_sortable (GTK_TREE_VIEW (getWidget()), 0); + if (numCols() >= 3) + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (getWidget()), TRUE); + + g_signal_connect (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (activated_cb), (YGTableView*) this); + if (opt.immediateMode.value()) + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); + } + + virtual void itemAdded (vector<string> elements, int index) + { + IMPL + addRow (index); + for (unsigned int c = 0; c < elements.size(); c++) + setItemText (elements[c], index, c); + + // always have one row selected + if (getCurrentRow() == -1) + setCurrentRow (index); + } + + virtual void itemsCleared() + { IMPL; deleteRows(); } + + virtual void cellChanged (int index, int colnum, const YCPString& text) + { IMPL; setItemText (text->value(), index, colnum); } + + virtual int getCurrentItem() + { IMPL; return getCurrentRow(); } + + virtual void setCurrentItem (int index) + { IMPL; setCurrentRow (index); } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createTable (YWidget *parent, YWidgetOpt & opt, + vector<string> headers) +{ + return new YGTable (opt, YGWidget::get (parent), headers); +} + +#include "YSelectionBox.h" + +class YGSelectionBox : public YSelectionBox, public YGTableView +{ +public: + YGSelectionBox (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label) + : YSelectionBox (opt, label), + YGTableView (this, parent, opt, label) + { + /* we'll have to wait for 09 to get nicer to construct vectors :P */ + vector <GType> types; + types.push_back (GDK_TYPE_PIXBUF); + types.push_back (G_TYPE_STRING); + initModel (types, false); + + insertColumn (1, "", G_TYPE_STRING); + setSearchCol (1); + // pixbuf column will be added later, if needed + + g_signal_connect (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (activated_cb), (YGTableView*) this); + if (opt.immediateMode.value()) + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); + else + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_delayed_cb), (YGTableView*) this); + } + + // YSelectionBox + virtual int getCurrentItem() + { IMPL; return getCurrentRow(); } + + virtual void setCurrentItem (int index) + { IMPL; setCurrentRow (index); } + + // YSelectionWidget + virtual void itemAdded (const YCPString &str, int index, bool selected) + { + IMPL + addRow (index); + + if (hasIcons()) { + if (m_colsNb == 1) // make space for pixbufs + insertColumn (0, "", GDK_TYPE_PIXBUF); + setItemIcon (itemIcon (index)->value(), index, 0); + } + setItemText (str->value(), index, 1); + + if (selected) + setCurrentRow (index); + } + + virtual void deleteAllItems() + { IMPL; deleteRows(); } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createSelectionBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label) +{ + IMPL + return new YGSelectionBox (opt, YGWidget::get (parent), label); +} + +#include "YMultiSelectionBox.h" + +class YGMultiSelectionBox : public YMultiSelectionBox, public YGTableView +{ +public: + YGMultiSelectionBox (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label) + : YMultiSelectionBox (opt, label), + YGTableView (this, parent, opt, label) + { + vector <GType> types; + types.push_back (G_TYPE_BOOLEAN); + types.push_back (GDK_TYPE_PIXBUF); + types.push_back (G_TYPE_STRING); + initModel (types, false); + + insertColumn (0, "", G_TYPE_BOOLEAN); + insertColumn (2, "", G_TYPE_STRING); + setSearchCol (2); + // pixbuf column will be added later, if needed + + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); + // Let the user toggle, using space/enter or double click (not an event). + g_signal_connect_after (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (multi_activated_cb), this); + } + + // YMultiSelectionBox + virtual int getCurrentItem() + { IMPL; return getCurrentRow(); } + + virtual void setCurrentItem (int index) + { IMPL; setCurrentRow (index); } + + // YSelectionWidget + virtual void itemAdded (const YCPString &str, int index, bool selected) + { + IMPL + addRow (index); + + if (hasIcons()) { + if (m_colsNb == 2) // make space for pixbufs + insertColumn (1, "", GDK_TYPE_PIXBUF); + setItemIcon (itemIcon (index)->value(), index, 1); + } + setItemBool (selected, index, 0); + setItemText (str->value(), index, 2); + } + + virtual void deleteAllItems() + { IMPL; deleteRows(); } + + // Toggle related methods follow + /* Returns the state of the toggle at the row "index". + Pass -1 for query only. 0 and 1 to set it false or true. */ + bool itemSelected (int id, int state) + { + IMPL + GtkTreeIter iter; + if (!getRowOf (&iter, id)) + throw "Row doesn't exist"; + + if (state != -1) + gtk_list_store_set (getStore(), &iter, 0, state, -1); + gtk_tree_model_get (getModel(), &iter, 0, &state, -1); + return state; + } + + virtual bool itemIsSelected (int index) + { + IMPL + bool state = 0; + try { state = itemSelected (index, -1); } + catch (char *str) { y2error ("%s - itemIsSelected(%d): %s - ignoring", + YMultiSelectionBox::widgetClass(), index, str); } + return state; + } + + virtual void selectItem (int index) + { + IMPL + try { itemSelected (index, 1); } + catch (char *str) { y2error ("%s - selectItem(%d): %s - ignoring", + YMultiSelectionBox::widgetClass(), index, str); } + } + + virtual void deselectAllItems() + { + for (int i = 0; ; i++) + try { itemSelected (i, false); } + catch (...) { break; } + } + + static void multi_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, YGMultiSelectionBox* pThis) + { + IMPL + pThis->toggle (path, 0); + } + + YGWIDGET_IMPL_COMMON +}; + +YWidget * +YGUI::createMultiSelectionBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label) +{ + IMPL + return new YGMultiSelectionBox (opt, YGWidget::get (parent), label); +} Added: trunk/gtk/unstable/src/YGTextEntry.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGTextEntry.cc?r... ============================================================================== --- trunk/gtk/unstable/src/YGTextEntry.cc (added) +++ trunk/gtk/unstable/src/YGTextEntry.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,74 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YTextEntry.h" +#include "YGWidget.h" +#include "ygtkfieldentry.h" + +class YGTextEntry : public YTextEntry, public YGLabeledWidget +{ +public: + YGTextEntry (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, const YCPString &text) + : YTextEntry (opt, label), + YGLabeledWidget (this, parent, label, YD_HORIZ, true, + YGTK_TYPE_FILTER_ENTRY, NULL) + { + gtk_entry_set_activates_default (GTK_ENTRY (getWidget()), TRUE); + setText (text); + + if (opt.passwordMode.value()) + gtk_entry_set_visibility (GTK_ENTRY (getWidget()), FALSE); + + // Signals to know of any text modification + g_signal_connect (G_OBJECT (getWidget()), "changed", + G_CALLBACK (text_changed_cb), this); + } + + virtual ~YGTextEntry() {} + + // YTextEntry + virtual YCPString getText() + { + return YCPString (gtk_entry_get_text (GTK_ENTRY (getWidget()))); + } + + virtual void setText (const YCPString &text) + { + /* No need to check for valid chars as that's the responsible of the YCP + application programmer. */ + gtk_entry_set_text (GTK_ENTRY (getWidget()), text->value_cstr()); + } + + virtual void setInputMaxLength (const YCPInteger &numberOfChars) + { + gtk_entry_set_width_chars (GTK_ENTRY (getWidget()), + numberOfChars->asInteger()->value()); + } + + virtual void setValidChars (const YCPString &validChars) + { + ygtk_filter_entry_set_valid_chars (YGTK_FILTER_ENTRY (getWidget()), + validChars->value_cstr()); + YTextEntry::setValidChars (validChars); + } + + static void text_changed_cb (GtkEditable *editable, YGTextEntry *pThis) + { + pThis->emitEvent (YEvent::ValueChanged); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YTextEntry) +}; + +YWidget * +YGUI::createTextEntry (YWidget *parent, YWidgetOpt & opt, + const YCPString & label, const YCPString & text) +{ + return new YGTextEntry (opt, YGWidget::get (parent), label, text); +} Added: trunk/gtk/unstable/src/YGTime.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGTime.cc?rev=42... ============================================================================== --- trunk/gtk/unstable/src/YGTime.cc (added) +++ trunk/gtk/unstable/src/YGTime.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,229 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" +#include "ygtkfieldentry.h" + +#include "YTime.h" + +class YGTime : public YTime, public YGLabeledWidget +{ +public: + YGTime (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, const YCPString &time) + : YTime (opt, label), + YGLabeledWidget (this, parent, label, YD_HORIZ, true, + YGTK_TYPE_FIELD_ENTRY, NULL) + { + IMPL + ygtk_field_entry_add_field (YGTK_FIELD_ENTRY (getWidget()), ':', + 2, "0123456789"); + ygtk_field_entry_add_field (YGTK_FIELD_ENTRY (getWidget()), ':', + 2, "0123456789"); + setNewTime (time); + + gtk_widget_show_all (getWidget()); + g_signal_connect (G_OBJECT (getWidget()), "field-entry-changed", + G_CALLBACK (value_changed_cb), this); + } + + virtual ~YGTime() {} + + // YTime + virtual void setNewTime (const YCPString &time) + { + IMPL + char hours[3], mins[3]; + sscanf (time->value_cstr(), "%2s:%2s", hours, mins); + + YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget()); + ygtk_field_entry_set_field_text (entry, 0, hours); + ygtk_field_entry_set_field_text (entry, 1, mins); + } + + virtual YCPString getTime() + { + IMPL + const gchar *hours, *mins; + YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget()); + hours = ygtk_field_entry_get_field_text (entry, 0); + mins = ygtk_field_entry_get_field_text (entry, 1); + + gchar *time = g_strdup_printf ("%02d:%02d:00", atoi (hours), atoi (mins)); + YCPString str = YCPString (time); + g_free (time); + return str; + } + + // callbacks + static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb, + YGTime *pThis) + { IMPL; pThis->emitEvent (YEvent::ValueChanged); } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YTime) +}; + +YWidget * +YGUI::createTime (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &time) +{ + IMPL + return new YGTime (opt, YGWidget::get (parent), label, time); +} + +#include "YDate.h" +#include "ygtkmenubutton.h" + +class YGDate : public YDate, public YGLabeledWidget +{ + GtkWidget *m_entry, *m_calendar, *m_popup_calendar; + +public: + YGDate (const YWidgetOpt &opt, YGWidget *parent, + const YCPString &label, const YCPString &date) + : YDate (opt, label), + YGLabeledWidget (this, parent, label, YD_HORIZ, true, GTK_TYPE_HBOX, NULL) + { + IMPL + m_entry = ygtk_field_entry_new(); + ygtk_field_entry_add_field (YGTK_FIELD_ENTRY (m_entry), '-', 4, "0123456789"); + ygtk_field_entry_add_field (YGTK_FIELD_ENTRY (m_entry), '-', 2, "0123456789"); + ygtk_field_entry_add_field (YGTK_FIELD_ENTRY (m_entry), '-', 2, "0123456789"); + + GtkWidget *menu_button = ygtk_menu_button_new(); + m_calendar = gtk_calendar_new(); + gtk_widget_show (m_calendar); + GtkWidget *popup = ygtk_popup_window_new (m_calendar); + ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (menu_button), popup); + + gtk_box_pack_start (GTK_BOX (getWidget()), m_entry, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (getWidget()), menu_button, FALSE, TRUE, 6); + gtk_widget_show_all (getWidget()); + + setNewDate (date); + g_signal_connect (G_OBJECT (m_entry), "field-entry-changed", + G_CALLBACK (value_changed_cb), this); + + g_signal_connect (G_OBJECT (m_calendar), "day-selected", + G_CALLBACK (calendar_changed_cb), this); + g_signal_connect (G_OBJECT (m_calendar), "day-selected-double-click", + G_CALLBACK (double_click_cb), popup); + } + + virtual ~YGDate() {} + + GtkCalendar *getCalendar() + { return GTK_CALENDAR (m_calendar); } + + YGtkFieldEntry *getEntry() + { return YGTK_FIELD_ENTRY (m_entry); } + + // YDate + virtual void setNewDate (const YCPString &date) + { + IMPL + char year[5], month[3], day[3]; + sscanf (date->value_cstr(), "%4s-%2s-%2s", year, month, day); + + gtk_calendar_select_month (getCalendar(), atoi (month)-1, atoi (year)); + gtk_calendar_select_day (getCalendar(), atoi (day)); + + YGtkFieldEntry *entry = getEntry(); + ygtk_field_entry_set_field_text (entry, 0, year); + ygtk_field_entry_set_field_text (entry, 1, month); + ygtk_field_entry_set_field_text (entry, 2, day); + } + + virtual YCPString getDate() + { + IMPL + const gchar *year, *month, *day; + YGtkFieldEntry *entry = getEntry(); + year = ygtk_field_entry_get_field_text (entry, 0); + month = ygtk_field_entry_get_field_text (entry, 1); + day = ygtk_field_entry_get_field_text (entry, 2); + + gchar *time = g_strdup_printf ("%04d-%02d-%02d", atoi (year), + atoi (month), atoi (day)); + YCPString str = YCPString (time); + g_free (time); + return str; + } + + // callbacks + static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb, + YGDate *pThis) + { + IMPL + int year, month, day; + year = atoi (ygtk_field_entry_get_field_text (pThis->getEntry(), 0)); + month = atoi (ygtk_field_entry_get_field_text (pThis->getEntry(), 1)); + day = atoi (ygtk_field_entry_get_field_text (pThis->getEntry(), 2)); + + if (day < 1 || day > 31 || month < 1 || month > 12) + return; // avoid GtkCalendar warnings + + g_signal_handlers_block_by_func (pThis->getCalendar(), + (gpointer) calendar_changed_cb, pThis); + + gtk_calendar_select_month (pThis->getCalendar(), month-1, year); + gtk_calendar_select_day (pThis->getCalendar(), day); + + g_signal_handlers_unblock_by_func (pThis->getCalendar(), + (gpointer) calendar_changed_cb, pThis); + + pThis->emitEvent (YEvent::ValueChanged); + } + + static void calendar_changed_cb (GtkCalendar *calendar, YGDate *pThis) + { + IMPL + guint year, month, day; + gtk_calendar_get_date (calendar, &year, &month, &day); + month += 1; // GTK calendar months go from 0 to 11 + + gchar *year_str, *month_str, *day_str; + year_str = g_strdup_printf ("%d", year); + month_str = g_strdup_printf ("%d", month); + day_str = g_strdup_printf ("%d", day); + + g_signal_handlers_block_by_func (pThis->getEntry(), + (gpointer) value_changed_cb, pThis); + + YGtkFieldEntry *entry = pThis->getEntry(); + ygtk_field_entry_set_field_text (entry, 0, year_str); + ygtk_field_entry_set_field_text (entry, 1, month_str); + ygtk_field_entry_set_field_text (entry, 2, day_str); + + g_signal_handlers_unblock_by_func (pThis->getEntry(), + (gpointer) value_changed_cb, pThis); + + g_free (year_str); + g_free (month_str); + g_free (day_str); + + pThis->emitEvent (YEvent::ValueChanged); + } + + static void double_click_cb (GtkCalendar *calendar, YGtkPopupWindow *popup) + { + // close popup + gtk_widget_hide (GTK_WIDGET (popup)); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(YDate) +}; + +YWidget * +YGUI::createDate (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &date) +{ + IMPL + return new YGDate (opt, YGWidget::get (parent), label, date); +} Added: trunk/gtk/unstable/src/YGTree.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGTree.cc?rev=42... ============================================================================== --- trunk/gtk/unstable/src/YGTree.cc (added) +++ trunk/gtk/unstable/src/YGTree.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,156 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YEvent.h" +#include "YTree.h" +#include "YGUtils.h" +#include "YGWidget.h" + +class YGTree : public YTree, public YGScrolledWidget +{ +public: + YGTree (const YWidgetOpt &opt, YGWidget *parent, YCPString label) + : YTree (opt, label) + , YGScrolledWidget (this, parent, label, YD_VERT, true, + GTK_TYPE_TREE_VIEW, NULL) + { + GtkTreeStore *tree = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); + gtk_tree_view_set_model(GTK_TREE_VIEW(getWidget()), GTK_TREE_MODEL(tree)); + g_object_unref (G_OBJECT (tree)); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (getWidget()), + 0, "", gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (getWidget()), FALSE); + + // Events + if (opt.notifyMode.value()) { + g_signal_connect (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (activated_cb), this); + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), this); + } + else + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (getWidget())), GTK_SELECTION_NONE); + } + + virtual ~YGTree() { } + + inline GtkTreeModel *getModel() + { return gtk_tree_view_get_model (GTK_TREE_VIEW (getWidget())); } + inline GtkTreeStore *getStore() + { return GTK_TREE_STORE (getModel()); } + + // YTree + void addItems (const YTreeItemList &items, GtkTreeIter *parent) + { + GtkTreeIter iter; + for (unsigned int i = 0; i < items.size(); i++) { + gtk_tree_store_append (getStore(), &iter, parent); + gtk_tree_store_set (getStore(), &iter, 0, + items[i]->getText()->value_cstr(), 1, items[i], -1); + + // store pointer to GtkTreePath for use in setCurrentItem() + { // need to create a path cause iterator would only return the path as a string + GtkTreePath* path = gtk_tree_model_get_path (getModel(), &iter); + // get current index... + gint depth = gtk_tree_path_get_depth (path); + gint *index = gtk_tree_path_get_indices (path) + depth - 1; + items[i]->setData (GINT_TO_POINTER (*index)); + gtk_tree_path_free (path); + } + + if (parent && items[i]->parent()->isOpenByDefault()) { + GtkTreePath *path = gtk_tree_model_get_path (getModel(), &iter); + gtk_tree_view_expand_to_path (GTK_TREE_VIEW (getWidget()), path); + gtk_tree_path_free(path); + } + + addItems (items[i]->itemList(), &iter); + } + } + + virtual void rebuildTree() + { + gtk_tree_store_clear (getStore()); + addItems (items, NULL); + } + +protected: + virtual const YTreeItem *getCurrentItem() const + { + GtkTreePath *path; + GtkTreeViewColumn *column; + gtk_tree_view_get_cursor + (GTK_TREE_VIEW(const_cast<YGTree *>(this)->getWidget()), + &path, &column); + if (path == NULL || column == NULL) + return NULL; + + GtkTreeIter iter; + YTreeItem *item = 0; + gtk_tree_model_get_iter + (const_cast<YGTree *>(this)->getModel(), &iter, path); + gtk_tree_model_get + (const_cast<YGTree *>(this)->getModel(), &iter, 1, &item, -1); + + return item; + } + + /* Constructs a GtkTreePath to the item. + path argument must have been created and unset. */ + void getItemPath (GtkTreePath *path, YTreeItem *item) + { + if (item == NULL) + return; + getItemPath (path, item->parent()); + gtk_tree_path_append_index (path, GPOINTER_TO_INT (item->data())); + } + + virtual void setCurrentItem (YTreeItem *item) + { + IMPL + GtkTreePath *path = gtk_tree_path_new(); + getItemPath (path, item); + + g_signal_handlers_block_by_func (getWidget(), (gpointer) selected_cb, this); + gtk_tree_view_expand_to_path (GTK_TREE_VIEW (getWidget()), path); + gtk_tree_view_set_cursor (GTK_TREE_VIEW(getWidget()), path, NULL, FALSE); + g_signal_handlers_unblock_by_func (getWidget(), (gpointer) selected_cb, this); + + gtk_tree_path_free (path); + } + + virtual void deleteAllItems() + { + gtk_tree_store_clear (getStore()); + YTree::deleteAllItems(); + } + + static void selected_cb (GtkTreeView *tree_view, YWidget* pThis) + { + if (pThis->getNotify() && !YGUI::ui()->eventPendingFor(pThis)) + YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::SelectionChanged)); + } + + static void activated_cb (GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, YGTree* pThis) + { + if (pThis->getNotify()) + YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::Activated)); + } + + YGWIDGET_IMPL_COMMON + YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN (YTree) +}; + +YWidget * +YGUI::createTree (YWidget *parent, YWidgetOpt & opt, const YCPString & label) +{ + return new YGTree (opt, YGWidget::get (parent), label); +} + Added: trunk/gtk/unstable/src/YGUI.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGUI.cc?rev=4251... ============================================================================== --- trunk/gtk/unstable/src/YGUI.cc (added) +++ trunk/gtk/unstable/src/YGUI.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,770 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <stdio.h> +#include <ycp/y2log.h> +#include <YEvent.h> +#include <YDialog.h> +#include <YMacroRecorder.h> +#include "YGUI.h" +#include "YGUtils.h" +#include "YGWidget.h" +#include "YGDialog.h" +#include <glib/gthread.h> +#include <sys/stat.h> +#include <sys/types.h> + +#define DEFAULT_MACRO_FILE_NAME "macro.ycp" +#define BUSY_CURSOR_TIMEOUT 250 + +YGUI::YGUI (int argc, char ** argv, + bool with_threads, + const char *macro_file) : + YUI (with_threads), + busy_timeout (0), + m_done_init (false), + m_argc (0), + m_argv (NULL) +{ + IMPL + m_have_wm = true; + m_no_border = m_fullscreen = false; + m_default_size.width = m_default_size.height = 0; + + m_argc = argc; + m_argv = g_new0 (char *, argc); + memcpy (m_argv, argv, sizeof (char *) * argc); + if (!with_threads) + checkInit(); + +#ifdef IMPL_DEBUG + fprintf (stderr, "I'm initialized '%s' - come & get me !\n", + with_threads ? "with threads !" : "no threads"); +#endif + + for (int i = 1; i < m_argc; i++) + { + const char *argp = m_argv[i]; + if (!argp) continue; + if (argp[0] != '-') { + printf ("Warning: Unknown argument '%s'\n", argp); + continue; + } + argp++; + if (argp[0] == '-') argp++; + + if (!strcmp (argp, "no-wm")) + m_have_wm = false; + else if (!strcmp (argp, "fullscreen")) + m_fullscreen = true; + else if (!strcmp (argp, "noborder")) + m_no_border = true; + else if (!strcmp (argp, "geometry")) { + argp = argv [++i]; + if (i == argc) + printf ("Warning: no value passed to --geometry\n"); + else if (sscanf (argp, "%dx%d", &m_default_size.width, + &m_default_size.height) == EOF) { + printf ("Warning: invalid --geometry value: %s\n", argp); + m_default_size.width = m_default_size.height = 0; + } + } + else if (!strcmp (argp, "help")) { + printf ( + "Command line options for the YaST2 Gtk UI:\n" + "\n" + "--no-wm assume no window manager is running\n" + "--noborder no window manager border for main dialogs\n" + "--fullscreen use full screen for main dialogs\n" + "--geomtry WxH sets a default size of W per H to main dialogs\n" + "--nothreads run without additional UI threads\n" + "--help prints this help text\n" + "\n" + ); + exit (0); + } + else + printf ("Warning: Unknown argument '--%s'\n", argp); + } + + if (macro_file) + playMacro (macro_file); + + // without this none of the (default) threading action works ... + topmostConstructorHasFinished(); +} + +YGUI::~YGUI() +{ + IMPL + g_free (m_argv); +} + +static gboolean +ycp_wakeup_fn (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + *(int *)data = TRUE; + return TRUE; +} + +void YGUI::checkInit() +{ + if (!m_done_init) { + gtk_init (&m_argc, &m_argv); + m_done_init = TRUE; + } +} + +void +YGUI::idleLoop (int fd_ycp) +{ + IMPL + // The rational for this is that we need somewhere to run + // the magic 'main' thread, that can process thread unsafe + // incoming CORBA messages for us + checkInit(); + + GIOChannel *wakeup; + wakeup = g_io_channel_unix_new (fd_ycp); + g_io_channel_set_encoding (wakeup, NULL, NULL); + g_io_channel_set_buffered (wakeup, FALSE); + + int woken = FALSE; + guint watch_tag = g_io_add_watch (wakeup, (GIOCondition)(G_IO_IN | G_IO_PRI), + ycp_wakeup_fn, &woken); + while (!woken) + g_main_context_iteration (NULL, TRUE); + + g_source_remove (watch_tag); + g_io_channel_unref (wakeup); +} + +static gboolean user_input_timeout_cb (YGUI *pThis) +{ + IMPL + if (!pThis->pendingEvent()) + pThis->sendEvent (new YTimeoutEvent()); + return FALSE; +} + +void +YGUI::sendEvent (YEvent *event) +{ + m_event_handler.sendEvent (event); + g_main_context_wakeup (NULL); +} + +// utility that implements both userInput() and pollInput() +YEvent * +YGUI::waitInput (unsigned long timeout_ms, bool block) +{ + IMPL + if (!currentYGDialog()) + return NULL; + + if (block) + normalCursor(); // waiting for input, so no more busy + + guint timeout = 0; + YEvent *event = NULL; + + if (timeout_ms > 0) + timeout = g_timeout_add (timeout_ms, + (GSourceFunc) user_input_timeout_cb, this); + + if (block) + { + while (!pendingEvent()) + g_main_context_iteration (NULL, TRUE); + } + else + while (g_main_context_iteration (NULL, FALSE)) ; + + if (pendingEvent()) + event = m_event_handler.consumePendingEvent(); + + if (timeout) + g_source_remove (timeout); + + if (block) // if YCP keeps working for more than X time, set busy cursor + busy_timeout = g_timeout_add (BUSY_CURSOR_TIMEOUT, busy_timeout_cb, this); + + return event; +} + +YEvent * +YGUI::userInput (unsigned long timeout_ms) +{ + return waitInput (timeout_ms, true); +} + +YEvent *YGUI::pollInput() +{ + return waitInput (0, false); +} + +// dialog bits + +static GdkScreen *getScreen () +{ + return gdk_display_get_default_screen (gdk_display_get_default()); +} + +int YGUI::getDisplayWidth() +{ + IMPL + return gdk_screen_get_width (getScreen()); +} + +int YGUI::getDisplayHeight() +{ + IMPL + return gdk_screen_get_height (getScreen()); +} + +int YGUI::getDefaultSize (YUIDimension dim) +{ + if (dim == YD_HORIZ) { + if (!m_default_size.width) { + if (m_fullscreen) + m_default_size.width = getDisplayWidth(); + else + m_default_size.width = MIN (600, getDisplayWidth()); + } + return m_default_size.width; + } + else { // YD_VERT + if (!m_default_size.height) { + if (m_fullscreen) + m_default_size.height = getDisplayHeight(); + else + m_default_size.height = MIN (450, getDisplayHeight()); + } + return m_default_size.height; + } +} + +// YWidget layout units -> pixels conversion. Same as yast-qt's. +long YGUI::deviceUnits (YUIDimension dim, float size) +{ + if (dim == YD_HORIZ) return (long) ((size * (640.0/80)) + 0.5); + else return (long) ((size * (480.0/25)) + 0.5); +} + +float YGUI::layoutUnits (YUIDimension dim, long device_units) +{ + float size = (float) device_units; + if (dim == YD_HORIZ) return size * (80/640.0); + else return size * (25/480.0); +} + +static void errorMsg (const char *msg) +{ + GtkWidget* dialog = gtk_message_dialog_new + (NULL, GtkDialogFlags (0), GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, "%s", msg); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +void YGUI::internalError (const char *msg) +{ + errorMsg (msg); + abort(); // going down +} + +/* File/directory dialogs. */ +#include <sstream> + +static YCPValue askForFileOrDirectory (GtkFileChooserAction action, + const YCPString &path, const YCPString &filter_pattern, + const YCPString &title) +{ + IMPL + GtkWidget *dialog; + dialog = gtk_file_chooser_dialog_new (title->value_cstr(), + YGUI::ui()->currentWindow(), action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + action == GTK_FILE_CHOOSER_ACTION_SAVE ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE); + + // Yast likes to pass the path and suggested filename as a whole. We will need to + // split that up for GTK+. + string dirpath (path->value()), filename; + if (!dirpath.empty()) { + string::size_type i; + // we don't support local paths + if (dirpath [0] != '/') { + filename = dirpath; + dirpath = ""; + } + else if (!(g_file_test (dirpath.c_str(), G_FILE_TEST_IS_DIR))) { + i = dirpath.find_last_of ("/"); + if (i == string::npos) { + filename = dirpath; + dirpath = ""; + } + else { + string path (dirpath); + dirpath = path.substr (0, i+1); + filename = path.substr (i+1); + } + } + + // check if dirpath and filename are valid + if (!dirpath.empty()) + if (!g_file_test (dirpath.c_str(), G_FILE_TEST_IS_DIR)) { + y2warning ("Path passed to file dialog isn't valid: '%s'", path->value_cstr()); + dirpath = ""; + } + i = filename.find ("/"); + if (i != string::npos) { + y2warning ("Path passed to file dialog isn't valid: '%s'", path->value_cstr()); + filename = ""; + } + } + + if (!dirpath.empty()) + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirpath.c_str()); + if (!filename.empty()) + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename.c_str()); + + string filter_str (filter_pattern->value()); + if (filter_str != "" && filter_str != "*") { + GtkFileFilter *filter = gtk_file_filter_new(); + gtk_file_filter_set_name (filter, filter_str.c_str()); + // cut filter_pattern into chuncks like GTK likes + std::istringstream stream (filter_str); + while (!stream.eof()) { + string str; + stream >> str; + if (!str.empty() && str [str.size()-1] == ',') + str.erase (str.size()-1); + gtk_file_filter_add_pattern (filter, str.c_str()); + } + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + } + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + char* filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + YCPString ret (filename); + g_free (filename); + + gtk_widget_destroy (dialog); + return ret; + } + gtk_widget_destroy (dialog); + return YCPVoid(); +} + +YCPValue YGUI::askForExistingDirectory (const YCPString &path, + const YCPString &title) +{ + IMPL + return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path, + YCPString (""), title); +} + +YCPValue YGUI::askForExistingFile (const YCPString &path, + const YCPString &filter, const YCPString &title) +{ + IMPL + return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_OPEN, path, filter, title); +} + +YCPValue YGUI::askForSaveFileName (const YCPString &path, + const YCPString &filter, const YCPString &title) +{ + IMPL + return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SAVE, path, filter, title); +} + +bool YGUI::textMode() IMPL_RET(false) +bool YGUI::hasImageSupport() IMPL_RET(true) +bool YGUI::hasLocalImageSupport() IMPL_RET(true) +bool YGUI::hasAnimationSupport() IMPL_RET(true) +bool YGUI::hasIconSupport() IMPL_RET(true) +bool YGUI::hasFullUtf8Support() IMPL_RET(true) +bool YGUI::richTextSupportsTable() IMPL_RET(false) +bool YGUI::leftHandedMouse() IMPL_RET(false) + +gboolean YGUI::busy_timeout_cb (gpointer data) +{ + YGUI *pThis = (YGUI *) data; + pThis->busyCursor(); + pThis->busy_timeout = 0; + return FALSE; +} + +void YGUI::busyCursor() +{ + YGDialog *dialog = currentYGDialog(); + if (dialog) + dialog->busyCursor(); +} + +void YGUI::normalCursor() +{ + if (busy_timeout) { + g_source_remove (busy_timeout); + busy_timeout = 0; + } + + YGDialog *dialog = currentYGDialog(); + if (dialog) + dialog->normalCursor(); +} + +void YGUI::redrawScreen() +{ + gtk_widget_queue_draw (GTK_WIDGET (currentWindow())); +} + +YCPValue YGUI::runPkgSelection (YWidget *packageSelector) +{ + y2milestone ("Running package selection..."); + + // TODO: we may have to do some trickery here to disable close button + // and auto activate dialogs (whatever that is) +// _wm_close_blocked = true; +// _auto_activate_dialogs = false; + + YCPValue input = YCPVoid(); + try { + input = evaluateUserInput(); + } + catch (const std::exception &e) { + y2error ("Caught std::exception: %s", e.what()); + y2error ("This is a libzypp problem. Do not file a bug against the UI!"); + } + catch (...) { + y2error ("Caught unspecified exception."); + y2error ("This is a libzypp problem. Do not file a bug against the UI!"); + } + +// _auto_activate_dialogs = true; +// _wm_close_blocked = false; + y2milestone ("Package selection done - returning %s", input->toString().c_str()); + + return input; +} + +void YGUI::makeScreenShot (string filename) +{ + IMPL + bool interactive = filename.empty(); + + GtkWidget *widget = GTK_WIDGET (currentWindow()); + if (!widget) { + if (interactive) + errorMsg ("No dialog to take screenshot of."); + return; + } + + GError *error = 0; + GdkPixbuf *shot = + gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (widget->window), + gdk_colormap_get_system(), 0, 0, 0, 0, widget->allocation.width, + widget->allocation.height); + + if (!shot) { + if (interactive) + errorMsg ("Couldn't take a screenshot."); + return; + } + + if (interactive) { + //** ask user for filename + // calculate a default directory... + if (screenShotNameTemplate.empty()) { + string dir; + const char *homedir = getenv("HOME"); + const char *ssdir = getenv("Y2SCREENSHOTS"); + if (!homedir || !strcmp (homedir, "/")) { + // no homedir defined (installer) + dir = "/tmp/" + (ssdir ? (string(ssdir)) : (string(""))); + if (mkdir (dir.c_str(), 0700) == -1) + dir = ""; + } + else { + dir = homedir + (ssdir ? ("/" + string(ssdir)) : (string(""))); + mkdir (dir.c_str(), 0750); // create a dir for what to put the pics + } + + screenShotNameTemplate = dir + "/%s-%03d.png"; + } + + // calculate a default filename... + const char *baseName = moduleName(); + if (!baseName) + baseName = "scr"; + + int nb; + map <string, int>::iterator it = screenShotNb.find (baseName); + if (it == screenShotNb.end()) + nb = 0; + + { + char *tmp_name = g_strdup_printf (screenShotNameTemplate.c_str(), baseName, nb); + filename = tmp_name; + g_free (tmp_name); + } + y2debug ("screenshot: %s", filename.c_str()); + + YCPValue ret = askForSaveFileName (YCPString (filename.c_str()), + YCPString ("*.png"), + YCPString ("Save screenshot to")); + if (!ret->isString()) { // user dismissed the dialog + y2debug ("Save screen shot canceled by user"); + goto makeScreenShot_ret; + } + + filename = ret->asString()->value(); + screenShotNb.erase (baseName); + screenShotNb[baseName] = nb + 1; + } + + y2debug ("Saving screen shot to %s", filename.c_str()); + if (gdk_pixbuf_save (shot, filename.c_str(), "png", &error, NULL)) { + y2error ("Couldn't save screen shot %s", filename.c_str()); + if (interactive) { + string msg = "Couldn't save screenshot to file " + filename + + " - " + error->message; + errorMsg (msg.c_str()); + } + goto makeScreenShot_ret; + } + + if (recordingMacro()) { + // save the taking of the screenshot and its name to the macro + macroRecorder->beginBlock(); + currentDialog()->saveUserInput (macroRecorder); + macroRecorder->recordMakeScreenShot (true, filename.c_str()); + macroRecorder->recordUserInput (YCPVoid()); + macroRecorder->endBlock(); + } + + makeScreenShot_ret: + g_object_unref (G_OBJECT (shot)); +} + +void YGUI::beep() +{ + gdk_beep(); + GtkWindow *window = currentWindow(); + if (window) + gtk_window_present (window); +} + +YCPString YGUI::glyph (const YCPSymbol &symbol) +{ + string sym = symbol->symbol(); + if (sym == YUIGlyph_ArrowLeft) + return YCPString ("\u2190"); + if (sym == YUIGlyph_ArrowRight) + return YCPString ("\u2192"); + if (sym == YUIGlyph_ArrowUp) + return YCPString ("\u2191"); + if (sym == YUIGlyph_ArrowDown) + return YCPString ("\u2193"); + if (sym == YUIGlyph_CheckMark) + return YCPString ("\u2714"); + if (sym == YUIGlyph_BulletArrowRight) + return YCPString ("\u279c"); + if (sym == YUIGlyph_BulletCircle) + return YCPString ("\u274d"); + if (sym == YUIGlyph_BulletSquare) + return YCPString ("\u274f"); + return YCPString (""); +} + +void YGUI::toggleRecordMacro() +{ + if (recordingMacro()) { + stopRecordMacro(); + normalCursor(); + + GtkWidget* dialog = gtk_message_dialog_new (NULL, + GtkDialogFlags (0), GTK_MESSAGE_INFO, GTK_BUTTONS_OK, + "Macro recording done."); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + else { + YCPValue ret = askForSaveFileName (YCPString (DEFAULT_MACRO_FILE_NAME), + YCPString ("*.ycp"), + YCPString ("Select Macro File to Record to")); + if (ret->isString()) { + YCPString filename = ret->asString(); + recordMacro (filename->value_cstr()); + } + } +} + +void YGUI::askPlayMacro() +{ + YCPValue ret = askForExistingFile (YCPString (DEFAULT_MACRO_FILE_NAME), + YCPString ("*.ycp"), YCPString ("Select Macro File to Play")); + + if (ret->isString()) { + busyCursor(); + YCPString filename = ret->asString(); + + playMacro (filename->value_cstr()); + sendEvent (new YEvent()); // flush + } +} + +void YGUI::askSaveLogs() +{ + YCPValue file = askForSaveFileName (YCPString ("/tmp/y2logs.tgz"), + YCPString ("*.tgz *.tar.gz"), YCPString ("Save y2logs to...")); + + if (file->isString()) { + std::string command = "/sbin/save_y2logs"; + command += " '" + file->asString()->value() + "'"; + y2milestone ("Saving y2logs: %s", command.c_str()); + int ret = system (command.c_str()); + if (ret == 0) + y2milestone ("y2logs saved to %s", file->asString()->value_cstr()); + else { + char *error = g_strdup_printf ( + "Error: couldn't save y2logs: \"%s\" (exit value: %d)", + command.c_str(), ret); + y2error (error); + errorMsg (error); + g_free (error); + } + } +} + +// debug dialogs + +static void destroy_dialog (GtkDialog *dialog, gint arg) +{ IMPL; gtk_widget_destroy (GTK_WIDGET (dialog)); } + +void dumpYastTree (YWidget *widget) +{ + IMPL + struct inner { + static void dumpYastTree (YWidget *widget, GtkTreeStore *store, + GtkTreeIter *parent_node) + { + YGWidget *ygwidget; + if (!widget || !(ygwidget = YGWidget::get (widget))) + return; + + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, parent_node); + + YContainerWidget *container = dynamic_cast <YContainerWidget *> (widget); + gchar *stretch = g_strdup_printf ("%d x %d", + ygwidget->isStretchable (YD_HORIZ), ygwidget->isStretchable (YD_VERT)); + gchar *weight = g_strdup_printf ("%ld x %ld", + widget->weight (YD_HORIZ), widget->weight (YD_VERT)); + gtk_tree_store_set (store, &iter, 0, widget->widgetClass(), + 1, ygwidget->getDebugLabel().c_str(), 2, stretch, 3, weight, -1); + g_free (stretch); + g_free (weight); + + if (container) + for (int i = 0; i < container->numChildren(); i++) + dumpYastTree (container->child (i), store, &iter); + } + }; + + GtkTreeStore *store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING); + inner::dumpYastTree (widget, store, NULL); + + GtkWidget *dialog = gtk_dialog_new_with_buttons ("YWidgets Tree", NULL, + GtkDialogFlags (GTK_DIALOG_NO_SEPARATOR), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); + gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 400); + + GtkWidget *view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), + gtk_tree_view_column_new_with_attributes ("Type", + gtk_cell_renderer_text_new(), "text", 0, NULL)); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), + gtk_tree_view_column_new_with_attributes ("Label", + gtk_cell_renderer_text_new(), "text", 1, NULL)); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), + gtk_tree_view_column_new_with_attributes ("Stretch", + gtk_cell_renderer_text_new(), "text", 2, NULL)); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), + gtk_tree_view_column_new_with_attributes ("Weight", + gtk_cell_renderer_text_new(), "text", 3, NULL)); + gtk_tree_view_expand_all (GTK_TREE_VIEW (view)); + gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (view), TRUE); + + GtkWidget *scroll_win = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll_win), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + + gtk_container_add (GTK_CONTAINER (scroll_win), view); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll_win); + gtk_widget_show_all (dialog); + + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (destroy_dialog), 0); +} + +#include <YRichText.h> + +void dumpYastHtml (YWidget *widget) +{ + struct inner { + static void dumpYastHtml (YWidget *widget, GtkBox *box) + { + YGWidget *ygwidget; + if (!widget || !(ygwidget = YGWidget::get (widget))) + return; + + YRichText *rtext = dynamic_cast <YRichText *> (widget); + if (rtext) { + std::string text = rtext->getText()->value(); + char *xml = ygutils_convert_to_xhmlt_and_subst (text.c_str(), NULL); + + GtkWidget *view = gtk_text_view_new(); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD); + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + gtk_text_buffer_set_text (buffer, xml, -1); + + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (scroll), view); + gtk_box_pack_start (box, scroll, TRUE, TRUE, 6); + + g_free (xml); + } + + YContainerWidget *container = dynamic_cast <YContainerWidget *> (widget); + if (container) + for (int i = 0; i < container->numChildren(); i++) + dumpYastHtml (container->child (i), box); + } + }; + + IMPL + GtkWidget *dialog = gtk_dialog_new_with_buttons ("YWidgets HTML", NULL, + GtkDialogFlags (GTK_DIALOG_NO_SEPARATOR), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); + gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300); + + inner::dumpYastHtml (widget, GTK_BOX (GTK_DIALOG (dialog)->vbox)); + + gtk_widget_show_all (dialog); + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (destroy_dialog), 0); +} + Added: trunk/gtk/unstable/src/YGUI.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGUI.h?rev=42514... ============================================================================== --- trunk/gtk/unstable/src/YGUI.h (added) +++ trunk/gtk/unstable/src/YGUI.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,313 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#ifndef YGUI_H +#define YGUI_H + +#include <gtk/gtk.h> +#include <YSimpleEventHandler.h> +#include <YUI.h> + +using std::string; +using std::vector; + +/* Comment the following line to disable debug messages */ +// #define IMPL_DEBUG +#define LOC fprintf (stderr, "%s (%s)\n", G_STRLOC, G_STRFUNC) +#ifdef IMPL_DEBUG + #define IMPL { LOC; } +#else + #define IMPL { } +#endif +#define IMPL_NULL { IMPL; return NULL; } +#define IMPL_VOID { IMPL; return YCPVoid(); } +#define IMPL_RET(a) { IMPL; return (a); } + +#define ICON_DIR THEMEDIR "/icons/22x22/apps/" + +/* Compatibility */ +#if YAST2_VERSION > 2014004 +# define YAST2_YGUI_CHECKBOX_FRAME 1 +#elif YAST2_VERSION >= 2014000 +# define YAST2_YGUI_CHECKBOX_FRAME 0 +#elif YAST2_VERSION > 2013032 +# define YAST2_YGUI_CHECKBOX_FRAME 1 +#else +# define YAST2_YGUI_CHECKBOX_FRAME 0 +#endif + +class YGDialog; + +class YGUI: public YUI +{ +public: + YGUI (int argc, char **argv, + bool with_threads, const char *macro_file); + virtual ~YGUI(); + + static YGUI *ui() { return (YGUI *)YUI::ui(); } + + // non abstract loop bits: + virtual void blockEvents (bool block = true) IMPL + virtual bool eventsBlocked() const IMPL_RET (false) + virtual void internalError (const char *msg); + virtual void idleLoop (int fd_ycp); + virtual YEvent * waitInput (unsigned long timeout_ms, bool block); + virtual YEvent * userInput (unsigned long timeout_millisec); + virtual YEvent * pollInput(); + + virtual void showDialog (YDialog *dialog); + virtual void closeDialog (YDialog *dialog); + // Non abstract virtuals: + virtual YCPValue setLanguage (const YCPTerm & term) IMPL_VOID + + // event pieces: + private: + YSimpleEventHandler m_event_handler; + public: + void sendEvent (YEvent *event); + YEvent *pendingEvent() const { return m_event_handler.pendingEvent(); } + bool eventPendingFor (YWidget *widget) const { return m_event_handler.eventPendingFor (widget); } + + // container widgets + virtual YDialog *createDialog (YWidgetOpt &opt); + virtual YContainerWidget *createSplit (YWidget *parent, YWidgetOpt &opt, YUIDimension dimension); + virtual YContainerWidget *createReplacePoint (YWidget *parent, YWidgetOpt &opt); + virtual YContainerWidget *createAlignment (YWidget *parent, YWidgetOpt &opt, + YAlignmentType halign, + YAlignmentType valign); + virtual YContainerWidget *createSquash (YWidget *parent, YWidgetOpt &opt, + bool hsquash, bool vsquash); + virtual YContainerWidget *createRadioButtonGroup (YWidget *parent, YWidgetOpt &opt); + virtual YContainerWidget *createFrame (YWidget *parent, YWidgetOpt &opt, + const YCPString &label); +#if YAST2_YGUI_CHECKBOX_FRAME + virtual YContainerWidget *createCheckBoxFrame( YWidget *parent, YWidgetOpt & opt, const YCPString & label, bool checked ); +#endif + + // leaf widgets + virtual YWidget *createEmpty (YWidget *parent, YWidgetOpt &opt); + virtual YWidget *createSpacing (YWidget *parent, YWidgetOpt &opt, float size, + bool horizontal, bool vertical); + virtual YWidget *createLabel (YWidget *parent, YWidgetOpt &opt, + const YCPString &text); + virtual YWidget *createRichText (YWidget *parent, YWidgetOpt &opt, + const YCPString &text); + virtual YWidget *createLogView (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, int visibleLines, + int maxLines); + virtual YWidget *createPushButton (YWidget *parent, YWidgetOpt &opt, + const YCPString & label); + virtual YWidget *createMenuButton (YWidget *parent, YWidgetOpt &opt, + const YCPString & label); + virtual YWidget *createRadioButton (YWidget *parent, YWidgetOpt &opt, + YRadioButtonGroup *rbg, + const YCPString &label, bool checked); + virtual YWidget *createCheckBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, bool checked); + virtual YWidget *createTextEntry (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &text); + virtual YWidget *createMultiLineEdit (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + const YCPString &text); + virtual YWidget *createSelectionBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label); + virtual YWidget *createMultiSelectionBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label); + virtual YWidget *createComboBox (YWidget *parent, YWidgetOpt &opt, + const YCPString &label); + virtual YWidget *createTree (YWidget *parent, YWidgetOpt &opt, + const YCPString &label); + virtual YWidget *createTable (YWidget *parent, YWidgetOpt &opt, + std::vector<std::string> header); + virtual YWidget *createProgressBar (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + const YCPInteger &maxprogress, + const YCPInteger &progress); + virtual YWidget *createImage (YWidget *parent, YWidgetOpt &opt, + YCPByteblock imagedata, YCPString defaulttext); + virtual YWidget *createImage (YWidget *parent, YWidgetOpt &opt, + YCPString file_name, YCPString defaulttext); + virtual YWidget *createIntField (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, int minValue, + int maxValue, int initialValue); + + // Package selector + virtual YWidget *createPackageSelector (YWidget *parent, YWidgetOpt &opt, + const YCPString &floppyDevice); + virtual YWidget *createPkgSpecial (YWidget *parent, YWidgetOpt &opt, + const YCPString &subwidget); + virtual YCPValue runPkgSelection (YWidget *packageSelector); + +/* + // FIXME: do we need to implement these new bits ? + + // New package selector bits ... + bool hasPatternSelector(); + YWidget * createPatternSelector ( YWidget * parent, + YWidgetOpt & opt ); + + bool hasSimplePatchSelector(); + YWidget * createSimplePatchSelector( YWidget * parent, + YWidgetOpt & opt ); +*/ + + // Optional widgets + virtual YWidget *createDummySpecialWidget (YWidget *parent, YWidgetOpt &opt) + IMPL_NULL; + virtual bool hasDummySpecialWidget() { return false; } + + virtual YWidget *createDownloadProgress (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, + const YCPString &filename, + int expectedSize); + virtual bool hasDownloadProgress() { return true; } + + virtual YWidget *createBarGraph (YWidget *parent, YWidgetOpt &opt); + virtual bool hasBarGraph() { return true; } + + virtual YWidget *createColoredLabel (YWidget *parent, YWidgetOpt &opt, + YCPString label, YColor foreground, + YColor background, int margin); + virtual bool hasColoredLabel() { return true; } + + virtual YWidget *createDate (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &date); + virtual bool hasDate() { return true; } + + virtual YWidget *createTime (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, const YCPString &time); + virtual bool hasTime() { return true; } + + virtual YWidget *createDumbTab (YWidget *parent, YWidgetOpt &opt); + virtual bool hasDumbTab() { return true; } + + virtual YWidget *createMultiProgressMeter (YWidget *parent, YWidgetOpt &opt, + bool horizontal, const YCPList & maxValues); + virtual bool hasMultiProgressMeter() { return true; } + + virtual YWidget *createSlider (YWidget *parent, YWidgetOpt &opt, + const YCPString &label, int min, + int max, int initial); + virtual bool hasSlider() { return true; } + + virtual YWidget *createPartitionSplitter (YWidget *parent, + YWidgetOpt &opt, + int usedSize, + int totalFreeSize, + int newPartSize, + int minNewPartSize, + int minFreeSize, + const YCPString &usedLabel, + const YCPString &freeLabel, + const YCPString &newPartLabel, + const YCPString &freeFieldLabel, + const YCPString &newPartFieldLabel); + virtual bool hasPartitionSplitter() { return true; } + + virtual YWidget *createPatternSelector (YWidget *parent, YWidgetOpt &opt) IMPL_NULL; + virtual bool hasPatternSelector() { return false; } + + virtual YWidget *createWizard (YWidget *parent, + YWidgetOpt &opt, + const YCPValue &backButtonId, + const YCPString &backButtonLabel, + const YCPValue &abortButtonId, + const YCPString &abortButtonLabel, + const YCPValue &nextButtonId, + const YCPString &nextButtonLabel); + virtual bool hasWizard() { return true; } + + + virtual int getDisplayWidth(); + virtual int getDisplayHeight(); + // let's fool YWidgets here because it tries to be smart if our default + // dialog size is too small + virtual int getDefaultWidth() { return 10000; } + virtual int getDefaultHeight() { return 10000; } + // Dunno where this is used in practice, but these can be got by a YCP + // apps, so better implement them. + virtual int getDisplayDepth() { return 24; } + virtual long getDisplayColors() { return 256*256*256; } + + virtual long deviceUnits (YUIDimension dim, float size); + virtual float layoutUnits (YUIDimension dim, long device_units); + + virtual bool textMode(); + virtual bool hasImageSupport(); + virtual bool hasLocalImageSupport(); + virtual bool hasAnimationSupport(); + virtual bool hasIconSupport(); + virtual bool hasFullUtf8Support(); + virtual bool richTextSupportsTable(); + virtual bool leftHandedMouse(); + + virtual YCPString glyph (const YCPSymbol &glyph); + virtual void redrawScreen(); + + // convience function to be used rather than currentDialog() + // NULL if there is no dialog at the moment. + GtkWindow *currentWindow(); + YGDialog *currentYGDialog(); + + virtual void busyCursor(); + virtual void normalCursor(); + + guint busy_timeout; // for busy cursor + static gboolean busy_timeout_cb (gpointer data); + + virtual void beep(); + virtual void makeScreenShot (string filename); + + /* File/directory dialogs. */ + virtual YCPValue askForExistingDirectory (const YCPString &startDir, + const YCPString &headline); + virtual YCPValue askForExistingFile (const YCPString &startWith, + const YCPString &filter, + const YCPString &headline); + virtual YCPValue askForSaveFileName (const YCPString &startWith, + const YCPString &filter, + const YCPString &headline); + + // Starts macro recording and asks for a filename to save it to + // If there is already one in progress, it just resumes/pauses as appropriate + // activated by Ctrl-Shift-Alt-M + void toggleRecordMacro(); + + // Plays a macro, opening a dialog first to ask for the filename + // activated by Ctrl-Shift-Alt-P + void askPlayMacro(); + + // On Shift-F8, run save_logs + void askSaveLogs(); + + private: + // window-related arguments + bool m_have_wm, m_no_border, m_fullscreen; + GtkRequisition m_default_size; + + // for delayed gtk+ init in the right thread + bool m_done_init; + int m_argc; + char **m_argv; + void checkInit(); + + // for screenshots: + map <string, int> screenShotNb; + string screenShotNameTemplate; + + public: + // Helpers for internal use [ visibility hidden ] + int getDefaultSize (YUIDimension dim); + bool setFullscreen() const { return m_fullscreen || !m_have_wm; } + bool hasWM() const { return m_have_wm; } + bool unsetBorder() const { return m_no_border; } +}; + +// debug helpers. +void dumpYastTree (YWidget *widget); +void dumpYastHtml (YWidget *widget); + +#endif // YGUI_H + Added: trunk/gtk/unstable/src/YGUtils.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGUtils.cc?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGUtils.cc (added) +++ trunk/gtk/unstable/src/YGUtils.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,727 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <YGUI.h> +#include "YGUtils.h" + +string YGUtils::mapKBAccel (const char *src) +{ + // we won't use use replace since we also want to escape _ to __ + string str; + int length = strlen (src); + str.reserve (length); + + for (int i = 0; i < length; i++) { + if (src[i] == '_') + str += "__"; + else if (src[i] == '&') + str += '_'; + else + str += src[i]; + } + return str; +} + +string YGUtils::filterText (const char* text, int length, const char *valid_chars) +{ + if (length == -1) + length = strlen (text); + if (valid_chars[0] == '\0') + return string(text); + + string str; + str.reserve (length); + for (int i = 0; text[i] && i < length; i++) { + for (int j = 0; valid_chars[j]; j++) + if(text[i] == valid_chars[j]) { + str += text[i]; + break; + } + } + return str; +} + +void YGUtils::filterText (GtkEditable *editable, int pos, int length, + const char *valid_chars) +{ + gchar *text = gtk_editable_get_chars (editable, pos, pos + length); + string str = filterText (text, length, valid_chars); + if (length == -1) + length = strlen (text); + + if (str != text) { // invalid text + // delete current text + gtk_editable_delete_text (editable, pos, length); + // insert correct text + gtk_editable_insert_text (editable, str.c_str(), str.length(), &pos); + + g_signal_stop_emission_by_name (editable, "insert_text"); + gdk_beep(); // BEEP! + } + + g_free (text); +} + +void YGUtils::replace (string &str, const char *mouth, int mouth_len, const char *food) +{ + if (mouth_len < 0) + mouth_len = strlen (mouth); + unsigned int i = 0; + while ((i = str.find (mouth, i)) != string::npos) + { + str.erase (i, mouth_len); + str.insert (i, food); + } +} + +void YGUtils::scrollTextViewDown(GtkTextView *text_view) +{ + GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view); + GtkTextIter end_iter; + gtk_text_buffer_get_end_iter (buffer, &end_iter); + GtkTextMark *end_mark; + end_mark = gtk_text_buffer_create_mark + (buffer, NULL, &end_iter, FALSE); + gtk_text_view_scroll_to_mark (text_view, + end_mark, 0.0, FALSE, 0, 0); + gtk_text_buffer_delete_mark (buffer, end_mark); +} + +void YGUtils::escapeMarkup (string &str) +{ + for (unsigned int i = 0; i < str.length(); i++) { + switch (str[i]) { + case '<': + str.erase (i, 1); + str.insert (i, "<"); + break; + case '>': + str.erase (i, 1); + str.insert (i, ">"); + break; + case '&': + str.erase (i, 1); + str.insert (i, "&"); + break; + default: + break; + } + } +} + +#define PROD_ENTITY "&product;" + +inline void skipSpace(const char *instr, int &i) +{ + while (g_ascii_isspace (instr[i])) i++; +} + +typedef struct { + GString *tag; + int tag_len : 31; + unsigned int early_closer : 1; +} TagEntry; + +static TagEntry * +tag_entry_new (GString *tag, int tag_len) +{ + static const char *early_closers[] = { "p", "li" }; + TagEntry *entry = g_new (TagEntry, 1); + entry->tag = tag; + entry->tag_len = tag_len; + entry->early_closer = FALSE; + + for (unsigned int i = 0; i < G_N_ELEMENTS (early_closers); i++) + if (!g_ascii_strncasecmp (tag->str, early_closers[i], tag_len)) + entry->early_closer = TRUE; + return entry; +} + +static void +tag_entry_free (TagEntry *entry) +{ + if (entry && entry->tag) + g_string_free (entry->tag, TRUE); + g_free (entry); +} + +static void +emit_unclosed_tags_for (GString *outp, GQueue *tag_queue, const char *tag_str, int tag_len) +{ + gboolean matched = FALSE; + + // top-level tag ... + if (g_queue_is_empty (tag_queue)) + return; + + do { + TagEntry *last_entry = (TagEntry *)g_queue_pop_tail (tag_queue); + if (!last_entry) + break; + + if (last_entry->tag_len != tag_len || + g_ascii_strncasecmp (last_entry->tag->str, tag_str, tag_len)) { + /* different tag - emit a close ... */ + g_string_append (outp, "</"); + g_string_append_len (outp, last_entry->tag->str, last_entry->tag_len); + g_string_append_c (outp, '>'); + } else + matched = TRUE; + + tag_entry_free (last_entry); + } while (!matched); +} + +static gboolean +check_early_close (GString *outp, GQueue *tag_queue, TagEntry *entry) +{ + TagEntry *last_tag; + + // Early closers: + if (!entry->early_closer) + return FALSE; + + last_tag = (TagEntry *) g_queue_peek_tail (tag_queue); + if (!last_tag || !last_tag->early_closer) + return FALSE; + + if (entry->tag_len != last_tag->tag_len || + g_ascii_strncasecmp (last_tag->tag->str, entry->tag->str, entry->tag_len)) + return FALSE; + + // Emit close & leave last tag on the stack + + g_string_append (outp, "</"); + g_string_append_len (outp, entry->tag->str, entry->tag_len); + g_string_append_c (outp, '>'); + + return TRUE; +} + + +// We have to: +// + manually substitute the product entity. +// + rewrite <br> and <hr> tags +// + deal with <a attrib=noquotes> +gchar *ygutils_convert_to_xhmlt_and_subst (const char *instr, const char *product) +{ + GString *outp = g_string_new (""); + GQueue *tag_queue = g_queue_new(); + int i = 0; + + skipSpace (instr, i); + + // We must add an outer tag to make GMarkup happy + gboolean addOuterTag = TRUE; +// gboolean addOuterTag = FALSE; +// if ((addOuterTag = (instr[i] != '<'))) + g_string_append (outp, "<body>"); + + for (; instr[i] != '\0'; i++) + { + // Tag foo + if (instr[i] == '<') { + // ignore comments + if (strncmp (&instr[i], "<!--", 4) == 0) { + for (i += 3; instr[i] != '\0'; i++) + if (strncmp (&instr[i], "-->", 3) == 0) { + i += 2; + break; + } + continue; + } + + gint j; + gboolean is_close = FALSE; + gboolean in_tag; + int tag_len; + GString *tag = g_string_sized_new (20); + + i++; + skipSpace (instr, i); + + if (instr[i] == '/') { + i++; + is_close = TRUE; + } + + skipSpace (instr, i); + + // find the tag name piece + in_tag = TRUE; + tag_len = 0; + for (; instr[i] != '>' && instr[i]; i++) { + if (in_tag) { + if (!g_ascii_isalnum(instr[i])) + in_tag = FALSE; + else + tag_len++; + } + g_string_append_c (tag, instr[i]); + } + + // Unmatched tags + if ( !is_close && tag_len == 2 && + (!g_ascii_strncasecmp (tag->str, "hr", 2) || + !g_ascii_strncasecmp (tag->str, "br", 2)) && + tag->str[tag->len - 1] != '/') + g_string_append_c (tag, '/'); + + // Add quoting for un-quoted attributes + for (int j = 0; j < (signed) tag->len; j++) { + if (tag->str[j] == '=') { + if (tag->str[j+1] != '"') { + g_string_insert_c (tag, j+1, '"'); + for (j++; !g_ascii_isspace (tag->str[j]) && tag->str[j]; j++) ; + g_string_insert_c (tag, j, '"'); + } + } + } + + // Is it an open or close ? + j = tag->len - 1; + + while (j > 0 && g_ascii_isspace (tag->str[j])) j--; + + gboolean is_open_close = (tag->str[j] == '/'); + if (is_open_close) + ; // ignore it + else if (is_close) + emit_unclosed_tags_for (outp, tag_queue, tag->str, tag_len); + else { + TagEntry *entry = tag_entry_new (tag, tag_len); + + entry->tag = tag; + entry->tag_len = tag_len; + + if (!check_early_close (outp, tag_queue, entry)) + g_queue_push_tail (tag_queue, entry); + else { + entry->tag = NULL; + tag_entry_free (entry); + } + } + + g_string_append_c (outp, '<'); + if (is_close) + g_string_append_c (outp, '/'); + g_string_append_len (outp, tag->str, tag->len); + g_string_append_c (outp, '>'); + + if (is_close || is_open_close) + g_string_free (tag, TRUE); + } +/* + else if (instr[i] == '&' && + !g_ascii_strncasecmp (instr + i, PROD_ENTITY, + sizeof (PROD_ENTITY) - 1)) { + // 1 Magic entity + g_string_append (outp, product); + i += sizeof (PROD_ENTITY) - 2; + } +*/ + // non-break space entity + else if (instr[i] == '&' && + !g_ascii_strncasecmp (instr + i, " ", + sizeof (" ") - 1)) { + // Replace this by a white-space + g_string_append (outp, " "); + i += sizeof (" ") - 2; + } + +#if 0 + // removing new-lines chars sure isn't a xhtml conversion + // but it's still valid xhtml and GtkTextView appreciates it + else if (/*cut_breaklines &&*/ instr[i] == '\n') { + // In HTML a breakline should be treated as a white space when + // not in the start of a paragraph. + if (i > 0 && instr[i-1] != '>' && !g_ascii_isspace (instr[i-1])) + g_string_append_c (outp, ' '); + } +#endif + + else // Normal text + g_string_append_c (outp, instr[i]); + } + + emit_unclosed_tags_for (outp, tag_queue, "", 0); + g_queue_free (tag_queue); + + if (addOuterTag) + g_string_append (outp, "</body>"); + + gchar *ret = g_string_free (outp, FALSE); + return ret; +} + +int YGUtils::getCharsWidth (GtkWidget *widget, int chars_nb) +{ + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics = pango_context_get_metrics (context, + widget->style->font_desc, NULL); + + int width = pango_font_metrics_get_approximate_char_width (metrics); + pango_font_metrics_unref (metrics); + + return PANGO_PIXELS (width) * chars_nb; +} + +int YGUtils::getCharsHeight (GtkWidget *widget, int chars_nb) +{ + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics = pango_context_get_metrics (context, + widget->style->font_desc, NULL); + + int height = pango_font_metrics_get_ascent (metrics) + + pango_font_metrics_get_descent (metrics); + pango_font_metrics_unref (metrics); + + return PANGO_PIXELS (height) * chars_nb; +} + +void YGUtils::setWidgetFont (GtkWidget *widget, PangoWeight weight, double scale) +{ + PangoFontDescription *font_desc = widget->style->font_desc; + int size = pango_font_description_get_size (font_desc); + + PangoFontDescription* font = pango_font_description_new(); + pango_font_description_set_weight (font, weight); + pango_font_description_set_size (font, (int)(size * scale)); + + gtk_widget_modify_font (widget, font); + pango_font_description_free (font); +} + +int ygutils_getCharsWidth (GtkWidget *widget, int chars_nb) +{ return YGUtils::getCharsWidth (widget, chars_nb); } +int ygutils_getCharsHeight (GtkWidget *widget, int chars_nb) +{ return YGUtils::getCharsHeight (widget, chars_nb); } +void ygutils_setWidgetFont (GtkWidget *widget, PangoWeight weight, double scale) +{ YGUtils::setWidgetFont (widget, weight, scale); } + +int YGUtils::strcmp (const char *str1, const char *str2) +{ + // (if you think this is ugly, just wait for the Perl version! :P) + const char *i, *j; + for (i = str1, j = str2; *i && *j; i++, j++) { + // number comparasion + if (isdigit (*i) && isdigit (*j)) { + int n1, n2; + for (n1 = 0; isdigit (*i); i++) + n1 = (*i - '0') + (n1 * 10); + for (n2 = 0; isdigit (*j); j++) + n2 = (*j - '0') + (n2 * 10); + + if (n1 != n2) + return n1 - n2; + + // prepare for loop + i--; j--; + } + + // regular character comparasion + else if (g_ascii_tolower (*i) != g_ascii_tolower(*j)) + return g_ascii_tolower (*i) - g_ascii_tolower (*j); + } + if (*i) + return -1; + if (*j) + return 1; + return 0; // identicals +} + +bool YGUtils::contains (const string &haystack, const string &needle) +{ + unsigned int i, j; + for (i = 0; i < haystack.length(); i++) { + for (j = 0; j < needle.length() && i+j < haystack.length(); j++) + if (g_ascii_tolower (haystack[i+j]) != g_ascii_tolower (needle[j])) + break; + if (j == needle.length()) + return true; + } + return false; +} + +std::list <string> YGUtils::splitString (const string &str, char separator) +{ + std::list <string> parts; + unsigned int i, j; + // ignore first character, if separator + i = j = (str[0] == separator) ? 1 : 0; + for (; i < str.length(); i++) + if (str[i] == separator) { + parts.push_back (str.substr (j, i - j)); + j = ++i; + } + parts.push_back (str.substr (j)); + return parts; +} + +void YGUtils::print_model (GtkTreeModel *model, int string_col) +{ + fprintf (stderr, "printing model...\n"); + int depth = 0; + GtkTreeIter iter; + + if (!gtk_tree_model_get_iter_first (model, &iter)) { + fprintf (stderr, "Couldn't even get a first iterator\n"); + return; + } + + while (true) + { + // print node + gchar *package_name = 0; + gtk_tree_model_get (model, &iter, string_col, &package_name, -1); + for (int i = 0; i < depth*4; i++) + fprintf (stderr, " "); + fprintf (stderr, "%s\n", package_name); + g_free (package_name); + + if (gtk_tree_model_iter_has_child (model, &iter)) { + GtkTreeIter parent = iter; + gtk_tree_model_iter_children (model, &iter, &parent); + depth++; + } + else { + if (gtk_tree_model_iter_next (model, &iter)) + ; // continue + else { + // let's see if there is a parent + GtkTreeIter child = iter; + if (gtk_tree_model_iter_parent (model, &iter, &child) && + gtk_tree_model_iter_next (model, &iter)) + depth--; + else + break; + } + } + } +} + +void YGUtils::tree_view_radio_toggle_cb (GtkCellRendererToggle *renderer, + gchar *path_str, GtkTreeModel *model) +{ + // Toggle the box + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + gint *column = (gint*) g_object_get_data (G_OBJECT (renderer), "column"); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + // Disable radio buttons from the same parent + GtkTreeIter parent_iter, child_iter; + if (gtk_tree_model_iter_parent (model, &parent_iter, &iter) && + gtk_tree_model_iter_children (model, &child_iter, &parent_iter)) { + do gtk_tree_store_set (GTK_TREE_STORE (model), &child_iter, column, FALSE, -1); + while (gtk_tree_model_iter_next (model, &child_iter)); + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, column, TRUE, -1); + } +} + +gint YGUtils::sort_compare_cb (GtkTreeModel *model, GtkTreeIter *a, + GtkTreeIter *b, gpointer data) +{ + IMPL + gint col = GPOINTER_TO_INT (data); + gchar *str1 = 0, *str2 = 0; + gtk_tree_model_get (model, a, col, &str1, -1); + gtk_tree_model_get (model, b, col, &str2, -1); + gint cmp = 0; + if (str1 && str2) + cmp = YGUtils::strcmp (str1, str2); + + if (str1) + g_free (str1); + if (str2) + g_free (str2); + return cmp; +} + +static void header_clicked_cb (GtkTreeViewColumn *column, GtkTreeSortable *sortable) +{ + IMPL + GtkTreeViewColumn *last_sorted = + (GtkTreeViewColumn *) g_object_get_data (G_OBJECT (sortable), "last-sorted"); + int id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (column), "id")); + + GtkSortType sort = GTK_SORT_ASCENDING; + if (last_sorted != column) { + if (last_sorted) + gtk_tree_view_column_set_sort_indicator (last_sorted, FALSE); + gtk_tree_view_column_set_sort_indicator (column, TRUE); + g_object_set_data (G_OBJECT (sortable), "last-sorted", column); + } + else { + sort = gtk_tree_view_column_get_sort_order (column); + sort = sort == GTK_SORT_ASCENDING ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING; + } + + gtk_tree_view_column_set_sort_order (column, sort); + gtk_tree_sortable_set_sort_column_id (sortable, id, sort); +} + +void YGUtils::tree_view_set_sortable (GtkTreeView *view, int default_sort_col) +{ + IMPL + g_assert (gtk_tree_view_get_headers_visible (view)); + + /* Set all string columns clickable. */ + GtkTreeSortable *sortable = GTK_TREE_SORTABLE (gtk_tree_view_get_model (view)); + // we need a pointer, this function is used by different stuff, so to we'll + // use g_object_*_data() to do of garbage collector + g_object_set_data (G_OBJECT (sortable), "last-sorted", NULL); + + GList *columns = gtk_tree_view_get_columns (view); + for (GList *i = g_list_first (columns); i; i = i->next) { + GtkTreeViewColumn *column = (GtkTreeViewColumn *) i->data; + int col_nb = g_list_position (columns, i); + + // check if it really is a string column + bool string_col = false; + GList *renderers = gtk_tree_view_column_get_cell_renderers (column); + for (GList *j = g_list_first (renderers); j; j = j->next) + if (GTK_IS_CELL_RENDERER_TEXT (j->data)) { + string_col = true; + break; + } + g_list_free (renderers); + if (!string_col) + continue; + + // set sortable and clickable + gtk_tree_sortable_set_sort_func (sortable, col_nb, sort_compare_cb, + GINT_TO_POINTER (col_nb), NULL); + g_object_set_data (G_OBJECT (column), "id", GINT_TO_POINTER (col_nb)); + gtk_tree_view_column_set_clickable (column, TRUE); + g_signal_connect (G_OBJECT (column), "clicked", + G_CALLBACK (header_clicked_cb), sortable); + if (col_nb == default_sort_col) + header_clicked_cb (column, sortable); + } + g_list_free (columns); +} + +GValue YGUtils::floatToGValue (float num) +{ + GValue value = { 0 }; + g_value_init (&value, G_TYPE_FLOAT); + g_value_set_float (&value, num); + return value; +} + +#define SCROLLING_TIME 700 +#define SCROLLING_STEP 100 +struct ScrollData { + int orix, oriy, diffx, diffy, time; + GtkTreeView *view; +}; + +static gboolean scroll_timeout (gpointer _data) { + ScrollData *data = (ScrollData *) _data; + data->time += SCROLLING_STEP; + + int x = data->orix + data->diffx; + int y = ((data->diffy * data->time) / SCROLLING_TIME) + data->oriy; + + gtk_tree_view_scroll_to_point (data->view, x, y); + return data->time < SCROLLING_TIME; +} + +void YGUtils::tree_view_smooth_scroll_to_point (GtkTreeView *view, gint x, gint y) { + GdkRectangle rect; + gtk_tree_view_get_visible_rect (view, &rect); + if (rect.x == x && rect.y == y) + return; + + ScrollData *data = (ScrollData *) g_malloc (sizeof (ScrollData)); + data->orix = rect.x; + data->oriy = rect.y; + data->diffx = x - rect.x; + data->diffy = y - rect.y; + data->time = 0; + data->view = view; + + static int id = 0; + if (id) + g_source_remove (id); + id = g_timeout_add_full (G_PRIORITY_DEFAULT, SCROLLING_STEP, scroll_timeout, data, g_free); +} + +#define ENGLISH_STOCK_ITEMS + +#ifdef ENGLISH_STOCK_ITEMS +struct StockMap { const char *ycp_label, *gtk_stock; }; +static const StockMap stockMap[] = { + // keep them sorted! + {"Abort", GTK_STOCK_CANCEL }, + {"Accept", GTK_STOCK_APPLY }, + {"Add", GTK_STOCK_ADD }, + {"Back", GTK_STOCK_GO_BACK }, + {"Cancel", GTK_STOCK_CANCEL }, + {"Configure", GTK_STOCK_PREFERENCES }, + {"Continue", GTK_STOCK_OK }, + {"Delete", GTK_STOCK_DELETE }, + {"Down", GTK_STOCK_GO_DOWN }, + {"Edit", GTK_STOCK_EDIT }, + {"Launch", GTK_STOCK_EXECUTE }, + {"Next", GTK_STOCK_GO_FORWARD }, + {"No", GTK_STOCK_NO }, + {"OK", GTK_STOCK_OK }, + {"Quit", GTK_STOCK_QUIT }, + {"Search", GTK_STOCK_FIND }, + {"Up", GTK_STOCK_GO_UP }, + {"Yes", GTK_STOCK_YES }, +}; +#define STOCKMAP_SIZE (sizeof (stockMap)/sizeof(StockMap)) +static int strcmp_cb (const void *a, const void *b) +{ return strcmp ((char *) a, ((StockMap *) b)->ycp_label); } + +void YGUtils::setStockIcon (GtkWidget *button, std::string ycp_str) +{ + // is English the current locale? + static bool firstTime = true, isEnglish; + if (firstTime) { + char *lang = getenv ("LANG"); + isEnglish = !lang || (!*lang) || !strcmp (lang, "C") || + (lang[0] == 'e' && lang[1] == 'n') || + !strcmp (lang, "POSIX"); + firstTime = false; + } + if (!isEnglish) + return; + + unsigned int i = 0; + while ((i = ycp_str.find ('_', i)) != string::npos) + ycp_str.erase (i, 1); + + bool failed = true; + void *ptr; + ptr = bsearch (ycp_str.c_str(), stockMap, STOCKMAP_SIZE, + sizeof(stockMap[0]), strcmp_cb); + if (ptr) { + const char *stock = ((StockMap *) ptr)->gtk_stock; + GdkPixbuf *pixbuf; + pixbuf = gtk_widget_render_icon (button, stock, + GTK_ICON_SIZE_BUTTON, NULL); + if (pixbuf) { + GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf); + gtk_button_set_image (GTK_BUTTON (button), image); + g_object_unref (G_OBJECT (pixbuf)); + failed = false; + } + } + if (failed) + gtk_button_set_image (GTK_BUTTON (button), NULL); +} + +void ygutils_setStockIcon (GtkWidget *button, const char *ycp_str) +{ YGUtils::setStockIcon (button, ycp_str); } + +#else +void ygutils_setStockIcon (GtkWidget *button, const char *ycp_str) {} +#endif + Added: trunk/gtk/unstable/src/YGUtils.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGUtils.h?rev=42... ============================================================================== --- trunk/gtk/unstable/src/YGUtils.h (added) +++ trunk/gtk/unstable/src/YGUtils.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,103 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#ifndef YGUTILS_H +#define YGUTILS_H + +#include <string> +#include <list> +#include <gtk/gtktextview.h> +#include <gtk/gtkeditable.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtktreemodel.h> +#include <gtk/gtkcellrenderertoggle.h> + +// TODO: do a cleanup here. We should probably split string, gtk and stuff +// Some GtkTreeView should probably go to their own files +// Let's avoid GTK+ stuff, better to replicate that, if needed, than leave in +// this general purpose utils. + +/* YGUtils.h/cc have some functionality that is shared between different parts + of the code. */ + +namespace YGUtils +{ + /* Replaces Yast's '&' accelerator by Gnome's '_' (and proper escaping). */ + std::string mapKBAccel (const char *src); + + /* Filters characters that are not on the valids_chars array from the text string + Length is used to tell the length of text, in case it isn't NUL + terminated (you may pass -1, if it is). + Use the compare string member if you want to see if there was any change. */ + std::string filterText (const char* text, int length, const char* valid_chars); + + /* Convenience call for widgets that implement GtkEditable interface. + This function inserts and deletes text, if needed, so you may want + to block those signals, if you have them set. */ + void filterText (GtkEditable *editable, int pos, int length, + const char *valid_chars); + + /* Replaces every 'mouth' by 'food' in 'str'. */ + void replace (std::string &str, const char *mouth, int mouth_len, const char *food); + + /* Escapes markup text (eg. changes '<' by '\<'). */ + void escapeMarkup (std::string &str); + + /* Adds functionality to GtkTextView to scroll to bottom. */ + void scrollTextViewDown(GtkTextView *text_view); + + /* Returns the average width of the given number of characters in pixels. */ + int getCharsWidth (GtkWidget *widget, int chars_nb); + int getCharsHeight (GtkWidget *widget, int chars_nb); + + /* Sets some widget font proprities. */ + void setWidgetFont (GtkWidget *widget, PangoWeight weight, double scale); + + /* A more sane strcmp() from the user point of view that honors numbers. + i.e. "20" < "100" */ + int strcmp (const char *str1, const char *str2); + + /* Checks if a std::string contains some other string (case insensitive). */ + bool contains (const std::string &haystack, const std::string &needle); + + /* Splits a string into parts as separated by the separator characters. + eg: splitString ("Office/Writer", '/') => { "Office", "Writer" } */ + std::list <std::string> splitString (const std::string &str, char separator); + + /* Prints a GtkTreeModel for debugging purposes. */ + void print_model (GtkTreeModel *model, int string_col); + + /* To be used as a callback to sort tree views. */ + gint sort_compare_cb (GtkTreeModel *model, GtkTreeIter *a, + GtkTreeIter *b, gpointer data); + + /* To be used as a callback for a GtkTreeView with toggle cells. */ + void tree_view_radio_toggle_cb (GtkCellRendererToggle *renderer, + gchar *path_str, GtkTreeModel *model); + + /* Goes through all GtkTreeView columns and checks for TextCellRenderers, + setting those columns as sortable. */ + void tree_view_set_sortable (GtkTreeView *view, int default_sort_col); + + /* Like gtk_tree_view_scroll_to_point(), but does smooth scroll. */ + void tree_view_smooth_scroll_to_point (GtkTreeView *view, gint x, gint y); + + /* Converts stuff to GValues */ + GValue floatToGValue (float num); + + void setStockIcon (GtkWidget *button, std::string ycp_str); +}; + +extern "C" { + int ygutils_getCharsWidth (GtkWidget *widget, int chars_nb); + int ygutils_getCharsHeight (GtkWidget *widget, int chars_nb); + void ygutils_setWidgetFont (GtkWidget *widget, PangoWeight weight, double scale); + + /* Convert html to xhtml (or at least try) */ + gchar *ygutils_convert_to_xhmlt_and_subst (const char *instr, const char *product); + void ygutils_setStockIcon (GtkWidget *button, const char *ycp_str); +}; + +#endif // YGUTILS_H + Added: trunk/gtk/unstable/src/YGWidget.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGWidget.cc?rev=... ============================================================================== --- trunk/gtk/unstable/src/YGWidget.cc (added) +++ trunk/gtk/unstable/src/YGWidget.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,312 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <stdarg.h> +#include "YGWidget.h" +#include "YGUtils.h" +#include "ygtkratiobox.h" + +// default widgets border -- may be overlapped with a setBorder(..) +#define DEFAULT_BORDER 6 +#define LABEL_WIDGET_SPACING 4 + +/* YGWidget follows */ + +YGWidget::YGWidget(YWidget *y_widget, YGWidget *parent, bool show, + GtkType type, const char *property_name, ...) + : m_y_widget (y_widget) +{ + va_list args; + va_start (args, property_name); + construct (y_widget, parent, show, type, property_name, args); + va_end (args); +} + +void YGWidget::construct (YWidget *y_widget, YGWidget *parent, bool _show, + GType type, const char *property_name, va_list args) +{ + m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args)); + + if (type == GTK_TYPE_WINDOW) + m_adj_size = m_widget; + else { + m_adj_size = ygtk_adj_size_new(); + g_object_ref_sink (G_OBJECT (m_adj_size)); + gtk_widget_show (m_adj_size); + gtk_container_add (GTK_CONTAINER (m_adj_size), m_widget); + } + + y_widget->setWidgetRep ((void *) this); + if (parent) + y_widget->setParent (parent->m_y_widget); + +#ifdef IMPL_DEBUG + fprintf (stderr, "Set YWidget %p rep to %p\n", y_widget, this); +#endif + + // Split by two so that with another widget it will have full border... + setBorder (DEFAULT_BORDER / 2); + + if (_show) + show(); +} + +YGWidget::~YGWidget() +{ + IMPL + gtk_widget_destroy (m_adj_size); + g_object_unref (G_OBJECT (m_adj_size)); +} + +void YGWidget::show() +{ + gtk_widget_show (m_widget); +} + +YGWidget *YGWidget::get (YWidget *y_widget) +{ + if (!y_widget || !y_widget->widgetRep()) { +#ifdef IMPL_DEBUG + if (y_widget) + fprintf (stderr, "Widget '%s' (label: '%s') not supported\n", + y_widget->widgetClass(), y_widget->debugLabel().c_str()); + else + fprintf (stderr, "YGWidget::get() on null\n"); +#endif + return NULL; + } + return (YGWidget *) (y_widget->widgetRep()); +} + +bool YGWidget::doSetKeyboardFocus() +{ + IMPL + gtk_widget_grab_focus (GTK_WIDGET (getWidget())); + return gtk_widget_is_focus (GTK_WIDGET (getWidget())); +} + +void YGWidget::doSetEnabling (bool enabled) +{ + gtk_widget_set_sensitive (getWidget(), enabled); +} + +void YGWidget::emitEvent(YEvent::EventReason reason, bool if_notify, + bool if_not_pending, bool immediate) +{ + struct inner + { + static gboolean dispatchEvent (gpointer data) + { + YWidgetEvent *event = (YWidgetEvent *) data; + if (!YGUI::ui()->eventPendingFor (event->widget())) + YGUI::ui()->sendEvent (event); + return FALSE; + } + }; + + if (!if_notify || m_y_widget->getNotify()) + { + if (!immediate) + g_timeout_add (250, inner::dispatchEvent, new YWidgetEvent (m_y_widget, reason)); + else if (!if_not_pending || !YGUI::ui()->eventPendingFor (m_y_widget)) + { + if (immediate) + YGUI::ui()->sendEvent (new YWidgetEvent (m_y_widget, reason)); + } + } +} + +void YGWidget::setBorder (unsigned int border) +{ + IMPL + gtk_container_set_border_width (GTK_CONTAINER (m_adj_size), border); +} + +void YGWidget::setMinSize (unsigned int width, unsigned int height) +{ + IMPL + ygtk_adj_size_set_min (YGTK_ADJ_SIZE (m_adj_size), width, height); +} + +void YGWidget::setMinSizeInChars (unsigned int width, unsigned int height) +{ + IMPL + if (width) + width = YGUtils::getCharsWidth (getWidget(), width); + if (height) + height = YGUtils::getCharsHeight (getWidget(), height); + setMinSize (width, height); +} + +void YGWidget::sync_stretchable (YWidget *child) +{ + IMPL + YWidget *parent = m_y_widget->yParent(); + if (parent) + // tell parent to sync too! + YGWidget::get (parent)->sync_stretchable (m_y_widget); +} + +// JEEZ. WHEN the hell will yast-ui code fix their damn code. +#if 1 +/* Checks everywhere in a container to see if there are children (so + he is completely initialized) so that we may ask him for stretchable() + because some YContainerWidgets crash when they don't have children. */ +#include "YSplit.h" +static bool safe_stretchable (YWidget *widget) +{ + YContainerWidget *container = dynamic_cast <YContainerWidget *> (widget); + if (container) { + YSplit *split = dynamic_cast <YSplit *> (widget); + // in the case of YSplit its safe to ask for stretchability with no kids + if (split) { + if (!split->hasChildren()) + return true; + } + else + if (!container->hasChildren()) + return false; + + for (int i = 0; i < container->numChildren(); i++) + if (!safe_stretchable (container->child (i))) + return false; + } + return true; +} +#else +static bool safe_stretchable (YWidget *widget) +{ + return true; +} +#endif + +bool YGWidget::isStretchable (YUIDimension dim) +{ + if (safe_stretchable (m_y_widget)) + return m_y_widget->stretchable (dim); + return false; +} + +/* YGLabeledWidget follows */ + +YGLabeledWidget::YGLabeledWidget (YWidget *y_widget, YGWidget *parent, + YCPString label_text, YUIDimension label_ori, + bool show, GType type, + const char *property_name, ...) + : YGWidget (y_widget, parent, show, + label_ori == YD_VERT ? GTK_TYPE_VBOX : GTK_TYPE_HBOX, + "spacing", LABEL_WIDGET_SPACING, NULL) +{ + // Create the field widget + va_list args; + va_start (args, property_name); + m_field = GTK_WIDGET (g_object_new_valist (type, property_name, args)); + va_end (args); + + // Create the label + m_label = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (m_label), 0.0, 0.5); + if (label_ori == YD_HORIZ) + gtk_label_set_line_wrap (GTK_LABEL (m_label), TRUE); + if(show) { + gtk_widget_show (m_label); + gtk_widget_show (m_field); + } + + setBuddy (m_field); + doSetLabel (label_text); + + // Set the container and show widgets + gtk_box_pack_start (GTK_BOX (m_widget), m_label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_widget), m_field, TRUE, TRUE, 0); + m_orientation = label_ori; +} + +void YGLabeledWidget::setLabelVisible (bool show) +{ + if (show) + gtk_widget_show (m_label); + else + gtk_widget_hide (m_label); +} + +void YGLabeledWidget::setBuddy (GtkWidget *widget) +{ + gtk_label_set_mnemonic_widget (GTK_LABEL (m_label), widget); +} + +void YGLabeledWidget::doSetLabel (const YCPString &label) +{ + string str = YGUtils::mapKBAccel (label->value_cstr()); + if (str.empty()) { + gtk_widget_hide (m_label); + } + else { + gtk_widget_show (m_label); + + // add a ':' at the end + int last = str.length()-1; + if (str [last] != ':' && str [last] != '.' && str [last] != ' ') + str += ':'; + + // set it as upper case + unsigned int first = (str [0] == '_') ? 1 : 0; + if (str [first] >= 'a' && str [first] <= 'z') + str [first] += 'A' - 'a'; + + gtk_label_set_text (GTK_LABEL (m_label), str.c_str()); + gtk_label_set_use_underline (GTK_LABEL (m_label), TRUE); + } +} + +/* YGScrolledWidget follows */ +#define MAX_SCROLL_WIDTH 120 + +YGScrolledWidget::YGScrolledWidget (YWidget *y_widget, YGWidget *parent, + bool show, GType type, + const char *property_name, ...) + : YGLabeledWidget (y_widget, parent, YCPString (""), YD_VERT, show, + YGTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) +{ + va_list args; + va_start (args, property_name); + construct(type, property_name, args); + va_end (args); + + setLabelVisible (false); +} + +YGScrolledWidget::YGScrolledWidget (YWidget *y_widget, YGWidget *parent, + YCPString label_text, YUIDimension label_ori, + bool show, GType type, + const char *property_name, ...) + : YGLabeledWidget (y_widget, parent, label_text, label_ori, show, + YGTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) +{ + va_list args; + va_start (args, property_name); + construct(type, property_name, args); + va_end (args); +} + +void YGScrolledWidget::construct (GType type, const char *property_name, + va_list args) +{ + m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args)); + setBuddy (m_widget); + + setPolicy (GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (YGLabeledWidget::getWidget()), m_widget); + gtk_widget_show (m_widget); +} + +void YGScrolledWidget::setPolicy (GtkPolicyType hpolicy, GtkPolicyType vpolicy) +{ + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (YGLabeledWidget::getWidget()), + hpolicy, vpolicy); + ygtk_scrolled_window_set_auto_policy (YGTK_SCROLLED_WINDOW (YGLabeledWidget::getWidget()), + hpolicy == GTK_POLICY_AUTOMATIC ? MAX_SCROLL_WIDTH : 0, 0); +} + Added: trunk/gtk/unstable/src/YGWidget.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGWidget.h?rev=4... ============================================================================== --- trunk/gtk/unstable/src/YGWidget.h (added) +++ trunk/gtk/unstable/src/YGWidget.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,151 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#ifndef YGWIDGET_H +#define YGWIDGET_H + +#include <gtk/gtk.h> +#include <stdarg.h> +#include "YGUI.h" +#include "YEvent.h" + +class YGWidget +{ +public: + YGWidget(YWidget *y_widget, YGWidget *parent, bool show, + GType type, const char *property_name, ...); + virtual ~YGWidget(); + + virtual GtkWidget *getWidget() { return m_widget; } + const char *getWidgetName() const + { return const_cast <YWidget *> (m_y_widget)->widgetClass(); } + // YWidget::debugLabel() sucks for most widgets -- let's allow it to be overload + virtual string getDebugLabel() const + { // container debug labels are worse than useless + if (dynamic_cast <YContainerWidget *> (m_y_widget) == NULL) + return const_cast <YWidget *> (m_y_widget)->debugLabel(); return string(); } + void show(); + + // containers should use this call rather than getWidget() + GtkWidget *getLayout() { return m_adj_size; } + + // Get the YGWidget associated with a YWidget + static YGWidget *get (YWidget *y_widget); + + // for YWidget + virtual bool doSetKeyboardFocus(); + virtual void doSetEnabling (bool enabled); + + // Event handling + void emitEvent(YEvent::EventReason reason, bool if_notify = true, + bool if_not_pending = false, bool immediate = true); + + // Aesthetics + void setBorder (unsigned int border); // in pixels + void setMinSize (unsigned int min_width, unsigned int min_height); + void setMinSizeInChars (unsigned int min_width, unsigned int min_height); + + // whenever the stretchable property may change (eg. when adding a child + // for a container), call this function to make sure it is honored. + virtual void sync_stretchable (YWidget *child = 0); + + // should be used instead of YWidget::stretchable() as this has some safeguards + // against crashes that some YContainerWidgets lead to + bool isStretchable (YUIDimension dim); + +protected: + GtkWidget *m_widget; // associated GtkWidget -- use getWidget() + YWidget *m_y_widget; // associated YWidget + GtkWidget *m_adj_size; // installed on m_widget, allows better size constrains + + void construct (YWidget *y_widget, YGWidget *parent, + bool show, GType type, + const char *property_name, va_list args); +}; + +/* + * Macros to help implement proxies between common YWidget virtual + * methods and the (multiply inherited) YGWidget base implementation + * for GTK+. + */ +#define YGWIDGET_IMPL_COMMON \ + virtual bool setKeyboardFocus() \ + { return doSetKeyboardFocus(); } \ + virtual void setEnabling (bool enabled) \ + { doSetEnabling (enabled); } \ + virtual long nicesize (YUIDimension dim) { return 0; } \ + virtual void moveChild (YWidget *child, long x, long y) {} \ + virtual void setSize (long width, long height) {} + +// for containers +// We can't use childAdded, since some classes don't want this called +// for some children. +#define YGWIDGET_IMPL_CHILD_ADDED(container) \ + virtual void addChild (YWidget *ychild) { \ + YContainerWidget::addChild (ychild); \ + GtkWidget *child = YGWidget::get (ychild)->getLayout(); \ + gtk_container_add (GTK_CONTAINER (container), child); \ + sync_stretchable(); \ + } +#define YGWIDGET_IMPL_CHILD_REMOVED(container) \ + virtual void childRemoved (YWidget *ychild) { \ + GtkWidget *child = YGWidget::get (ychild)->getLayout(); \ + gtk_container_remove (GTK_CONTAINER (container), child); \ + } + +/* This is a convenience class that allows for a label next to the + intended widget. It should be used, in case you have the need for + such, as it gives an uniform API. */ +class YGLabeledWidget : public YGWidget +{ + public: + YGLabeledWidget(YWidget *y_widget, YGWidget *parent, + YCPString label_text, YUIDimension label_ori, + bool show, GType type, const char *property_name, ...); + virtual ~YGLabeledWidget () {} + + virtual GtkWidget* getWidget() { return m_field; } + + void setLabelVisible(bool show); + void setBuddy (GtkWidget *widget); + virtual void doSetLabel (const YCPString &label); + + YUIDimension orientation() { return m_orientation; } + GtkWidget *getLabelWidget() { return m_label; } + + protected: + GtkWidget *m_label, *m_field; + YUIDimension m_orientation; +}; + +#define YGLABEL_WIDGET_IMPL_SET_LABEL_CHAIN(ParentClass) \ + virtual void setLabel (const YCPString &label) { \ + IMPL \ + doSetLabel (label); \ + ParentClass::setLabel (label); \ + } + +/* This is a convenience class for widgets that need scrollbars. */ +class YGScrolledWidget : public YGLabeledWidget +{ + public: + YGScrolledWidget(YWidget *y_widget, YGWidget *parent, + bool show, GType type, const char *property_name, ...); + // if you want a label, use: + YGScrolledWidget(YWidget *y_widget, YGWidget *parent, + YCPString label_text, YUIDimension label_ori, + bool show, GType type, const char *property_name, ...); + virtual ~YGScrolledWidget () {} + + virtual GtkWidget *getWidget() { return m_widget; } + + // you should use this method, not gtk_scrolled_window_set... + void setPolicy (GtkPolicyType hpolicy, GtkPolicyType vpolicy); + + protected: + void construct(GType type, const char *property_name, va_list args); + GtkWidget *m_widget; +}; + +#endif /*YGWIDGET_H*/ Added: trunk/gtk/unstable/src/YGWizard.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGWizard.cc?rev=... ============================================================================== --- trunk/gtk/unstable/src/YGWizard.cc (added) +++ trunk/gtk/unstable/src/YGWizard.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,374 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <ycp/y2log.h> +#include <YGUI.h> +#include "YGWidget.h" +#include "YGUtils.h" +#include "ygtkwizard.h" +#include "YWizard.h" +#include "YPushButton.h" + +class YGWizard : public YWizard, public YGWidget +{ + bool m_verboseCommands; + + /* YCP requires us to allow people to use YPushButton API on the wizard buttons. + Wizard already has handlers for them; this seems like bad design. + + We could support wrapping right in our framework. One way, would be to subclass + YWidgetOpt to have a wrapping field where we would set a GtkWidget*. Then, + classes should pass opt to YGWidget and it would create a shallow instance + around it. However, this isn't really doable. The problem is that, like + in this case, the API isn't really exact; events must be sent as YWizard events. + */ + struct YGWButton : public YPushButton { + /* Thin class; just changes the associated button label and keeps track + of id change. */ + YGWButton (GtkWidget *widget, const YCPString &label, const YCPValue &id) + : YPushButton (YWidgetOpt(), label) + { m_widget = widget; setId (id); setLabel (label); } + + void setLabel (const YCPString &label) { + string str = YGUtils::mapKBAccel (label->value_cstr()); + gtk_button_set_label (GTK_BUTTON (m_widget), str.c_str()); + str.empty() ? gtk_widget_hide (m_widget) : gtk_widget_show (m_widget); + YGUtils::setStockIcon (m_widget, str); + YPushButton::setLabel (label); + } + + long nicesize (YUIDimension dim) { return 0; } + void setEnabling (bool enable) { + gtk_widget_set_sensitive (m_widget, enable); + YWidget::setEnabling (enable); + } + + private: + GtkWidget *m_widget; + }; + + YGWButton *m_back_button, *m_abort_button, *m_next_button; + // release notes button would be a little more hassle to support; yast-qt + // doesn't support it too anyway. + +public: + YGWizard (const YWidgetOpt &opt, YGWidget *parent, + const YCPValue &backButtonId, const YCPString &backButtonLabel, + const YCPValue &abortButtonId, const YCPString &abortButtonLabel, + const YCPValue &nextButtonId, const YCPString &nextButtonLabel) + : YWizard (opt, backButtonId, backButtonLabel, + abortButtonId, abortButtonLabel, + nextButtonId, nextButtonLabel), + YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL) + { + IMPL + setBorder (0); + m_verboseCommands = false; + + //** Application area + { + // We set a YReplacePoint as child with a certain id and it will then be + // replaced by the actual content. We put a YEmpty on it because it would + // crash otherwise (stretchable() functions should really check for + // hasChildren() first!). + + YWidgetOpt opt, stretchOpt; + stretchOpt.isHStretchable.setValue( true ); + stretchOpt.isVStretchable.setValue( true ); + + YWidget *align, *rp, *empty; + align = YGUI::ui()->createAlignment (this, stretchOpt, + YAlignCenter, YAlignCenter); + rp = YGUI::ui()->createReplacePoint (align, opt); + rp->setId (YCPSymbol (YWizardContentsReplacePointID)); + empty = YGUI::ui()->createEmpty (rp, opt); + + ((YContainerWidget *) align)->addChild (rp); + ((YContainerWidget *) rp)->addChild (empty); + this->addChild (align); + } + + YGtkWizard *ygtk_wizard = YGTK_WIZARD (getWidget()); + + //** Steps/tree pane + bool steps_enabled = opt.stepsEnabled.value(); + bool tree_enabled = opt.treeEnabled.value(); + if (steps_enabled && tree_enabled) { + y2error ("YGWizard doesn't support both steps and tree enabled at the " + "same time.\nDisabling the steps..."); + steps_enabled = false; + } + if (steps_enabled) + ygtk_wizard_enable_steps (ygtk_wizard); + if (tree_enabled) + ygtk_wizard_enable_tree (ygtk_wizard); + + //** Setting the bottom buttons + m_back_button = new YGWButton (ygtk_wizard->m_back_button, backButtonLabel, + backButtonId); + m_abort_button = new YGWButton (ygtk_wizard->m_abort_button, abortButtonLabel, + abortButtonId); + m_next_button = new YGWButton (ygtk_wizard->m_next_button, nextButtonLabel, + nextButtonId); + YContainerWidget::addChild (m_back_button); + YContainerWidget::addChild (m_abort_button); + YContainerWidget::addChild (m_next_button); + + ygtk_wizard_set_back_button_id (ygtk_wizard, new YCPValue (backButtonId), + delete_data_cb); + ygtk_wizard_set_abort_button_id (ygtk_wizard, new YCPValue (abortButtonId), + delete_data_cb); + ygtk_wizard_set_next_button_id (ygtk_wizard, new YCPValue (nextButtonId), + delete_data_cb); + + //** All event are sent through this signal together with an id + g_signal_connect (G_OBJECT (getWidget()), "action-triggered", + G_CALLBACK (action_triggered_cb), this); + } + + ~YGWizard() + { + delete m_back_button; + delete m_abort_button; + delete m_next_button; + } + + /* The purpose of this function is to do some sanity checks, besides + the simple test "cmd->name() == func". + args_type is a reverse hexadecimal number where + any = 0, string = 1, boolean = 2. */ + static bool isCommand (const YCPTerm &cmd, const char *func, + guint args_nb, guint args_type) + { + if (cmd->name() == func) { + if ((unsigned) cmd->size() != args_nb) { + y2error ("YGWizard: expected %d arguments for the '%s' command. %d given.", + args_nb, func, cmd->size()); + return false; + } + + guint i, t; + for (i = 0, t = args_type; i < args_nb; i++, t >>= 4) + switch (t % 0x4) { + case 0x1: + if (!cmd->value(i)->isString()) { + y2error ("YGWizard: expected string as the %d argument for " + "the '%s' command.", i+1, func); + return false; + } + break; + case 0x2: + if (!cmd->value(i)->isBoolean()) { + y2error ("YGWizard: expected boolean as the %d argument for " + "the '%s' command.", i+1, func); + return false; + } + break; + } + return true; + } + return false; + } + +#define getStdStringArg(cmd, arg) (cmd->value(arg)->asString()->value()) +#define getCStringArg(cmd, arg) (cmd->value(arg)->asString()->value_cstr()) +#define getBoolArg(cmd, arg) (cmd->value(arg)->asBoolean()->value()) +#define getAnyArg(cmd, arg) (cmd->value(arg)) + + YCPValue command (const YCPTerm &cmd) + { + IMPL + if (m_verboseCommands) + y2milestone ("Processing wizard command: %s\n", cmd->name().c_str()); + + YGtkWizard *wizard = YGTK_WIZARD (getWidget()); + if (isCommand (cmd, "SetHelpText", 1, 0x1)) + ygtk_wizard_set_help_text (wizard, getCStringArg (cmd, 0)); + + else if (isCommand (cmd, "AddTreeItem", 3, 0x111)) { + if (!ygtk_wizard_add_tree_item (wizard, getCStringArg (cmd, 0), + getCStringArg (cmd, 1), getCStringArg (cmd, 2))) { + y2error ("YGWizard: there is no tree item with id '%s'", + getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + else if (isCommand (cmd, "DeleteTreeItems", 0, 0)) + ygtk_wizard_clear_tree (wizard); + else if (isCommand (cmd, "SelectTreeItem", 1, 0x1)) { + if (!ygtk_wizard_select_tree_item (wizard, getCStringArg (cmd, 0))) { + y2error ("YGWizard: there is no tree item with id '%s'", + getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + + else if (isCommand (cmd, "SetDialogHeading", 1, 0x1)) + ygtk_wizard_set_header_text (wizard, YGUI::ui()->currentWindow(), + getCStringArg (cmd, 0)); + else if (isCommand (cmd, "SetDialogIcon", 1, 0x1)) { + if (!ygtk_wizard_set_header_icon (wizard, + YGUI::ui()->currentWindow(), getCStringArg (cmd, 0))) { + y2warning ("YGWizard: could not load image: %s", getCStringArg (cmd, 0)); +// return YCPBoolean (false); - installer relies on this succeeding + } + } + + else if (isCommand (cmd, "SetAbortButtonLabel", 1, 0x1) || + isCommand (cmd, "SetCancelButtonLabel", 1, 0x1)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 0)); + ygtk_wizard_set_abort_button_label (wizard, str.c_str()); + } + else if (isCommand (cmd, "SetBackButtonLabel", 1, 0x1)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 0)); + ygtk_wizard_set_back_button_label (wizard, str.c_str()); + } + else if (isCommand (cmd, "SetNextButtonLabel", 1, 0x1) || + isCommand (cmd, "SetAcceptButtonLabel", 1, 0x1)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 0)); + ygtk_wizard_set_next_button_label (wizard, str.c_str()); + } + + else if (isCommand (cmd, "SetAbortButtonID", 1, 0x0)) { + YCPValue *id = new YCPValue (getAnyArg (cmd, 0)); + ygtk_wizard_set_abort_button_id (wizard, id, delete_data_cb); + m_abort_button->setId (*id); + } + else if (isCommand (cmd, "SetBackButtonID", 1, 0x0)) { + YCPValue *id = new YCPValue (getAnyArg (cmd, 0)); + ygtk_wizard_set_back_button_id (wizard, id, delete_data_cb); + m_back_button->setId (*id); + } + else if (isCommand (cmd, "SetNextButtonID", 1, 0x0)) { + YCPValue *id = new YCPValue (getAnyArg (cmd, 0)); + ygtk_wizard_set_next_button_id (wizard, id, delete_data_cb); + m_next_button->setId (*id); + } + + else if (isCommand (cmd, "EnableAbortButton", 1, 0x2)) + ygtk_wizard_enable_abort_button (wizard, getBoolArg (cmd, 0)); + else if (isCommand (cmd, "EnableBackButton", 1, 0x2)) + ygtk_wizard_enable_back_button (wizard, getBoolArg (cmd, 0)); + else if (isCommand (cmd, "EnableNextButton", 1, 0x2)) + ygtk_wizard_enable_next_button (wizard, getBoolArg (cmd, 0)); + + else if (isCommand (cmd, "ProtectNextButton", 1, 0x2)) + ygtk_wizard_protect_next_button (wizard, getBoolArg (cmd, 0)); + + else if (isCommand (cmd, "SetFocusToNextButton", 0, 0)) + ygtk_wizard_focus_next_button (wizard); + else if (isCommand (cmd, "SetFocusToBackButton", 0, 0)) + ygtk_wizard_focus_back_button (wizard); + + else if (isCommand (cmd, "AddMenu", 2, 0x11)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 0)); + ygtk_wizard_add_menu (wizard, str.c_str(), getCStringArg (cmd, 1)); + } + else if (isCommand (cmd, "AddMenuEntry", 3, 0x111)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 1)); + if (!ygtk_wizard_add_menu_entry (wizard, getCStringArg (cmd, 0), + str.c_str(), getCStringArg (cmd, 2))) { + y2error ("YGWizard: there is no menu item with id '%s'", + getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + else if (isCommand (cmd, "AddSubMenu", 3, 0x111)) { + string str = YGUtils::mapKBAccel(getCStringArg (cmd, 1)); + if (!ygtk_wizard_add_sub_menu (wizard, getCStringArg (cmd, 0), + str.c_str(), getCStringArg (cmd, 2))) { + y2error ("YGWizard: there is no menu item with id '%s'", + getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + else if (isCommand (cmd, "AddMenuSeparator", 3, 0x111)) { + if (!ygtk_wizard_add_menu_separator (wizard, getCStringArg (cmd, 0))) { + y2error ("YGWizard: there is no menu item with id '%s'", + getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + + else if (isCommand (cmd, "SetVerboseCommands", 1, 0x2)) + m_verboseCommands = getBoolArg (cmd, 0); + else if (isCommand (cmd, "Ping", 0, 0)) + y2debug ("YGWizard is active"); + + else if (isCommand (cmd, "AddStepHeading", 1, 0x1)) + ygtk_wizard_add_step_header (wizard, getCStringArg (cmd, 0)); + else if (isCommand (cmd, "AddStep", 2, 0x11)) + ygtk_wizard_add_step (wizard, getCStringArg (cmd, 0), getCStringArg (cmd, 1)); + else if (isCommand (cmd, "SetCurrentStep", 1, 0x1)) { + if (!ygtk_wizard_set_current_step (wizard, getCStringArg (cmd, 0))) { + y2error ("YGWizard: there is no step with id %s.", getCStringArg (cmd, 0)); + return YCPBoolean (false); + } + } + else if (isCommand (cmd, "UpdateSteps", 0, 0)) + ; + else if (isCommand (cmd, "DeleteSteps", 0, 0)) + ygtk_wizard_clear_steps (wizard); + + else if (isCommand (cmd, "ShowReleaseNotesButton", 2, 0x01)) { + string label = YGUtils::mapKBAccel(getCStringArg (cmd, 0)); + ygtk_wizard_set_release_notes_button_label (wizard, label.c_str(), + new YCPValue (getAnyArg (cmd, 1)), delete_data_cb); + } + else if (isCommand (cmd, "HideReleaseNotesButton", 0, 0)) + ygtk_wizard_show_release_notes_button (wizard, FALSE); + + else if (isCommand (cmd, "RetranslateInternalButtons", 0, 0)) + ; // we don't need this as we don't use switch buttons + + else { + y2error ("Unsupported wizard command (or invalid arguments): %s\n", + cmd->name().c_str()); + return YCPBoolean (false); + } + return YCPBoolean (true); + } + + virtual YCPString currentTreeSelection() + { + YGtkWizard *wizard = YGTK_WIZARD (getWidget()); + const char *selected = ygtk_wizard_get_tree_selection (wizard); + if (selected) + return YCPString (selected); + return YCPString (""); + } + + static void action_triggered_cb (YGtkWizard *wizard, gpointer id, + gint id_type, YGWizard *pThis) + { + IMPL + if ((GType) id_type == G_TYPE_STRING) { + YCPString _id ((char *) id); + YGUI::ui()->sendEvent (new YMenuEvent (YCPValue (_id))); + } + else + YGUI::ui()->sendEvent (new YMenuEvent (*((YCPValue *) id))); + } + + static void delete_data_cb (gpointer data) + { delete (YCPValue*) data; } + + + YGWIDGET_IMPL_COMMON + YGWIDGET_IMPL_CHILD_ADDED (getWidget()) + YGWIDGET_IMPL_CHILD_REMOVED (getWidget()) +}; + +YWidget * +YGUI::createWizard (YWidget *parent, YWidgetOpt &opt, + const YCPValue &backButtonId, const YCPString &backButtonLabel, + const YCPValue &abortButtonId, const YCPString &abortButtonLabel, + const YCPValue &nextButtonId, const YCPString &nextButtonLabel) +{ + return new YGWizard (opt, YGWidget::get (parent), + backButtonId, backButtonLabel, + abortButtonId, abortButtonLabel, + nextButtonId, nextButtonLabel); +} Added: trunk/gtk/unstable/src/YGi18n.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/YGi18n.h?rev=425... ============================================================================== --- trunk/gtk/unstable/src/YGi18n.h (added) +++ trunk/gtk/unstable/src/YGi18n.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------\ +| | +| __ __ ____ _____ ____ | +| \ \ / /_ _/ ___|_ _|___ \ | +| \ V / _` \___ \ | | __) | | +| | | (_| |___) || | / __/ | +| |_|\__,_|____/ |_| |_____| | +| | +| core system | +| (C) SuSE GmbH | +\----------------------------------------------------------------------/ + + File: YGi18n.h + + Author: Jiri Srain <jsrain@suse.cz> + +/-*/ + +// -*- c++ -*- + +#ifndef YGi18n_h +#define YGi18n_h + +#include <libintl.h> + + +inline const char * _( const char * msgid ) +{ + return ( !msgid || !*msgid ) ? "" : gettext(msgid ); +} + +inline const char * _( const char * msgid1, const char * msgid2, unsigned long int n ) +{ + return ngettext(msgid1, msgid2, n ); +} + + +#endif // YGi18n_h Added: trunk/gtk/unstable/src/dummy.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/dummy.cc?rev=425... ============================================================================== --- trunk/gtk/unstable/src/dummy.cc (added) +++ trunk/gtk/unstable/src/dummy.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,12 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <YGUI.h> + +int main (int argc, char **argv) +{ + YGUI(argc, argv, false, "foo"); + return 0; +} Added: trunk/gtk/unstable/src/icons/cat-development.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-develo... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-development.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-development.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,328 @@ +/* XPM */ +static const char * cat_development_xpm[] = { +"22 22 303 2", +" c None", +". c #C4A61B", +"+ c #C4A419", +"@ c #C5A30C", +"# c #C6A40C", +"$ c #C7A610", +"% c #C5A30B", +"& c #C4A414", +"* c #C4A71E", +"= c #C4A417", +"- c #F7F2E1", +"; c #F3EDD4", +"> c #F9F5DB", +", c #FBFAE7", +"' c #FAF7E9", +") c #F9F7EC", +"! c #EFE7C1", +"~ c #C5A40C", +"{ c #C6A406", +"] c #D9C257", +"^ c #F9F5E5", +"/ c #F8EFA2", +"( c #FAF1A4", +"_ c #FAF1A2", +": c #F9F09E", +"< c #F3EAA1", +"[ c #E7D779", +"} c #DDCA72", +"| c #C6A408", +"1 c #C8A70D", +"2 c #D0B333", +"3 c #EDE1A5", +"4 c #FDFBE9", +"5 c #FBF3B0", +"6 c #FCF4B1", +"7 c #FDF5B1", +"8 c #FCF4AC", +"9 c #FBF2A2", +"0 c #E9DA7F", +"a c #F4EDC2", +"b c #EFE5B8", +"c c #C5A205", +"d c #C7A60A", +"e c #C7A407", +"f c #F9F4CF", +"g c #FCF8D9", +"h c #FDFBE7", +"i c #FBF4B9", +"j c #FCF4B6", +"k c #FCF4B4", +"l c #FCF4AD", +"m c #FAF2A4", +"n c #E8D875", +"o c #F3E887", +"p c #F8F0B2", +"q c #F7F1CF", +"r c #D6BE52", +"s c #C6A308", +"t c #F7F1C8", +"u c #F9F3C3", +"v c #F8F1B4", +"w c #FBF7D5", +"x c #FBF5C4", +"y c #FAF3B5", +"z c #F9F2AF", +"A c #F9F0A8", +"B c #F8EF9F", +"C c #E7D673", +"D c #F5EA8A", +"E c #F7EFA7", +"F c #FAF6D2", +"G c #EADD9C", +"H c #C7A40A", +"I c #C7A408", +"J c #E9DC9B", +"K c #F6F0B8", +"L c #F5EDA5", +"M c #F7F0B0", +"N c #F9F3C2", +"O c #FAF4C3", +"P c #F8F0AF", +"Q c #F7EFA8", +"R c #F7EDA0", +"S c #F5EB96", +"T c #EBDC79", +"U c #F3E782", +"V c #F8F0B3", +"W c #F5EB9F", +"X c #F5EDAD", +"Y c #E2D082", +"Z c #C5A202", +"` c #C4A20E", +" . c #D7C054", +".. c #F6F0C3", +"+. c #F1E790", +"@. c #F3EA9B", +"#. c #F4ECA4", +"$. c #F5EDA8", +"%. c #F6EFB1", +"&. c #F5ECA3", +"*. c #F5EB9D", +"=. c #F4EA95", +"-. c #F0E588", +";. c #F0E37F", +">. c #F0E379", +",. c #F5EEAB", +"'. c #EDDF6C", +"). c #E9D952", +"!. c #EFE6AA", +"~. c #C7A409", +"{. c #C4A208", +"]. c #E2D183", +"^. c #F1E89F", +"/. c #EEE383", +"(. c #F0E58B", +"_. c #F1E792", +":. c #F2E896", +"<. c #F2E892", +"[. c #F1E68D", +"}. c #F1E586", +"|. c #EEE07B", +"1. c #EEE174", +"2. c #EDE070", +"3. c #EEE37E", +"4. c #E8D852", +"5. c #E5D33E", +"6. c #F0E79E", +"7. c #D7BE53", +"8. c #C5A30A", +"9. c #F4EFD0", +"0. c #E8DA68", +"a. c #EADD71", +"b. c #ECDF79", +"c. c #EDE17E", +"d. c #EEE281", +"e. c #EEE27F", +"f. c #EDE17B", +"g. c #ECE074", +"h. c #EBDC6B", +"i. c #EADB64", +"j. c #E8D856", +"k. c #E5D447", +"l. c #E1CF30", +"m. c #E0CC2A", +"n. c #E8DA66", +"o. c #E9DEA8", +"p. c #C4A209", +"q. c #F6F2D1", +"r. c #E5D555", +"s. c #E6D75D", +"t. c #E8D964", +"u. c #E6D658", +"v. c #E6D654", +"w. c #E3D243", +"x. c #E3D343", +"y. c #E4D243", +"z. c #E3D140", +"A. c #E3D03B", +"B. c #DFCC2A", +"C. c #DECA26", +"D. c #DECA24", +"E. c #DDC921", +"F. c #DCC81E", +"G. c #DBC61A", +"H. c #EDE29E", +"I. c #C4A30A", +"J. c #C5A308", +"K. c #F5F0C9", +"L. c #DCC92A", +"M. c #DDC929", +"N. c #DBC519", +"O. c #DAC517", +"P. c #ECE183", +"Q. c #E9DB6E", +"R. c #E6D860", +"S. c #E5D452", +"T. c #E2D143", +"U. c #DFCD33", +"V. c #DCC823", +"W. c #C5B112", +"X. c #D9C414", +"Y. c #D8C311", +"Z. c #D7C20E", +"`. c #F4EFC3", +" + c #C5A40D", +".+ c #F9F6E1", +"++ c #D4BD04", +"@+ c #D5BE05", +"#+ c #D5BF08", +"$+ c #D6C00A", +"%+ c #E2D14A", +"&+ c #D7C10D", +"*+ c #D7C10E", +"=+ c #D7C10C", +"-+ c #BFAB08", +";+ c #D6C009", +">+ c #D5BF07", +",+ c #D4BE05", +"'+ c #F3EDBD", +")+ c #C19F04", +"!+ c #C3A20A", +"~+ c #EEE5A9", +"{+ c #E7DA72", +"]+ c #D3BC01", +"^+ c #D3BC00", +"/+ c #DDCB38", +"(+ c #BEA900", +"_+ c #D4BE07", +":+ c #DFCE43", +"<+ c #F2EBBD", +"[+ c #BA9900", +"}+ c #C9B142", +"|+ c #E6D791", +"1+ c #F1E8A6", +"2+ c #E4D55D", +"3+ c #DBC92E", +"4+ c #BFAA00", +"5+ c #D6C00F", +"6+ c #E2D355", +"7+ c #E3D45B", +"8+ c #EFE6BB", +"9+ c #A58700", +"0+ c #967C08", +"a+ c #D8C360", +"b+ c #E1D356", +"c+ c #E7DA6D", +"d+ c #DECD40", +"e+ c #DBC82D", +"f+ c #DAC82B", +"g+ c #C7B313", +"h+ c #E1D04B", +"i+ c #E6D86B", +"j+ c #E5D867", +"k+ c #F8F4D8", +"l+ c #EADEAA", +"m+ c #CCB337", +"n+ c #F1E9B9", +"o+ c #E0D04A", +"p+ c #E0CF46", +"q+ c #E1D14E", +"r+ c #E2D356", +"s+ c #E1D24F", +"t+ c #E0CF48", +"u+ c #E4D55F", +"v+ c #E8DC76", +"w+ c #E9DC78", +"x+ c #E8DC77", +"y+ c #E8DB73", +"z+ c #F3ECB7", +"A+ c #F4EFD3", +"B+ c #C29F05", +"C+ c #AE9006", +"D+ c #D8C25F", +"E+ c #F2ECBB", +"F+ c #E9DE7F", +"G+ c #E2D252", +"H+ c #E3D45A", +"I+ c #E5D662", +"J+ c #E6D86A", +"K+ c #E7DA71", +"L+ c #E9DD7D", +"M+ c #EADE80", +"N+ c #EADF81", +"O+ c #EADE7F", +"P+ c #F7F3D1", +"Q+ c #F7F3D9", +"R+ c #D6BD4E", +"S+ c #886F00", +"T+ c #B99905", +"U+ c #D5BC4D", +"V+ c #F2EBC2", +"W+ c #F4EEC4", +"X+ c #ECE18D", +"Y+ c #E5D765", +"Z+ c #E7D96D", +"`+ c #E8DB75", +" @ c #EBE084", +".@ c #F0E9AB", +"+@ c #F8F4D6", +"@@ c #F9F7E2", +"#@ c #EEE4B7", +"$@ c #D6BC4D", +"%@ c #B09001", +"&@ c #A58800", +"*@ c #C19F06", +"=@ c #E0D085", +"-@ c #EADFAD", +";@ c #F2ECCE", +">@ c #F5F0D7", +",@ c #F7F3DC", +"'@ c #F7F3DD", +")@ c #F4F0D6", +"!@ c #F2ECCF", +"~@ c #E3D38B", +"{@ c #D5BE51", +"]@ c #C2A006", +"^@ c #A1860A", +"/@ c #A78A08", +"(@ c #AA8C08", +"_@ c #AC8E08", +":@ c #B09108", +"<@ c #9C8109", +"[@ c #9D830A", +" . + @ # $ % & * . ", +" = - ; > , ' ) ! ~ ", +" { ] ^ / ( _ : < [ } | ", +" 1 2 3 4 5 6 7 8 9 0 a b c d ", +" e c f g h i j k l m n o p q r ", +" s t u v w x y z A B C D E F G H ", +" I J K L M N O P Q R S T U V W X Y Z ", +" ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~. ", +" {.].^./.(._.:.:.<.[.}.|.1.2.3.4.5.6.7.` ", +" 8.9.0.a.b.c.d.d.e.f.g.h.i.j.k.l.m.n.o.p. ", +" 8.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I. ", +" J.K.L.M.N.O.P.Q.R.S.T.U.V.W.O.X.Y.Z.`.{. ", +" +.+++@+#+$+%+&+*+*+*+&+=+-+;+>+,+#+'+)+ ", +" !+~+{+]+^+^+/+^+^+^+^+^+^+(+^+^+_+:+<+[+ ", +" }+|+1+2+_+^+3+^+^+^+^+^+^+4+^+5+6+7+8+9+ ", +" 0+a+b+c+d+e+f+^+^+^+^+^+^+g+h+i+j+k+l+ ", +" m+n+o+p+q+r+r+s+o+t+u+v+w+x+y+z+A+B+ ", +" C+D+E+F+G+H+I+J+K+x+L+M+N+O+P+Q+R+S+ ", +" T+U+V+W+X+Y+Z+`+L+ @.@+@@@#@$@%@ ", +" &@*@=@-@;@>@,@'@)@!@~@{@]@ ", +" ^@/@(@_@:@/@<@[@ ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-documentation.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-docume... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-documentation.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-documentation.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,257 @@ +/* XPM */ +static const char * cat_documentation_xpm[] = { +"22 22 232 2", +" c None", +". c #204A87", +"+ c #4C6E9F", +"@ c #879DBE", +"# c #B3C1D6", +"$ c #E0E6EE", +"% c #B4C2D7", +"& c #879EBE", +"* c #4C6E9E", +"= c #29518B", +"- c #A0B2CC", +"; c #E6EBF1", +"> c #A4B5CE", +", c #7893B7", +"' c #4E71A1", +") c #5072A3", +"! c #7D96BB", +"~ c #A9BAD2", +"{ c #E9EDF3", +"] c #A1B3CD", +"^ c #29518C", +"/ c #4A6C9E", +"( c #DFE5EE", +"_ c #A9B9D1", +": c #355C94", +"< c #2F5791", +"[ c #335B94", +"} c #365E96", +"| c #386098", +"1 c #396199", +"2 c #3A6299", +"3 c #466B9F", +"4 c #B5C4D9", +"5 c #4D6EA0", +"6 c #29528C", +"7 c #6C88B0", +"8 c #2D5690", +"9 c #6281AD", +"0 c #B5C4D8", +"a c #E3E8F0", +"b c #F8F9FB", +"c c #F3F5F8", +"d c #DAE2EC", +"e c #92A9C7", +"f c #446B9F", +"g c #41699E", +"h c #829CBF", +"i c #E0E6EF", +"j c #A3B4CD", +"k c #A8B9D0", +"l c #345C95", +"m c #FFFFFF", +"n c #A9BCD4", +"o c #4B71A5", +"p c #486FA3", +"q c #BAC8DB", +"r c #A6B8D0", +"s c #214B87", +"t c #5071A0", +"u c #E5EAF1", +"v c #375E95", +"w c #345D95", +"x c #3B639A", +"y c #A8BAD2", +"z c #B8C7DB", +"A c #7B97BD", +"B c #6688B3", +"C c #A6BAD4", +"D c #ECF0F5", +"E c #547AAC", +"F c #5177A9", +"G c #587CAB", +"H c #5273A2", +"I c #8CA2C1", +"J c #42699F", +"K c #4B72A5", +"L c #5076A8", +"M c #557BAC", +"N c #5A7FB0", +"O c #6B8DB8", +"P c #F0F3F7", +"Q c #5E83B2", +"R c #5A7FAF", +"S c #B6C6DB", +"T c #90A7C5", +"U c #BAC7DA", +"V c #7691B6", +"W c #386097", +"X c #40679D", +"Y c #577CAD", +"Z c #5D82B2", +"` c #6488B6", +" . c #CED9E8", +".. c #C2D1E3", +"+. c #678BB9", +"@. c #6287B5", +"#. c #96ADCB", +"$. c #BDCBDD", +"%. c #224C88", +"&. c #E7ECF2", +"*. c #4E71A2", +"=. c #3C649A", +"-. c #456CA1", +";. c #4D74A7", +">. c #6489B7", +",. c #CBD7E7", +"'. c #E1E8F1", +"). c #7799C3", +"!. c #7093BF", +"~. c #6B8EBB", +"{. c #7796BE", +"]. c #E6EBF2", +"^. c #E8EDF3", +"/. c #5074A4", +"(. c #496FA3", +"_. c #5278AA", +":. c #5A80B0", +"<. c #6387B6", +"[. c #B2C5DB", +"}. c #E0E8F2", +"|. c #83A4CB", +"1. c #7C9FC8", +"2. c #789BC5", +"3. c #7295C0", +"4. c #6B8FBB", +"5. c #7C9AC2", +"6. c #E7ECF3", +"7. c #224B88", +"8. c #BECBDD", +"9. c #7C96BB", +"0. c #4C72A5", +"a. c #5E83B3", +"b. c #E1E9F1", +"c. c #9EB9D8", +"d. c #88A9D0", +"e. c #85A7CE", +"f. c #80A2CA", +"g. c #9FB6D3", +"h. c #C1CEDF", +"i. c #234D89", +"j. c #94A8C5", +"k. c #A6B8D1", +"l. c #446BA0", +"m. c #4E74A7", +"n. c #577DAE", +"o. c #6185B4", +"p. c #6A8EBB", +"q. c #81A2C9", +"r. c #89AACF", +"s. c #8EAFD4", +"t. c #91B2D6", +"u. c #8DAFD4", +"v. c #86A7CE", +"w. c #7D9FC8", +"x. c #7397C1", +"y. c #C1D0E2", +"z. c #97ACC9", +"A. c #5879A6", +"B. c #4C71A4", +"C. c #587DAE", +"D. c #6286B5", +"E. c #6B8FBC", +"F. c #D3DEEB", +"G. c #E7EDF5", +"H. c #E9EFF6", +"I. c #9FBCDC", +"J. c #9BBBDD", +"K. c #92B3D7", +"L. c #88AAD0", +"M. c #7EA1C9", +"N. c #7C9DC5", +"O. c #EEF2F7", +"P. c #5575A4", +"Q. c #AFBFD5", +"R. c #AFC0D6", +"S. c #6186B4", +"T. c #E9EFF5", +"U. c #9FBBDA", +"V. c #86A8CE", +"W. c #C8D6E7", +"X. c #B2C2D8", +"Y. c #2E568F", +"Z. c #809BC0", +"`. c #5F83B3", +" + c #688CB9", +".+ c #E9EEF5", +"++ c #98B5D6", +"@+ c #89AAD0", +"#+ c #86A8CF", +"$+ c #80A3CA", +"%+ c #A4BBD7", +"&+ c #E9EEF4", +"*+ c #2C538D", +"=+ c #5878A6", +"-+ c #B5C5DB", +";+ c #6285B3", +">+ c #6388B6", +",+ c #7396C1", +"'+ c #799CC5", +")+ c #7DA0C8", +"!+ c #7FA1C9", +"~+ c #83A4CA", +"{+ c #C9D7E7", +"]+ c #EAEFF5", +"^+ c #5576A5", +"/+ c #214B88", +"(+ c #B4C4D9", +"_+ c #B7C7DC", +":+ c #99B1CF", +"<+ c #7E9DC4", +"[+ c #83A2C7", +"}+ c #A3BAD7", +"|+ c #C1D1E4", +"1+ c #B5C5DA", +"2+ c #2C558E", +"3+ c #214A86", +"4+ c #5C7CA8", +"5+ c #9CB0CC", +"6+ c #C8D3E3", +"7+ c #EDF1F6", +"8+ c #C9D4E4", +"9+ c #9DB1CC", +"0+ c #5978A5", +"a+ c #224982", +"b+ c #132C51", +"c+ c #193866", +"d+ c #20457A", +"e+ c #204985", +"f+ c #214982", +"g+ c #1E4173", +"h+ c #15325A", +"i+ c #0F2341", +" ", +" . . . . . . . . ", +" . . + @ # $ $ % & * . ", +" . = - ; > , ' ) ! ~ { ] ^ . ", +" . / ( _ : < [ } | 1 2 3 4 $ 5 . ", +" . 6 $ 7 8 9 0 a b c d e f g h i ^ ", +" . j k 8 l ~ m m m m m m n o p q r s ", +" . t u v w x y z A B C m m D E F G D H ", +" . I - [ 2 J K L M N O m m P Q R M S T . ", +" . U V W X p L Y Z ` .m m ..+.@.Z #.$.%. ", +" . &.*.=.-.;.M Z >.,.m m '.).!.~.>.{.].s ", +" . ^./.X (._.:.<.[.m m }.|.1.2.3.4.5.6.7. ", +" . 8.9.J 0.M a.+.b.m m c.d.e.f.2.!.g.h.i. ", +" . j.k.l.m.n.o.p.).q.r.s.t.u.v.w.x.y.z.. ", +" . A.].B.m.C.D.E.F.G.H.I.J.K.L.M.N.O.P. ", +" . Q.R.m.n.S.p.T.m m U.K.s.V.w.W.X.i. ", +" Y.&.Z.M `. +.+m m ++@+#+$+%+&+*+ ", +" s =+6.-+;+>+E.,+'+)+!+~+{+]+^+ ", +" /+Y.(+&+_+:+<+[+}+|+O.1+2+ ", +" 3+4+5+6+7+7+8+9+0+a+ ", +" b+c+d+e+f+g+h+i+ ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-emulators.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-emulat... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-emulators.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-emulators.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,193 @@ +/* XPM */ +static const char * cat_emulators_xpm[] = { +"22 22 168 2", +" c None", +". c #888A85", +"+ c #F7F8F7", +"@ c #70726D", +"# c #F9F9F8", +"$ c #ECEEEB", +"% c #E6E8E4", +"& c #DFE1DD", +"* c #DDDFDB", +"= c #D8D9D5", +"- c #D1D4CF", +"; c #D5D8D3", +"> c #E6E7E5", +", c #ECEDEA", +"' c #446EA0", +") c #204A87", +"! c #426D9F", +"~ c #CDCFCA", +"{ c #6A7583", +"] c #6B7888", +"^ c #6C798D", +"/ c #6E7D90", +"( c #989F92", +"_ c #6F7F95", +": c #6F7F96", +"< c #6E7D92", +"[ c #6E7C8F", +"} c #6C7A8D", +"| c #C1C4BE", +"1 c #6C798B", +"2 c #6F7E95", +"3 c #99A297", +"4 c #B8BB97", +"5 c #9BA39A", +"6 c #72859E", +"7 c #72849E", +"8 c #72849D", +"9 c #70839B", +"0 c #6F8099", +"a c #6E7E95", +"b c #B7BAB4", +"c c #6F7E93", +"d c #708098", +"e c #70839D", +"f c #CDCC97", +"g c #FEFADE", +"h c #B9BE9B", +"i c #738AA6", +"j c #748AA6", +"k c #7389A5", +"l c #7388A3", +"m c #72879F", +"n c #495E7B", +"o c #72859F", +"p c #9CA79E", +"q c #E5DF96", +"r c #FFFFFF", +"s c #DCD998", +"t c #778FAD", +"u c #7790AD", +"v c #9EADA5", +"w c #758EAC", +"x c #738BA7", +"y c #536F91", +"z c #2B4A73", +"A c #193963", +"B c #4D6487", +"C c #5F7798", +"D c #CACB94", +"E c #FEFADD", +"F c #ECE596", +"G c #9AABA3", +"H c #90A49C", +"I c #A8B389", +"J c #778D84", +"K c #234E7F", +"L c #214979", +"M c #1D4573", +"N c #1D3F6C", +"O c #1D416E", +"P c #1F4776", +"Q c #B0B25E", +"R c #C8C45C", +"S c #FEF8CA", +"T c #92A26D", +"U c #C8C55E", +"V c #B2B663", +"W c #658176", +"X c #637F73", +"Y c #637A6F", +"Z c #60776A", +"` c #B4BAAE", +" . c #C6C158", +".. c #C7C25A", +"+. c #E2D756", +"@. c #93A26E", +"#. c #B4B966", +"$. c #FDF3A5", +"%. c #D8D15B", +"&. c #B3B764", +"*. c #B1B461", +"=. c #424904", +"-. c #B3B965", +";. c #6A8A80", +">. c #CAC961", +",. c #6C8D84", +"'. c #444D11", +"). c #C7C35B", +"!. c #C8C55D", +"~. c #C9C75E", +"{. c #6A8A81", +"]. c #6C8D85", +"^. c #B6BD6A", +"/. c #CBCB63", +"(. c #336FA2", +"_. c #B5BC69", +":. c #B3BA67", +"<. c #B3B765", +"[. c #B2B563", +"}. c #B6B9B3", +"|. c #919E69", +"1. c #94A571", +"2. c #2F669A", +"3. c #316CA0", +"4. c #99AD79", +"5. c #9AAF7B", +"6. c #3775A7", +"7. c #3571A5", +"8. c #316BA0", +"9. c #2B6094", +"0. c #27598C", +"a. c #255588", +"b. c #295C8F", +"c. c #2D6397", +"d. c #316B9E", +"e. c #336FA3", +"f. c #71978E", +"g. c #749C92", +"h. c #3B79AD", +"i. c #3775A8", +"j. c #356FA3", +"k. c #2F699D", +"l. c #2D6396", +"m. c #295C8E", +"n. c #275588", +"o. c #295E91", +"p. c #2F6498", +"q. c #3572A5", +"r. c #3B78AC", +"s. c #9DB37F", +"t. c #3F81B5", +"u. c #3B7DB1", +"v. c #3978AB", +"w. c #336B9F", +"x. c #2D6398", +"y. c #295A8F", +"z. c #C0C3BD", +"A. c #EBEDEA", +"B. c #C4C7C1", +"C. c #F7F8F6", +"D. c #E2E4E0", +"E. c #D4D7D2", +"F. c #C8CBC5", +"G. c #C2C4BF", +"H. c #BCBFB9", +"I. c #C2C5BF", +"J. c #C6C9C3", +"K. c #6C6E69", +" . . . . . . . . . . . . . . . . . . ", +" . + + + + + + + + + + + + + + + + + + @ ", +". + # $ % & & & & & & & & & * = - - ; > + . ", +". + , ' ) ) ) ) ) ) ) ) ) ) ) ) ) ) ! ~ + . ", +". + % ) { ] ^ / ( _ : : : _ < [ } ] ) | + . ", +". + & ) 1 / 2 3 4 5 6 6 7 8 9 0 a / ) b + . ", +". + & ) c d e f g h i j i k l m e n ) b + . ", +". + & ) 9 o p q r s t u v w x y z A ) b + . ", +". + & ) B C D E F E G H I J K L M N ) b + . ", +". + & ) O P Q r R S T U r V W X Y Z ) ` + . ", +". + & ) ...r +.@.S #.$.%.r &.V *.Q ) ` + . ", +". + & =.r r r -.;.S >.r ,.S r r r r ) ` + . ", +". + & '.).!.~.{.].^.r /.(.^._.:.<.[.) }.+ . ", +". + & ) |.T 1.2.3.4.r 5.6.7.8.2.9.0.) }.+ . ", +". + & ) a.b.c.d.e.f.$.g.h.i.j.k.l.m.) }.+ . ", +". + % ) n.o.p.8.q.r.s.t.u.v.7.w.x.y.) z.+ . ", +". + A.' ) ) ) ) ) ) ) ) ) ) ) ) ) ) ' B.+ . ", +". + C.D.E.F.G.H.H.H.H.H.H.H.H.H.H.I.B.J.+ . ", +" . + + + + + + + + + + + + + + + + + + K. ", +" . . . . . . . . . . . . . . . . . . ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-games.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-games.... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-games.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-games.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,166 @@ +/* XPM */ +static const char * cat_games_xpm[] = { +"22 22 141 2", +" c None", +". c #898B86", +"+ c #8C8E8A", +"@ c #8D8F8B", +"# c #9B9C99", +"$ c #BFC0BE", +"% c #D5D6D4", +"& c #959792", +"* c #8C8E89", +"= c #8E8F8B", +"- c #898B87", +"; c #9C9D99", +"> c #C2C4C2", +", c #D2D2D1", +"' c #A4A6A2", +") c #91938E", +"! c #90928E", +"~ c #90928D", +"{ c #8F918C", +"] c #8D8F8A", +"^ c #8A8C87", +"/ c #B5B7B4", +"( c #E1E1E0", +"_ c #F3F3F3", +": c #FBFBFB", +"< c #FDFDFD", +"[ c #FAFAFA", +"} c #B1B2AF", +"| c #DDDEDC", +"1 c #FCFCFC", +"2 c #ECEDEC", +"3 c #FEFEFE", +"4 c #F8F8F8", +"5 c #F5F5F5", +"6 c #F1F1F1", +"7 c #EDEDED", +"8 c #ECECEC", +"9 c #A0A19E", +"0 c #F6F6F5", +"a c #F7F7F7", +"b c #F2F2F2", +"c c #F0F0F0", +"d c #EFEFEF", +"e c #8B8D88", +"f c #838383", +"g c #7F7F7F", +"h c #E7E7E7", +"i c #A1A29F", +"j c #F6F6F6", +"k c #EEEEEE", +"l c #8E908B", +"m c #C0C0C0", +"n c #030303", +"o c #000000", +"p c #404040", +"q c #A1A39F", +"r c #8B8C88", +"s c #DBDBDB", +"t c #707070", +"u c #171717", +"v c #F4F4F4", +"w c #EAEAEA", +"x c #BBBCB9", +"y c #D8D8D8", +"z c #868686", +"A c #464646", +"B c #E3E3E3", +"C c #A2A3A0", +"D c #ECDCDC", +"E c #E9CFCF", +"F c #E8CECE", +"G c #E8D4D4", +"H c #EBEBEB", +"I c #939490", +"J c #969696", +"K c #E8E8E8", +"L c #A2A4A0", +"M c #E9D0D0", +"N c #DC5757", +"O c #DB4E4E", +"P c #DD6464", +"Q c #D94545", +"R c #D84141", +"S c #E3ABAB", +"T c #E9E9E9", +"U c #A3A4A1", +"V c #F3F3F2", +"W c #E4A0A0", +"X c #DB4B4B", +"Y c #DA4646", +"Z c #D94242", +"` c #D83E3E", +" . c #D73A3A", +".. c #DB6767", +"+. c #F1F1F0", +"@. c #A4A5A1", +"#. c #E7CBCB", +"$. c #D94343", +"%. c #D83F3F", +"&. c #D63333", +"*. c #D32323", +"=. c #DD9696", +"-. c #E5E5E5", +";. c #8A8B87", +">. c #DCDEDC", +",. c #DC7070", +"'. c #D11C1C", +"). c #CE0B0B", +"!. c #CC0101", +"~. c #D13B3B", +"{. c #E1DCDC", +"]. c #E2E2E2", +"^. c #E4E4E4", +"/. c #B2B3AF", +"(. c #F9F9F9", +"_. c #E3E1E1", +":. c #D56161", +"<. c #CC0000", +"[. c #D23D3D", +"}. c #E1DADA", +"|. c #E1E1E1", +"1. c #DA9494", +"2. c #E0DADA", +"3. c #A3A5A1", +"4. c #EFEFEE", +"5. c #EAEAE9", +"6. c #E0E0E0", +"7. c #D1D2D0", +"8. c #AFB1AE", +"9. c #AAABA8", +"0. c #EDEDEC", +"a. c #888A86", +"b. c #8D8E8A", +"c. c #CACBC9", +"d. c #9C9E9A", +"e. c #8A8C88", +"f. c #D8D8D7", +"g. c #FFFFFF", +"h. c #888985", +"i. c #888A85", +"j. c #898A86", +" . ", +" + @ . # $ % & ", +" * = - ; > , ' ) ! ~ { ] ^ ^ ^ . . . = ", +"] / ( _ : < [ } | 1 1 1 1 < < < < 1 1 1 2 ] ", +"^ 3 4 5 6 7 8 9 0 a _ _ b b 6 6 c c d c : e ", +"* : _ c f g h i j 5 6 c c c d d k 7 7 k : e ", +"l c j m n o p q j 5 c c d d k k 7 8 8 k : r ", +" s 4 t o o u q 5 v d d k k k 8 8 8 w 8 : ^ ", +" x : y z A B C v v k k D E 8 F G w w H [ ^ ", +" I < c d J K L v _ k M N O P Q R S T w : ^ ", +" ] : _ c d k U V _ 7 W X Y Z ` ...h T : ^ ", +" l +.j c d k @.b b 8 #.$.%. .&.*.=.-.K : ;.", +" >.4 k 8 w C c c T w ,.'.).!.~.{.].^.: . ", +" /.(.-.-.-.L d 7 ^.B _.:.<.[.}.].|.B : . ", +" { < -.-.-.U d 8 B B B ].1.2.].|.|.B : . ", +" ] (.T -.-.3.4.8 B B ].].].|.|.|.|.].: . ", +" l 5.d -.-.@.7 8 B ].].].|.|.|.|.6.].: . ", +" 7._ -.-.' 7 8 ].].].|.|.|.|.6.6.].: . ", +" 8.: j 1 9.0.8 ].].|.].].|.|.|.].B 1 a.", +" b.c.$ d.e.f.g.3 3 3 3 3 3 < < 1 1 w ^ ", +" h.i.i.i.i.i.i.i.i.i.i.j.. ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-hardware.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-hardwa... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-hardware.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-hardware.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,89 @@ +/* XPM */ +static const char * cat_hardware_xpm[] = { +"22 22 64 1", +" c None", +". c #2A5700", +"+ c #8AE234", +"@ c #788600", +"# c #6E7729", +"$ c #555B38", +"% c #8E9A23", +"& c #53593A", +"* c #535939", +"= c #6B7526", +"- c #849115", +"; c #778500", +"> c #83C020", +", c #54593F", +"' c #E0E1DC", +") c #525741", +"! c #525839", +"~ c #CFD0CD", +"{ c #585C41", +"] c #768402", +"^ c #5F6825", +"/ c #4F543E", +"( c #828578", +"_ c #808276", +": c #7F8275", +"< c #808375", +"[ c #7D8072", +"} c #7E8174", +"| c #4F5636", +"1 c #636E1A", +"2 c #4F543D", +"3 c #DBDCD8", +"4 c #BCBDB9", +"5 c #BFC0BA", +"6 c #ABACA8", +"7 c #555753", +"8 c #4F553C", +"9 c #8C981F", +"0 c #859215", +"a c #878A7C", +"b c #898C7C", +"c c #51563A", +"d c #798709", +"e c #788405", +"f c #849117", +"g c #8A961D", +"h c #849012", +"i c #7A8804", +"j c #889518", +"k c #7B8905", +"l c #89951A", +"m c #839113", +"n c #BEB400", +"o c #828D04", +"p c #EDD400", +"q c #7D8A08", +"r c #879104", +"s c #FCE94F", +"t c #7D8909", +"u c #7D8A06", +"v c #85CD28", +"w c #8EB41D", +"x c #275200", +"y c #264E00", +" ", +" ", +" ", +" ................... ", +" .+++++++++++++++++. ", +" .+@@#$%&%*=%%-;;;>. ", +" .+@@,')'!~{@]%-;;>. ", +" .+^/(_:<[}(|1;%-;>. ", +" .+23(44444(5)%%%;>. ", +" .+^/(67777(/1@@%@>. ", +" .+8'(((((((5)9%0@>. ", +" .+^//a/b/b/c1@9@@>. ", +" .+@@@/d/e/f0g@@h@>. ", +" .+iijkk%k%kk9kklk>. ", +" .+mnn@nnknnknnono>. ", +" .+@pp@ppqppkpprpr>. ", +" .+@ss@sstsskssusu>. ", +" .v>ss>ss>ss>sswsw>. ", +" x.................y ", +" ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-multimedia.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-multim... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-multimedia.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-multimedia.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,184 @@ +/* XPM */ +static const char * cat_multimedia_xpm[] = { +"22 22 159 2", +" c None", +". c #2F3436", +"+ c #34383A", +"@ c #434748", +"# c #5C5E5F", +"$ c #2E3335", +"% c #35393B", +"& c #454849", +"* c #4C4F51", +"= c #585A5A", +"- c #A2A2A2", +"; c #DCDCDC", +"> c #6C6C6C", +", c #191919", +"' c #353A3C", +") c #2F3435", +"! c #3A3E3F", +"~ c #4A4E4F", +"{ c #494C4D", +"] c #D2D2D2", +"^ c #D8D8D8", +"/ c #1F1F1F", +"( c #090909", +"_ c #C9C9C9", +": c #D0D0D0", +"< c #111111", +"[ c #3B4042", +"} c #323738", +"| c #404446", +"1 c #505454", +"2 c #767676", +"3 c #8A8A8A", +"4 c #E5E5E5", +"5 c #999999", +"6 c #0A0A0A", +"7 c #616161", +"8 c #DADADA", +"9 c #8D8D8D", +"0 c #050505", +"a c #656565", +"b c #A8AAAB", +"c c #868888", +"d c #414547", +"e c #404445", +"f c #3E4243", +"g c #737373", +"h c #5B5B5B", +"i c #020202", +"j c #9B9B9B", +"k c #E6E6E6", +"l c #2F2F2F", +"m c #0E0E0E", +"n c #C2C2C2", +"o c #A6A8A9", +"p c #4E5252", +"q c #393D3F", +"r c #383D3F", +"s c #424748", +"t c #C4C4C4", +"u c #B6B6B6", +"v c #9C9C9C", +"w c #333333", +"x c #E9E9E9", +"y c #9B9D9D", +"z c #575859", +"A c #3F4446", +"B c #B7B7B7", +"C c #A7A7A7", +"D c #7A7A7A", +"E c #2E3436", +"F c #2D3335", +"G c #585858", +"H c #B1B1B1", +"I c #A5A5A5", +"J c #666666", +"K c #6F6F6F", +"L c #A1A1A1", +"M c #B4B4B4", +"N c #949494", +"O c #707070", +"P c #7F7F7F", +"Q c #BABABA", +"R c #B3B3B3", +"S c #6D6D6D", +"T c #6B6B6B", +"U c #C1C1C1", +"V c #34393B", +"W c #717171", +"X c #757575", +"Y c #777777", +"Z c #808080", +"` c #505050", +" . c #000000", +".. c #3E3E3E", +"+. c #FCFCFC", +"@. c #EDEDED", +"#. c #1A1A1A", +"$. c #FDFDFD", +"%. c #676767", +"&. c #5E5E5E", +"*. c #373C3D", +"=. c #CACACA", +"-. c #A3A3A3", +";. c #3A3A3A", +">. c #4F4F4F", +",. c #E8E8E8", +"'. c #434343", +"). c #AAAAAA", +"!. c #F1F1F1", +"~. c #BBBBBB", +"{. c #E4E4E4", +"]. c #4B4B4B", +"^. c #BFBFBF", +"/. c #444748", +"(. c #404444", +"_. c #414445", +":. c #434546", +"<. c #414446", +"[. c #404344", +"}. c #3F4243", +"|. c #3F4244", +"1. c #3E4142", +"2. c #606264", +"3. c #5C5C5C", +"4. c #9D9D9D", +"5. c #F6F6F6", +"6. c #595959", +"7. c #575757", +"8. c #9F9F9F", +"9. c #555555", +"0. c #545454", +"a. c #535353", +"b. c #525252", +"c. c #5E6161", +"d. c #6C6E6F", +"e. c #5A5A5A", +"f. c #F4F4F4", +"g. c #797979", +"h. c #515151", +"i. c #6A6C6C", +"j. c #727475", +"k. c #5F5F5F", +"l. c #C5C5C5", +"m. c #F7F7F7", +"n. c #6E6F6F", +"o. c #787A7A", +"p. c #9A9A9A", +"q. c #818282", +"r. c #565656", +"s. c #7D7D7D", +"t. c #898989", +"u. c #747474", +"v. c #7B7B7B", +"w. c #888888", +"x. c #4E4E4E", +"y. c #878787", +"z. c #868686", +"A. c #848484", +"B. c #828282", +" . + @ # ", +" $ % & * = - ; > , ' ", +" $ ) ! ~ { > ] ^ / ( _ : < , [ ", +" } | 1 2 3 4 5 6 7 8 9 0 a b c d e f ", +" d : g h i j k l m n o p q r % ", +" s t u v w x y z @ A ", +" ' B C t D E E F F F F F F F F F F F F E ", +" F G v H I a J K L M N O P Q R S T Q U V ", +" F Q W X Y Z ` ...+.@.#. .B $.%. .&.$.*. ", +" F =.-.;.>.n ,.J '.).!.~.'.G {.{.7 ].^.+ ", +" E E /.(._.:.:.<.<._._.(.[.}.|.}.1.1.q E ", +" E 2.h 3.4.3.5.v 6.G 7.8.9.0.8.a.b.c.E ", +" E d.e.%.$.v f.~.g.G 7.8.G 9.8.b.h.i.E ", +" E j.k.8.l.m.l.; 8.l.l.8.8.l.8.6.h.n.E ", +" E o.6.h $.3.h H h 3.I p.Q {.J 0.` 2 E ", +" E q.r.8.8.8.8.8.8.8.l.l.8.$.8.h.` s.E ", +" E t.9.9.9.9.9.9.0.0.a.a.u.h.h.` >.v.E ", +" E w.a.0.0.0.0.a.a.a.b.b.h.` ` >.x.D E ", +" E 3 w.w.w.y.y.y.y.z.z.z.A.A.A.B.B.g.E ", +" E E E E E E E E E E E E E E E E E E E ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-network.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-networ... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-network.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-network.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,304 @@ +/* XPM */ +static const char * cat_network_xpm[] = { +"22 22 279 2", +" c None", +". c #465586", +"+ c #3E5E93", +"@ c #32578F", +"# c #264E8A", +"$ c #224C88", +"% c #2B528D", +"& c #33558D", +"* c #38558C", +"= c #3E5D91", +"- c #234D89", +"; c #4570A7", +"> c #5D89BC", +", c #6A97C8", +"' c #719DCC", +") c #759FCD", +"! c #6993C2", +"~ c #4C75AB", +"{ c #305088", +"] c #4B6B9D", +"^ c #4771A7", +"/ c #6B98C9", +"( c #93B5D9", +"_ c #9EB8D9", +": c #BED0E5", +"< c #D6E4F4", +"[ c #D9E5F2", +"} c #F0F4F9", +"| c #CBD8E8", +"1 c #C4D6E9", +"2 c #87A2C5", +"3 c #6A85AD", +"4 c #7C91B5", +"5 c #98B1CF", +"6 c #B2CAE4", +"7 c #DAE2ED", +"8 c #E6EDF7", +"9 c #F4F9FE", +"0 c #FDFEFF", +"a c #FFFFFF", +"b c #FDFDFE", +"c c #F5F8FB", +"d c #BBCCE0", +"e c #6083B2", +"f c #4A75AB", +"g c #2B508A", +"h c #8B95B5", +"i c #C6D2E2", +"j c #EDF2F8", +"k c #FCFDFD", +"l c #E7ECF5", +"m c #E9F2FC", +"n c #F4F9FF", +"o c #FEFEFF", +"p c #FCFDFE", +"q c #F6F8FB", +"r c #EAEEF4", +"s c #D8E0EB", +"t c #8EA6C6", +"u c #6A92C1", +"v c #406AA2", +"w c #244884", +"x c #7992B7", +"y c #A4B9D3", +"z c #BECCDD", +"A c #D9E3EF", +"B c #E9F4FF", +"C c #EDF5FF", +"D c #F6FAFF", +"E c #F1F7FF", +"F c #F3F8FD", +"G c #E5ECF4", +"H c #CCD8E8", +"I c #A5BEDB", +"J c #9DB5D2", +"K c #C8D3E3", +"L c #D2DCE8", +"M c #88ABD1", +"N c #264E88", +"O c #9FA7C1", +"P c #6787B2", +"Q c #6F8EB8", +"R c #9BB2D1", +"S c #DFEEFC", +"T c #EFF7FF", +"U c #E8F3FF", +"V c #DEEEFF", +"W c #E0EFFF", +"X c #DFEDFB", +"Y c #BCD0E6", +"Z c #6788B4", +"` c #587DAE", +" . c #688EBC", +".. c #688DBB", +"+. c #5F81AE", +"@. c #DDE5EF", +"#. c #7F98BD", +"$. c #5D75A1", +"%. c #8AA7CA", +"&. c #CBDCEF", +"*. c #E5EEF8", +"=. c #E9F2FB", +"-. c #EDF6FE", +";. c #D6EAFF", +">. c #D3E9FF", +",. c #CEE5FC", +"'. c #B5CFED", +"). c #4D72A6", +"!. c #466DA2", +"~. c #40689F", +"{. c #3B649C", +"]. c #39639C", +"^. c #436CA3", +"/. c #7B98BE", +"(. c #C0CDDF", +"_. c #426193", +":. c #385B92", +"<. c #A3BEDC", +"[. c #E8EEF5", +"}. c #FAFBFD", +"|. c #F2F7FC", +"1. c #E5EFFA", +"2. c #C7DFF8", +"3. c #C6DEF8", +"4. c #BFD9F4", +"5. c #8FAFD4", +"6. c #476EA3", +"7. c #436AA0", +"8. c #3E679E", +"9. c #39639B", +"0. c #345F99", +"a. c #3E6CA4", +"b. c #91A9C7", +"c. c #7F9FC5", +"d. c #8195B7", +"e. c #335991", +"f. c #AAC5E1", +"g. c #F8F9FC", +"h. c #FEFEFE", +"i. c #EFF3F7", +"j. c #C7D9EB", +"k. c #B7D1EE", +"l. c #B4D0EE", +"m. c #AFCCEB", +"n. c #96B6DB", +"o. c #446CA1", +"p. c #3B659C", +"q. c #37619A", +"r. c #325D97", +"s. c #315E98", +"t. c #7796BE", +"u. c #739AC7", +"v. c #204986", +"w. c #2C528B", +"x. c #8EB0D6", +"y. c #F9FAFC", +"z. c #F6F8FA", +"A. c #BDCCDF", +"B. c #9AB9DA", +"C. c #A2C2E4", +"D. c #9EBFE2", +"E. c #97B9DE", +"F. c #789ECA", +"G. c #7299C6", +"H. c #4C76AB", +"I. c #345F98", +"J. c #305B96", +"K. c #7C97BC", +"L. c #85A2C4", +"M. c #6A96C7", +"N. c #254A86", +"O. c #9DB6D5", +"P. c #EEF3F9", +"Q. c #D6DFEB", +"R. c #D7E0EB", +"S. c #E3E9F1", +"T. c #97ACCA", +"U. c #6F94C0", +"V. c #8DB1D8", +"W. c #87ACD5", +"X. c #7EA6D0", +"Y. c #749DCB", +"Z. c #5D86B8", +"`. c #4E73A6", +" + c #5074A6", +".+ c #88A2C4", +"++ c #6688B2", +"@+ c #204A87", +"#+ c #879DC0", +"$+ c #C2D4E7", +"%+ c #94ADCD", +"&+ c #859FC1", +"*+ c #5578A8", +"=+ c #DBE2ED", +"-+ c #CBD8E7", +";+ c #88ACD3", +">+ c #769FCC", +",+ c #6F99C8", +"'+ c #729BC8", +")+ c #81A2C9", +"!+ c #89A1C2", +"~+ c #AABBD3", +"{+ c #ADBED5", +"]+ c #7393BA", +"^+ c #9AABC6", +"/+ c #8FAED2", +"(+ c #628EC0", +"_+ c #3E69A1", +":+ c #3C649C", +"<+ c #42699F", +"[+ c #7B9CC3", +"}+ c #D6E2EF", +"|+ c #BCCFE4", +"1+ c #7DA2CB", +"2+ c #ADC3DA", +"3+ c #F2F5F8", +"4+ c #F8F9FB", +"5+ c #C8D3E2", +"6+ c #80A5CE", +"7+ c #28518B", +"8+ c #395C91", +"9+ c #446DA3", +"0+ c #6C98C8", +"a+ c #406CA5", +"b+ c #305C96", +"c+ c #3E6AA2", +"d+ c #5F8BBE", +"e+ c #90AFD2", +"f+ c #C1D2E5", +"g+ c #D4DFED", +"h+ c #D4E0ED", +"i+ c #F7F9FB", +"j+ c #E5EBF2", +"k+ c #8DA4C4", +"l+ c #456493", +"m+ c #244A83", +"n+ c #648EBF", +"o+ c #356099", +"p+ c #4272AB", +"q+ c #497BB3", +"r+ c #4779B2", +"s+ c #4376B0", +"t+ c #5B86B6", +"u+ c #CCD8E7", +"v+ c #F3F5F9", +"w+ c #FCFCFD", +"x+ c #FBFCFD", +"y+ c #E0E4EB", +"z+ c #94A4BB", +"A+ c #1D447C", +"B+ c #406BA3", +"C+ c #5D85B5", +"D+ c #507BAD", +"E+ c #698DB7", +"F+ c #8BA6C5", +"G+ c #B7C6D9", +"H+ c #99ADC7", +"I+ c #A4B3CB", +"J+ c #CAD3E1", +"K+ c #D6DBE2", +"L+ c #B4BCC7", +"M+ c #A0A5AA", +"N+ c #1C3D6E", +"O+ c #5D83B2", +"P+ c #85A6CC", +"Q+ c #7CA4CF", +"R+ c #9CBCDD", +"S+ c #749ECB", +"T+ c #5983B5", +"U+ c #4B6C9B", +"V+ c #526B8F", +"W+ c #768599", +"X+ c #939393", +"Y+ c #405B82", +"Z+ c #1D437A", +"`+ c #1F4783", +" @ c #1F4986", +".@ c #1C4278", +"+@ c #173561", +" ", +" . + @ # $ % & * ", +" = - ; > , ' ) ! ~ - { ", +" ] ^ / ( _ : < [ } | 1 2 3 ", +" 4 5 6 7 8 9 0 a b c d e ! f g ", +" h i j k l m n o o p q r s t u v w ", +" x y z A B C D E F G H I J K L M N ", +" O P Q R S T U V W X Y Z ` ...+.@.#. ", +" $.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._. ", +" :.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d. ", +" e.f.g.h.i.j.k.l.m.n.o.~.p.q.r.s.t.u.v. ", +" w.x.y.a z.A.B.C.D.E.F.G.H.I.J.K.L.M.v. ", +" N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++> @+ ", +" #+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+; @+ ", +" ^+/+(+_+:+<+[+}+|+1+1+2+3+4+5+6+7+ ", +" 8+9+0+a+b+c+d+e+f+g+h+i+a h.j+k+l+ ", +" m+f n+o+p+q+r+s+t+u+v+w+x+y+z+ ", +" A+B+/ C+D+E+F+G+H+I+J+K+L+M+ ", +" N+- O+P+Q+R+S+T+U+V+W+X+ ", +" Y+Z+`+ @`+.@+@ ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-office.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-office... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-office.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-office.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,201 @@ +/* XPM */ +static const char * cat_office_xpm[] = { +"22 22 176 2", +" c None", +". c #6587B3", +"+ c #5A81B3", +"@ c #547DB2", +"# c #5980B3", +"$ c #BAC9DD", +"% c #B7C9DF", +"& c #5981B4", +"* c #75551A", +"= c #5B451C", +"- c #577FB3", +"; c #C5D3E4", +"> c #6C92C0", +", c #AEC2DA", +"' c #557EB2", +") c #7F5F22", +"! c #D1BA80", +"~ c #A0854B", +"{ c #567EB2", +"] c #3F6FAB", +"^ c #7799C3", +"/ c #9EB6D2", +"( c #CBB27E", +"_ c #E4DAAB", +": c #9A7D40", +"< c #587FB2", +"[ c #658EBE", +"} c #83A3C8", +"| c #9FB7D3", +"1 c #527CB1", +"2 c #987C45", +"3 c #DBB46A", +"4 c #BC8D36", +"5 c #765619", +"6 c #577EB2", +"7 c #6E95C1", +"8 c #7C9DC5", +"9 c #99B3D0", +"0 c #527BB0", +"a c #C4A770", +"b c #D09B37", +"c c #85601D", +"d c #5B81B3", +"e c #5880B4", +"f c #7399C4", +"g c #90ACCC", +"h c #93ACCD", +"i c #577DAE", +"j c #9A9A98", +"k c #9A9B99", +"l c #999997", +"m c #949492", +"n c #8F908E", +"o c #907440", +"p c #DBB369", +"q c #B88321", +"r c #745415", +"s c #5E83B3", +"t c #6589B7", +"u c #7599C2", +"v c #9AB4D1", +"w c #7E9EC4", +"x c #FFFFFF", +"y c #BB9C64", +"z c #D19D3B", +"A c #87631D", +"B c #888A85", +"C c #5D82B3", +"D c #678BB9", +"E c #6F94BF", +"F c #9DB6D3", +"G c #7093BE", +"H c #6688B3", +"I c #DBDBDA", +"J c #D9D9D8", +"K c #CEC2AB", +"L c #DAB268", +"M c #BB8520", +"N c #79602D", +"O c #778BA5", +"P c #6F96C2", +"Q c #668DBB", +"R c #9CB5D2", +"S c #C9C3B7", +"T c #B59558", +"U c #D29F3F", +"V c #8C651B", +"W c #EEEEEC", +"X c #8C98A6", +"Y c #6382A7", +"Z c #7094BE", +"` c #6C92BD", +" . c #98B2D0", +".. c #7296BF", +"+. c #6586B2", +"@. c #D8B166", +"#. c #BE8E33", +"$. c #8D8979", +"%. c #EFEFEE", +"&. c #FEFEFE", +"*. c #E7ECF2", +"=. c #929695", +"-. c #969996", +";. c #949796", +">. c #929694", +",. c #969790", +"'. c #97968D", +"). c #919189", +"!. c #FDFDFD", +"~. c #F4F4F4", +"{. c #E9E9E9", +"]. c #F3F6F9", +"^. c #FBFCFD", +"/. c #B0C4DC", +"(. c #A2B9D3", +"_. c #97AEC6", +":. c #C3B191", +"<. c #C4BDB1", +"[. c #FAFBFC", +"}. c #C8BFAF", +"|. c #A6BCD5", +"1. c #99B1CE", +"2. c #8DA1B6", +"3. c #D9D9D9", +"4. c #EBEBEB", +"5. c #F4F4F3", +"6. c #EAE5DD", +"7. c #C8BEAD", +"8. c #C1B59D", +"9. c #A7BCD4", +"0. c #A9B8CA", +"a. c #92AAC7", +"b. c #E3E3E2", +"c. c #F5F5F5", +"d. c #D2CBBC", +"e. c #CFC1A9", +"f. c #BDB198", +"g. c #BDB7A9", +"h. c #91A9C5", +"i. c #7E9DC1", +"j. c #D4D4D2", +"k. c #F8F8F8", +"l. c #878984", +"m. c #FCFCFC", +"n. c #C7C1B4", +"o. c #C9BAA2", +"p. c #D7C6B2", +"q. c #D0C3B5", +"r. c #CBCCCC", +"s. c #D7D7D7", +"t. c #91A5BB", +"u. c #A4B8CE", +"v. c #F5F6F5", +"w. c #787A76", +"x. c #D8D8D8", +"y. c #F2F2F2", +"z. c #D0CBC2", +"A. c #C7B69C", +"B. c #CEC2B0", +"C. c #D0CDCB", +"D. c #CECDCD", +"E. c #C4C4C4", +"F. c #DCDCDC", +"G. c #EFEFEF", +"H. c #7C7E7A", +"I. c #82847F", +"J. c #DADADA", +"K. c #FBFBFB", +"L. c #FAF9F8", +"M. c #FAFAF9", +"N. c #F6F6F6", +"O. c #F7F7F7", +"P. c #C6C7C6", +"Q. c #747571", +"R. c #81837E", +"S. c #71736F", +". + @ ", +"# $ % & * = ", +"- ; > , ' ) ! ~ ", +". { ] ^ / ' ( _ : ", +" { < [ } | 1 2 3 4 5 ", +" - 6 7 8 9 0 a b c ", +" - d e f g h i j k l m n o p q r ", +" - # s t u v w . x x x x y z A B ", +" { d C D E F G H I J K L M N B ", +" { O + P Q R G H S T U V W B ", +" B X Y Z ` ...+.@.#.$.%.B ", +" B &.*.=.-.;.>.,.'.).!.~.B ", +" B &.&.x x x x x x x {.~.B ", +" B &.&.].^./.(._.:.<.{.~.B ", +" B &.&.x [.}.|.1.2.3.4.5.B ", +" B &.&.x 6.7.8.9.0.a.b.c.B ", +" B &.!.x d.e.f.g.h.i.j.k.B ", +" l.m.c.n.o.p.q.r.s.t.u.v.l. ", +" w.x.y.z.A.B.C.D.E.F.G.{.H. ", +" I.J.K.L.M.N.c.N.O.P.I. ", +" Q.I.B B B B B R.S. ", +" "}; Added: trunk/gtk/unstable/src/icons/cat-system.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-system... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-system.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-system.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,273 @@ +/* XPM */ +static const char * cat_system_xpm[] = { +"22 22 248 2", +" c None", +". c #3A5A8A", +"+ c #3465A4", +"@ c #8A9BBA", +"# c #7F92B2", +"$ c #7988AC", +"% c #345F99", +"& c #537BAE", +"* c #8A9BB8", +"= c #5E769E", +"- c #7484A6", +"; c #35609A", +"> c #5F76A2", +", c #466594", +"' c #BBC3D3", +") c #9DA7BC", +"! c #7796C1", +"~ c #9DA9C4", +"{ c #5B729D", +"] c #8794B1", +"^ c #7786A5", +"/ c #969BB8", +"( c #7A89AF", +"_ c #34619E", +": c #899DBB", +"< c #ABB7CC", +"[ c #BEC7D8", +"} c #BFC6D6", +"| c #C3C8D5", +"1 c #A3AFC7", +"2 c #919FBC", +"3 c #5D739D", +"4 c #5E749E", +"5 c #6378A1", +"6 c #798AAE", +"7 c #6D7C9C", +"8 c #7E8FB0", +"9 c #687BA3", +"0 c #8A94B5", +"a c #A1A1BC", +"b c #466FA8", +"c c #3D5E92", +"d c #BFC7D5", +"e c #BEC7D7", +"f c #AFB9CF", +"g c #ADB7CD", +"h c #7183AA", +"i c #6377A1", +"j c #6578A2", +"k c #6679A3", +"l c #687AA4", +"m c #6A7BA5", +"n c #6C7DA6", +"o c #6D7EA7", +"p c #808CB1", +"q c #8490B4", +"r c #3E68A4", +"s c #476CA0", +"t c #C6CDDC", +"u c #B2BCD1", +"v c #9FABC5", +"w c #7283AA", +"x c #909DBB", +"y c #B2BBD0", +"z c #AAB4CB", +"A c #94A0BE", +"B c #7383AA", +"C c #7584AB", +"D c #969EBE", +"E c #496BA0", +"F c #6683AC", +"G c #C5CBDB", +"H c #B6BFD3", +"I c #ACB6CD", +"J c #B0B8CF", +"K c #A0A7BD", +"L c #6F7F9E", +"M c #7A87A4", +"N c #99A2BB", +"O c #9CA6C3", +"P c #AAB2CB", +"Q c #7D89B0", +"R c #848FB4", +"S c #888EAB", +"T c #3462A0", +"U c #5C83B6", +"V c #B6C2D7", +"W c #B9C1D5", +"X c #ACB5CD", +"Y c #A5AEC9", +"Z c #969FB5", +"` c #376099", +" . c #929BB3", +".. c #9FA7C4", +"+. c #A2AAC6", +"@. c #98A0C0", +"#. c #B1B6CD", +"$. c #A2ABBF", +"%. c #B0B7C8", +"&. c #C7CBD9", +"*. c #BFC6D8", +"=. c #A3ACC7", +"-. c #9DA6C3", +";. c #405E8D", +">. c #4D5575", +",. c #ACB1CA", +"'. c #D1D4E3", +"). c #BFC3D8", +"!. c #BFC1D7", +"~. c #A7AAC7", +"{. c #9EA1BE", +"]. c #9A9DB7", +"^. c #C0C5D9", +"/. c #ABB2CC", +"(. c #B0B7CF", +"_. c #9BA3C2", +":. c #8E97BA", +"<. c #858EB5", +"[. c #C6C9D7", +"}. c #35619C", +"|. c #A2A7BE", +"1. c #E0E2EC", +"2. c #B7B9D3", +"3. c #989BC0", +"4. c #999CC1", +"5. c #9B9DC2", +"6. c #AAACCA", +"7. c #8E95B1", +"8. c #9299B7", +"9. c #9DA5C4", +"0. c #8992B7", +"a. c #8B93B8", +"b. c #8C94B9", +"c. c #C7CBD8", +"d. c #3B5F94", +"e. c #CCCEDE", +"f. c #DADBE8", +"g. c #9EA0C3", +"h. c #A4A6C7", +"i. c #A7A8C3", +"j. c #9A9BB7", +"k. c #9395B0", +"l. c #3464A3", +"m. c #9EA3C4", +"n. c #9398BD", +"o. c #9499BE", +"p. c #BDC0D7", +"q. c #858FA9", +"r. c #3464A2", +"s. c #7F86A0", +"t. c #DCDDEA", +"u. c #C0C0D8", +"v. c #A6A5C8", +"w. c #B2B1CF", +"x. c #4A5D84", +"y. c #5274A8", +"z. c #9A9EC1", +"A. c #9C9FC2", +"B. c #CECFE0", +"C. c #939DB4", +"D. c #4D638C", +"E. c #5A6D93", +"F. c #8C92AD", +"G. c #DEDEEA", +"H. c #E0E0EB", +"I. c #ABAACB", +"J. c #ADABCC", +"K. c #9698B4", +"L. c #375F98", +"M. c #657EAC", +"N. c #AEB0CD", +"O. c #A4A4C7", +"P. c #A7A6C9", +"Q. c #C3C3DA", +"R. c #DBDAE9", +"S. c #DDDCEA", +"T. c #D2D0E3", +"U. c #CFCCE1", +"V. c #B3AFD0", +"W. c #B8B4D3", +"X. c #8389A7", +"Y. c #3364A3", +"Z. c #436EA7", +"`. c #ACB0C7", +" + c #ADABCD", +".+ c #ACA9CC", +"++ c #AEAACD", +"@+ c #AFABCE", +"#+ c #B1ADCF", +"$+ c #B3AED0", +"%+ c #B4AFD0", +"&+ c #B8B2D2", +"*+ c #D7D3E5", +"=+ c #D7D3E6", +"-+ c #BBB4D4", +";+ c #BDB5D5", +">+ c #BAB5CF", +",+ c #8C93B3", +"'+ c #3463A1", +")+ c #A2A9C5", +"!+ c #B7B5D3", +"~+ c #B2AECF", +"{+ c #BEBBD6", +"]+ c #C0BCD8", +"^+ c #B8B2D3", +"/+ c #BAB4D4", +"(+ c #BCB5D5", +"_+ c #BEB6D6", +":+ c #C6C0DC", +"<+ c #DED9EA", +"[+ c #B9B3CD", +"}+ c #C8BEDC", +"|+ c #C7BDDC", +"1+ c #A2A1BB", +"2+ c #36629D", +"3+ c #33609B", +"4+ c #476DA4", +"5+ c #BFBAD8", +"6+ c #ADACC6", +"7+ c #456290", +"8+ c #697CA5", +"9+ c #C2BCD6", +"0+ c #C4BBD9", +"a+ c #C4BAD9", +"b+ c #C7BED9", +"c+ c #949CBE", +"d+ c #385F9A", +"e+ c #335E97", +"f+ c #8793B9", +"g+ c #ADB1D2", +"h+ c #747B9A", +"i+ c #305A92", +"j+ c #325C93", +"k+ c #446DA8", +"l+ c #5175AD", +"m+ c #2F5C96", +"n+ c #284D7E", +"o+ c #CFC5E0", +"p+ c #C9BEDD", +"q+ c #5D7DB2", +"r+ c #22426C", +"s+ c #2C568B", +"t+ c #3F6599", +"u+ c #2C5285", +"v+ c #305E98", +"w+ c #CCC1DE", +"x+ c #2D578F", +"y+ c #2F5B95", +" . + + + + ", +" + @ # $ + + ", +" % & + * = - + ; > + ", +" , ' ) + + + ! ~ { ] + + + ^ / ( + ", +" _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b ", +" c d e f g h i j k l m n o p q r ", +" s t u v w x y y z A B C D E ", +" F G H I J K L M N O P Q R S T ", +"+ + + U V W X Y Z ` ...+.@.#.+ + + + ", +"+ $.%.&.*.=.-.&.;. >.,.'.).!.~.{.].+ ", +"+ ^./.(._.:.<.[.}. |.1.2.3.4.5.6.+ ", +"+ 7.8.9.0.a.b.c.d. e.f.g.h.i.j.k.+ ", +"l.+ + + m.n.o.p.q.r. s.t.u.v.w.x.+ + + ", +" y.z.A.g.B.C.D.E.F.G.H.I.J.K.L. ", +" l.M.N.O.v.P.Q.R.S.T.U.U.V.W.X.l. ", +" Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,++ ", +" '+)+!+~+{+]+^+^+/+(+_+:+<+[+}+|+1+2+ ", +" 3+4+5+6++ 7+8+9+0+a+b+c+d+e+f+g+h+i+ ", +" j+k+l+m+ n++ o+p+p+q+r+ s+t+u+ ", +" v+ + S.w+S.+ ", +" + S.S.S.+ ", +" x++ + + y+ "}; Added: trunk/gtk/unstable/src/icons/cat-utilities.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/cat-utilit... ============================================================================== --- trunk/gtk/unstable/src/icons/cat-utilities.xpm (added) +++ trunk/gtk/unstable/src/icons/cat-utilities.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,240 @@ +/* XPM */ +static const char * cat_utilities_xpm[] = { +"22 22 215 2", +" c None", +". c #8F918C", +"+ c #8D8F8A", +"@ c #888A85", +"# c #90928E", +"$ c #91938E", +"% c #C2C4C1", +"& c #9C9D99", +"* c #90928D", +"= c #D2D3D1", +"- c #929490", +"; c #C4A000", +"> c #939590", +", c #D7D8D6", +"' c #E2E2E2", +") c #9F9F9C", +"! c #9B9C98", +"~ c #ABACA8", +"{ c #E3E3E3", +"] c #D0D1D0", +"^ c #A0A19D", +"/ c #C6A304", +"( c #EBEBEB", +"_ c #DCDDDC", +": c #8C8E89", +"< c #E3E3E2", +"[ c #E0E0E0", +"} c #D8D9D8", +"| c #959792", +"1 c #C5A202", +"2 c #D5B934", +"3 c #C4A104", +"4 c #9D9E9A", +"5 c #E8E8E8", +"6 c #E1E1E1", +"7 c #B2B3B1", +"8 c #A4A6A2", +"9 c #C5C6C3", +"0 c #DFDFDF", +"a c #989A95", +"b c #C8A710", +"c c #FAF1AE", +"d c #C5A105", +"e c #E0E0DF", +"f c #92948F", +"g c #DEDEDE", +"h c #CBCCCB", +"i c #91938F", +"j c #C6A203", +"k c #F3E690", +"l c #FDF6BD", +"m c #C9C9C8", +"n c #AAABA8", +"o c #949691", +"p c #D4D5D3", +"q c #DDDDDD", +"r c #E6D162", +"s c #FAF09E", +"t c #C5A204", +"u c #C5A004", +"v c #C2C3C0", +"w c #9C9E9A", +"x c #A4A5A2", +"y c #DCDCDC", +"z c #B1B2B0", +"A c #D4B82F", +"B c #FCF3AE", +"C c #FBE95B", +"D c #FBF1AC", +"E c #8A8C87", +"F c #EAEAE9", +"G c #D6D6D6", +"H c #A9ABA7", +"I c #C1C3C1", +"J c #DBDBDB", +"K c #DEDEDD", +"L c #C8A60D", +"M c #F9EEA4", +"N c #FAE96B", +"O c #F8E44A", +"P c #FBF2AC", +"Q c #ADAEAB", +"R c #B0B2AF", +"S c #BEBFBD", +"T c #979995", +"U c #C6A202", +"V c #F0E182", +"W c #F9EB82", +"X c #ECD539", +"Y c #F2DD41", +"Z c #C3A003", +"` c #DFE0DE", +" . c #DADADA", +".. c #D8D8D8", +"+. c #B3B4B1", +"@. c #BABCBA", +"#. c #C6A303", +"$. c #E2CB54", +"%. c #F9ED96", +"&. c #F2DC43", +"*. c #CBA90A", +"=. c #F1DB3F", +"-. c #F8EEA0", +";. c #9B8F8B", +">. c #BFC0BE", +",. c #A99592", +"'. c #D1B426", +"). c #F8EC9D", +"!. c #F2DE4E", +"~. c #D6B719", +"{. c #EED83D", +"]. c #F7EB9B", +"^. c #B00606", +"/. c #946F6B", +"(. c #B6B3B1", +"_. c #B32304", +":. c #C7A40A", +"<. c #F2DF5E", +"[. c #E2C82B", +"}. c #E9D237", +"|. c #C4A003", +"1. c #B30808", +"2. c #B50909", +"3. c #AE0505", +"4. c #DA3130", +"5. c #C73A39", +"6. c #AA0303", +"7. c #AE0504", +"8. c #B6100C", +"9. c #CA582F", +"0. c #E0B62E", +"a. c #E9D135", +"b. c #F1E288", +"c. c #C4A103", +"d. c #D41A1A", +"e. c #DC1F1F", +"f. c #E12121", +"g. c #B71809", +"h. c #B94E04", +"i. c #E6CD31", +"j. c #F0E286", +"k. c #AD0505", +"l. c #DC1E1E", +"m. c #C41111", +"n. c #CE1717", +"o. c #CB1515", +"p. c #A40000", +"q. c #AE5855", +"r. c #AD2F00", +"s. c #B31309", +"t. c #C51D12", +"u. c #AD0504", +"v. c #E1C72B", +"w. c #C3A002", +"x. c #AE1211", +"y. c #E72525", +"z. c #C91313", +"A. c #D71C1C", +"B. c #B10707", +"C. c #BA6A04", +"D. c #C46215", +"E. c #B64403", +"F. c #B0200F", +"G. c #E1C629", +"H. c #ECDB78", +"I. c #AE0D0C", +"J. c #EF2929", +"K. c #BE0D0D", +"L. c #B20808", +"M. c #E22222", +"N. c #B40909", +"O. c #C5A101", +"P. c #E4CF5E", +"Q. c #BA1F12", +"R. c #B41608", +"S. c #C07A05", +"T. c #BE0F0C", +"U. c #B22A0A", +"V. c #C9A707", +"W. c #DFC326", +"X. c #EAD770", +"Y. c #B00909", +"Z. c #CC1515", +"`. c #C71111", +" + c #E32323", +".+ c #B60A0A", +"++ c #D7BD39", +"@+ c #ECDA74", +"#+ c #C86A19", +"$+ c #BA1C0D", +"%+ c #CC1715", +"&+ c #B41A0B", +"*+ c #DDC124", +"=+ c #DBBF22", +"-+ c #C5A102", +";+ c #C4A002", +">+ c #BC0D0D", +",+ c #C51212", +"'+ c #D81A1A", +")+ c #D01818", +"!+ c #CBAA16", +"~+ c #EAD978", +"{+ c #EBD97A", +"]+ c #EAD876", +"^+ c #CA5B33", +"/+ c #D06B38", +"(+ c #E5D165", +"_+ c #E4D063", +":+ c #E2CE5F", +"<+ c #B20707", +"[+ c #C4A001", +"}+ c #BB6104", +"|+ c #B63005", +"1+ c #B73006", +"2+ c #BD5A05", +" . + @ # ", +" $ % & * = - @ ; ", +" > , ' ) ! > ~ { ] ^ / ; ", +" . ( ' _ ! : < [ } | 1 2 3 ", +" @ 4 5 6 7 8 | 9 0 ' a b c d ", +" @ e [ [ a f 6 g h i j k l d ", +" @ * ( 0 m n o p q ' : / r s t u ", +" @ v [ q 4 w x y y z > 1 A B C D 3 ", +" E F y G H I J K | L M N O P 3 ", +" @ Q 0 J R S y T U V W X Y ; Z ", +" E ` ...+.@.! #.$.%.&.*.=.-.3 ", +" @ ;.' ..>.,. '.).!.~.; {.].3 ", +" ^./.(. (./._.:.k <.[.1 ; }.t |. ", +" 1.2.3.4.5.6.5.4.7.8.9.0.#. ; a.b.c. ", +" 2.d.e.f.f.6.6.6.f.f.e.d.g.h. ; i.j.c. ", +" k.l.m.^.n.o.p.q.r.o.n.s.t.l.u. ; v.; w. ", +"x.y.z.3.6.A.B. C.B.A.D.E.z.y.F.; G.H.c. ", +"I.J.K. L.M.N. O.P.Q.M.R.S.T.J.U.V.W.X.c. ", +"Y.f.Z.`. +.+ 1 ++@+#+$+ +`.%+f.&+*+=+-+;+ ", +">+,+'+)+.+.+ !+~+{+]+^+.+)+'+,+/+(+_+:+c. ", +" 1.<+ ; [+c.c.c.c.}+|+1+2+c.c.c.c.; ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-3D.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-3D.xpm... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-3D.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-3D.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,76 @@ +/* XPM */ +static const char * pkg_3D_xpm[] = { +"32 32 41 1", +" c None", +". c #000000", +"+ c #151515", +"@ c #5A5A5A", +"# c #727272", +"$ c #3F3F3F", +"% c #040404", +"& c #797979", +"* c #787878", +"= c #6B6B6B", +"- c #454545", +"; c #080808", +"> c #060606", +", c #737373", +"' c #090909", +") c #686868", +"! c #0A0A0A", +"~ c #3E3E3E", +"{ c #020202", +"] c #343434", +"^ c #2E2E2E", +"/ c #1B1B1B", +"( c #010101", +"_ c #2A2A2A", +": c #6A6A6A", +"< c #565656", +"[ c #636363", +"} c #2D2D2D", +"| c #0E0E0E", +"1 c #1C1C1C", +"2 c #434343", +"3 c #121212", +"4 c #050505", +"5 c #575757", +"6 c #242424", +"7 c #030303", +"8 c #545454", +"9 c #0D0D0D", +"0 c #555555", +"a c #393939", +"b c #6E6E6E", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ...... ......... ", +" ........ .......... ", +" ........+ ........... ", +" ..@##$..%& ...&&*=-;..> ", +" &&&,..'&& ...&&&&&)!..~ ", +" &, {..]&& ...&& ^../& ", +" ....(,&& ...&& ..'& ", +" ...(_:&& ...&& ..(&& ", +" .....>< ...&& ..;&& ", +" [}..| ...&& ..1&& ", +" ..{& ...&& ...2&& ", +" . {..3&&...&& ...4#&& ", +" .........2&&...........5&& ", +" ........6*&&.........78&&& ", +" .9%(!60&&& ......7+ab&&& ", +" &&&&&&&&& &&&&&&&&&& ", +" &&&&&& &&&&&&&&& ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-available-locked.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-availa... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-available-locked.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-available-locked.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,553 @@ +/* XPM */ +static const char * pkg_available_locked_xpm[] = { +"32 32 518 2", +" c None", +". c #3E4174", +"+ c #3F4275", +"@ c #3D3E71", +"# c #3A3B6C", +"$ c #3C3E71", +"% c #3E4074", +"& c #3C3F73", +"* c #3B3D71", +"= c #434475", +"- c #8588A7", +"; c #BFC4D6", +"> c #E3E7EE", +", c #F1F2F5", +"' c #F6F7F9", +") c #E0E6EF", +"! c #C6D2E4", +"~ c #A4B2CD", +"{ c #6B739B", +"] c #3E3F71", +"^ c #393B6F", +"/ c #3F4172", +"( c #A0A6C0", +"_ c #EAEEF2", +": c #D6DDE5", +"< c #D9DDE2", +"[ c #FEFEFE", +"} c #959BA2", +"| c #BFD4EA", +"1 c #C0D3E8", +"2 c #C6D7EA", +"3 c #C6D5E7", +"4 c #7A86AB", +"5 c #3D3E70", +"6 c #3D3D71", +"7 c #595B86", +"8 c #EAECF0", +"9 c #E8EBEE", +"0 c #CACED3", +"a c #C2CAD3", +"b c #DAE8F6", +"c c #FDFDFD", +"d c #C5C7C8", +"e c #8A9095", +"f c #ABBAC9", +"g c #BCD2EA", +"h c #B4CBE6", +"i c #ACC4E1", +"j c #DEE5ED", +"k c #EFF0F2", +"l c #C6CCD8", +"m c #4B4E7C", +"n c #74779C", +"o c #F1F2F4", +"p c #B4BBC3", +"q c #BEC9D5", +"r c #C4CDD7", +"s c #A4B0BC", +"t c #D7E5F2", +"u c #ACAEB1", +"v c #AAB7C6", +"w c #D0E1F4", +"x c #B5C1CE", +"y c #B6CAE0", +"z c #B9CFE9", +"A c #DFE6ED", +"B c #CDD0D3", +"C c #B5BDC5", +"D c #E5E6E8", +"E c #E8E9EC", +"F c #5D6188", +"G c #5A5D88", +"H c #FBFBFC", +"I c #C1CAD4", +"J c #CAE0F6", +"K c #FCFDFD", +"L c #E2E3E5", +"M c #D8E7F4", +"N c #E0EFFE", +"O c #D0DDEB", +"P c #DAEAFA", +"Q c #D5E5F7", +"R c #CDE0F3", +"S c #CBDEF1", +"T c #C2CEDB", +"U c #A9B6C4", +"V c #939BA4", +"W c #E5EAEE", +"X c #F7F7F7", +"Y c #EEEEEE", +"Z c #E7E7E9", +"` c #4C4E7A", +" . c #454677", +".. c #F1F2F3", +"+. c #ECECED", +"@. c #C3C4C6", +"#. c #AFB5BD", +"$. c #E2F0FF", +"%. c #DFEDFC", +"&. c #D8E8F9", +"*. c #D0E2F5", +"=. c #BFCEDF", +"-. c #C3C9CF", +";. c #FCFCFC", +">. c #EFEFEF", +",. c #E9E9E9", +"'. c #D3D3D8", +"). c #3D3F71", +"!. c #A5A8C0", +"~. c #FFFFFF", +"{. c #D2D3D5", +"]. c #ADB7C2", +"^. c #CDDAE6", +"/. c #E1F0FF", +"(. c #DAEAFB", +"_. c #D1E4F6", +":. c #CEDFF3", +"<. c #F0F1F3", +"[. c #F4F5F5", +"}. c #F8F9F9", +"|. c #F2F2F2", +"1. c #E5E5E5", +"2. c #E6E6E6", +"3. c #7D819A", +"4. c #424475", +"5. c #A3A6A8", +"6. c #9FABB6", +"7. c #D5E5F4", +"8. c #E0EFFF", +"9. c #DBEBFC", +"0. c #D1E4F7", +"a. c #EAEDF1", +"b. c #C8CACD", +"c. c #768697", +"d. c #A9B1BA", +"e. c #C2C5CA", +"f. c #E3E4E5", +"g. c #F4F4F4", +"h. c #E7E7E7", +"i. c #DDDDDD", +"j. c #DCDCDD", +"k. c #3C3E6E", +"l. c #8689A7", +"m. c #BBBDC0", +"n. c #B4C5D6", +"o. c #DEEEFF", +"p. c #DFEEFF", +"q. c #DFEFFF", +"r. c #D9EAFB", +"s. c #D0E3F6", +"t. c #BCC6D2", +"u. c #C6CBD1", +"v. c #D6DEE7", +"w. c #ABBED4", +"x. c #869DB7", +"y. c #819CB9", +"z. c #A1AAB4", +"A. c #E8E8E8", +"B. c #DBDBDB", +"C. c #E0E0E0", +"D. c #626487", +"E. c #3E4173", +"F. c #CDCEDA", +"G. c #CCCED0", +"H. c #CDCFD1", +"I. c #899CB0", +"J. c #CCE2FB", +"K. c #DCEDFF", +"L. c #DDEDFE", +"M. c #D5E7FA", +"N. c #EFF2F4", +"O. c #F0F1F2", +"P. c #F3F5F6", +"Q. c #DADFE5", +"R. c #E3E6E9", +"S. c #D3D3D4", +"T. c #D4D5D5", +"U. c #9A9BAB", +"V. c #3A3D6F", +"W. c #414476", +"X. c #EFEFF3", +"Y. c #818B96", +"Z. c #88A2BE", +"`. c #93A8C0", +" + c #B6D0EB", +".+ c #C4DDF7", +"++ c #D0E6FC", +"@+ c #DDEEFF", +"#+ c #DCEDFE", +"$+ c #D7E8FB", +"%+ c #CFE3F7", +"&+ c #E3E9F0", +"*+ c #B0B5BA", +"=+ c #C3C7CB", +"-+ c #CFD0D0", +";+ c #79899C", +">+ c #A3A7B2", +",+ c #37396B", +"'+ c #3F4072", +")+ c #F8F8FA", +"!+ c #95A9C0", +"~+ c #B2C8E0", +"{+ c #A9C7E8", +"]+ c #B2CFED", +"^+ c #BBD6F2", +"/+ c #C2DCF6", +"(+ c #CCE2F9", +"_+ c #D5E8FB", +":+ c #D3E6FA", +"<+ c #CEE2F7", +"[+ c #C8DDF3", +"}+ c #F7F8F8", +"|+ c #92A1B2", +"1+ c #D6D6D6", +"2+ c #CBCBCB", +"3+ c #8E9CAE", +"4+ c #393B6E", +"5+ c #3A3A6E", +"6+ c #E0E3E8", +"7+ c #ECEDEF", +"8+ c #C7CCD1", +"9+ c #9DBCDF", +"0+ c #AAC8E9", +"a+ c #B1CEED", +"b+ c #B8D3F0", +"c+ c #BCD6F3", +"d+ c #C0D9F4", +"e+ c #C5DCF4", +"f+ c #C7DDF4", +"g+ c #C4DBF2", +"h+ c #C9DCF2", +"i+ c #EBEBEB", +"j+ c #969FA9", +"k+ c #B2B7BC", +"l+ c #535F6D", +"m+ c #8CA1BB", +"n+ c #39396D", +"o+ c #3C3D70", +"p+ c #CCD9EA", +"q+ c #7D9AB9", +"r+ c #A2ACB8", +"s+ c #A6B7CB", +"t+ c #E1E8F0", +"u+ c #CBD4DD", +"v+ c #C3D4E7", +"w+ c #B0CDEC", +"x+ c #B2CEED", +"y+ c #AFCCEB", +"z+ c #ACC9EA", +"A+ c #A7C5E6", +"B+ c #D4D8DC", +"C+ c #F1F1F1", +"D+ c #D1D1D2", +"E+ c #B1B5BA", +"F+ c #546F90", +"G+ c #889EBD", +"H+ c #B9C8DE", +"I+ c #90B2D7", +"J+ c #86ABD4", +"K+ c #8DA2B8", +"L+ c #F3F3F4", +"M+ c #B8C9DC", +"N+ c #A5C4E6", +"O+ c #A3C2E5", +"P+ c #9FBFE3", +"Q+ c #99BBE0", +"R+ c #91AFCF", +"S+ c #BABEC3", +"T+ c #949AA1", +"U+ c #9FA6AD", +"V+ c #F9F9F9", +"W+ c #F5F5F5", +"X+ c #EAEAEA", +"Y+ c #DEDEDE", +"Z+ c #D3D3D3", +"`+ c #B3B5B6", +" @ c #426083", +".@ c #7C90B1", +"+@ c #383A6E", +"@@ c #3C3F71", +"#@ c #96A7C6", +"$@ c #9DB9DA", +"%@ c #7EA5D0", +"&@ c #C1D2E4", +"*@ c #FBFBFB", +"=@ c #B2C3D4", +"-@ c #9BBCE0", +";@ c #97B9DE", +">@ c #93B6DC", +",@ c #8FB2DA", +"'@ c #89AED6", +")@ c #799DC5", +"!@ c #79A0CC", +"~@ c #739CCA", +"{@ c #EBEDEE", +"]@ c #ECECEC", +"^@ c #848484", +"/@ c #393939", +"(@ c #2D2D2D", +"_@ c #0F1316", +":@ c #161F29", +"<@ c #4F5C7A", +"[@ c #393A6C", +"}@ c #646F99", +"|@ c #B1C8E1", +"1@ c #749DCB", +"2@ c #D6DDE4", +"3@ c #E8EAED", +"4@ c #98B1CE", +"5@ c #88ADD6", +"6@ c #83A9D3", +"7@ c #78A0CD", +"8@ c #719AC9", +"9@ c #6994C5", +"0@ c #A4ADB8", +"a@ c #707070", +"b@ c #7B7B7B", +"c@ c #D2D2D2", +"d@ c #BBBBBB", +"e@ c #707072", +"f@ c #12121D", +"g@ c #B2C6DF", +"h@ c #779ECA", +"i@ c #9DAEC0", +"j@ c #FAFAFA", +"k@ c #FBFCFC", +"l@ c #6C7C90", +"m@ c #7CA3CF", +"n@ c #6D98C7", +"o@ c #6792C4", +"p@ c #5F8DC0", +"q@ c #505A66", +"r@ c #858585", +"s@ c #BEBEBE", +"t@ c #3F3F3F", +"u@ c #1E1E1E", +"v@ c #1C1D1E", +"w@ c #4D4D4E", +"x@ c #B1B1B1", +"y@ c #6B7BA5", +"z@ c #9EBAD9", +"A@ c #6892C2", +"B@ c #C0C4C9", +"C@ c #F6F6F6", +"D@ c #CED0D3", +"E@ c #6589B1", +"F@ c #709AC9", +"G@ c #6C97C7", +"H@ c #6893C4", +"I@ c #638FC1", +"J@ c #5C8ABE", +"K@ c #5585BA", +"L@ c #343638", +"M@ c #C2C2C2", +"N@ c #212121", +"O@ c #BCBCBC", +"P@ c #909295", +"Q@ c #6C84A5", +"R@ c #525E89", +"S@ c #2E2E2E", +"T@ c #AAAAAA", +"U@ c #000000", +"V@ c #3C3F72", +"W@ c #9BB2D0", +"X@ c #80A3CC", +"Y@ c #5F88B6", +"Z@ c #CED0D2", +"`@ c #B4B8BB", +" # c #6089B7", +".# c #6490C2", +"+# c #618EC0", +"@# c #5D8ABE", +"## c #5886BB", +"$# c #5282B8", +"%# c #4B7DB5", +" c #2C2C2C", +"*# c #C0C0C0", +"=# c #191919", +"-# c #989A9C", +";# c #4C5E75", +"># c #7385A5", +",# c #393B6D", +"'# c #161616", +")# c #C1C0C0", +"!# c #474B7C", +"~# c #A1B9D5", +"{# c #6E96C4", +"]# c #B3BAC2", +"^# c #9EA3A8", +"/# c #48627E", +"(# c #5A89BD", +"_# c #5887BC", +":# c #5584BA", +"<# c #5181B8", +"[# c #4C7EB5", +"}# c #4779B2", +"|# c #28486D", +"1# c #141312", +"2# c #9B9794", +"3# c #201D1C", +"4# c #0B0B07", +"5# c #040302", +"6# c #050403", +"7# c #2F2921", +"8# c #A8A39E", +"9# c #1A130B", +"0# c #2F335E", +"a# c #4E5785", +"b# c #9CB5D3", +"c# c #A8B3C0", +"d# c #CDCDCD", +"e# c #CFCFCF", +"f# c #687685", +"g# c #4F80B7", +"h# c #4E7FB6", +"i# c #4C7DB5", +"j# c #497BB3", +"k# c #4678B1", +"l# c #4175AF", +"m# c #3E71AB", +"n# c #A59176", +"o# c #E0C4A0", +"p# c #DFC4A3", +"q# c #DABE9A", +"r# c #D6BA94", +"s# c #CDA676", +"t# c #815A2B", +"u# c #2E3058", +"v# c #444977", +"w# c #B4B9C4", +"x# c #8F949A", +"y# c #375A82", +"z# c #4376B0", +"A# c #4275AF", +"B# c #4074AE", +"C# c #3E72AC", +"D# c #3E6FA9", +"E# c #3D6CA4", +"F# c #3C699F", +"G# c #E2C5A1", +"H# c #D8B58C", +"I# c #CA9F68", +"J# c #AC8758", +"K# c #A78252", +"L# c #A78253", +"M# c #A37B4B", +"N# c #BC8849", +"O# c #AC712E", +"P# c #202040", +"Q# c #3A3B6D", +"R# c #6E718E", +"S# c #8697AD", +"T# c #81A0C4", +"U# c #648AB7", +"V# c #4E79AC", +"W# c #4672A6", +"X# c #3E6BA0", +"Y# c #446EA0", +"Z# c #4C71A1", +"`# c #5E7EA6", +" $ c #E3C6A2", +".$ c #D5AE7E", +"+$ c #B08D5F", +"@$ c #D5B284", +"#$ c #CFAB7C", +"$$ c #CFAC7B", +"%$ c #CBA471", +"&$ c #BC8746", +"*$ c #AA6F2B", +"=$ c #2A2B50", +"-$ c #505985", +";$ c #6D7FA6", +">$ c #7E93B6", +",$ c #869BBB", +"'$ c #8AA1BE", +")$ c #8297B6", +"!$ c #798CAC", +"~$ c #66759A", +"{$ c #E1C4A0", +"]$ c #D0A674", +"^$ c #C79B64", +"/$ c #AA8455", +"($ c #A47E4E", +"_$ c #A07744", +":$ c #BA8442", +"<$ c #1D1D37", +"[$ c #2F3057", +"}$ c #353765", +"|$ c #363969", +"1$ c #39396A", +"2$ c #363768", +"3$ c #343664", +"4$ c #2E2F56", +"5$ c #E1C29C", +"6$ c #CEA470", +"7$ c #AD8D64", +"8$ c #D2B289", +"9$ c #CDAC83", +"0$ c #CEAD83", +"a$ c #CCA77B", +"b$ c #B8803E", +"c$ c #AD7332", +"d$ c #E0C29E", +"e$ c #D4AC79", +"f$ c #CDA66E", +"g$ c #AF8D5E", +"h$ c #AB8758", +"i$ c #AB8858", +"j$ c #A8814C", +"k$ c #B47E3E", +"l$ c #D0A874", +"m$ c #C6965D", +"n$ c #BE8D50", +"o$ c #BA894B", +"p$ c #BD8C4E", +"q$ c #BC8A4C", +"r$ c #BA8647", +"s$ c #A47136", +" ", +" ", +" . + @ # $ % & ", +" * = - ; > , ' ) ! ~ { ] ^ ", +" / ( _ : < [ [ [ } | 1 2 3 4 5 ", +" 6 7 8 9 0 a b c d e f g h i j k l m ^ ", +" n o p q r s t u v w x y z A B C D E F ", +" G H I J K L M N O P Q R S T U V W X Y Z ` ", +" ., [ [ ..+.@.#.$.$.%.&.*.=.-.;.[ [ ;.>.,.'.). ", +" !.~.[ [ [ {.].^./././.(._.:.<.[.}.[ [ |.1.2.3. ", +" 4.H [ [ c 5.6.7.8.8.8.8.9.0.a.b.c.d.e.f.g.h.i.j.k. ", +" l.~.[ [ m.n.o.p.q.q.q.q.r.s.t.u.v.w.x.y.z.A.B.C.D. ", +" E.F.;.G.H.I.J.K.o.o.o.o.L.M.s.N.[ [ O.P.Q.R.h.S.T.U.V. ", +" W.X.Y.Z.`. +.+++@+@+@+#+$+%+&+[ [ [ [ [ [ *+=+-+;+>+,+ ", +" '+)+!+~+{+]+^+/+(+_+_+:+<+[+}+[ [ [ [ [ ;.+.|+1+2+3+4+ ", +" 5+6+7+8+9+0+a+b+c+d+e+f+g+h+[ [ [ [ [ [ X i+j+k+l+m+n+ ", +" o+p+q+r+s+t+u+v+w+x+a+y+z+A+B+[ [ [ [ ;.C+1.D+E+F+G+4+ ", +" & H+I+J+K+[ [ L+M+N+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@ ", +" @@#@$@%@&@[ [ [ *@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@ ", +" }@|@1@2@[ [ [ [ [ 3@4@5@6@%@7@8@9@0@a@b@c@B.B.d@e@f@ ", +" $ g@h@i@j@[ [ [ [ k@l@m@7@~@n@o@p@q@r@s@t@u@v@w@x@^@ ", +" y@z@A@B@|.C@V+j@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@ ", +" V@W@X@Y@Z@A.i+]@`@ #.#+#@###$#%#*#=#-#;#>#,#'#)#U@ ", +" !#~#{#]#B.i.^#/#(#_#:#<#[#}#|#1#2#3#4#5#5#6#7#8#9# ", +" 0#a#b#c#d#e#f#g#h#i#j#k#l#m#U@n#o#p#p#q#q#q#r#s#t#U@", +" u#v#w#1+x#y#z#A#B#C#D#E#F#U@G#H#I#J#K#K#L#M#N#O#U@", +" P#Q#R#S#T#U#V#W#X#Y#Z#`#U@ $.$+$@$#$#$$$%$&$*$U@", +" =$Q#-$;$>$,$'$)$!$~$U@{$]$^$/$($($($_$:$O#U@", +" <$[$}$|$1$2$3$4$U@5$6$7$8$9$9$0$a$b$c$U@", +" U@d$e$f$g$h$h$i$j$&$k$U@", +" U@l$m$n$n$o$o$p$q$r$s$U@", +" U@U@U@U@U@U@U@U@U@U@ "}; Added: trunk/gtk/unstable/src/icons/pkg-available.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-availa... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-available.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-available.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,505 @@ +/* XPM */ +static const char * pkg_available_xpm[] = { +"32 32 470 2", +" c None", +". c #3E4174", +"+ c #3F4275", +"@ c #3D3E71", +"# c #3A3B6C", +"$ c #3C3E71", +"% c #3E4074", +"& c #3C3F73", +"* c #3B3D71", +"= c #434475", +"- c #8588A7", +"; c #BFC4D6", +"> c #E3E7EE", +", c #F1F2F5", +"' c #F6F7F9", +") c #E0E6EF", +"! c #C6D2E4", +"~ c #A4B2CD", +"{ c #6B739B", +"] c #3E3F71", +"^ c #393B6F", +"/ c #3F4172", +"( c #A0A6C0", +"_ c #EAEEF2", +": c #D6DDE5", +"< c #D9DDE2", +"[ c #FEFEFE", +"} c #959BA2", +"| c #BFD4EA", +"1 c #C0D3E8", +"2 c #C6D7EA", +"3 c #C6D5E7", +"4 c #7A86AB", +"5 c #3D3E70", +"6 c #3D3D71", +"7 c #595B86", +"8 c #EAECF0", +"9 c #E8EBEE", +"0 c #CACED3", +"a c #C2CAD3", +"b c #DAE8F6", +"c c #FDFDFD", +"d c #C5C7C8", +"e c #8A9095", +"f c #ABBAC9", +"g c #BCD2EA", +"h c #B4CBE6", +"i c #ACC4E1", +"j c #DEE5ED", +"k c #EFF0F2", +"l c #C6CCD8", +"m c #4B4E7C", +"n c #74779C", +"o c #F1F2F4", +"p c #B4BBC3", +"q c #BEC9D5", +"r c #C4CDD7", +"s c #A4B0BC", +"t c #D7E5F2", +"u c #ACAEB1", +"v c #AAB7C6", +"w c #D0E1F4", +"x c #B5C1CE", +"y c #B6CAE0", +"z c #B9CFE9", +"A c #DFE6ED", +"B c #CDD0D3", +"C c #B5BDC5", +"D c #E5E6E8", +"E c #E8E9EC", +"F c #5D6188", +"G c #5A5D88", +"H c #FBFBFC", +"I c #C1CAD4", +"J c #CAE0F6", +"K c #FCFDFD", +"L c #E2E3E5", +"M c #D8E7F4", +"N c #E0EFFE", +"O c #D0DDEB", +"P c #DAEAFA", +"Q c #D5E5F7", +"R c #CDE0F3", +"S c #CBDEF1", +"T c #C2CEDB", +"U c #A9B6C4", +"V c #939BA4", +"W c #E5EAEE", +"X c #F7F7F7", +"Y c #EEEEEE", +"Z c #E7E7E9", +"` c #4C4E7A", +" . c #454677", +".. c #F1F2F3", +"+. c #ECECED", +"@. c #C3C4C6", +"#. c #AFB5BD", +"$. c #E2F0FF", +"%. c #DFEDFC", +"&. c #D8E8F9", +"*. c #D0E2F5", +"=. c #BFCEDF", +"-. c #C3C9CF", +";. c #FCFCFC", +">. c #EFEFEF", +",. c #E9E9E9", +"'. c #D3D3D8", +"). c #3D3F71", +"!. c #A5A8C0", +"~. c #FFFFFF", +"{. c #D2D3D5", +"]. c #ADB7C2", +"^. c #CDDAE6", +"/. c #E1F0FF", +"(. c #DAEAFB", +"_. c #D1E4F6", +":. c #CEDFF3", +"<. c #F0F1F3", +"[. c #F4F5F5", +"}. c #F8F9F9", +"|. c #F2F2F2", +"1. c #E5E5E5", +"2. c #E6E6E6", +"3. c #7D819A", +"4. c #424475", +"5. c #A3A6A8", +"6. c #9FABB6", +"7. c #D5E5F4", +"8. c #E0EFFF", +"9. c #DBEBFC", +"0. c #D1E4F7", +"a. c #EAEDF1", +"b. c #C8CACD", +"c. c #768697", +"d. c #A9B1BA", +"e. c #C2C5CA", +"f. c #E3E4E5", +"g. c #F4F4F4", +"h. c #E7E7E7", +"i. c #DDDDDD", +"j. c #DCDCDD", +"k. c #3C3E6E", +"l. c #8689A7", +"m. c #BBBDC0", +"n. c #B4C5D6", +"o. c #DEEEFF", +"p. c #DFEEFF", +"q. c #DFEFFF", +"r. c #D9EAFB", +"s. c #D0E3F6", +"t. c #BCC6D2", +"u. c #C6CBD1", +"v. c #D6DEE7", +"w. c #ABBED4", +"x. c #869DB7", +"y. c #819CB9", +"z. c #A1AAB4", +"A. c #E8E8E8", +"B. c #DBDBDB", +"C. c #E0E0E0", +"D. c #626487", +"E. c #3E4173", +"F. c #CDCEDA", +"G. c #CCCED0", +"H. c #CDCFD1", +"I. c #899CB0", +"J. c #CCE2FB", +"K. c #DCEDFF", +"L. c #DDEDFE", +"M. c #D5E7FA", +"N. c #EFF2F4", +"O. c #F0F1F2", +"P. c #F3F5F6", +"Q. c #DADFE5", +"R. c #E3E6E9", +"S. c #D3D3D4", +"T. c #D4D5D5", +"U. c #9A9BAB", +"V. c #3A3D6F", +"W. c #414476", +"X. c #EFEFF3", +"Y. c #818B96", +"Z. c #88A2BE", +"`. c #93A8C0", +" + c #B6D0EB", +".+ c #C4DDF7", +"++ c #D0E6FC", +"@+ c #DDEEFF", +"#+ c #DCEDFE", +"$+ c #D7E8FB", +"%+ c #CFE3F7", +"&+ c #E3E9F0", +"*+ c #B0B5BA", +"=+ c #C3C7CB", +"-+ c #CFD0D0", +";+ c #79899C", +">+ c #A3A7B2", +",+ c #37396B", +"'+ c #3F4072", +")+ c #F8F8FA", +"!+ c #95A9C0", +"~+ c #B2C8E0", +"{+ c #A9C7E8", +"]+ c #B2CFED", +"^+ c #BBD6F2", +"/+ c #C2DCF6", +"(+ c #CCE2F9", +"_+ c #D5E8FB", +":+ c #D3E6FA", +"<+ c #CEE2F7", +"[+ c #C8DDF3", +"}+ c #F7F8F8", +"|+ c #92A1B2", +"1+ c #D6D6D6", +"2+ c #CBCBCB", +"3+ c #8E9CAE", +"4+ c #393B6E", +"5+ c #3A3A6E", +"6+ c #E0E3E8", +"7+ c #ECEDEF", +"8+ c #C7CCD1", +"9+ c #9DBCDF", +"0+ c #AAC8E9", +"a+ c #B1CEED", +"b+ c #B8D3F0", +"c+ c #BCD6F3", +"d+ c #C0D9F4", +"e+ c #C5DCF4", +"f+ c #C7DDF4", +"g+ c #C4DBF2", +"h+ c #C9DCF2", +"i+ c #EBEBEB", +"j+ c #969FA9", +"k+ c #B2B7BC", +"l+ c #535F6D", +"m+ c #8CA1BB", +"n+ c #39396D", +"o+ c #3C3D70", +"p+ c #CCD9EA", +"q+ c #7D9AB9", +"r+ c #A2ACB8", +"s+ c #A6B7CB", +"t+ c #E1E8F0", +"u+ c #CBD4DD", +"v+ c #C3D4E7", +"w+ c #B0CDEC", +"x+ c #B2CEED", +"y+ c #AFCCEB", +"z+ c #ACC9EA", +"A+ c #A7C5E6", +"B+ c #D4D8DC", +"C+ c #F1F1F1", +"D+ c #D1D1D2", +"E+ c #B1B5BA", +"F+ c #546F90", +"G+ c #889EBD", +"H+ c #B9C8DE", +"I+ c #90B2D7", +"J+ c #86ABD4", +"K+ c #8DA2B8", +"L+ c #F3F3F4", +"M+ c #B8C9DC", +"N+ c #A5C4E6", +"O+ c #A3C2E5", +"P+ c #9FBFE3", +"Q+ c #99BBE0", +"R+ c #91AFCF", +"S+ c #BABEC3", +"T+ c #949AA1", +"U+ c #9FA6AD", +"V+ c #F9F9F9", +"W+ c #F5F5F5", +"X+ c #EAEAEA", +"Y+ c #DEDEDE", +"Z+ c #D3D3D3", +"`+ c #B3B5B6", +" @ c #426083", +".@ c #7C90B1", +"+@ c #383A6E", +"@@ c #3C3F71", +"#@ c #96A7C6", +"$@ c #9DB9DA", +"%@ c #7EA5D0", +"&@ c #C1D2E4", +"*@ c #FBFBFB", +"=@ c #B2C3D4", +"-@ c #9BBCE0", +";@ c #97B9DE", +">@ c #93B6DC", +",@ c #8FB2DA", +"'@ c #89AED6", +")@ c #799DC5", +"!@ c #79A0CC", +"~@ c #739CCA", +"{@ c #EBEDEE", +"]@ c #ECECEC", +"^@ c #E2E2E2", +"/@ c #D7D7D7", +"(@ c #CCCCCC", +"_@ c #475566", +":@ c #5E80A9", +"<@ c #68789F", +"[@ c #3A3B6D", +"}@ c #646F99", +"|@ c #B1C8E1", +"1@ c #749DCB", +"2@ c #D6DDE4", +"3@ c #E8EAED", +"4@ c #98B1CE", +"5@ c #88ADD6", +"6@ c #83A9D3", +"7@ c #78A0CD", +"8@ c #719AC9", +"9@ c #6994C5", +"0@ c #AFB9C5", +"a@ c #E3E3E3", +"b@ c #D9D9D9", +"c@ c #CECECE", +"d@ c #A2A5A8", +"e@ c #325784", +"f@ c #7691B3", +"g@ c #4E5682", +"h@ c #B2C6DF", +"i@ c #779ECA", +"j@ c #9DAEC0", +"k@ c #FAFAFA", +"l@ c #FBFCFC", +"m@ c #6C7C90", +"n@ c #7CA3CF", +"o@ c #6D98C7", +"p@ c #6792C4", +"q@ c #5F8DC0", +"r@ c #8DA1B8", +"s@ c #CFCFCF", +"t@ c #C5C5C5", +"u@ c #93969A", +"v@ c #446897", +"w@ c #7C92B1", +"x@ c #3B3C6E", +"y@ c #6B7BA5", +"z@ c #9EBAD9", +"A@ c #6892C2", +"B@ c #C0C4C9", +"C@ c #F6F6F6", +"D@ c #CED0D3", +"E@ c #6589B1", +"F@ c #709AC9", +"G@ c #6C97C7", +"H@ c #6893C4", +"I@ c #638FC1", +"J@ c #5C8ABE", +"K@ c #5585BA", +"L@ c #92A7BE", +"M@ c #BCBCBC", +"N@ c #909295", +"O@ c #6C84A5", +"P@ c #525E89", +"Q@ c #3C3F72", +"R@ c #9BB2D0", +"S@ c #80A3CC", +"T@ c #5F88B6", +"U@ c #CED0D2", +"V@ c #B4B8BB", +"W@ c #6089B7", +"X@ c #6490C2", +"Y@ c #618EC0", +"Z@ c #5D8ABE", +"`@ c #5886BB", +" # c #5282B8", +".# c #4B7DB5", +"+# c #889AAF", +"@# c #C3C3C3", +"## c #BBBBBB", +"$# c #989A9C", +"%# c #4C5E75", +" c #7385A5", +"*# c #393B6D", +"=# c #474B7C", +"-# c #A1B9D5", +";# c #6E96C4", +"># c #B3BAC2", +",# c #9EA3A8", +"'# c #48627E", +")# c #5A89BD", +"!# c #5887BC", +"~# c #5584BA", +"{# c #5181B8", +"]# c #4C7EB5", +"^# c #4779B2", +"/# c #4174AF", +"(# c #597DA6", +"_# c #B8B8B8", +":# c #B0B0B0", +"<# c #898B8F", +"[# c #798BA8", +"}# c #3F4371", +"|# c #2F335E", +"1# c #4E5785", +"2# c #9CB5D3", +"3# c #A8B3C0", +"4# c #CDCDCD", +"5# c #687685", +"6# c #4F80B7", +"7# c #4E7FB6", +"8# c #4C7DB5", +"9# c #497BB3", +"0# c #4678B1", +"a# c #4175AF", +"b# c #3E71AB", +"c# c #3D6DA5", +"d# c #3D699E", +"e# c #A4A5A7", +"f# c #ACADAD", +"g# c #7B8392", +"h# c #464B78", +"i# c #2C2D56", +"j# c #2E3058", +"k# c #444977", +"l# c #B4B9C4", +"m# c #8F949A", +"n# c #375A82", +"o# c #4376B0", +"p# c #4275AF", +"q# c #4074AE", +"r# c #3E72AC", +"s# c #3E6FA9", +"t# c #3D6CA4", +"u# c #3C699F", +"v# c #3B6599", +"w# c #496D9B", +"x# c #7D8899", +"y# c #6D788E", +"z# c #2A2B51", +"A# c #202040", +"B# c #6E718E", +"C# c #8697AD", +"D# c #81A0C4", +"E# c #648AB7", +"F# c #4E79AC", +"G# c #4672A6", +"H# c #3E6BA0", +"I# c #446EA0", +"J# c #4C71A1", +"K# c #5E7EA6", +"L# c #758DAF", +"M# c #7E91B0", +"N# c #565E87", +"O# c #38396B", +"P# c #1D1D38", +"Q# c #2A2B50", +"R# c #505985", +"S# c #6D7FA6", +"T# c #7E93B6", +"U# c #869BBB", +"V# c #8AA1BE", +"W# c #8297B6", +"X# c #798CAC", +"Y# c #66759A", +"Z# c #4B517C", +"`# c #3A3B6B", +" $ c #292A4D", +".$ c #1D1D37", +"+$ c #2F3057", +"@$ c #353765", +"#$ c #363969", +"$$ c #39396A", +"%$ c #363768", +"&$ c #343664", +"*$ c #2E2F56", +"=$ c #1B1B35", +" ", +" ", +" . + @ # $ % & ", +" * = - ; > , ' ) ! ~ { ] ^ ", +" / ( _ : < [ [ [ } | 1 2 3 4 5 ", +" 6 7 8 9 0 a b c d e f g h i j k l m ^ ", +" n o p q r s t u v w x y z A B C D E F ", +" G H I J K L M N O P Q R S T U V W X Y Z ` ", +" ., [ [ ..+.@.#.$.$.%.&.*.=.-.;.[ [ ;.>.,.'.). ", +" !.~.[ [ [ {.].^./././.(._.:.<.[.}.[ [ |.1.2.3. ", +" 4.H [ [ c 5.6.7.8.8.8.8.9.0.a.b.c.d.e.f.g.h.i.j.k. ", +" l.~.[ [ m.n.o.p.q.q.q.q.r.s.t.u.v.w.x.y.z.A.B.C.D. ", +" E.F.;.G.H.I.J.K.o.o.o.o.L.M.s.N.[ [ O.P.Q.R.h.S.T.U.V. ", +" W.X.Y.Z.`. +.+++@+@+@+#+$+%+&+[ [ [ [ [ [ *+=+-+;+>+,+ ", +" '+)+!+~+{+]+^+/+(+_+_+:+<+[+}+[ [ [ [ [ ;.+.|+1+2+3+4+ ", +" 5+6+7+8+9+0+a+b+c+d+e+f+g+h+[ [ [ [ [ [ X i+j+k+l+m+n+ ", +" o+p+q+r+s+t+u+v+w+x+a+y+z+A+B+[ [ [ [ ;.C+1.D+E+F+G+4+ ", +" & H+I+J+K+[ [ L+M+N+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@ ", +" @@#@$@%@&@[ [ [ *@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@ ", +" }@|@1@2@[ [ [ [ [ 3@4@5@6@%@7@8@9@0@a@b@c@d@e@f@g@ ", +" $ h@i@j@k@[ [ [ [ l@m@n@7@~@o@p@q@r@b@s@t@u@v@w@x@ ", +" y@z@A@B@|.C@V+k@D@E@F@G@H@I@J@K@L@c@t@M@N@O@P@ ", +" Q@R@S@T@U@A.i+]@V@W@X@Y@Z@`@ #.#+#@###$#%#*# ", +" =#-#;#>#B.i.,#'#)#!#~#{#]#^#/#(#_#:#<#[#}# ", +" |#1#2#3#4#s@5#6#7#8#9#0#a#b#c#d#e#f#g#h#i# ", +" j#k#l#1+m#n#o#p#q#r#s#t#u#v#w#x#y#}#z# ", +" A#[@B#C#D#E#F#G#H#I#J#K#L#M#N#O#P# ", +" Q#[@R#S#T#U#V#W#X#Y#Z#`# $ ", +" .$+$@$#$$$%$&$*$=$ ", +" ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-install-auto.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-install-auto.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-install-auto.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,325 @@ +/* XPM */ +static const char * pkg_install_auto_xpm[] = { +"32 32 290 2", +" c None", +". c #1F4B8A", +"+ c #214C89", +"@ c #214C8A", +"# c #214D8A", +"$ c #204A88", +"% c #204B88", +"& c #2B558F", +"* c #5B80AF", +"= c #7998C0", +"- c #89A6C9", +"; c #85A2C6", +"> c #698AB5", +", c #355D95", +"' c #1F4C89", +") c #5377A7", +"! c #8AA5CA", +"~ c #8BA7CB", +"{ c #90ABCE", +"] c #93ADCE", +"^ c #96AFD0", +"/ c #98B1D1", +"( c #99B2D1", +"_ c #6C8CB6", +": c #234E89", +"< c #1F4987", +"[ c #5B7CAA", +"} c #5B7CAB", +"| c #41669C", +"1 c #446BA0", +"2 c #6283B2", +"3 c #90ABCD", +"4 c #93ADCF", +"5 c #8CA7CC", +"6 c #8AA6CB", +"7 c #94ADCF", +"8 c #7C99C1", +"9 c #325A91", +"0 c #2D558F", +"a c #1F4C87", +"b c #214C88", +"c c #315891", +"d c #86A2C7", +"e c #8DA9CC", +"f c #84A1C8", +"g c #809FC6", +"h c #6587B3", +"i c #204B8B", +"j c #224C88", +"k c #325C93", +"l c #7F9EC6", +"m c #7B9BC4", +"n c #7A9AC3", +"o c #91ACCE", +"p c #305991", +"q c #1E4A86", +"r c #204A8A", +"s c #6A8BB7", +"t c #83A1C8", +"u c #7697C2", +"v c #7395C1", +"w c #86A3C9", +"x c #6183B1", +"y c #1F4A87", +"z c #545454", +"A c #595959", +"B c #5C5C5C", +"C c #4D5766", +"D c #446798", +"E c #89A5CB", +"F c #7193BF", +"G c #6D90BE", +"H c #7797C2", +"I c #7F9DC4", +"J c #284E83", +"K c #5B5B5B", +"L c #585858", +"M c #535353", +"N c #AFAFAF", +"O c #FCFCFC", +"P c #FEFEFE", +"Q c #FDFDFD", +"R c #F0F2F5", +"S c #6B8FBD", +"T c #698DBC", +"U c #6A8EBD", +"V c #8EA9CC", +"W c #2A528D", +"X c #F6F6F6", +"Y c #F5F5F5", +"Z c #F4F4F4", +"` c #F3F3F3", +" . c #F2F2F2", +".. c #959595", +"+. c #AFBCCE", +"@. c #8CA8CC", +"#. c #658ABA", +"$. c #6388B9", +"%. c #6187B8", +"&. c #95AECF", +"*. c #6F89AD", +"=. c #DEDEDE", +"-. c #979797", +";. c #F8F8F8", +">. c #E5E5E5", +",. c #9CADC3", +"'. c #385E95", +"). c #7A99C2", +"!. c #8DA8CC", +"~. c #5F85B8", +"{. c #5D84B7", +"]. c #5B82B6", +"^. c #94AFCF", +"/. c #97B0D0", +"(. c #6182B0", +"_. c #486A9B", +":. c #D9DADB", +"<. c #EDEDED", +"[. c #7E7E7E", +"}. c #DFDFDF", +"|. c #ECECEC", +"1. c #E0E0E0", +"2. c #E3E3E3", +"3. c #869BB9", +"4. c #3A6198", +"5. c #7B9AC3", +"6. c #5A82B5", +"7. c #5981B5", +"8. c #5880B4", +"9. c #4E79B0", +"0. c #4370AB", +"a. c #3969A7", +"b. c #6C8FBE", +"c. c #6889B6", +"d. c #345A90", +"e. c #CACDD2", +"f. c #D7D7D7", +"g. c #E2E2E2", +"h. c #C3C3C3", +"i. c #696969", +"j. c #FAFAFA", +"k. c #E1E1E1", +"l. c #E4E4E4", +"m. c #E7E7E7", +"n. c #6C87AC", +"o. c #42699C", +"p. c #7B9BC3", +"q. c #5881B5", +"r. c #4A76AE", +"s. c #416EAA", +"t. c #3666A5", +"u. c #3364A4", +"v. c #5C83B6", +"w. c #7493BE", +"x. c #2D568F", +"y. c #BBC3CE", +"z. c #DCDCDC", +"A. c #D9D9D9", +"B. c #E9E9E9", +"C. c #5F5F5F", +"D. c #BDBDBD", +"E. c #F0F0F0", +"F. c #E0E1E2", +"G. c #5A78A3", +"H. c #426A9F", +"I. c #3A69A7", +"J. c #4D78B0", +"K. c #7D9CC4", +"L. c #315992", +"M. c #A2B0C2", +"N. c #DBDBDB", +"O. c #DADADA", +"P. c #D8D8D8", +"Q. c #A2A2A2", +"R. c #555555", +"S. c #DDDDDD", +"T. c #D8D9DA", +"U. c #486A9A", +"V. c #476EA2", +"W. c #6F92BF", +"X. c #416FAA", +"Y. c #82A0C7", +"Z. c #3C6298", +"`. c #7E93B1", +" + c #919191", +".+ c #D6D6D6", +"++ c #CCCED2", +"@+ c #395E93", +"#+ c #557AAC", +"$+ c #7092BF", +"%+ c #3D6CA9", +"&+ c #7E9DC6", +"*+ c #4A70A2", +"=+ c #58769F", +"-+ c #D0D0D0", +";+ c #D1D1D1", +">+ c #D2D2D2", +",+ c #D4D4D4", +"'+ c #7F7F7F", +")+ c #D5D5D5", +"!+ c #BABFC6", +"~+ c #2F578E", +"{+ c #5E82B1", +"]+ c #89A5CA", +"^+ c #597CAD", +"/+ c #3C6093", +"(+ c #C1C3C5", +"_+ c #CACACA", +":+ c #CCCCCC", +"<+ c #CDCDCD", +"[+ c #676767", +"}+ c #CECECE", +"|+ c #C8C8C8", +"1+ c #AEB4BD", +"2+ c #2B538C", +"3+ c #4D72A6", +"4+ c #2B548D", +"5+ c #B0B5BB", +"6+ c #C4C4C4", +"7+ c #C6C6C6", +"8+ c #D3D3D3", +"9+ c #626262", +"0+ c #B6B6B6", +"a+ c #EBEBEB", +"b+ c #CFCFCF", +"c+ c #CBCBCB", +"d+ c #A2ABB8", +"e+ c #9D9D9D", +"f+ c #555753", +"g+ c #575955", +"h+ c #CDD0D5", +"i+ c #575757", +"j+ c #DBDCDA", +"k+ c #BABBB9", +"l+ c #585A56", +"m+ c #E8E8E8", +"n+ c #DCDDDB", +"o+ c #BBBCBA", +"p+ c #595B57", +"q+ c #B7B7B7", +"r+ c #5A5C58", +"s+ c #B0B0B0", +"t+ c #B4B4B4", +"u+ c #B3B3B3", +"v+ c #B2B2B2", +"w+ c #B1B1B1", +"x+ c #AEAEAE", +"y+ c #ADADAD", +"z+ c #ACACAC", +"A+ c #ABABAB", +"B+ c #AAAAAA", +"C+ c #A8A8A8", +"D+ c #A7A7A7", +"E+ c #A6A6A6", +"F+ c #A5A5A5", +"G+ c #A4A4A4", +"H+ c #A1A1A1", +"I+ c #A0A0A0", +"J+ c #9F9F9F", +"K+ c #B9B9B9", +"L+ c #565854", +"M+ c #DDDEDC", +"N+ c #989898", +"O+ c #C5C5C5", +"P+ c #949494", +"Q+ c #C2C2C2", +"R+ c #929292", +"S+ c #C1C1C1", +"T+ c #909090", +"U+ c #BFBFBF", +"V+ c #DCDDDA", +"W+ c #C0C1BF", +"X+ c #C1C2C0", +"Y+ c #969696", +"Z+ c #C0C0C0", +"`+ c #8F8F8F", +" @ c #C4C5C3", +".@ c #C3C4C2", +"+@ c #A9A9A9", +"@@ c #939393", +"#@ c #CCCDCB", +"$@ c #525252", +"%@ c #D4D5D3", +"&@ c #C9C9C9", +"*@ c #C7C7C7", +"=@ c #BBBBBB", +"-@ c #515151", +";@ c #D7D8D6", +">@ c #505050", +",@ c #D3D4D2", +" ", +" . + @ # $ ", +" % & * = - ; > , ' ", +" % ) ! ~ { ] ^ / ( _ : ", +" < [ } | 1 2 3 4 5 6 7 8 # ", +" 9 0 a b c d e f g 3 h i ", +" < j k 3 l m n o p ", +" q r s t u v w x y ", +" z A B B B B C D E F G H I J B K K K L M ", +" M N O P Q Q O R c ~ S T U V W X Y Z ` ... ", +" z Y +.y y y y y : @.#.$.%.&.y y y y y *.=.M ", +" -.;.>.,.'.).t w 6 !.~.{.].^./.( / (._.:.<.[. ", +" M }.|.1.2.3.4.5.#.].6.7.8.9.0.a.b.c.d.e.f.g.h.M ", +" i.j.k.l.m.m.n.o.p.q.r.s.t.u.u.v.w.x.y.z.A.A.B.C. ", +" z D.E.k.>.>.l.F.G.H.U I.u.u.u.J.K.L.M.z.N.O.P.l.Q. ", +" R.E.l.>.l.g.1.S.T.U.V.W.a.u.X.Y.Z.`.P.A.O.O.O.O.P.M ", +" +Y z.m.1.z.A..+.+++@+#+$+%+&+*+=+-+;+>+,+.+=.,+>.'+ ", +" M P.m.z.2.}..+)+)+,+;+!+~+{+]+^+/+(+_+:+<+-+P.N.>+N.D.z ", +" [+Y z.A.f.}.}.f.,+;+}+|+1+2+3+4+5+6+7+_+<+P.A.<+-+8+1.9+ ", +" 0+a+P.f.f..+O.g.=.f.b+c+|+d+y d+7+_+-+f.O.>+}+b+>+P.S.e+ ", +" M B.1.f+g+f+f+>+)+.+A.z.z.N.O.h+A.N.A.f.-+}+b+;+8+g.X O.8+i+ ", +" M X z.g+j+k+l+.+z.N.A.P.f..+,+,+,+)+.+f.f.P.P.P.f..+f.)+m+R. ", +" M E.1.g+n+o+p+P.}.=.S.S.S.z.z.N.N.O.O.O.A.P.f.f..+.+)+)+-+M ", +" M B.q+f+n+o+r+s+t+u+v+w+N x+y+z+A+B+C+D+E+F+G+Q.H+I+J+J+K+M ", +"f+f+f+L+r+M+o+p+f+f+f+f+B+z+y+x+A+B+N+O+-.h.P+Q+R+S+T+U+J+q+M ", +"f+V+n+M+n+n+W+W+W+W+X+f+B+A+y+y+A+B+N+O+Y+h.P+Q+ +Z+`+U+J+t+M ", +"f+j+ @.@.@.@.@.@.@.@.@f+B+A+y+z+B++@N+O+Y+h.@@S+ +Z+`+U+J+v+M ", +"f+f+f+f+f+#@#@l+f+f+f+f+y+B+z+z+B++@-.6+..h.@@S+T+U+`+U+I+x+M ", +" $@O+k.f+%@%@l+)+f.)+8+;+b+<+c+&@*@6+Q+U+D.=@K+0+t+v+w+N ..-@ ", +" -@M f+;@;@L+M M M M M M M M M M M M M M M M M M M M M >@ ", +" f+,@,@g+ ", +" L+g+g+L+ "}; Added: trunk/gtk/unstable/src/icons/pkg-install.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-install.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-install.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,318 @@ +/* XPM */ +static const char * pkg_install_xpm[] = { +"32 32 283 2", +" c None", +". c #1F4B8A", +"+ c #214C89", +"@ c #214C8A", +"# c #214D8A", +"$ c #204A88", +"% c #204B88", +"& c #2B558F", +"* c #5B80AF", +"= c #7998C0", +"- c #89A6C9", +"; c #85A2C6", +"> c #698AB5", +", c #355D95", +"' c #1F4C89", +") c #5377A7", +"! c #8AA5CA", +"~ c #8BA7CB", +"{ c #90ABCE", +"] c #93ADCE", +"^ c #96AFD0", +"/ c #98B1D1", +"( c #99B2D1", +"_ c #6C8CB6", +": c #234E89", +"< c #1F4987", +"[ c #5B7CAA", +"} c #5B7CAB", +"| c #41669C", +"1 c #446BA0", +"2 c #6283B2", +"3 c #90ABCD", +"4 c #93ADCF", +"5 c #8CA7CC", +"6 c #8AA6CB", +"7 c #94ADCF", +"8 c #7C99C1", +"9 c #325A91", +"0 c #2D558F", +"a c #1F4C87", +"b c #214C88", +"c c #315891", +"d c #86A2C7", +"e c #8DA9CC", +"f c #84A1C8", +"g c #809FC6", +"h c #6587B3", +"i c #204B8B", +"j c #224C88", +"k c #325C93", +"l c #7F9EC6", +"m c #7B9BC4", +"n c #7A9AC3", +"o c #91ACCE", +"p c #305991", +"q c #1E4A86", +"r c #204A8A", +"s c #6A8BB7", +"t c #83A1C8", +"u c #7697C2", +"v c #7395C1", +"w c #86A3C9", +"x c #6183B1", +"y c #1F4A87", +"z c #545454", +"A c #595959", +"B c #5C5C5C", +"C c #4D5766", +"D c #446798", +"E c #89A5CB", +"F c #7193BF", +"G c #6D90BE", +"H c #7797C2", +"I c #7F9DC4", +"J c #284E83", +"K c #5B5B5B", +"L c #585858", +"M c #535353", +"N c #AFAFAF", +"O c #FCFCFC", +"P c #FEFEFE", +"Q c #FDFDFD", +"R c #F0F2F5", +"S c #6B8FBD", +"T c #698DBC", +"U c #6A8EBD", +"V c #8EA9CC", +"W c #2A528D", +"X c #F6F6F6", +"Y c #F5F5F5", +"Z c #F4F4F4", +"` c #F3F3F3", +" . c #F2F2F2", +".. c #959595", +"+. c #AFBCCE", +"@. c #8CA8CC", +"#. c #658ABA", +"$. c #6388B9", +"%. c #6187B8", +"&. c #95AECF", +"*. c #6F89AD", +"=. c #DEDEDE", +"-. c #979797", +";. c #F8F8F8", +">. c #E5E5E5", +",. c #9CADC3", +"'. c #385E95", +"). c #7A99C2", +"!. c #8DA8CC", +"~. c #5F85B8", +"{. c #5D84B7", +"]. c #5B82B6", +"^. c #94AFCF", +"/. c #97B0D0", +"(. c #6182B0", +"_. c #486A9B", +":. c #D9DADB", +"<. c #EDEDED", +"[. c #7E7E7E", +"}. c #DFDFDF", +"|. c #ECECEC", +"1. c #E0E0E0", +"2. c #E3E3E3", +"3. c #869BB9", +"4. c #3A6198", +"5. c #7B9AC3", +"6. c #5A82B5", +"7. c #5981B5", +"8. c #5880B4", +"9. c #4E79B0", +"0. c #4370AB", +"a. c #3969A7", +"b. c #6C8FBE", +"c. c #6889B6", +"d. c #345A90", +"e. c #CACDD2", +"f. c #D7D7D7", +"g. c #E2E2E2", +"h. c #C3C3C3", +"i. c #696969", +"j. c #FAFAFA", +"k. c #E1E1E1", +"l. c #E4E4E4", +"m. c #E7E7E7", +"n. c #6C87AC", +"o. c #42699C", +"p. c #7B9BC3", +"q. c #5881B5", +"r. c #4A76AE", +"s. c #416EAA", +"t. c #3666A5", +"u. c #3364A4", +"v. c #5C83B6", +"w. c #7493BE", +"x. c #2D568F", +"y. c #BBC3CE", +"z. c #DCDCDC", +"A. c #D9D9D9", +"B. c #E9E9E9", +"C. c #5F5F5F", +"D. c #BDBDBD", +"E. c #F0F0F0", +"F. c #E0E1E2", +"G. c #5A78A3", +"H. c #426A9F", +"I. c #3A69A7", +"J. c #4D78B0", +"K. c #7D9CC4", +"L. c #315992", +"M. c #A2B0C2", +"N. c #DBDBDB", +"O. c #DADADA", +"P. c #D8D8D8", +"Q. c #A2A2A2", +"R. c #555555", +"S. c #DDDDDD", +"T. c #D8D9DA", +"U. c #486A9A", +"V. c #476EA2", +"W. c #6F92BF", +"X. c #416FAA", +"Y. c #82A0C7", +"Z. c #3C6298", +"`. c #7E93B1", +" + c #919191", +".+ c #D6D6D6", +"++ c #CCCED2", +"@+ c #395E93", +"#+ c #557AAC", +"$+ c #7092BF", +"%+ c #3D6CA9", +"&+ c #7E9DC6", +"*+ c #4A70A2", +"=+ c #58769F", +"-+ c #D0D0D0", +";+ c #D1D1D1", +">+ c #D2D2D2", +",+ c #D4D4D4", +"'+ c #7F7F7F", +")+ c #D5D5D5", +"!+ c #BABFC6", +"~+ c #2F578E", +"{+ c #5E82B1", +"]+ c #89A5CA", +"^+ c #597CAD", +"/+ c #3C6093", +"(+ c #C1C3C5", +"_+ c #CACACA", +":+ c #CCCCCC", +"<+ c #CDCDCD", +"[+ c #676767", +"}+ c #CECECE", +"|+ c #C8C8C8", +"1+ c #AEB4BD", +"2+ c #2B538C", +"3+ c #4D72A6", +"4+ c #2B548D", +"5+ c #B0B5BB", +"6+ c #C4C4C4", +"7+ c #C6C6C6", +"8+ c #D3D3D3", +"9+ c #626262", +"0+ c #B6B6B6", +"a+ c #EBEBEB", +"b+ c #CFCFCF", +"c+ c #CBCBCB", +"d+ c #A2ABB8", +"e+ c #9D9D9D", +"f+ c #F7F7F7", +"g+ c #CDD0D5", +"h+ c #575757", +"i+ c #E8E8E8", +"j+ c #BABABA", +"k+ c #B9B9B9", +"l+ c #B8B8B8", +"m+ c #B7B7B7", +"n+ c #B5B5B5", +"o+ c #B4B4B4", +"p+ c #B3B3B3", +"q+ c #B2B2B2", +"r+ c #B1B1B1", +"s+ c #AEAEAE", +"t+ c #ADADAD", +"u+ c #ACACAC", +"v+ c #ABABAB", +"w+ c #AAAAAA", +"x+ c #A8A8A8", +"y+ c #A7A7A7", +"z+ c #A6A6A6", +"A+ c #A5A5A5", +"B+ c #A4A4A4", +"C+ c #A1A1A1", +"D+ c #A0A0A0", +"E+ c #9F9F9F", +"F+ c #EAEAEA", +"G+ c #848484", +"H+ c #8A8A8A", +"I+ c #929292", +"J+ c #999999", +"K+ c #9E9E9E", +"L+ c #A3A3A3", +"M+ c #989898", +"N+ c #C5C5C5", +"O+ c #949494", +"P+ c #C2C2C2", +"Q+ c #C1C1C1", +"R+ c #909090", +"S+ c #BFBFBF", +"T+ c #878787", +"U+ c #969696", +"V+ c #C0C0C0", +"W+ c #8F8F8F", +"X+ c #8E8E8E", +"Y+ c #8C8C8C", +"Z+ c #A9A9A9", +"`+ c #939393", +" @ c #B0B0B0", +".@ c #525252", +"+@ c #C9C9C9", +"@@ c #C7C7C7", +"#@ c #BBBBBB", +"$@ c #515151", +"%@ c #505050", +" ", +" . + @ # $ ", +" % & * = - ; > , ' ", +" % ) ! ~ { ] ^ / ( _ : ", +" < [ } | 1 2 3 4 5 6 7 8 # ", +" 9 0 a b c d e f g 3 h i ", +" < j k 3 l m n o p ", +" q r s t u v w x y ", +" z A B B B B C D E F G H I J B K K K L M ", +" M N O P Q Q O R c ~ S T U V W X Y Z ` ... ", +" z Y +.y y y y y : @.#.$.%.&.y y y y y *.=.M ", +" -.;.>.,.'.).t w 6 !.~.{.].^./.( / (._.:.<.[. ", +" M }.|.1.2.3.4.5.#.].6.7.8.9.0.a.b.c.d.e.f.g.h.M ", +" i.j.k.l.m.m.n.o.p.q.r.s.t.u.u.v.w.x.y.z.A.A.B.C. ", +" z D.E.k.>.>.l.F.G.H.U I.u.u.u.J.K.L.M.z.N.O.P.l.Q. ", +" R.E.l.>.l.g.1.S.T.U.V.W.a.u.X.Y.Z.`.P.A.O.O.O.O.P.M ", +" +Y z.m.1.z.A..+.+++@+#+$+%+&+*+=+-+;+>+,+.+=.,+>.'+ ", +" M P.m.z.2.}..+)+)+,+;+!+~+{+]+^+/+(+_+:+<+-+P.N.>+N.D.z ", +" [+Y z.A.f.}.}.f.,+;+}+|+1+2+3+4+5+6+7+_+<+P.A.<+-+8+1.9+ ", +" 0+a+S.O.P..+O.g.=.f.b+c+|+d+y d+7+_+-+f.O.>+}+b+>+P.S.e+ ", +" M B.k.f+m.O.A..+)+.+A.z.z.N.O.g+A.N.A.f.-+}+b+;+8+g.X O.8+h+ ", +" M X z.S.N.z.z.z.z.N.A.P.f..+,+,+,+)+.+f.f.P.P.P.f..+f.)+i+R. ", +" M E.1.k.k.1.1.}.}.=.S.S.S.z.z.N.N.O.O.O.A.P.f.f..+.+)+)+-+M ", +" M |.j+j+k+l+m+n+o+p+q+r+N s+t+u+v+w+x+y+z+A+B+Q.C+D+E+E+k+M ", +" M F+j+j+G+H+I+J+K+L+y+w+u+t+s+v+w+M+N+-.h.O+P+I+Q+R+S+E+m+M ", +" M B.j+k+T+H+I+J+K+L+y+w+v+t+t+v+w+M+N+U+h.O+P+ +V+W+S+E+o+M ", +" M m.j+k+X+Y+I+J+K+L+y+w+v+t+u+w+Z+M+N+U+h.`+Q+ +V+W+S+E+q+M ", +" M l.j+l+l+n+k+p+ @N u+t+w+u+u+w+Z+-.6+..h.`+Q+R+S+W+S+D+s+M ", +" .@N+k.1.=.z.N.A.f.)+8+;+b+<+c++@@@6+P+S+D.#@k+0+o+q+r+N ..$@ ", +" $@M M M M M M M M M M M M M M M M M M M M M M M M M M %@ ", +" ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-installed-locked.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-installed-locked.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-installed-locked.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,595 @@ +/* XPM */ +static const char * pkg_installed_locked_xpm[] = { +"32 32 560 2", +" c None", +". c #949594", +"+ c #909090", +"@ c #8F8F8F", +"# c #8D8D8D", +"$ c #8B8B8B", +"% c #898989", +"& c #878787", +"* c #868686", +"= c #848484", +"- c #828282", +"; c #808080", +"> c #7E7E7E", +", c #7D7D7D", +"' c #7B7B7B", +") c #797979", +"! c #777777", +"~ c #7C7C7C", +"{ c #959595", +"] c #F1F2EF", +"^ c #F5F6F3", +"/ c #F4F5F3", +"( c #F4F5F2", +"_ c #F4F4F2", +": c #F3F4F2", +"< c #F3F4F1", +"[ c #F2F4F1", +"} c #F2F3F1", +"| c #EDEEEB", +"1 c #A2A2A2", +"2 c #F2F3F0", +"3 c #B9BBC8", +"4 c #3E3F8E", +"5 c #545592", +"6 c #535491", +"7 c #525290", +"8 c #515190", +"9 c #52528F", +"0 c #51518F", +"a c #50508F", +"b c #51518E", +"c c #53548D", +"d c #52538D", +"e c #52528B", +"f c #51518B", +"g c #53538D", +"h c #55568E", +"i c #54548E", +"j c #55558E", +"k c #54548D", +"l c #535494", +"m c #D4D7D0", +"n c #EEF0ED", +"o c #858685", +"p c #AAAAA9", +"q c #F0F2EE", +"r c #A7AAC0", +"s c #6A6A91", +"t c #7E7E96", +"u c #7D7D95", +"v c #7C7C94", +"w c #7A7A93", +"x c #797992", +"y c #777790", +"z c #767690", +"A c #75758F", +"B c #74748D", +"C c #73738D", +"D c #71718B", +"E c #70708B", +"F c #6F6F8A", +"G c #6D6D88", +"H c #6B6B86", +"I c #6A6A85", +"J c #696985", +"K c #494A8B", +"L c #A4A5A2", +"M c #CFD1CF", +"N c #8D8E8D", +"O c #AFB0AF", +"P c #EFF0ED", +"Q c #9697B8", +"R c #67678C", +"S c #6E6E89", +"T c #686884", +"U c #676783", +"V c #666683", +"W c #656582", +"X c #646482", +"Y c #636380", +"Z c #626280", +"` c #454688", +" . c #D3D6CF", +".. c #EAECE8", +"+. c #959695", +"@. c #B8B8B7", +"#. c #EEEFEB", +"$. c #8284AD", +"%. c #646488", +"&. c #6A6A86", +"*. c #676784", +"=. c #646481", +"-. c #616180", +";. c #61617F", +">. c #5F5F7F", +",. c #5F5F7E", +"'. c #535375", +"). c #3F4084", +"!. c #B2B4B0", +"~. c #B7B8B7", +"{. c #9B9C9B", +"]. c #BFBFBE", +"^. c #ECEDE9", +"/. c #7173A4", +"(. c #646486", +"_. c #696986", +":. c #676785", +"<. c #666684", +"[. c #656583", +"}. c #646483", +"|. c #636381", +"1. c #626281", +"2. c #616181", +"3. c #606080", +"4. c #60607F", +"5. c #5E5E7E", +"6. c #5B5B7D", +"7. c #49496E", +"8. c #36365F", +"9. c #292954", +"0. c #242450", +"a. c #373880", +"b. c #D2D5CE", +"c. c #E5E7E3", +"d. c #A4A5A3", +"e. c #C5C5C3", +"f. c #EAECE7", +"g. c #61639D", +"h. c #5F5F80", +"i. c #5D5D7F", +"j. c #5C5C7E", +"k. c #565679", +"l. c #3E3E66", +"m. c #2A2A56", +"n. c #272754", +"o. c #282855", +"p. c #34357E", +"q. c #B8BBB6", +"r. c #ACADAB", +"s. c #CACBC9", +"t. c #E8EAE5", +"u. c #575998", +"v. c #606081", +"w. c #5E5E80", +"x. c #5C5C7F", +"y. c #5B5B7E", +"z. c #5A5A7E", +"A. c #5A5A7D", +"B. c #58587C", +"C. c #545479", +"D. c #3F3F69", +"E. c #2C2C59", +"F. c #2A2A58", +"G. c #2B2B59", +"H. c #2B2B5A", +"I. c #2C2C5A", +"J. c #2C2C5B", +"K. c #30317C", +"L. c #D0D4CD", +"M. c #E0E2DD", +"N. c #B0B1AF", +"O. c #8C8C8C", +"P. c #CFD0CD", +"Q. c #E7E9E4", +"R. c #535595", +"S. c #5B5B7F", +"T. c #59597E", +"U. c #59597D", +"V. c #58587D", +"W. c #57577C", +"X. c #55557C", +"Y. c #474770", +"Z. c #31315F", +"`. c #2D2D5C", +" + c #2E2E5D", +".+ c #2F2F5E", +"++ c #2F2F5F", +"@+ c #30305F", +"#+ c #303060", +"$+ c #2D2D7B", +"%+ c #BFC1BC", +"&+ c #A4A4A3", +"*+ c #B6B7B5", +"=+ c #5D5D5D", +"-+ c #8E8E8E", +";+ c #D3D5D2", +">+ c #E5E7E2", +",+ c #525393", +"'+ c #58587F", +")+ c #58587E", +"!+ c #57577D", +"~+ c #56567D", +"{+ c #54547C", +"]+ c #53537B", +"^+ c #4D4D76", +"/+ c #393967", +"(+ c #313160", +"_+ c #313161", +":+ c #323262", +"<+ c #333363", +"[+ c #333364", +"}+ c #343465", +"|+ c #2E2E7A", +"1+ c #C5C9C7", +"2+ c #DBDDD8", +"3+ c #BBBCB9", +"4+ c #5E5E5E", +"5+ c #8E8E8D", +"6+ c #D8D8D6", +"7+ c #E3E6E0", +"8+ c #505192", +"9+ c #54547D", +"0+ c #52527B", +"a+ c #4F4F79", +"b+ c #41416E", +"c+ c #353565", +"d+ c #353566", +"e+ c #353567", +"f+ c #363667", +"g+ c #363668", +"h+ c #373768", +"i+ c #373769", +"j+ c #383869", +"k+ c #38386A", +"l+ c #303078", +"m+ c #B8BCC3", +"n+ c #D8DBD5", +"o+ c #C0C1BE", +"p+ c #606060", +"q+ c #DCDDDA", +"r+ c #E1E4DE", +"s+ c #4C4D90", +"t+ c #51517C", +"u+ c #50507C", +"v+ c #50507B", +"w+ c #4E4E7B", +"x+ c #464674", +"y+ c #39396B", +"z+ c #3A3A6C", +"A+ c #3A3A6D", +"B+ c #3B3B6D", +"C+ c #3B3B6E", +"D+ c #3C3C6F", +"E+ c #3C3C70", +"F+ c #313179", +"G+ c #ADB0BD", +"H+ c #D5D9D3", +"I+ c #C4C6C2", +"J+ c #8A8A89", +"K+ c #DFE0DE", +"L+ c #DFE1DC", +"M+ c #48498E", +"N+ c #4B4B7A", +"O+ c #444474", +"P+ c #3C3C6E", +"Q+ c #3D3D70", +"R+ c #3D3D71", +"S+ c #3E3E71", +"T+ c #3E3E72", +"U+ c #3F3F73", +"V+ c #404074", +"W+ c #404075", +"X+ c #323277", +"Y+ c #A0A3B9", +"Z+ c #D4D6D0", +"`+ c #C8CAC7", +" @ c #5E5E5C", +".@ c #E3E3E1", +"+@ c #DCE0D9", +"@@ c #41418B", +"#@ c #404072", +"$@ c #414175", +"%@ c #414176", +"&@ c #424276", +"*@ c #424277", +"=@ c #434378", +"-@ c #434379", +";@ c #444479", +">@ c #44447A", +",@ c #45457A", +"'@ c #36367B", +")@ c #9193B1", +"!@ c #D1D5CF", +"~@ c #CCCECB", +"{@ c #585958", +"]@ c #848584", +"^@ c #E5E6E3", +"/@ c #DBDED6", +"(@ c #3C3C88", +"_@ c #45457B", +":@ c #46467C", +"<@ c #47477D", +"[@ c #47477E", +"}@ c #48487E", +"|@ c #48487F", +"1@ c #49497F", +"2@ c #3D3D7E", +"3@ c #8183AA", +"4@ c #CFD2CC", +"5@ c #D1D2CF", +"6@ c #575756", +"7@ c #808180", +"8@ c #E7E9E6", +"9@ c #D9DCD5", +"0@ c #383987", +"a@ c #46467D", +"b@ c #494980", +"c@ c #4A4A81", +"d@ c #4B4B82", +"e@ c #4B4B83", +"f@ c #4C4C84", +"g@ c #4D4D85", +"h@ c #454583", +"i@ c #7073A3", +"j@ c #CDD1CB", +"k@ c #D3D6D1", +"l@ c #525252", +"m@ c #EAEBE8", +"n@ c #D7DAD2", +"o@ c #202184", +"p@ c #3B3C87", +"q@ c #3B3C88", +"r@ c #3B3B88", +"s@ c #3B3C89", +"t@ c #3C3C89", +"u@ c #3C3C8A", +"v@ c #3C3D8A", +"w@ c #3D3D8A", +"x@ c #373889", +"y@ c #66689F", +"z@ c #CBCFC8", +"A@ c #D7D9D5", +"B@ c #4D4D4D", +"C@ c #787878", +"D@ c #EAECE9", +"E@ c #D1D4CE", +"F@ c #CED2CA", +"G@ c #CED1CA", +"H@ c #CDD1C9", +"I@ c #CDD0C9", +"J@ c #CCD0C8", +"K@ c #CCCFC8", +"L@ c #CBCFC7", +"M@ c #CBCEC7", +"N@ c #CACEC6", +"O@ c #AEB0AB", +"P@ c #B3B6AF", +"Q@ c #C9CCC5", +"R@ c #C8CCC4", +"S@ c #C8CBC4", +"T@ c #C7CBC4", +"U@ c #C7CAC3", +"V@ c #C6CAC3", +"W@ c #747672", +"X@ c #343534", +"Y@ c #2C2C2B", +"Z@ c #2B2C2B", +"`@ c #2F302F", +" # c #A6A8A5", +".# c #494949", +"+# c #D4D6D2", +"@# c #EBECE9", +"## c #E9EBE7", +"$# c #E8EAE6", +"%# c #E7E9E5", +" c #E6E8E5", +"*# c #E6E8E4", +"=# c #E4E6E2", +"-# c #E3E6E1", +";# c #E2E5E1", +"># c #E2E4E0", +",# c #E1E3DF", +"'# c #D2D4D1", +")# c #6F706E", +"!# c #D2D2D2", +"~# c #DBDBDB", +"{# c #BCBCBC", +"]# c #767676", +"^# c #272727", +"/# c #747474", +"(# c #6E6E6E", +"_# c #6C6C6C", +":# c #6A6A6A", +"<# c #686868", +"[# c #676767", +"}# c #656565", +"|# c #636363", +"1# c #616161", +"2# c #5F5F5F", +"3# c #5C5C5C", +"4# c #5A5A5A", +"5# c #585858", +"6# c #565656", +"7# c #555555", +"8# c #535353", +"9# c #515151", +"0# c #313131", +"a# c #838383", +"b# c #BABABA", +"c# c #383838", +"d# c #1D1D1D", +"e# c #4C4C4C", +"f# c #B1B1B1", +"g# c #4F504E", +"h# c #838581", +"i# c #ACAFA9", +"j# c #ADB0AA", +"k# c #8B8E89", +"l# c #8D908C", +"m# c #ABADAA", +"n# c #A7A7A6", +"o# c #363636", +"p# c #C1C1C1", +"q# c #0D0D0D", +"r# c #2E2E2E", +"s# c #AAAAAA", +"t# c #000000", +"u# c #525451", +"v# c #9B9E9A", +"w# c #AFB2AC", +"x# c #B1B3AE", +"y# c #AEB1AB", +"z# c #A8AAA5", +"A# c #2C2C2C", +"B# c #BFBFBF", +"C# c #141414", +"D# c #A1A1A1", +"E# c #A5A5A5", +"F# c #A8A8A8", +"G# c #171717", +"H# c #C1C0C0", +"I# c #595959", +"J# c #595958", +"K# c #585857", +"L# c #575757", +"M# c #515150", +"N# c #505050", +"O# c #14120F", +"P# c #9B9794", +"Q# c #201D1C", +"R# c #0B0B07", +"S# c #040302", +"T# c #050403", +"U# c #2F2921", +"V# c #A8A39E", +"W# c #1A130B", +"X# c #DCE0D8", +"Y# c #DFE3DB", +"Z# c #DFE3DA", +"`# c #E0E3DA", +" $ c #E0E3DB", +".$ c #E1E3DB", +"+$ c #E0E4DB", +"@$ c #E0E4DC", +"#$ c #A59176", +"$$ c #E0C4A0", +"%$ c #DFC4A3", +"&$ c #DABE9A", +"*$ c #D6BA94", +"=$ c #CDA676", +"-$ c #815A2B", +";$ c #949693", +">$ c #9F9F9E", +",$ c #9D9D9D", +"'$ c #E2C5A1", +")$ c #D8B58C", +"!$ c #CA9F68", +"~$ c #AC8758", +"{$ c #A78252", +"]$ c #A78253", +"^$ c #A37B4B", +"/$ c #BC8849", +"($ c #AC712E", +"_$ c #636463", +":$ c #BBBDB8", +"<$ c #9FA09F", +"[$ c #9C9D9C", +"}$ c #E3C6A2", +"|$ c #D5AE7E", +"1$ c #B08D5F", +"2$ c #D5B284", +"3$ c #CFAB7C", +"4$ c #CFAC7B", +"5$ c #CBA471", +"6$ c #BC8746", +"7$ c #AA6F2B", +"8$ c #676867", +"9$ c #BDC0BC", +"0$ c #A7A9A6", +"a$ c #AEAEAE", +"b$ c #ACACAB", +"c$ c #E1C4A0", +"d$ c #D0A674", +"e$ c #C79B64", +"f$ c #AA8455", +"g$ c #A47E4E", +"h$ c #A07744", +"i$ c #BA8442", +"j$ c #A4A7A2", +"k$ c #959991", +"l$ c #7A7D77", +"m$ c #A3A6A0", +"n$ c #777874", +"o$ c #858782", +"p$ c #989B94", +"q$ c #E1C29C", +"r$ c #CEA470", +"s$ c #AD8D64", +"t$ c #D2B289", +"u$ c #CDAC83", +"v$ c #CEAD83", +"w$ c #CCA77B", +"x$ c #B8803E", +"y$ c #AD7332", +"z$ c #D4D9D1", +"A$ c #E0E5DC", +"B$ c #E1E5DE", +"C$ c #E2E5DE", +"D$ c #E1E6DD", +"E$ c #E2E6DE", +"F$ c #E1E6DF", +"G$ c #E2E7DE", +"H$ c #E2E7DD", +"I$ c #E3E7DE", +"J$ c #E3E8DE", +"K$ c #E3E8DF", +"L$ c #E0C29E", +"M$ c #D4AC79", +"N$ c #CDA66E", +"O$ c #AF8D5E", +"P$ c #AB8758", +"Q$ c #AB8858", +"R$ c #A8814C", +"S$ c #B47E3E", +"T$ c #575857", +"U$ c #5A5B5A", +"V$ c #595A59", +"W$ c #555655", +"X$ c #535453", +"Y$ c #525352", +"Z$ c #515251", +"`$ c #525251", +" % c #D0A874", +".% c #C6965D", +"+% c #BE8D50", +"@% c #BA894B", +"#% c #BD8C4E", +"$% c #BC8A4C", +"%% c #BA8647", +"&% c #A47136", +" . + @ @ @ @ @ @ @ @ @ @ # $ % & * = - ; > , ' ) ! ~ ", +" { ] ^ ^ ^ ^ ^ ^ / / / / ( ( _ _ : : : < < < [ } | ) ", +" 1 2 3 4 5 5 6 7 8 9 0 a b c d e f g h i j k l m n o ", +" p q r s t u v w x y z A B C D E F G G H I J K L M N ", +" O P Q R z A B C D E S G G H I T U V W X Y Z ` ...+. ", +" @.#.$.%.S G G H &.J T *.V V =.=.Z -.;.>.,.'.).!.~.{. ", +" ].^./.(._.:.*.<.[.}.|.1.2.3.4.>.5.6.7.8.9.0.a.b.c.d. ", +" e.f.g.(.}.}.1.2.2.h.h.i.i.j.6.k.l.m.n.n.o.o.p.q.r.r. ", +" s.t.u.2.v.h.w.x.x.y.z.A.B.C.D.E.F.G.G.H.I.J.K.L.M.N. ", +" O.P.Q.R.x.S.S.T.U.V.W.W.X.Y.Z.`. + +.+.+++@+#+$+%+&+*+=+ ", +" -+;+>+,+'+)+!+~+X.{+]+^+/+(+_+_+:+:+<+[+[+}+}+|+1+2+3+4+ ", +" 5+6+7+8+9+{+{+0+0+a+b+c+}+d+d+e+f+g+h+i+j+k+k+l+m+n+o+p+ ", +" # q+r+s+t+u+v+w+x+y+i+k+k+y+y+z+z+A+B+C+D+D+E+F+G+H+I+4+ ", +" J+K+L+M+w+N+O+D+B+C+P+D+E+Q+R+S+T+T+U+U+V+V+W+X+Y+Z+`+ @ ", +" & .@+@@@#@R+T+T+U+U+V+V+W+$@%@&@*@*@=@-@;@>@,@'@)@!@~@{@ ", +" ]@^@/@(@%@&@*@*@=@=@;@;@>@_@_@:@:@<@<@[@}@|@1@2@3@4@5@6@ ", +" 7@8@9@0@_@:@:@a@<@[@}@|@1@b@b@c@c@d@d@e@f@f@g@h@i@j@k@l@ ", +" ~ m@n@o@p@q@r@r@q@s@t@t@t@s@s@t@u@v@v@v@w@v@v@x@y@z@A@B@ ", +" C@D@E@F@G@H@I@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.# ", +" C@+#@#@#..m@##$#$#%#*#c.>+=#-#;#>#,#'#)#' !#~#~#{#]#^# ", +" /#(#_#:#<#[#}#|#1#2#4+3#4#5#6#7#8#9#0#a#b#c#d#d#e#f#a# ", +" g#h#i#j#k#k#k#k#k#l#m#n#o#p#q# r#s#t# ", +" u#v#w#x#w#y#j#j#y#y#j#z#A#B#C#D#E#F#E#G#H#t# ", +" <#|#1#2#4+3#I#5#J#I#K#L#7#8#9#M#N#0#O#P#Q#R#S#S#T#U#V#W# ", +" |#X#Y#Y#Z#Y#Y#`# $`# $.$+$+$+$@$@$t##$$$%$%$&$&$&$*$=$-$t#", +" ;$>$,$,$,$,$,$,$,$,$,$,$,$,$,$,$,$t#'$)$!$~${${$]$^$/$($t#", +" _$:$E#E#E#<$[$[$[$[$[$[$[$[$[$[$E#E#t#}$|$1$2$3$3$4$5$6$7$t#", +" 8$9$s#s#s#0$a$a$a$a$a$a$a$a$a$b$&+a$t#c$d$e$f$g$g$g$h$i$($t#", +" j$k$l$l$l$m$n$n$n$n$n$n$n$n$n$o$p$l$t#q$r$s$t$u$u$v$w$x$y$t#", +" 2#z$@$@$A$A$B$C$D$E$D$F$G$G$H$G$I$J$K$t#L$M$N$O$P$P$Q$R$6$S$t#", +" I#T$U$V$T$W$X$Y$Y$Y$Z$Z$Z$Z$`$`$`$`$`$t# %.%+%+%@%@%#%$%%%&%t#", +" t#t#t#t#t#t#t#t#t#t# "}; Added: trunk/gtk/unstable/src/icons/pkg-installed-upgradable-locked.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-installed-upgradable-locked.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-installed-upgradable-locked.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,595 @@ +/* XPM */ +static const char * pkg_installed_upgradable_locked_xpm[] = { +"32 32 560 2", +" c None", +". c #949594", +"+ c #909090", +"@ c #8F8F8F", +"# c #8D8D8D", +"$ c #8B8B8B", +"% c #898989", +"& c #878787", +"* c #868686", +"= c #848382", +"- c #B76F2C", +"; c #CB6913", +"> c #CE5F05", +", c #CE5C00", +"' c #CD5F04", +") c #C66512", +"! c #986B47", +"~ c #7C7C7C", +"{ c #959595", +"] c #F1F2EF", +"^ c #F5F6F3", +"/ c #F4F5F3", +"( c #F4F5F2", +"_ c #F4F4F2", +": c #DFB994", +"< c #D16911", +"[ c #E0811C", +"} c #F0A132", +"| c #F7AE3B", +"1 c #F8B13E", +"2 c #F7AC3B", +"3 c #F09F32", +"4 c #DD7F1E", +"5 c #C36110", +"6 c #A2A2A2", +"7 c #F2F3F0", +"8 c #B9BBC8", +"9 c #3E3F8E", +"0 c #545592", +"a c #535491", +"b c #525290", +"c c #515190", +"d c #52528F", +"e c #51518F", +"f c #50508F", +"g c #51518E", +"h c #53548D", +"i c #52538D", +"j c #795659", +"k c #CF6005", +"l c #EE9C2F", +"m c #F8AC3D", +"n c #F79A38", +"o c #F79537", +"p c #F79938", +"q c #F8A63B", +"r c #E9972E", +"s c #CC5D00", +"t c #AAAAA9", +"u c #F0F2EE", +"v c #A7AAC0", +"w c #6A6A91", +"x c #7E7E96", +"y c #7D7D95", +"z c #7C7C94", +"A c #7A7A93", +"B c #797992", +"C c #777790", +"D c #767690", +"E c #75758F", +"F c #74748D", +"G c #73738D", +"H c #717087", +"I c #CE660D", +"J c #EE9C2E", +"K c #F8A33B", +"L c #FBD8B7", +"M c #FFFFFF", +"N c #FBD5B0", +"O c #F89E39", +"P c #E7952B", +"Q c #CC5C00", +"R c #AFB0AF", +"S c #EFF0ED", +"T c #9697B8", +"U c #67678C", +"V c #71718B", +"W c #70708B", +"X c #6E6E89", +"Y c #6D6D88", +"Z c #6B6B86", +"` c #AE672B", +" . c #E1811D", +".. c #F8AB3C", +"+. c #FBD5B2", +"@. c #F8A43A", +"#. c #DA7A14", +"$. c #B8B8B7", +"%. c #EEEFEB", +"&. c #8284AD", +"*. c #646488", +"=. c #6A6A86", +"-. c #696985", +";. c #686884", +">. c #676784", +",. c #666683", +"'. c #CA6510", +"). c #F69130", +"!. c #FAC796", +"~. c #FBD4AE", +"{. c #FAC898", +"]. c #F79837", +"^. c #E7962A", +"/. c #BFBFBE", +"(. c #ECEDE9", +"_. c #7173A4", +":. c #646486", +"<. c #696986", +"[. c #676785", +"}. c #666684", +"|. c #656583", +"1. c #646483", +"2. c #636381", +"3. c #626281", +"4. c #616181", +"5. c #606080", +"6. c #F7AB3B", +"7. c #F69132", +"8. c #F9B97B", +"9. c #FBCEA3", +"0. c #F8B778", +"a. c #F78E2A", +"b. c #F79333", +"c. c #EFA033", +"d. c #CD5B00", +"e. c #C5C5C3", +"f. c #EAECE7", +"g. c #61639D", +"h. c #5F5F80", +"i. c #5D5D7F", +"j. c #5C5C7E", +"k. c #F8AD3D", +"l. c #F79434", +"m. c #F58416", +"n. c #F6A352", +"o. c #F9BD82", +"p. c #F8A85B", +"q. c #F57900", +"r. c #F57A01", +"s. c #F68517", +"t. c #F7912E", +"u. c #F1A235", +"v. c #CACBC9", +"w. c #E8EAE5", +"x. c #575998", +"y. c #606081", +"z. c #5E5E80", +"A. c #5C5C7F", +"B. c #5B5B7E", +"C. c #5A5A7E", +"D. c #5A5A7D", +"E. c #58587C", +"F. c #545479", +"G. c #CB5D02", +"H. c #F6A531", +"I. c #F78F29", +"J. c #F68415", +"K. c #F57A02", +"L. c #EB9929", +"M. c #8C8C8C", +"N. c #CFD0CD", +"O. c #E7E9E4", +"P. c #535595", +"Q. c #5B5B7F", +"R. c #59597E", +"S. c #59597D", +"T. c #58587D", +"U. c #57577C", +"V. c #55557C", +"W. c #474770", +"X. c #31315F", +"Y. c #BE5B0C", +"Z. c #F0921D", +"`. c #F57E04", +" + c #F57D04", +".+ c #E69426", +"++ c #8E8E8E", +"@+ c #D3D5D2", +"#+ c #E5E7E2", +"$+ c #525393", +"%+ c #58587F", +"&+ c #58587E", +"*+ c #57577D", +"=+ c #56567D", +"-+ c #54547C", +";+ c #53537B", +">+ c #4D4D76", +",+ c #393967", +"'+ c #313160", +")+ c #313161", +"!+ c #744334", +"~+ c #D87814", +"{+ c #F79116", +"]+ c #EC9222", +"^+ c #D87712", +"/+ c #8E8E8D", +"(+ c #D8D8D6", +"_+ c #E3E6E0", +":+ c #505192", +"<+ c #54547D", +"[+ c #52527B", +"}+ c #4F4F79", +"|+ c #41416E", +"1+ c #353565", +"2+ c #343465", +"3+ c #353566", +"4+ c #353567", +"5+ c #BA580D", +"6+ c #EA9020", +"7+ c #F6870D", +"8+ c #F58A13", +"9+ c #D88B26", +"0+ c #DCDDDA", +"a+ c #E1E4DE", +"b+ c #4C4D90", +"c+ c #51517C", +"d+ c #50507C", +"e+ c #50507B", +"f+ c #4E4E7B", +"g+ c #464674", +"h+ c #39396B", +"i+ c #373769", +"j+ c #38386A", +"k+ c #3A3A6C", +"l+ c #544058", +"m+ c #C65A04", +"n+ c #E38E23", +"o+ c #F79117", +"p+ c #EF9425", +"q+ c #DC9433", +"r+ c #C65B05", +"s+ c #8A8A89", +"t+ c #DFE0DE", +"u+ c #DFE1DC", +"v+ c #48498E", +"w+ c #4B4B7A", +"x+ c #444474", +"y+ c #3C3C6F", +"z+ c #3B3B6D", +"A+ c #3B3B6E", +"B+ c #3C3C6E", +"C+ c #3C3C70", +"D+ c #3D3D70", +"E+ c #3D3D71", +"F+ c #3E3E71", +"G+ c #3E3E72", +"H+ c #533F55", +"I+ c #AF5313", +"J+ c #D17518", +"K+ c #DD8C25", +"L+ c #EC9727", +"M+ c #F19927", +"N+ c #E09029", +"O+ c #DD912E", +"P+ c #D0802B", +"Q+ c #C66D25", +"R+ c #765D47", +"S+ c #E3E3E1", +"T+ c #DCE0D9", +"U+ c #41418B", +"V+ c #404072", +"W+ c #3F3F73", +"X+ c #404074", +"Y+ c #404075", +"Z+ c #414175", +"`+ c #414176", +" @ c #424276", +".@ c #424277", +"+@ c #434378", +"@@ c #6E433A", +"#@ c #A04F19", +"$@ c #C15706", +"%@ c #CB5A00", +"&@ c #BF5706", +"*@ c #B05F24", +"=@ c #B18762", +"-@ c #CCCECB", +";@ c #585958", +">@ c #848584", +",@ c #E5E6E3", +"'@ c #DBDED6", +")@ c #3C3C88", +"!@ c #444479", +"~@ c #44447A", +"{@ c #45457B", +"]@ c #46467C", +"^@ c #47477D", +"/@ c #47477E", +"(@ c #48487E", +"_@ c #48487F", +":@ c #49497F", +"<@ c #3D3D7E", +"[@ c #8183AA", +"}@ c #CFD2CC", +"|@ c #D1D2CF", +"1@ c #575756", +"2@ c #808180", +"3@ c #E7E9E6", +"4@ c #D9DCD5", +"5@ c #383987", +"6@ c #46467D", +"7@ c #494980", +"8@ c #4A4A81", +"9@ c #4B4B82", +"0@ c #4B4B83", +"a@ c #4C4C84", +"b@ c #4D4D85", +"c@ c #454583", +"d@ c #7073A3", +"e@ c #CDD1CB", +"f@ c #D3D6D1", +"g@ c #525252", +"h@ c #EAEBE8", +"i@ c #D7DAD2", +"j@ c #202184", +"k@ c #3B3C87", +"l@ c #3B3C88", +"m@ c #3B3B88", +"n@ c #3B3C89", +"o@ c #3C3C89", +"p@ c #3C3C8A", +"q@ c #3C3D8A", +"r@ c #3D3D8A", +"s@ c #373889", +"t@ c #66689F", +"u@ c #CBCFC8", +"v@ c #D7D9D5", +"w@ c #4D4D4D", +"x@ c #787878", +"y@ c #EAECE9", +"z@ c #D1D4CE", +"A@ c #CED2CA", +"B@ c #CED1CA", +"C@ c #CDD1C9", +"D@ c #CDD0C9", +"E@ c #CCD0C8", +"F@ c #CCCFC8", +"G@ c #CBCFC7", +"H@ c #CBCEC7", +"I@ c #CACEC6", +"J@ c #AEB0AB", +"K@ c #B3B6AF", +"L@ c #C9CCC5", +"M@ c #C8CCC4", +"N@ c #C8CBC4", +"O@ c #C7CBC4", +"P@ c #C7CAC3", +"Q@ c #C6CAC3", +"R@ c #747672", +"S@ c #343534", +"T@ c #2C2C2B", +"U@ c #2B2C2B", +"V@ c #2F302F", +"W@ c #A6A8A5", +"X@ c #494949", +"Y@ c #D4D6D2", +"Z@ c #EBECE9", +"`@ c #EAECE8", +" # c #E9EBE7", +".# c #E8EAE6", +"+# c #E7E9E5", +"@# c #E6E8E5", +"## c #E6E8E4", +"$# c #E5E7E3", +"%# c #E4E6E2", +" c #E3E6E1", +"*# c #E2E5E1", +"=# c #E2E4E0", +"-# c #E1E3DF", +";# c #D2D4D1", +"># c #6F706E", +",# c #7B7B7B", +"'# c #D2D2D2", +")# c #DBDBDB", +"!# c #BCBCBC", +"~# c #767676", +"{# c #272727", +"]# c #747474", +"^# c #6E6E6E", +"/# c #6C6C6C", +"(# c #6A6A6A", +"_# c #686868", +":# c #676767", +"<# c #656565", +"[# c #636363", +"}# c #616161", +"|# c #5F5F5F", +"1# c #5E5E5E", +"2# c #5C5C5C", +"3# c #5A5A5A", +"4# c #585858", +"5# c #565656", +"6# c #555555", +"7# c #535353", +"8# c #515151", +"9# c #313131", +"0# c #838383", +"a# c #BABABA", +"b# c #383838", +"c# c #1D1D1D", +"d# c #4C4C4C", +"e# c #B1B1B1", +"f# c #4F504E", +"g# c #838581", +"h# c #ACAFA9", +"i# c #ADB0AA", +"j# c #8B8E89", +"k# c #8D908C", +"l# c #ABADAA", +"m# c #A7A7A6", +"n# c #363636", +"o# c #C1C1C1", +"p# c #0D0D0D", +"q# c #2E2E2E", +"r# c #AAAAAA", +"s# c #000000", +"t# c #525451", +"u# c #9B9E9A", +"v# c #AFB2AC", +"w# c #B1B3AE", +"x# c #AEB1AB", +"y# c #A8AAA5", +"z# c #2C2C2C", +"A# c #BFBFBF", +"B# c #141414", +"C# c #A1A1A1", +"D# c #A5A5A5", +"E# c #A8A8A8", +"F# c #171717", +"G# c #C1C0C0", +"H# c #595959", +"I# c #595958", +"J# c #585857", +"K# c #575757", +"L# c #515150", +"M# c #505050", +"N# c #14120F", +"O# c #9B9794", +"P# c #201D1C", +"Q# c #0B0B07", +"R# c #040302", +"S# c #050403", +"T# c #2F2921", +"U# c #A8A39E", +"V# c #1A130B", +"W# c #DCE0D8", +"X# c #DFE3DB", +"Y# c #DFE3DA", +"Z# c #E0E3DA", +"`# c #E0E3DB", +" $ c #E1E3DB", +".$ c #E0E4DB", +"+$ c #E0E4DC", +"@$ c #A59176", +"#$ c #E0C4A0", +"$$ c #DFC4A3", +"%$ c #DABE9A", +"&$ c #D6BA94", +"*$ c #CDA676", +"=$ c #815A2B", +"-$ c #949693", +";$ c #9F9F9E", +">$ c #9D9D9D", +",$ c #E2C5A1", +"'$ c #D8B58C", +")$ c #CA9F68", +"!$ c #AC8758", +"~$ c #A78252", +"{$ c #A78253", +"]$ c #A37B4B", +"^$ c #BC8849", +"/$ c #AC712E", +"($ c #636463", +"_$ c #BBBDB8", +":$ c #9FA09F", +"<$ c #9C9D9C", +"[$ c #E3C6A2", +"}$ c #D5AE7E", +"|$ c #B08D5F", +"1$ c #D5B284", +"2$ c #CFAB7C", +"3$ c #CFAC7B", +"4$ c #CBA471", +"5$ c #BC8746", +"6$ c #AA6F2B", +"7$ c #676867", +"8$ c #BDC0BC", +"9$ c #A7A9A6", +"0$ c #AEAEAE", +"a$ c #ACACAB", +"b$ c #A4A4A3", +"c$ c #E1C4A0", +"d$ c #D0A674", +"e$ c #C79B64", +"f$ c #AA8455", +"g$ c #A47E4E", +"h$ c #A07744", +"i$ c #BA8442", +"j$ c #A4A7A2", +"k$ c #959991", +"l$ c #7A7D77", +"m$ c #A3A6A0", +"n$ c #777874", +"o$ c #858782", +"p$ c #989B94", +"q$ c #E1C29C", +"r$ c #CEA470", +"s$ c #AD8D64", +"t$ c #D2B289", +"u$ c #CDAC83", +"v$ c #CEAD83", +"w$ c #CCA77B", +"x$ c #B8803E", +"y$ c #AD7332", +"z$ c #D4D9D1", +"A$ c #E0E5DC", +"B$ c #E1E5DE", +"C$ c #E2E5DE", +"D$ c #E1E6DD", +"E$ c #E2E6DE", +"F$ c #E1E6DF", +"G$ c #E2E7DE", +"H$ c #E2E7DD", +"I$ c #E3E7DE", +"J$ c #E3E8DE", +"K$ c #E3E8DF", +"L$ c #E0C29E", +"M$ c #D4AC79", +"N$ c #CDA66E", +"O$ c #AF8D5E", +"P$ c #AB8758", +"Q$ c #AB8858", +"R$ c #A8814C", +"S$ c #B47E3E", +"T$ c #575857", +"U$ c #5A5B5A", +"V$ c #595A59", +"W$ c #555655", +"X$ c #535453", +"Y$ c #525352", +"Z$ c #515251", +"`$ c #525251", +" % c #D0A874", +".% c #C6965D", +"+% c #BE8D50", +"@% c #BA894B", +"#% c #BD8C4E", +"$% c #BC8A4C", +"%% c #BA8647", +"&% c #A47136", +" . + @ @ @ @ @ @ @ @ @ @ # $ % & * = - ; > , ' ) ! ~ ", +" { ] ^ ^ ^ ^ ^ ^ / / / / ( ( _ _ : < [ } | 1 2 3 4 5 ", +" 6 7 8 9 0 0 a b c d e f g h i j k l m n o o o p q r s ", +" t u v w x y z A B C D E F G H I J K o o L M N o o O P Q ", +" R S T U D E F G V W X Y Y Z ` ...o o o L M +.o o o @.#. ", +" $.%.&.*.X Y Y Z =.-.;.>.,.,.'.3 p o o ).!.~.{.o o o ].^., ", +" /.(._.:.<.[.>.}.|.1.2.3.4.5.' 6.o o o 7.8.9.0.a.b.o o c.d.", +" e.f.g.:.1.1.3.4.4.h.h.i.i.j., k.o o l.m.n.o.p.q.r.s.t.u., ", +" v.w.x.4.y.h.z.A.A.B.C.D.E.F.G.H.I.J.K.q.q.q.q.q.q.q.q.L., ", +" M.N.O.P.A.Q.Q.R.S.T.U.U.V.W.X.Y.Z.`.q.q.q.o.M 8.q.q.q. +.+, ", +" ++@+#+$+%+&+*+=+V.-+;+>+,+'+)+!+~+{+q.q.q.o.M 8.q.q.q.]+^+ ", +" /+(+_+:+<+-+-+[+[+}+|+1+2+3+3+4+5+6+7+q.q.q.q.q.q.q.8+9+, ", +" # 0+a+b+c+d+e+f+g+h+i+j+j+h+h+k+l+m+n+o+ +q.q.q. +p+q+r+ ", +" s+t+u+v+f+w+x+y+z+A+B+y+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+ ", +" & S+T+U+V+E+G+G+W+W+X+X+Y+Z+`+ @.@.@+@@@#@$@%@&@*@=@-@;@ ", +" >@,@'@)@`+ @.@.@+@+@!@!@~@{@{@]@]@^@^@/@(@_@:@<@[@}@|@1@ ", +" 2@3@4@5@{@]@]@6@^@/@(@_@:@7@7@8@8@9@9@0@a@a@b@c@d@e@f@g@ ", +" ~ h@i@j@k@l@m@m@l@n@o@o@o@n@n@o@p@q@q@q@r@q@q@s@t@u@v@w@ ", +" x@y@z@A@B@C@D@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@ ", +" x@Y@Z@Z@`@h@ #.#.#+#@###$##+%#*#=#-#;#>#,#'#)#)#!#~#{# ", +" ]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#0#a#b#c#c#d#e#0# ", +" f#g#h#i#j#j#j#j#j#k#l#m#n#o#p# q#r#s# ", +" t#u#v#w#v#x#i#i#x#x#i#y#z#A#B#C#D#E#D#F#G#s# ", +" _#[#}#|#1#2#H#4#I#H#J#K#6#7#8#L#M#9#N#O#P#Q#R#R#S#T#U#V# ", +" [#W#X#X#Y#X#X#Z#`#Z#`# $.$.$.$+$+$s#@$#$$$$$%$%$%$&$*$=$s#", +" -$;$>$>$>$>$>$>$>$>$>$>$>$>$>$>$>$s#,$'$)$!$~$~${$]$^$/$s#", +" ($_$D#D#D#:$<$<$<$<$<$<$<$<$<$<$D#D#s#[$}$|$1$2$2$3$4$5$6$s#", +" 7$8$r#r#r#9$0$0$0$0$0$0$0$0$0$a$b$0$s#c$d$e$f$g$g$g$h$i$/$s#", +" j$k$l$l$l$m$n$n$n$n$n$n$n$n$n$o$p$l$s#q$r$s$t$u$u$v$w$x$y$s#", +" |#z$+$+$A$A$B$C$D$E$D$F$G$G$H$G$I$J$K$s#L$M$N$O$P$P$Q$R$5$S$s#", +" H#T$U$V$T$W$X$Y$Y$Y$Z$Z$Z$Z$`$`$`$`$`$s# %.%+%+%@%@%#%$%%%&%s#", +" s#s#s#s#s#s#s#s#s#s# "}; Added: trunk/gtk/unstable/src/icons/pkg-installed-upgradable.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-installed-upgradable.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-installed-upgradable.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,557 @@ +/* XPM */ +static const char * pkg_installed_upgradable_xpm[] = { +"32 32 522 2", +" c None", +". c #949594", +"+ c #909090", +"@ c #8F8F8F", +"# c #8D8D8D", +"$ c #8B8B8B", +"% c #898989", +"& c #878787", +"* c #868686", +"= c #848382", +"- c #B76F2C", +"; c #CB6913", +"> c #CE5F05", +", c #CE5C00", +"' c #CD5F04", +") c #C66512", +"! c #986B47", +"~ c #7C7C7C", +"{ c #959595", +"] c #F1F2EF", +"^ c #F5F6F3", +"/ c #F4F5F3", +"( c #F4F5F2", +"_ c #F4F4F2", +": c #DFB994", +"< c #D16911", +"[ c #E0811C", +"} c #F0A132", +"| c #F7AE3B", +"1 c #F8B13E", +"2 c #F7AC3B", +"3 c #F09F32", +"4 c #DD7F1E", +"5 c #C36110", +"6 c #A2A2A2", +"7 c #F2F3F0", +"8 c #B9BBC8", +"9 c #3E3F8E", +"0 c #545592", +"a c #535491", +"b c #525290", +"c c #515190", +"d c #52528F", +"e c #51518F", +"f c #50508F", +"g c #51518E", +"h c #53548D", +"i c #52538D", +"j c #795659", +"k c #CF6005", +"l c #EE9C2F", +"m c #F8AC3D", +"n c #F79A38", +"o c #F79537", +"p c #F79938", +"q c #F8A63B", +"r c #E9972E", +"s c #CC5D00", +"t c #AAAAA9", +"u c #F0F2EE", +"v c #A7AAC0", +"w c #6A6A91", +"x c #7E7E96", +"y c #7D7D95", +"z c #7C7C94", +"A c #7A7A93", +"B c #797992", +"C c #777790", +"D c #767690", +"E c #75758F", +"F c #74748D", +"G c #73738D", +"H c #717087", +"I c #CE660D", +"J c #EE9C2E", +"K c #F8A33B", +"L c #FBD8B7", +"M c #FFFFFF", +"N c #FBD5B0", +"O c #F89E39", +"P c #E7952B", +"Q c #CC5C00", +"R c #AFB0AF", +"S c #EFF0ED", +"T c #9697B8", +"U c #67678C", +"V c #71718B", +"W c #70708B", +"X c #6E6E89", +"Y c #6D6D88", +"Z c #6B6B86", +"` c #AE672B", +" . c #E1811D", +".. c #F8AB3C", +"+. c #FBD5B2", +"@. c #F8A43A", +"#. c #DA7A14", +"$. c #B8B8B7", +"%. c #EEEFEB", +"&. c #8284AD", +"*. c #646488", +"=. c #6A6A86", +"-. c #696985", +";. c #686884", +">. c #676784", +",. c #666683", +"'. c #CA6510", +"). c #F69130", +"!. c #FAC796", +"~. c #FBD4AE", +"{. c #FAC898", +"]. c #F79837", +"^. c #E7962A", +"/. c #BFBFBE", +"(. c #ECEDE9", +"_. c #7173A4", +":. c #646486", +"<. c #696986", +"[. c #676785", +"}. c #666684", +"|. c #656583", +"1. c #646483", +"2. c #636381", +"3. c #626281", +"4. c #616181", +"5. c #606080", +"6. c #F7AB3B", +"7. c #F69132", +"8. c #F9B97B", +"9. c #FBCEA3", +"0. c #F8B778", +"a. c #F78E2A", +"b. c #F79333", +"c. c #EFA033", +"d. c #CD5B00", +"e. c #C5C5C3", +"f. c #EAECE7", +"g. c #61639D", +"h. c #5F5F80", +"i. c #5D5D7F", +"j. c #5C5C7E", +"k. c #F8AD3D", +"l. c #F79434", +"m. c #F58416", +"n. c #F6A352", +"o. c #F9BD82", +"p. c #F8A85B", +"q. c #F57900", +"r. c #F57A01", +"s. c #F68517", +"t. c #F7912E", +"u. c #F1A235", +"v. c #CACBC9", +"w. c #E8EAE5", +"x. c #575998", +"y. c #606081", +"z. c #5E5E80", +"A. c #5C5C7F", +"B. c #5B5B7E", +"C. c #5A5A7E", +"D. c #5A5A7D", +"E. c #58587C", +"F. c #545479", +"G. c #CB5D02", +"H. c #F6A531", +"I. c #F78F29", +"J. c #F68415", +"K. c #F57A02", +"L. c #EB9929", +"M. c #8C8C8C", +"N. c #CFD0CD", +"O. c #E7E9E4", +"P. c #535595", +"Q. c #5B5B7F", +"R. c #59597E", +"S. c #59597D", +"T. c #58587D", +"U. c #57577C", +"V. c #55557C", +"W. c #474770", +"X. c #31315F", +"Y. c #BE5B0C", +"Z. c #F0921D", +"`. c #F57E04", +" + c #F57D04", +".+ c #E69426", +"++ c #8E8E8E", +"@+ c #D3D5D2", +"#+ c #E5E7E2", +"$+ c #525393", +"%+ c #58587F", +"&+ c #58587E", +"*+ c #57577D", +"=+ c #56567D", +"-+ c #54547C", +";+ c #53537B", +">+ c #4D4D76", +",+ c #393967", +"'+ c #313160", +")+ c #313161", +"!+ c #744334", +"~+ c #D87814", +"{+ c #F79116", +"]+ c #EC9222", +"^+ c #D87712", +"/+ c #8E8E8D", +"(+ c #D8D8D6", +"_+ c #E3E6E0", +":+ c #505192", +"<+ c #54547D", +"[+ c #52527B", +"}+ c #4F4F79", +"|+ c #41416E", +"1+ c #353565", +"2+ c #343465", +"3+ c #353566", +"4+ c #353567", +"5+ c #BA580D", +"6+ c #EA9020", +"7+ c #F6870D", +"8+ c #F58A13", +"9+ c #D88B26", +"0+ c #DCDDDA", +"a+ c #E1E4DE", +"b+ c #4C4D90", +"c+ c #51517C", +"d+ c #50507C", +"e+ c #50507B", +"f+ c #4E4E7B", +"g+ c #464674", +"h+ c #39396B", +"i+ c #373769", +"j+ c #38386A", +"k+ c #3A3A6C", +"l+ c #544058", +"m+ c #C65A04", +"n+ c #E38E23", +"o+ c #F79117", +"p+ c #EF9425", +"q+ c #DC9433", +"r+ c #C65B05", +"s+ c #8A8A89", +"t+ c #DFE0DE", +"u+ c #DFE1DC", +"v+ c #48498E", +"w+ c #4B4B7A", +"x+ c #444474", +"y+ c #3C3C6F", +"z+ c #3B3B6D", +"A+ c #3B3B6E", +"B+ c #3C3C6E", +"C+ c #3C3C70", +"D+ c #3D3D70", +"E+ c #3D3D71", +"F+ c #3E3E71", +"G+ c #3E3E72", +"H+ c #533F55", +"I+ c #AF5313", +"J+ c #D17518", +"K+ c #DD8C25", +"L+ c #EC9727", +"M+ c #F19927", +"N+ c #E09029", +"O+ c #DD912E", +"P+ c #D0802B", +"Q+ c #C66D25", +"R+ c #765D47", +"S+ c #E3E3E1", +"T+ c #DCE0D9", +"U+ c #41418B", +"V+ c #404072", +"W+ c #3F3F73", +"X+ c #404074", +"Y+ c #404075", +"Z+ c #414175", +"`+ c #414176", +" @ c #424276", +".@ c #424277", +"+@ c #434378", +"@@ c #6E433A", +"#@ c #A04F19", +"$@ c #C15706", +"%@ c #CB5A00", +"&@ c #BF5706", +"*@ c #B05F24", +"=@ c #B18762", +"-@ c #CCCECB", +";@ c #585958", +">@ c #848584", +",@ c #E5E6E3", +"'@ c #DBDED6", +")@ c #3C3C88", +"!@ c #444479", +"~@ c #44447A", +"{@ c #45457B", +"]@ c #46467C", +"^@ c #47477D", +"/@ c #47477E", +"(@ c #48487E", +"_@ c #48487F", +":@ c #49497F", +"<@ c #3D3D7E", +"[@ c #8183AA", +"}@ c #CFD2CC", +"|@ c #D1D2CF", +"1@ c #575756", +"2@ c #808180", +"3@ c #E7E9E6", +"4@ c #D9DCD5", +"5@ c #383987", +"6@ c #46467D", +"7@ c #494980", +"8@ c #4A4A81", +"9@ c #4B4B82", +"0@ c #4B4B83", +"a@ c #4C4C84", +"b@ c #4D4D85", +"c@ c #454583", +"d@ c #7073A3", +"e@ c #CDD1CB", +"f@ c #D3D6D1", +"g@ c #525252", +"h@ c #EAEBE8", +"i@ c #D7DAD2", +"j@ c #202184", +"k@ c #3B3C87", +"l@ c #3B3C88", +"m@ c #3B3B88", +"n@ c #3B3C89", +"o@ c #3C3C89", +"p@ c #3C3C8A", +"q@ c #3C3D8A", +"r@ c #3D3D8A", +"s@ c #373889", +"t@ c #66689F", +"u@ c #CBCFC8", +"v@ c #D7D9D5", +"w@ c #4D4D4D", +"x@ c #787878", +"y@ c #EAECE9", +"z@ c #D1D4CE", +"A@ c #CED2CA", +"B@ c #CED1CA", +"C@ c #CDD1C9", +"D@ c #CDD0C9", +"E@ c #CCD0C8", +"F@ c #CCCFC8", +"G@ c #CBCFC7", +"H@ c #CBCEC7", +"I@ c #CACEC6", +"J@ c #AEB0AB", +"K@ c #B3B6AF", +"L@ c #C9CCC5", +"M@ c #C8CCC4", +"N@ c #C8CBC4", +"O@ c #C7CBC4", +"P@ c #C7CAC3", +"Q@ c #C6CAC3", +"R@ c #C6C9C3", +"S@ c #C5C9C3", +"T@ c #C5C8C2", +"U@ c #C4C8C2", +"V@ c #C5C9C2", +"W@ c #D9DBD7", +"X@ c #4A4A4A", +"Y@ c #D4D6D2", +"Z@ c #EBECE9", +"`@ c #EAECE8", +" # c #E9EBE7", +".# c #E8EAE6", +"+# c #E7E9E5", +"@# c #E6E8E5", +"## c #E6E8E4", +"$# c #E5E7E3", +"%# c #E4E6E2", +" c #E3E6E1", +"*# c #E2E5E1", +"=# c #E2E4E0", +"-# c #E1E3DF", +";# c #E0E2DE", +"># c #DFE2DD", +",# c #DEE1DC", +"'# c #DEE0DC", +")# c #DDDFDB", +"!# c #DCDEDA", +"~# c #C0C2BE", +"{# c #4D4D4C", +"]# c #747474", +"^# c #6E6E6E", +"/# c #6C6C6C", +"(# c #6A6A6A", +"_# c #686868", +":# c #676767", +"<# c #656565", +"[# c #636363", +"}# c #616161", +"|# c #5F5F5F", +"1# c #5E5E5E", +"2# c #5C5C5C", +"3# c #5A5A5A", +"4# c #585858", +"5# c #565656", +"6# c #555555", +"7# c #535353", +"8# c #515151", +"9# c #4F4F4F", +"0# c #4C4C4C", +"a# c #484848", +"b# c #4F504E", +"c# c #838581", +"d# c #ACAFA9", +"e# c #ADB0AA", +"f# c #8B8E89", +"g# c #8D908C", +"h# c #ABADAA", +"i# c #A7A7A6", +"j# c #A1A1A0", +"k# c #7C7D7C", +"l# c #525451", +"m# c #9B9E9A", +"n# c #AFB2AC", +"o# c #B1B3AE", +"p# c #AEB1AB", +"q# c #A8AAA5", +"r# c #9D9F9D", +"s# c #939392", +"t# c #A1A1A1", +"u# c #A5A5A5", +"v# c #A8A8A8", +"w# c #595959", +"x# c #595958", +"y# c #585857", +"z# c #575757", +"A# c #515150", +"B# c #505050", +"C# c #4E4E4E", +"D# c #AAAAAA", +"E# c #A7A7A7", +"F# c #ACACAC", +"G# c #DCE0D8", +"H# c #DFE3DB", +"I# c #DFE3DA", +"J# c #E0E3DA", +"K# c #E0E3DB", +"L# c #E1E3DB", +"M# c #E0E4DB", +"N# c #E0E4DC", +"O# c #E1E4DB", +"P# c #E1E4DC", +"Q# c #DDE2D9", +"R# c #545654", +"S# c #949693", +"T# c #9F9F9E", +"U# c #9D9D9D", +"V# c #9A9B9A", +"W# c #DADDD5", +"X# c #9B9B9A", +"Y# c #9B9B9B", +"Z# c #9A9B99", +"`# c #959792", +" $ c #636463", +".$ c #BBBDB8", +"+$ c #9FA09F", +"@$ c #9C9D9C", +"#$ c #C9CCC6", +"$$ c #A0A19F", +"%$ c #BCC0B9", +"&$ c #5C5D5C", +"*$ c #ABABAB", +"=$ c #676867", +"-$ c #BDC0BC", +";$ c #A7A9A6", +">$ c #AEAEAE", +",$ c #ACACAB", +"'$ c #A4A4A3", +")$ c #B1B2B0", +"!$ c #B4B6B1", +"~$ c #AAABAA", +"{$ c #BEC1BC", +"]$ c #606160", +"^$ c #A4A7A2", +"/$ c #959991", +"($ c #7A7D77", +"_$ c #A3A6A0", +":$ c #777874", +"<$ c #858782", +"[$ c #989B94", +"}$ c #989B95", +"|$ c #D2D4CD", +"1$ c #868983", +"2$ c #848882", +"3$ c #9EA19A", +"4$ c #A6A9A4", +"5$ c #D4D9D1", +"6$ c #E0E5DC", +"7$ c #E1E5DE", +"8$ c #E2E5DE", +"9$ c #E1E6DD", +"0$ c #E2E6DE", +"a$ c #E1E6DF", +"b$ c #E2E7DE", +"c$ c #E2E7DD", +"d$ c #E3E7DE", +"e$ c #E3E8DE", +"f$ c #E3E8DF", +"g$ c #E4E8DF", +"h$ c #E5E8E0", +"i$ c #E4E9E0", +"j$ c #E5E9E0", +"k$ c #E5E9E1", +"l$ c #DCE1D9", +"m$ c #575857", +"n$ c #5A5B5A", +"o$ c #595A59", +"p$ c #555655", +"q$ c #535453", +"r$ c #525352", +"s$ c #515251", +"t$ c #525251", +"u$ c #535352", +"v$ c #545453", +"w$ c #4D4E4D", +" . + @ @ @ @ @ @ @ @ @ @ # $ % & * = - ; > , ' ) ! ~ ", +" { ] ^ ^ ^ ^ ^ ^ / / / / ( ( _ _ : < [ } | 1 2 3 4 5 ", +" 6 7 8 9 0 0 a b c d e f g h i j k l m n o o o p q r s ", +" t u v w x y z A B C D E F G H I J K o o L M N o o O P Q ", +" R S T U D E F G V W X Y Y Z ` ...o o o L M +.o o o @.#. ", +" $.%.&.*.X Y Y Z =.-.;.>.,.,.'.3 p o o ).!.~.{.o o o ].^., ", +" /.(._.:.<.[.>.}.|.1.2.3.4.5.' 6.o o o 7.8.9.0.a.b.o o c.d.", +" e.f.g.:.1.1.3.4.4.h.h.i.i.j., k.o o l.m.n.o.p.q.r.s.t.u., ", +" v.w.x.4.y.h.z.A.A.B.C.D.E.F.G.H.I.J.K.q.q.q.q.q.q.q.q.L., ", +" M.N.O.P.A.Q.Q.R.S.T.U.U.V.W.X.Y.Z.`.q.q.q.o.M 8.q.q.q. +.+, ", +" ++@+#+$+%+&+*+=+V.-+;+>+,+'+)+!+~+{+q.q.q.o.M 8.q.q.q.]+^+ ", +" /+(+_+:+<+-+-+[+[+}+|+1+2+3+3+4+5+6+7+q.q.q.q.q.q.q.8+9+, ", +" # 0+a+b+c+d+e+f+g+h+i+j+j+h+h+k+l+m+n+o+ +q.q.q. +p+q+r+ ", +" s+t+u+v+f+w+x+y+z+A+B+y+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+ ", +" & S+T+U+V+E+G+G+W+W+X+X+Y+Z+`+ @.@.@+@@@#@$@%@&@*@=@-@;@ ", +" >@,@'@)@`+ @.@.@+@+@!@!@~@{@{@]@]@^@^@/@(@_@:@<@[@}@|@1@ ", +" 2@3@4@5@{@]@]@6@^@/@(@_@:@7@7@8@8@9@9@0@a@a@b@c@d@e@f@g@ ", +" ~ h@i@j@k@l@m@m@l@n@o@o@o@n@n@o@p@q@q@q@r@q@q@s@t@u@v@w@ ", +" x@y@z@A@B@C@D@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@ ", +" x@Y@Z@Z@`@h@ #.#.#+#@###$##+%#*#=#-#-#;#>#,#'#)#!#~#{# ", +" ]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#w@0#X@a#a#a#w@ ", +" b#c#d#e#f#f#f#f#f#g#h#i#j#k# ", +" l#m#n#o#n#p#e#e#p#p#e#q#r#s#6 t#u#v#u# ", +" _#[#}#|#1#2#w#4#x#w#y#z#6#7#8#A#B#9#w@0#0#0#w@C#<#D#E#F# ", +" [#G#H#H#I#H#H#J#K#J#K#L#M#M#M#N#N#M#N#M#N#O#P#Q#R# v#D#", +" S#T#U#U#U#U#U#U#U#U#U#U#U#U#U#U#U#U#V#W#X#Y#Y#Z#`# 6 v#", +" $.$u#u#u#+$@$@$@$@$@$@$@$@$@$@$u#u#u#u##$$$u#u#u#%$&$E#*$ ", +" =$-$D#D#D#;$>$>$>$>$>$>$>$>$>$,$'$>$>$>$)$!$~$D#D#{$]$ ", +" ^$/$($($($_$:$:$:$:$:$:$:$:$:$<$[$($($($}$|$1$2$2$3$4$ ", +" |#5$N#N#6$6$7$8$9$0$9$a$b$b$c$b$d$e$f$g$g$h$i$j$i$i$k$l$8# ", +" w#m$n$o$m$p$q$r$r$r$s$s$s$s$t$t$t$t$t$t$t$t$u$u$u$u$v$B#w$ ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-installed.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-instal... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-installed.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-installed.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,558 @@ +/* XPM */ +static const char * pkg_installed_xpm[] = { +"32 32 523 2", +" c None", +". c #949594", +"+ c #909090", +"@ c #8F8F8F", +"# c #8D8D8D", +"$ c #8B8B8B", +"% c #898989", +"& c #878787", +"* c #868686", +"= c #848484", +"- c #828282", +"; c #808080", +"> c #7E7E7E", +", c #7D7D7D", +"' c #7B7B7B", +") c #797979", +"! c #777777", +"~ c #7C7C7C", +"{ c #959595", +"] c #F1F2EF", +"^ c #F5F6F3", +"/ c #F4F5F3", +"( c #F4F5F2", +"_ c #F4F4F2", +": c #F3F4F2", +"< c #F3F4F1", +"[ c #F2F4F1", +"} c #F2F3F1", +"| c #EDEEEB", +"1 c #A2A2A2", +"2 c #F2F3F0", +"3 c #B9BBC8", +"4 c #3E3F8E", +"5 c #545592", +"6 c #535491", +"7 c #525290", +"8 c #515190", +"9 c #52528F", +"0 c #51518F", +"a c #50508F", +"b c #51518E", +"c c #53548D", +"d c #52538D", +"e c #52528B", +"f c #51518B", +"g c #53538D", +"h c #55568E", +"i c #54548E", +"j c #55558E", +"k c #54548D", +"l c #535494", +"m c #D4D7D0", +"n c #EEF0ED", +"o c #858685", +"p c #AAAAA9", +"q c #F0F2EE", +"r c #A7AAC0", +"s c #6A6A91", +"t c #7E7E96", +"u c #7D7D95", +"v c #7C7C94", +"w c #7A7A93", +"x c #797992", +"y c #777790", +"z c #767690", +"A c #75758F", +"B c #74748D", +"C c #73738D", +"D c #71718B", +"E c #70708B", +"F c #6F6F8A", +"G c #6D6D88", +"H c #6B6B86", +"I c #6A6A85", +"J c #696985", +"K c #494A8B", +"L c #A4A5A2", +"M c #CFD1CF", +"N c #8D8E8D", +"O c #AFB0AF", +"P c #EFF0ED", +"Q c #9697B8", +"R c #67678C", +"S c #6E6E89", +"T c #686884", +"U c #676783", +"V c #666683", +"W c #656582", +"X c #646482", +"Y c #636380", +"Z c #626280", +"` c #454688", +" . c #D3D6CF", +".. c #EAECE8", +"+. c #959695", +"@. c #B8B8B7", +"#. c #EEEFEB", +"$. c #8284AD", +"%. c #646488", +"&. c #6A6A86", +"*. c #676784", +"=. c #646481", +"-. c #616180", +";. c #61617F", +">. c #5F5F7F", +",. c #5F5F7E", +"'. c #535375", +"). c #3F4084", +"!. c #B2B4B0", +"~. c #B7B8B7", +"{. c #9B9C9B", +"]. c #BFBFBE", +"^. c #ECEDE9", +"/. c #7173A4", +"(. c #646486", +"_. c #696986", +":. c #676785", +"<. c #666684", +"[. c #656583", +"}. c #646483", +"|. c #636381", +"1. c #626281", +"2. c #616181", +"3. c #606080", +"4. c #60607F", +"5. c #5E5E7E", +"6. c #5B5B7D", +"7. c #49496E", +"8. c #36365F", +"9. c #292954", +"0. c #242450", +"a. c #373880", +"b. c #D2D5CE", +"c. c #E5E7E3", +"d. c #A4A5A3", +"e. c #C5C5C3", +"f. c #EAECE7", +"g. c #61639D", +"h. c #5F5F80", +"i. c #5D5D7F", +"j. c #5C5C7E", +"k. c #565679", +"l. c #3E3E66", +"m. c #2A2A56", +"n. c #272754", +"o. c #282855", +"p. c #34357E", +"q. c #B8BBB6", +"r. c #ACADAB", +"s. c #CACBC9", +"t. c #E8EAE5", +"u. c #575998", +"v. c #606081", +"w. c #5E5E80", +"x. c #5C5C7F", +"y. c #5B5B7E", +"z. c #5A5A7E", +"A. c #5A5A7D", +"B. c #58587C", +"C. c #545479", +"D. c #3F3F69", +"E. c #2C2C59", +"F. c #2A2A58", +"G. c #2B2B59", +"H. c #2B2B5A", +"I. c #2C2C5A", +"J. c #2C2C5B", +"K. c #30317C", +"L. c #D0D4CD", +"M. c #E0E2DD", +"N. c #B0B1AF", +"O. c #8C8C8C", +"P. c #CFD0CD", +"Q. c #E7E9E4", +"R. c #535595", +"S. c #5B5B7F", +"T. c #59597E", +"U. c #59597D", +"V. c #58587D", +"W. c #57577C", +"X. c #55557C", +"Y. c #474770", +"Z. c #31315F", +"`. c #2D2D5C", +" + c #2E2E5D", +".+ c #2F2F5E", +"++ c #2F2F5F", +"@+ c #30305F", +"#+ c #303060", +"$+ c #2D2D7B", +"%+ c #BFC1BC", +"&+ c #A4A4A3", +"*+ c #B6B7B5", +"=+ c #5D5D5D", +"-+ c #8E8E8E", +";+ c #D3D5D2", +">+ c #E5E7E2", +",+ c #525393", +"'+ c #58587F", +")+ c #58587E", +"!+ c #57577D", +"~+ c #56567D", +"{+ c #54547C", +"]+ c #53537B", +"^+ c #4D4D76", +"/+ c #393967", +"(+ c #313160", +"_+ c #313161", +":+ c #323262", +"<+ c #333363", +"[+ c #333364", +"}+ c #343465", +"|+ c #2E2E7A", +"1+ c #C5C9C7", +"2+ c #DBDDD8", +"3+ c #BBBCB9", +"4+ c #5E5E5E", +"5+ c #8E8E8D", +"6+ c #D8D8D6", +"7+ c #E3E6E0", +"8+ c #505192", +"9+ c #54547D", +"0+ c #52527B", +"a+ c #4F4F79", +"b+ c #41416E", +"c+ c #353565", +"d+ c #353566", +"e+ c #353567", +"f+ c #363667", +"g+ c #363668", +"h+ c #373768", +"i+ c #373769", +"j+ c #383869", +"k+ c #38386A", +"l+ c #303078", +"m+ c #B8BCC3", +"n+ c #D8DBD5", +"o+ c #C0C1BE", +"p+ c #606060", +"q+ c #DCDDDA", +"r+ c #E1E4DE", +"s+ c #4C4D90", +"t+ c #51517C", +"u+ c #50507C", +"v+ c #50507B", +"w+ c #4E4E7B", +"x+ c #464674", +"y+ c #39396B", +"z+ c #3A3A6C", +"A+ c #3A3A6D", +"B+ c #3B3B6D", +"C+ c #3B3B6E", +"D+ c #3C3C6F", +"E+ c #3C3C70", +"F+ c #313179", +"G+ c #ADB0BD", +"H+ c #D5D9D3", +"I+ c #C4C6C2", +"J+ c #8A8A89", +"K+ c #DFE0DE", +"L+ c #DFE1DC", +"M+ c #48498E", +"N+ c #4B4B7A", +"O+ c #444474", +"P+ c #3C3C6E", +"Q+ c #3D3D70", +"R+ c #3D3D71", +"S+ c #3E3E71", +"T+ c #3E3E72", +"U+ c #3F3F73", +"V+ c #404074", +"W+ c #404075", +"X+ c #323277", +"Y+ c #A0A3B9", +"Z+ c #D4D6D0", +"`+ c #C8CAC7", +" @ c #5E5E5C", +".@ c #E3E3E1", +"+@ c #DCE0D9", +"@@ c #41418B", +"#@ c #404072", +"$@ c #414175", +"%@ c #414176", +"&@ c #424276", +"*@ c #424277", +"=@ c #434378", +"-@ c #434379", +";@ c #444479", +">@ c #44447A", +",@ c #45457A", +"'@ c #36367B", +")@ c #9193B1", +"!@ c #D1D5CF", +"~@ c #CCCECB", +"{@ c #585958", +"]@ c #848584", +"^@ c #E5E6E3", +"/@ c #DBDED6", +"(@ c #3C3C88", +"_@ c #45457B", +":@ c #46467C", +"<@ c #47477D", +"[@ c #47477E", +"}@ c #48487E", +"|@ c #48487F", +"1@ c #49497F", +"2@ c #3D3D7E", +"3@ c #8183AA", +"4@ c #CFD2CC", +"5@ c #D1D2CF", +"6@ c #575756", +"7@ c #808180", +"8@ c #E7E9E6", +"9@ c #D9DCD5", +"0@ c #383987", +"a@ c #46467D", +"b@ c #494980", +"c@ c #4A4A81", +"d@ c #4B4B82", +"e@ c #4B4B83", +"f@ c #4C4C84", +"g@ c #4D4D85", +"h@ c #454583", +"i@ c #7073A3", +"j@ c #CDD1CB", +"k@ c #D3D6D1", +"l@ c #525252", +"m@ c #EAEBE8", +"n@ c #D7DAD2", +"o@ c #202184", +"p@ c #3B3C87", +"q@ c #3B3C88", +"r@ c #3B3B88", +"s@ c #3B3C89", +"t@ c #3C3C89", +"u@ c #3C3C8A", +"v@ c #3C3D8A", +"w@ c #3D3D8A", +"x@ c #373889", +"y@ c #66689F", +"z@ c #CBCFC8", +"A@ c #D7D9D5", +"B@ c #4D4D4D", +"C@ c #787878", +"D@ c #EAECE9", +"E@ c #D1D4CE", +"F@ c #CED2CA", +"G@ c #CED1CA", +"H@ c #CDD1C9", +"I@ c #CDD0C9", +"J@ c #CCD0C8", +"K@ c #CCCFC8", +"L@ c #CBCFC7", +"M@ c #CBCEC7", +"N@ c #CACEC6", +"O@ c #AEB0AB", +"P@ c #B3B6AF", +"Q@ c #C9CCC5", +"R@ c #C8CCC4", +"S@ c #C8CBC4", +"T@ c #C7CBC4", +"U@ c #C7CAC3", +"V@ c #C6CAC3", +"W@ c #C6C9C3", +"X@ c #C5C9C3", +"Y@ c #C5C8C2", +"Z@ c #C4C8C2", +"`@ c #C5C9C2", +" # c #D9DBD7", +".# c #4A4A4A", +"+# c #D4D6D2", +"@# c #EBECE9", +"## c #E9EBE7", +"$# c #E8EAE6", +"%# c #E7E9E5", +" c #E6E8E5", +"*# c #E6E8E4", +"=# c #E4E6E2", +"-# c #E3E6E1", +";# c #E2E5E1", +"># c #E2E4E0", +",# c #E1E3DF", +"'# c #E0E2DE", +")# c #DFE2DD", +"!# c #DEE1DC", +"~# c #DEE0DC", +"{# c #DDDFDB", +"]# c #DCDEDA", +"^# c #C0C2BE", +"/# c #4D4D4C", +"(# c #747474", +"_# c #6E6E6E", +":# c #6C6C6C", +"<# c #6A6A6A", +"[# c #686868", +"}# c #676767", +"|# c #656565", +"1# c #636363", +"2# c #616161", +"3# c #5F5F5F", +"4# c #5C5C5C", +"5# c #5A5A5A", +"6# c #585858", +"7# c #565656", +"8# c #555555", +"9# c #535353", +"0# c #515151", +"a# c #4F4F4F", +"b# c #4C4C4C", +"c# c #484848", +"d# c #4F504E", +"e# c #838581", +"f# c #ACAFA9", +"g# c #ADB0AA", +"h# c #8B8E89", +"i# c #8D908C", +"j# c #ABADAA", +"k# c #A7A7A6", +"l# c #A1A1A0", +"m# c #7C7D7C", +"n# c #525451", +"o# c #9B9E9A", +"p# c #AFB2AC", +"q# c #B1B3AE", +"r# c #AEB1AB", +"s# c #A8AAA5", +"t# c #9D9F9D", +"u# c #939392", +"v# c #A1A1A1", +"w# c #A5A5A5", +"x# c #A8A8A8", +"y# c #595959", +"z# c #595958", +"A# c #585857", +"B# c #575757", +"C# c #515150", +"D# c #505050", +"E# c #4E4E4E", +"F# c #AAAAAA", +"G# c #A7A7A7", +"H# c #ACACAC", +"I# c #DCE0D8", +"J# c #DFE3DB", +"K# c #DFE3DA", +"L# c #E0E3DA", +"M# c #E0E3DB", +"N# c #E1E3DB", +"O# c #E0E4DB", +"P# c #E0E4DC", +"Q# c #E1E4DB", +"R# c #E1E4DC", +"S# c #DDE2D9", +"T# c #545654", +"U# c #949693", +"V# c #9F9F9E", +"W# c #9D9D9D", +"X# c #9A9B9A", +"Y# c #DADDD5", +"Z# c #9B9B9A", +"`# c #9B9B9B", +" $ c #9A9B99", +".$ c #959792", +"+$ c #636463", +"@$ c #BBBDB8", +"#$ c #9FA09F", +"$$ c #9C9D9C", +"%$ c #C9CCC6", +"&$ c #A0A19F", +"*$ c #BCC0B9", +"=$ c #5C5D5C", +"-$ c #ABABAB", +";$ c #676867", +">$ c #BDC0BC", +",$ c #A7A9A6", +"'$ c #AEAEAE", +")$ c #ACACAB", +"!$ c #B1B2B0", +"~$ c #B4B6B1", +"{$ c #AAABAA", +"]$ c #BEC1BC", +"^$ c #606160", +"/$ c #A4A7A2", +"($ c #959991", +"_$ c #7A7D77", +":$ c #A3A6A0", +"<$ c #777874", +"[$ c #858782", +"}$ c #989B94", +"|$ c #989B95", +"1$ c #D2D4CD", +"2$ c #868983", +"3$ c #848882", +"4$ c #9EA19A", +"5$ c #A6A9A4", +"6$ c #D4D9D1", +"7$ c #E0E5DC", +"8$ c #E1E5DE", +"9$ c #E2E5DE", +"0$ c #E1E6DD", +"a$ c #E2E6DE", +"b$ c #E1E6DF", +"c$ c #E2E7DE", +"d$ c #E2E7DD", +"e$ c #E3E7DE", +"f$ c #E3E8DE", +"g$ c #E3E8DF", +"h$ c #E4E8DF", +"i$ c #E5E8E0", +"j$ c #E4E9E0", +"k$ c #E5E9E0", +"l$ c #E5E9E1", +"m$ c #DCE1D9", +"n$ c #575857", +"o$ c #5A5B5A", +"p$ c #595A59", +"q$ c #555655", +"r$ c #535453", +"s$ c #525352", +"t$ c #515251", +"u$ c #525251", +"v$ c #535352", +"w$ c #545453", +"x$ c #4D4E4D", +" . + @ @ @ @ @ @ @ @ @ @ # $ % & * = - ; > , ' ) ! ~ ", +" { ] ^ ^ ^ ^ ^ ^ / / / / ( ( _ _ : : : < < < [ } | ) ", +" 1 2 3 4 5 5 6 7 8 9 0 a b c d e f g h i j k l m n o ", +" p q r s t u v w x y z A B C D E F G G H I J K L M N ", +" O P Q R z A B C D E S G G H I T U V W X Y Z ` ...+. ", +" @.#.$.%.S G G H &.J T *.V V =.=.Z -.;.>.,.'.).!.~.{. ", +" ].^./.(._.:.*.<.[.}.|.1.2.3.4.>.5.6.7.8.9.0.a.b.c.d. ", +" e.f.g.(.}.}.1.2.2.h.h.i.i.j.6.k.l.m.n.n.o.o.p.q.r.r. ", +" s.t.u.2.v.h.w.x.x.y.z.A.B.C.D.E.F.G.G.H.I.J.K.L.M.N. ", +" O.P.Q.R.x.S.S.T.U.V.W.W.X.Y.Z.`. + +.+.+++@+#+$+%+&+*+=+ ", +" -+;+>+,+'+)+!+~+X.{+]+^+/+(+_+_+:+:+<+[+[+}+}+|+1+2+3+4+ ", +" 5+6+7+8+9+{+{+0+0+a+b+c+}+d+d+e+f+g+h+i+j+k+k+l+m+n+o+p+ ", +" # q+r+s+t+u+v+w+x+y+i+k+k+y+y+z+z+A+B+C+D+D+E+F+G+H+I+4+ ", +" J+K+L+M+w+N+O+D+B+C+P+D+E+Q+R+S+T+T+U+U+V+V+W+X+Y+Z+`+ @ ", +" & .@+@@@#@R+T+T+U+U+V+V+W+$@%@&@*@*@=@-@;@>@,@'@)@!@~@{@ ", +" ]@^@/@(@%@&@*@*@=@=@;@;@>@_@_@:@:@<@<@[@}@|@1@2@3@4@5@6@ ", +" 7@8@9@0@_@:@:@a@<@[@}@|@1@b@b@c@c@d@d@e@f@f@g@h@i@j@k@l@ ", +" ~ m@n@o@p@q@r@r@q@s@t@t@t@s@s@t@u@v@v@v@w@v@v@x@y@z@A@B@ ", +" C@D@E@F@G@H@I@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.# ", +" C@+#@#@#..m@##$#$#%#*#c.>+=#-#;#>#,#,#'#)#!#~#{#]#^#/# ", +" (#_#:#<#[#}#|#1#2#3#4+4#5#6#7#8#9#0#a#B@b#.#c#c#c#B@ ", +" d#e#f#g#h#h#h#h#h#i#j#k#l#m# ", +" n#o#p#q#p#r#g#g#r#r#g#s#t#u#1 v#w#x#w# ", +" [#1#2#3#4+4#y#6#z#y#A#B#8#9#0#C#D#a#B@b#b#b#B@E#|#F#G#H# ", +" 1#I#J#J#K#J#J#L#M#L#M#N#O#O#O#P#P#O#P#O#P#Q#R#S#T# x#F#", +" U#V#W#W#W#W#W#W#W#W#W#W#W#W#W#W#W#W#X#Y#Z#`#`# $.$ 1 x#", +" +$@$w#w#w##$$$$$$$$$$$$$$$$$$$$$w#w#w#w#%$&$w#w#w#*$=$G#-$ ", +" ;$>$F#F#F#,$'$'$'$'$'$'$'$'$'$)$&+'$'$'$!$~${$F#F#]$^$ ", +" /$($_$_$_$:$<$<$<$<$<$<$<$<$<$[$}$_$_$_$|$1$2$3$3$4$5$ ", +" 3#6$P#P#7$7$8$9$0$a$0$b$c$c$d$c$e$f$g$h$h$i$j$k$j$j$l$m$0# ", +" y#n$o$p$n$q$r$s$s$s$t$t$t$t$u$u$u$u$u$u$u$u$v$v$v$v$w$D#x$ ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-list-mode.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-list-m... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-list-mode.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-list-mode.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,22 @@ +/* XPM */ +static const char * pkg_list_mode_xpm[] = { +"16 16 3 1", +" c None", +". c #000000", +"+ c #707070", +" ", +" ......... ", +" +++++++++ ", +" ", +" ", +" ............ ", +" ++++++++++++ ", +" ", +" ", +" ......... ", +" +++++++++ ", +" ", +" ", +" ............ ", +" ++++++++++++ ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-locked.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-locked... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-locked.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-locked.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,109 @@ +/* XPM */ +static const char * pkg_locked_xpm[] = { +"16 16 90 1", +" c None", +". c #000000", +"+ c #1E1E1E", +"@ c #7A7A7A", +"# c #D2D2D2", +"$ c #DBDBDB", +"% c #BCBCBC", +"& c #727272", +"* c #080808", +"= c #848484", +"- c #BEBEBE", +"; c #383838", +"> c #1C1C1C", +", c #4D4D4D", +"' c #B1B1B1", +") c #2D2D2D", +"! c #C2C2C2", +"~ c #090909", +"{ c #2E2E2E", +"] c #AAAAAA", +"^ c #2B2B2B", +"/ c #C0C0C0", +"( c #161616", +"_ c #C1C0C0", +": c #13110E", +"< c #9B9794", +"[ c #201D1C", +"} c #0B0B07", +"| c #040302", +"1 c #050403", +"2 c #2F2921", +"3 c #A8A39E", +"4 c #1A130B", +"5 c #A59176", +"6 c #E0C4A0", +"7 c #DFC4A3", +"8 c #DABE9A", +"9 c #D6BA94", +"0 c #CDA676", +"a c #815A2B", +"b c #E2C5A1", +"c c #D8B58C", +"d c #CA9F68", +"e c #AC8758", +"f c #A78252", +"g c #A78253", +"h c #A37B4B", +"i c #BC8849", +"j c #AC712E", +"k c #E3C6A2", +"l c #D5AE7E", +"m c #B08D5F", +"n c #D5B284", +"o c #CFAB7C", +"p c #CFAC7B", +"q c #CBA471", +"r c #BC8746", +"s c #AA6F2B", +"t c #E1C4A0", +"u c #D0A674", +"v c #C79B64", +"w c #AA8455", +"x c #A47E4E", +"y c #A07744", +"z c #BA8442", +"A c #E1C29C", +"B c #CEA470", +"C c #AD8D64", +"D c #D2B289", +"E c #CDAC83", +"F c #CEAD83", +"G c #CCA77B", +"H c #B8803E", +"I c #AD7332", +"J c #E0C29E", +"K c #D4AC79", +"L c #CDA66E", +"M c #AF8D5E", +"N c #AB8758", +"O c #AB8858", +"P c #A8814C", +"Q c #B47E3E", +"R c #D0A874", +"S c #C6965D", +"T c #BE8D50", +"U c #BA894B", +"V c #BD8C4E", +"W c #BC8A4C", +"X c #BA8647", +"Y c #A47136", +" ", +" .... ", +" +@#$$%&* ", +" =-;>>,'= ", +" )!~ {]. ", +" ^/. (_. ", +" :<[}||1234 ", +" .567788890a. ", +" .bcdeffghij. ", +" .klmnoopqrs. ", +" .tuvwxxxyzj. ", +" .ABCDEEFGHI. ", +" .JKLMNNOPrQ. ", +" .RSTTUUVWXY. ", +" .......... ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-remove-auto.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-remove... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-remove-auto.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-remove-auto.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,424 @@ +/* XPM */ +static const char * pkg_remove_auto_xpm[] = { +"32 32 389 2", +" c None", +". c #8D8E89", +"+ c #888A85", +"@ c #8B8D88", +"# c #8D8F8A", +"$ c #F3F3F3", +"% c #F7F7F7", +"& c #F6F6F6", +"* c #F5F5F5", +"= c #F2F2F2", +"- c #E6E6E6", +"; c #E5E5E5", +"> c #E4E4E4", +", c #E3E3E3", +"' c #E2E2E2", +") c #E1E1E1", +"! c #F4F4F4", +"~ c #204B88", +"{ c #234D8A", +"] c #868A88", +"^ c #F1F1F1", +"/ c #CACACA", +"( c #C3C3C3", +"_ c #C2C2C2", +": c #C1C1C1", +"< c #C8C8C8", +"[ c #E0E0E0", +"} c #244E8C", +"| c #224C89", +"1 c #5485C5", +"2 c #598BCB", +"3 c #7D8181", +"4 c #DDDDDD", +"5 c #CECECE", +"6 c #CDCDCD", +"7 c #CCCCCC", +"8 c #CBCBCB", +"9 c #DEDEDE", +"0 c #7D7F7A", +"a c #4C7DBC", +"b c #214C89", +"c c #3965A2", +"d c #6090CD", +"e c #727676", +"f c #C9C9C9", +"g c #BABABA", +"h c #A6A6A6", +"i c #9F9F9F", +"j c #9E9E9E", +"k c #A4A4A4", +"l c #B8B8B8", +"m c #B7B7B7", +"n c #B6B6B6", +"o c #727470", +"p c #325F9C", +"q c #5B86C1", +"r c #406492", +"s c #646763", +"t c #6B6D69", +"u c #6A6B67", +"v c #6D6E6A", +"w c #395983", +"x c #224C8A", +"y c #28528E", +"z c #769FD4", +"A c #5A8BCB", +"B c #3B5D88", +"C c #243953", +"D c #243954", +"E c #263B56", +"F c #263B57", +"G c #273D59", +"H c #273E5A", +"I c #283E5B", +"J c #283F5D", +"K c #29405E", +"L c #29415F", +"M c #2A4261", +"N c #2B4362", +"O c #2B4463", +"P c #2C4565", +"Q c #2D4666", +"R c #2D4768", +"S c #2E4869", +"T c #2E496A", +"U c #2F4A6C", +"V c #304B6D", +"W c #3C5074", +"X c #5C85C2", +"Y c #5E8ECC", +"Z c #2B5793", +"` c #5179B1", +" . c #739DD3", +".. c #5F81BC", +"+. c #89425D", +"@. c #AB1213", +"#. c #AB1314", +"$. c #884B67", +"%. c #5477AE", +"&. c #7499C8", +"*. c #6794CE", +"=. c #588ACA", +"-. c #667AB0", +";. c #BE4E52", +">. c #E18080", +",. c #E17E7E", +"'. c #B84C52", +"). c #758BBC", +"!. c #234D89", +"~. c #224D8A", +"{. c #7A9AC5", +"]. c #5581BA", +"^. c #4978B5", +"/. c #4878B5", +"(. c #4976B2", +"_. c #704D72", +":. c #6B5178", +"<. c #4877B3", +"[. c #668DC1", +"}. c #2F5892", +"|. c #214B88", +"1. c #587BAB", +"2. c #809DC2", +"3. c #819EC3", +"4. c #809DC3", +"5. c #7F9DC2", +"6. c #7E9BC1", +"7. c #7C9AC1", +"8. c #7C9AC0", +"9. c #7A98C0", +"0. c #7998BF", +"a. c #7897BE", +"b. c #7796BE", +"c. c #7595BD", +"d. c #7494BD", +"e. c #7393BC", +"f. c #7192BB", +"g. c #7191BB", +"h. c #7091BB", +"i. c #6E8FBA", +"j. c #6D8FBA", +"k. c #6C8EB9", +"l. c #6A8CB7", +"m. c #29518C", +"n. c #204A85", +"o. c #204A87", +"p. c #204986", +"q. c #898A89", +"r. c #B8B9B6", +"s. c #8B8D89", +"t. c #838581", +"u. c #C6C6C5", +"v. c #BDBEBD", +"w. c #B3B4B3", +"x. c #B0B0AF", +"y. c #A9AAA8", +"z. c #B0B1B0", +"A. c #C4C5C4", +"B. c #B1B2B1", +"C. c #ADADAC", +"D. c #B6B7B5", +"E. c #ABACAA", +"F. c #B5B5B4", +"G. c #787A76", +"H. c #9D9E9B", +"I. c #BFC0BD", +"J. c #C3C4C3", +"K. c #7D7F7C", +"L. c #888985", +"M. c #848581", +"N. c #C0C1C0", +"O. c #BBBBBB", +"P. c #BCBDBC", +"Q. c #B4B5B4", +"R. c #BFC0BF", +"S. c #BFBFBE", +"T. c #A4A4A3", +"U. c #B2B3B2", +"V. c #C8C8C7", +"W. c #C6C6C6", +"X. c #B1B1B0", +"Y. c #B4B5B3", +"Z. c #B9B9B8", +"`. c #7C7D7A", +" + c #A9AAA6", +".+ c #C8C8C6", +"++ c #C0C1BE", +"@+ c #727371", +"#+ c #BEBFBC", +"$+ c #8E908A", +"%+ c #898B86", +"&+ c #BDBDBC", +"*+ c #BEBFBE", +"=+ c #B6B7B6", +"-+ c #BEBEBD", +";+ c #D2D2D2", +">+ c #A6A7A5", +",+ c #C7C8C7", +"'+ c #C9C9C8", +")+ c #B2B3B1", +"!+ c #C1C2C1", +"~+ c #CFCFCF", +"{+ c #B8B9B8", +"]+ c #BABAB9", +"^+ c #B8B9B5", +"/+ c #D2D3D0", +"(+ c #BCBDBA", +"_+ c #686A66", +":+ c #C4C5C2", +"<+ c #92948F", +"[+ c #CBCCCB", +"}+ c #C4C4C3", +"|+ c #BDBEBC", +"1+ c #C3C3C2", +"2+ c #D3D3D3", +"3+ c #AFB0AE", +"4+ c #CDCDCC", +"5+ c #D1D1D1", +"6+ c #BBBCBA", +"7+ c #B7B7B6", +"8+ c #C5C6C5", +"9+ c #D6D6D6", +"0+ c #8F918C", +"a+ c #BFC0BC", +"b+ c #D8D9D6", +"c+ c #B5B7B3", +"d+ c #C8C9C7", +"e+ c #999A93", +"f+ c #92938E", +"g+ c #D9D9D9", +"h+ c #C9CAC9", +"i+ c #C7C7C6", +"j+ c #BFC0BE", +"k+ c #DBDBDB", +"l+ c #BEBFBD", +"m+ c #C2C2C1", +"n+ c #D0D0CF", +"o+ c #DFDFDF", +"p+ c #C1C2C0", +"q+ c #C3C4C2", +"r+ c #CACAC9", +"s+ c #B6B6B5", +"t+ c #989994", +"u+ c #C8C8C4", +"v+ c #DEDEDC", +"w+ c #ABADA9", +"x+ c #C8C9C6", +"y+ c #9C9E9A", +"z+ c #91938F", +"A+ c #EAEAEA", +"B+ c #D8D8D7", +"C+ c #D2D2D1", +"D+ c #A0A09D", +"E+ c #CFCFCE", +"F+ c #CBCBCA", +"G+ c #D6D6D5", +"H+ c #E0E0DF", +"I+ c #D1D2D1", +"J+ c #B2B3B0", +"K+ c #9EA09B", +"L+ c #CCCDC9", +"M+ c #E2E3E0", +"N+ c #A1A29E", +"O+ c #555753", +"P+ c #565854", +"Q+ c #A0A19E", +"R+ c #E7E7E6", +"S+ c #E3E4E3", +"T+ c #E8E8E8", +"U+ c #929490", +"V+ c #DEDEDD", +"W+ c #D5D5D4", +"X+ c #DDDEDD", +"Y+ c #DADAD9", +"Z+ c #D3D4D2", +"`+ c #DCDCDC", +" @ c #D4D5D4", +".@ c #AAABA8", +"+@ c #E4E4E3", +"@@ c #A0A29E", +"#@ c #D1D2CE", +"$@ c #E7E7E5", +"%@ c #90928F", +"&@ c #575955", +"*@ c #DBDCDA", +"=@ c #BABBB9", +"-@ c #585A56", +";@ c #EDEDEC", +">@ c #EFEFEE", +",@ c #D3D3D2", +"'@ c #AFB1AB", +")@ c #C4C4C2", +"!@ c #E9E9E9", +"~@ c #D9D9D8", +"{@ c #E7E7E7", +"]@ c #D1D2D0", +"^@ c #D7D8D7", +"/@ c #EBEBEA", +"(@ c #F0F0F0", +"_@ c #9A9B96", +":@ c #EEEEED", +"<@ c #D4D5D1", +"[@ c #EBEBE9", +"}@ c #838480", +"|@ c #DCDDDB", +"1@ c #595B57", +"2@ c #949591", +"3@ c #E1E2E1", +"4@ c #D2D3D1", +"5@ c #AEAFAC", +"6@ c #B5B7B1", +"7@ c #A0A29D", +"8@ c #BABBB8", +"9@ c #AEB0AC", +"0@ c #E2E3E2", +"a@ c #9D9E99", +"b@ c #A2A39F", +"c@ c #B5B6B2", +"d@ c #D7D8D3", +"e@ c #767774", +"f@ c #A9ABA5", +"g@ c #9FA09B", +"h@ c #969794", +"i@ c #BBBDB7", +"j@ c #B3B5AF", +"k@ c #959792", +"l@ c #999A96", +"m@ c #9B9D98", +"n@ c #A2A39E", +"o@ c #ABADA7", +"p@ c #979995", +"q@ c #989995", +"r@ c #9A9C97", +"s@ c #A6A7A2", +"t@ c #B2B4AE", +"u@ c #C8C9C3", +"v@ c #EBECEA", +"w@ c #5A5C58", +"x@ c #DDDEDC", +"y@ c #B9BBB5", +"z@ c #CBCDC7", +"A@ c #D7D8D4", +"B@ c #DCDDDA", +"C@ c #C0C1BF", +"D@ c #CDCEC8", +"E@ c #D9DAD6", +"F@ c #E8E8E6", +"G@ c #C4C5C3", +"H@ c #AEB0AA", +"I@ c #C6C8C2", +"J@ c #DADAD6", +"K@ c #E3E4E1", +"L@ c #CCCDCB", +"M@ c #AFB1AD", +"N@ c #B0B1AE", +"O@ c #B0B2AE", +"P@ c #B1B2AD", +"Q@ c #B1B3AF", +"R@ c #B2B3AE", +"S@ c #B2B4AF", +"T@ c #B2B3AF", +"U@ c #B3B4B1", +"V@ c #B4B5B1", +"W@ c #B4B5B0", +"X@ c #B5B6B1", +"Y@ c #B4B5B2", +"Z@ c #BEC0BC", +"`@ c #D3D4D1", +" # c #D8D9D5", +".# c #D4D5D3", +"+# c #C3C4C1", +"@# c #C7C7C5", +"## c #C7C7C4", +"$# c #C6C7C4", +"%# c #C6C6C3", +" c #C5C6C3", +"*# c #C5C5C3", +"=# c #C5C5C2", +"-# c #C6C6C4", +";# c #DBDBD9", +"># c #D7D8D6", +",# c #D9D9D7", +"'# c #DDDDDC", +")# c #DEDFDD", +"!# c #DFDFDD", +"~# c #DFDFDE", +"{# c #5F5F5D", +"]# c #454744", +"^# c #414541", +" ", +" . + + + + + + + + + + + + + + + + + + @ ", +" # $ % & & & & & & & & & & & & * * * * + ", +" @ = - ; > > , , , , , ' ' ' ' ) ' , ! + ", +" ~ { ] ^ , / ( ( _ _ _ _ _ _ _ _ : : < [ $ + } | ", +" | 1 2 3 4 5 6 7 8 8 8 8 / 8 7 7 8 8 8 8 / 9 0 2 a b ", +" c d 2 e f g h i i i i j j k l m m m m m n / o 2 2 p ", +" { q d r s t u u u u u u u u u u u u u u u u v u w 2 a x ", +" y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ", +" | ` .2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 ..+.@.#.$.%.{ ", +" } &.*.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.-.;.>.,.'.).!. ", +" ~.{.].^.^.^.^.^.^.^.^.^././././././././././././.(._.:.<.[.}. ", +" |.1.2.3.3.3.3.3.3.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m. ", +" n.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.p. ", +" q.r.s.t.u.v.v.w._ x.f y.z.A.f B.C.v.5 D.E.F.G.H.I.J. ", +" K.r.L.M.N.O.P.Q.R.S.5 T.U.V.W.X.X._ 6 Y.C.Z.`. +.+++ ", +" @+#+$+%+( &+*+=+S.-+;+>+Q.,+'+Y.)+!+~+{+B.]+%+^+/+(+ ", +" _+:+<+# [+}+A.|+1+-+2+3+{+4+5+6+7+8+9+N.7+v.0+a+b+c+ ", +" d+e+f+g+4 h+i+4+j+k+l+m+n+o+p+q+r+[ ;+s+m+t+u+v+w+ ", +" x+y+z+A+4+B+C+, D+, E+F+G+H+F+I+E+> ; J+'+K+L+M+N+ ", +" O+P+O+O+Q+R+S+T+U+V+[ W+X+Y+Z+`+ @- = .@+@@@#@$@%@ ", +" &@*@=@-@<+;@>@,@'@)@!@~@{@]@4+{@^@/@(@_@:@3+<@[@}@ ", +" P+|@6+1@2@3@4@5@6@7@{@,@V+8@9@W+W+3@0@a@b@c@d@[@e@ ", +" O+|@6+1@f@g@h@'@i@j@k@l@m@n@o@7@p@q@r@s@t@u@d@v@ ", +"O+O+O+P+w@x@6+w@O+O+O+O+i@i@i@i@y@i@i@i@i@i@i@i@i@z@A@v@ ", +"O+B@|@x@|@|@C@C@C@C@p+O+i@i@i@i@i@i@i@i@i@i@i@i@i@D@E@F@ ", +"O+*@G@q+q+q+q+q+q+q+q+O+H@H@H@H@H@H@H@H@H@H@H@H@H@I@J@K@ ", +"O+O+O+O+O+L@L@-@O+O+O+O+M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ # ", +" O+.#.#-@+#@#@###$#$#$#$#%#%#*#*#=#-#;#(+ ", +" O+>#>#-@,#'#'#X+V+v+v+v+V+V+)#)#)#!#!#~#~#B@m+{# ", +" O+Z+Z+P+]#]#]#]#]#]#]#]#]#]#]#]#]#]#]#]#]#]#^# ", +" P+&@&@P+ "}; Added: trunk/gtk/unstable/src/icons/pkg-remove.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-remove... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-remove.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-remove.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,435 @@ +/* XPM */ +static const char * pkg_remove_xpm[] = { +"32 32 400 2", +" c None", +". c #8D8E89", +"+ c #888A85", +"@ c #8B8D88", +"# c #8D8F8A", +"$ c #F3F3F3", +"% c #F7F7F7", +"& c #F6F6F6", +"* c #F5F5F5", +"= c #F2F2F2", +"- c #E6E6E6", +"; c #E5E5E5", +"> c #E4E4E4", +", c #E3E3E3", +"' c #E2E2E2", +") c #E1E1E1", +"! c #F4F4F4", +"~ c #204B88", +"{ c #234D8A", +"] c #868A88", +"^ c #F1F1F1", +"/ c #CACACA", +"( c #C3C3C3", +"_ c #C2C2C2", +": c #C1C1C1", +"< c #C8C8C8", +"[ c #E0E0E0", +"} c #244E8C", +"| c #224C89", +"1 c #5485C5", +"2 c #598BCB", +"3 c #7D8181", +"4 c #DDDDDD", +"5 c #CECECE", +"6 c #CDCDCD", +"7 c #CCCCCC", +"8 c #CBCBCB", +"9 c #DEDEDE", +"0 c #7D7F7A", +"a c #4C7DBC", +"b c #214C89", +"c c #3965A2", +"d c #6090CD", +"e c #727676", +"f c #C9C9C9", +"g c #BABABA", +"h c #A6A6A6", +"i c #9F9F9F", +"j c #9E9E9E", +"k c #A4A4A4", +"l c #B8B8B8", +"m c #B7B7B7", +"n c #B6B6B6", +"o c #727470", +"p c #325F9C", +"q c #5B86C1", +"r c #406492", +"s c #646763", +"t c #6B6D69", +"u c #6A6B67", +"v c #6D6E6A", +"w c #395983", +"x c #224C8A", +"y c #28528E", +"z c #769FD4", +"A c #5A8BCB", +"B c #3B5D88", +"C c #243953", +"D c #243954", +"E c #263B56", +"F c #263B57", +"G c #273D59", +"H c #273E5A", +"I c #283E5B", +"J c #283F5D", +"K c #29405E", +"L c #29415F", +"M c #2A4261", +"N c #2B4362", +"O c #2B4463", +"P c #2C4565", +"Q c #2D4666", +"R c #2D4768", +"S c #2E4869", +"T c #2E496A", +"U c #2F4A6C", +"V c #304B6D", +"W c #3C5074", +"X c #5C85C2", +"Y c #5E8ECC", +"Z c #2B5793", +"` c #5179B1", +" . c #739DD3", +".. c #5F81BC", +"+. c #89425D", +"@. c #AB1213", +"#. c #AB1314", +"$. c #884B67", +"%. c #5477AE", +"&. c #7499C8", +"*. c #6794CE", +"=. c #588ACA", +"-. c #667AB0", +";. c #BE4E52", +">. c #E18080", +",. c #E17E7E", +"'. c #B84C52", +"). c #758BBC", +"!. c #234D89", +"~. c #224D8A", +"{. c #7A9AC5", +"]. c #5581BA", +"^. c #4978B5", +"/. c #4878B5", +"(. c #4976B2", +"_. c #704D72", +":. c #6B5178", +"<. c #4877B3", +"[. c #668DC1", +"}. c #2F5892", +"|. c #214B88", +"1. c #587BAB", +"2. c #809DC2", +"3. c #819EC3", +"4. c #809DC3", +"5. c #7F9DC2", +"6. c #7E9BC1", +"7. c #7C9AC1", +"8. c #7C9AC0", +"9. c #7A98C0", +"0. c #7998BF", +"a. c #7897BE", +"b. c #7796BE", +"c. c #7595BD", +"d. c #7494BD", +"e. c #7393BC", +"f. c #7192BB", +"g. c #7191BB", +"h. c #7091BB", +"i. c #6E8FBA", +"j. c #6D8FBA", +"k. c #6C8EB9", +"l. c #6A8CB7", +"m. c #29518C", +"n. c #204A85", +"o. c #204A87", +"p. c #204986", +"q. c #898A89", +"r. c #B8B9B6", +"s. c #8B8D89", +"t. c #838581", +"u. c #C6C6C5", +"v. c #BDBEBD", +"w. c #B3B4B3", +"x. c #B0B0AF", +"y. c #A9AAA8", +"z. c #B0B1B0", +"A. c #C4C5C4", +"B. c #B1B2B1", +"C. c #ADADAC", +"D. c #B6B7B5", +"E. c #ABACAA", +"F. c #B5B5B4", +"G. c #787A76", +"H. c #9D9E9B", +"I. c #BFC0BD", +"J. c #C3C4C3", +"K. c #7D7F7C", +"L. c #888985", +"M. c #848581", +"N. c #C0C1C0", +"O. c #BBBBBB", +"P. c #BCBDBC", +"Q. c #B4B5B4", +"R. c #BFC0BF", +"S. c #BFBFBE", +"T. c #A4A4A3", +"U. c #B2B3B2", +"V. c #C8C8C7", +"W. c #C6C6C6", +"X. c #B1B1B0", +"Y. c #B4B5B3", +"Z. c #B9B9B8", +"`. c #7C7D7A", +" + c #A9AAA6", +".+ c #C8C8C6", +"++ c #C0C1BE", +"@+ c #727371", +"#+ c #BEBFBC", +"$+ c #8E908A", +"%+ c #898B86", +"&+ c #BDBDBC", +"*+ c #BEBFBE", +"=+ c #B6B7B6", +"-+ c #BEBEBD", +";+ c #D2D2D2", +">+ c #A6A7A5", +",+ c #C7C8C7", +"'+ c #C9C9C8", +")+ c #B2B3B1", +"!+ c #C1C2C1", +"~+ c #CFCFCF", +"{+ c #B8B9B8", +"]+ c #BABAB9", +"^+ c #B8B9B5", +"/+ c #D2D3D0", +"(+ c #BCBDBA", +"_+ c #686A66", +":+ c #C4C5C2", +"<+ c #92948F", +"[+ c #CBCCCB", +"}+ c #C4C4C3", +"|+ c #BDBEBC", +"1+ c #C3C3C2", +"2+ c #D3D3D3", +"3+ c #AFB0AE", +"4+ c #CDCDCC", +"5+ c #D1D1D1", +"6+ c #BBBCBA", +"7+ c #B7B7B6", +"8+ c #C5C6C5", +"9+ c #D6D6D6", +"0+ c #8F918C", +"a+ c #BFC0BC", +"b+ c #D8D9D6", +"c+ c #B5B7B3", +"d+ c #C8C9C7", +"e+ c #999A93", +"f+ c #92938E", +"g+ c #D9D9D9", +"h+ c #C9CAC9", +"i+ c #C7C7C6", +"j+ c #BFC0BE", +"k+ c #DBDBDB", +"l+ c #BEBFBD", +"m+ c #C2C2C1", +"n+ c #D0D0CF", +"o+ c #DFDFDF", +"p+ c #C1C2C0", +"q+ c #C3C4C2", +"r+ c #CACAC9", +"s+ c #B6B6B5", +"t+ c #989994", +"u+ c #C8C8C4", +"v+ c #DEDEDC", +"w+ c #ABADA9", +"x+ c #CCCDCA", +"y+ c #9EA09C", +"z+ c #929490", +"A+ c #EAEAEA", +"B+ c #D8D8D7", +"C+ c #D2D2D1", +"D+ c #A0A09D", +"E+ c #CFCFCE", +"F+ c #CBCBCA", +"G+ c #D6D6D5", +"H+ c #E0E0DF", +"I+ c #D1D2D1", +"J+ c #B2B3B0", +"K+ c #9EA09B", +"L+ c #CCCDC9", +"M+ c #E2E3E0", +"N+ c #A1A29E", +"O+ c #CACBC8", +"P+ c #A7A9A3", +"Q+ c #AEAEAC", +"R+ c #A3A4A1", +"S+ c #E7E7E6", +"T+ c #E3E4E3", +"U+ c #E8E8E8", +"V+ c #DEDEDD", +"W+ c #D5D5D4", +"X+ c #DDDEDD", +"Y+ c #DADAD9", +"Z+ c #D3D4D2", +"`+ c #DCDCDC", +" @ c #D4D5D4", +".@ c #AAABA8", +"+@ c #E4E4E3", +"@@ c #A0A29E", +"#@ c #D1D2CE", +"$@ c #E7E7E5", +"%@ c #90928F", +"&@ c #CACAC8", +"*@ c #A9ABA7", +"=@ c #DCDDDC", +"-@ c #F8F8F8", +";@ c #959792", +">@ c #EDEDEC", +",@ c #EFEFEE", +"'@ c #D3D3D2", +")@ c #AFB1AB", +"!@ c #C4C4C2", +"~@ c #E9E9E9", +"{@ c #D9D9D8", +"]@ c #E7E7E7", +"^@ c #D1D2D0", +"/@ c #D7D8D7", +"(@ c #EBEBEA", +"_@ c #F0F0F0", +":@ c #9A9B96", +"<@ c #EEEEED", +"[@ c #D4D5D1", +"}@ c #EBEBE9", +"|@ c #838480", +"1@ c #C6C7C4", +"2@ c #BABCB6", +"3@ c #A2A4A0", +"4@ c #989995", +"5@ c #E1E2E1", +"6@ c #D2D3D1", +"7@ c #AEAFAC", +"8@ c #B5B7B1", +"9@ c #A0A29D", +"0@ c #BABBB8", +"a@ c #AEB0AC", +"b@ c #E2E3E2", +"c@ c #9D9E99", +"d@ c #A2A39F", +"e@ c #B5B6B2", +"f@ c #D7D8D3", +"g@ c #767774", +"h@ c #C1C2BE", +"i@ c #BDBFBC", +"j@ c #A3A5A0", +"k@ c #9FA19C", +"l@ c #AEB0AA", +"m@ c #9FA09B", +"n@ c #969794", +"o@ c #BBBDB7", +"p@ c #B3B5AF", +"q@ c #999A96", +"r@ c #9B9D98", +"s@ c #A2A39E", +"t@ c #ABADA7", +"u@ c #979995", +"v@ c #9A9C97", +"w@ c #A6A7A2", +"x@ c #B2B4AE", +"y@ c #C8C9C3", +"z@ c #EBECEA", +"A@ c #BBBCB9", +"B@ c #C1C3BE", +"C@ c #B9BBB5", +"D@ c #CBCDC7", +"E@ c #D7D8D4", +"F@ c #C4C5C0", +"G@ c #CDCEC8", +"H@ c #D9DAD6", +"I@ c #E8E8E6", +"J@ c #AAADA9", +"K@ c #C7C8C4", +"L@ c #B4B6B0", +"M@ c #C6C8C2", +"N@ c #DADAD6", +"O@ c #E3E4E1", +"P@ c #C5C5C3", +"Q@ c #B2B4AF", +"R@ c #ADAFAB", +"S@ c #AEAFAB", +"T@ c #B0B1AC", +"U@ c #B0B2AC", +"V@ c #AFB1AD", +"W@ c #B0B1AE", +"X@ c #B0B2AE", +"Y@ c #B1B2AD", +"Z@ c #B1B3AF", +"`@ c #B2B3AE", +" # c #B2B3AF", +".# c #B3B4B1", +"+# c #B4B5B1", +"@# c #B4B5B0", +"## c #B5B6B1", +"$# c #B4B5B2", +"%# c #BEC0BC", +" c #D3D4D1", +"*# c #D8D9D5", +"=# c #6B6D6B", +"-# c #C7C8C5", +";# c #C7C7C5", +"># c #C7C7C4", +",# c #C6C6C3", +"'# c #C5C6C3", +")# c #C5C5C2", +"!# c #C6C6C4", +"~# c #DBDBD9", +"{# c #484946", +"]# c #B3B3B0", +"^# c #DCDDDB", +"/# c #DDDDDB", +"(# c #DDDDDC", +"_# c #DEDFDD", +":# c #DFDFDD", +"<# c #DFDFDE", +"[# c #DCDDDA", +"}# c #5F5F5D", +"|# c #424442", +"1# c #454643", +"2# c #454744", +"3# c #414541", +" ", +" . + + + + + + + + + + + + + + + + + + @ ", +" # $ % & & & & & & & & & & & & * * * * + ", +" @ = - ; > > , , , , , ' ' ' ' ) ' , ! + ", +" ~ { ] ^ , / ( ( _ _ _ _ _ _ _ _ : : < [ $ + } | ", +" | 1 2 3 4 5 6 7 8 8 8 8 / 8 7 7 8 8 8 8 / 9 0 2 a b ", +" c d 2 e f g h i i i i j j k l m m m m m n / o 2 2 p ", +" { q d r s t u u u u u u u u u u u u u u u u v u w 2 a x ", +" y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ", +" | ` .2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 ..+.@.#.$.%.{ ", +" } &.*.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.-.;.>.,.'.).!. ", +" ~.{.].^.^.^.^.^.^.^.^.^././././././././././././.(._.:.<.[.}. ", +" |.1.2.3.3.3.3.3.3.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m. ", +" n.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.p. ", +" q.r.s.t.u.v.v.w._ x.f y.z.A.f B.C.v.5 D.E.F.G.H.I.J. ", +" K.r.L.M.N.O.P.Q.R.S.5 T.U.V.W.X.X._ 6 Y.C.Z.`. +.+++ ", +" @+#+$+%+( &+*+=+S.-+;+>+Q.,+'+Y.)+!+~+{+B.]+%+^+/+(+ ", +" _+:+<+# [+}+A.|+1+-+2+3+{+4+5+6+7+8+9+N.7+v.0+a+b+c+ ", +" d+e+f+g+4 h+i+4+j+k+l+m+n+o+p+q+r+[ ;+s+m+t+u+v+w+ ", +" x+y+z+A+4+B+C+, D+, E+F+G+H+F+I+E+> ; J+'+K+L+M+N+ ", +" O+P+Q+& R+S+T+U+z+V+[ W+X+Y+Z+`+ @- = .@+@@@#@$@%@ ", +" &@*@=@-@;@>@,@'@)@!@~@{@]@^@4+]@/@(@_@:@<@3+[@}@|@ ", +" 1@2@3@H+4@5@6@7@8@9@]@'@V+0@a@W+W+5@b@c@d@e@f@}@g@ ", +" h@i@j@k@l@m@n@)@o@p@;@q@r@s@t@9@u@4@v@w@x@y@f@z@ ", +" A@B@o@o@o@o@o@o@o@o@o@o@C@o@o@o@o@o@o@o@o@D@E@z@ ", +" F.F@o@o@o@o@o@o@o@o@o@o@o@o@o@o@o@o@o@o@o@G@H@I@ ", +" J@K@L@l@l@l@l@l@l@l@l@l@l@l@l@l@l@l@l@l@l@M@N@O@ ", +" q@P@Q@R@S@a@T@U@V@W@X@Y@Z@`@Q@ #.#+#@###$#%#*# ", +" =#W+x+-#-#;#;#>#1@1@1@1@,#,#'#'#'#'#P@P@)#!#~#(+ ", +" {#]#^#/#/#(#(#X+V+v+v+v+V+V+_#_#_#:#:#<#<#[#m+}# ", +" |#1#2#2#2#2#2#2#2#2#2#2#2#2#2#2#2#2#2#2#2#3# ", +" "}; Added: trunk/gtk/unstable/src/icons/pkg-tiles-mode.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-tiles-... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-tiles-mode.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-tiles-mode.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,22 @@ +/* XPM */ +static const char * pkg_tiles_mode_xpm[] = { +"16 16 3 1", +" c None", +". c #000000", +"+ c #707070", +" ", +" ...... ...... ", +" .++++.+ .++++.+", +" .+ .+ .+ .+", +" .+ .+ .+ .+", +" .+ .+ .+ .+", +" ......+ ......+", +" ++++++ ++++++", +" ", +" ...... ...... ", +" .++++.+ .++++.+", +" .+ .+ .+ .+", +" .+ .+ .+ .+", +" .+ .+ .+ .+", +" ......+ ......+", +" ++++++ ++++++"}; Added: trunk/gtk/unstable/src/icons/pkg-unlocked.xpm URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/icons/pkg-unlock... ============================================================================== --- trunk/gtk/unstable/src/icons/pkg-unlocked.xpm (added) +++ trunk/gtk/unstable/src/icons/pkg-unlocked.xpm Thu Nov 29 18:22:01 2007 @@ -0,0 +1,107 @@ +/* XPM */ +static const char * pkg_unlocked_xpm[] = { +"16 16 88 1", +" c None", +". c #000000", +"+ c #1E1E1E", +"@ c #7A7A7A", +"# c #D2D2D2", +"$ c #DBDBDB", +"% c #727272", +"& c #080808", +"* c #848484", +"= c #BEBEBE", +"- c #363636", +"; c #1D1D1D", +"> c #B1B1B1", +", c #2D2D2D", +"' c #C2C2C2", +") c #090909", +"! c #2E2E2E", +"~ c #AAAAAA", +"{ c #2B2B2B", +"] c #C0C0C0", +"^ c #161616", +"/ c #C1C0C0", +"( c #13110E", +"_ c #9B9794", +": c #201D1C", +"< c #0B0B07", +"[ c #040302", +"} c #050403", +"| c #0D0C09", +"1 c #282624", +"2 c #1A130B", +"3 c #A59176", +"4 c #E0C4A0", +"5 c #DFC4A3", +"6 c #DABE9A", +"7 c #D6BA94", +"8 c #CDA676", +"9 c #815A2B", +"0 c #E2C5A1", +"a c #D8B58C", +"b c #CA9F68", +"c c #AC8758", +"d c #A78252", +"e c #A78253", +"f c #A37B4B", +"g c #BC8849", +"h c #AC712E", +"i c #E3C6A2", +"j c #D5AE7E", +"k c #B08D5F", +"l c #D5B284", +"m c #CFAB7C", +"n c #CFAC7B", +"o c #CBA471", +"p c #BC8746", +"q c #AA6F2B", +"r c #E1C4A0", +"s c #D0A674", +"t c #C79B64", +"u c #AA8455", +"v c #A47E4E", +"w c #A07744", +"x c #BA8442", +"y c #E1C29C", +"z c #CEA470", +"A c #AD8D64", +"B c #D2B289", +"C c #CDAC83", +"D c #CEAD83", +"E c #CCA77B", +"F c #B8803E", +"G c #AD7332", +"H c #E0C29E", +"I c #D4AC79", +"J c #CDA66E", +"K c #AF8D5E", +"L c #AB8758", +"M c #AB8858", +"N c #A8814C", +"O c #B47E3E", +"P c #D0A874", +"Q c #C6965D", +"R c #BE8D50", +"S c #BA894B", +"T c #BD8C4E", +"U c #BC8A4C", +"V c #BA8647", +"W c #A47136", +" ", +" .. ", +" +@#$%& ", +" *=-;>* ", +",') !~. ", +"{]. ^/. ", +" (_:<[[}|12 ", +" .3455666789.", +" .0abcddefgh.", +" .ijklmmnopq.", +" .rstuvvvwxh.", +" .yzABCCDEFG.", +" .HIJKLLMNpO.", +" .PQRRSSTUVW.", +" .......... ", +" "}; Added: trunk/gtk/unstable/src/mng-loader.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/mng-loader.c?rev... ============================================================================== --- trunk/gtk/unstable/src/mng-loader.c (added) +++ trunk/gtk/unstable/src/mng-loader.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,342 @@ +#include "mng-loader.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include <sys/mman.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> + +/* Some select chunk IDs, from libmng.h */ +#define MNG_UINT_MHDR 0x4d484452L +#define MNG_UINT_BACK 0x4241434bL +#define MNG_UINT_PLTE 0x504c5445L +#define MNG_UINT_tRNS 0x74524e53L +#define MNG_UINT_IHDR 0x49484452L +#define MNG_UINT_IDAT 0x49444154L +#define MNG_UINT_IEND 0x49454e44L +#define MNG_UINT_MEND 0x4d454e44L +#define MNG_UINT_FRAM 0x4652414dL +#define MNG_UINT_LOOP 0x4c4f4f50L +#define MNG_UINT_ENDL 0x454e444cL +#define MNG_UINT_TERM 0x5445524dL + +//** Utilities to read the MNG file + +typedef gboolean (*ChunkParser)(YGdkMngPixbuf*, guint8*, GError**); + +struct ChunkLoad { + guint8 Id; + ChunkParser Function; + +}; + +static gboolean read_signature (FILE *file) +{ + guchar buf[8]; + fread (buf, 1, 8, file); + return memcmp (buf, "\212MNG\r\n\032\n", 8) == 0; +} + +static gboolean read_uint8 (FILE *file, guint8 *value) +{ + return fread (value, 1, 1, file) >= 1; +} + +static gboolean read_uint32 (FILE *file, guint32 *value) +{ + guint8 buffer[4]; + if (fread (buffer, 1, 4, file) < 4) + return FALSE; + *value = buffer[0] << 24; *value |= buffer[1] << 16; + *value |= buffer[2] << 8; *value |= buffer[3]; + return TRUE; +} + +static gboolean read_data (FILE *file, guint32 size, GdkPixbufLoader *loader, + GError **error) +{ + guchar data [size]; + if (fread (data, 1, size, file) < size) + { + g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + "Unexpected end of file when reading PNG chunk"); + return FALSE; + } + return gdk_pixbuf_loader_write (loader, data, size, error); +} + +static void image_prepared_cb (GdkPixbufLoader *loader, YGdkMngPixbuf *mng_pixbuf) +{ + GdkPixbuf *pix = gdk_pixbuf_loader_get_pixbuf (loader); + mng_pixbuf->frames = g_list_append (mng_pixbuf->frames, pix); +} + +//** YGdkMngPixbuf + +G_DEFINE_TYPE (YGdkMngPixbuf, ygdk_mng_pixbuf, GDK_TYPE_PIXBUF_ANIMATION) + +static void ygdk_mng_pixbuf_init (YGdkMngPixbuf *pixbuf) +{ +} + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, + GError **error_msg) +{ + gboolean error = FALSE; + #define SET_ERROR(msg) { error = TRUE; \ + g_set_error (error_msg, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, msg); } + + FILE *file = fopen (filename, "rb"); + if (!file) + { + SET_ERROR ("Could not open specified file") + return NULL; + } + + if (!read_signature (file)) + { + SET_ERROR ("Not a MNG file") + return NULL; + } + + YGdkMngPixbuf *mng_pixbuf = g_object_new (YGDK_TYPE_MNG_PIXBUF, NULL); + mng_pixbuf->iteration_max = 0x7fffffff; + + guint32 chunk_size, chunk_id; + long offset; + GdkPixbufLoader *loader = NULL; /* currently loading... */ + gboolean first_read = TRUE; + + do { + error = !read_uint32 (file, &chunk_size); + error = error || !read_uint32 (file, &chunk_id); + if (error) + { + SET_ERROR ("Unexpected end of file on new chunk") + break; + } + offset = ftell (file) + chunk_size + 4/*CRC*/; + + if (first_read && chunk_id != MNG_UINT_MHDR) + { + SET_ERROR ("MHDR chunk must come first") + break; + } + + // not currently reading a PNG stream + if (!loader) + { + switch (chunk_id) + { + case MNG_UINT_MHDR: + if (!first_read) + { + SET_ERROR ("Only one MHDR chunk allowed") + break; + } + + if (chunk_size == 7*4) + { + // Read MHDR chunk data + error = !read_uint32 (file, &mng_pixbuf->frame_width); + error = error || !read_uint32 (file, &mng_pixbuf->frame_height); + error = error || !read_uint32 (file, &mng_pixbuf->ticks_per_second); + if (error) + SET_ERROR ("Unexpected end of file on MHDR chunk") + + /* Next atttributes: Nominal_layer_count, Nominal_frame_count, + Nominal_play_time, Simplicity_profile */ + else if (mng_pixbuf->frame_width <= 0 || + mng_pixbuf->frame_height <= 0 || + mng_pixbuf->ticks_per_second < 0) + SET_ERROR ("Invalid MHDR parameter") + } + else + SET_ERROR ("MHDR chunk must be 28 bytes long") + break; + case MNG_UINT_IHDR: + loader = gdk_pixbuf_loader_new_with_type ("png", NULL); + g_signal_connect (G_OBJECT (loader), "area-prepared", + G_CALLBACK (image_prepared_cb), mng_pixbuf); + gdk_pixbuf_loader_set_size (loader, mng_pixbuf->frame_width, + mng_pixbuf->frame_height); + + { + const guchar sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + if(!gdk_pixbuf_loader_write (loader, sig, 8, error_msg)) + { + error = TRUE; + break; + } + } + break; + case MNG_UINT_TERM: + if (chunk_size > 1) + { + // Read TERM chunk data + guint8 t; + error = !read_uint8 (file, &t); // term action + if (t == 3 && chunk_size == 2+8) + { + error = error || !read_uint8 (file, &t); // after term action + error = error || !read_uint32 (file, &mng_pixbuf->last_frame_delay); + error = error || !read_uint32 (file, &mng_pixbuf->iteration_max); + if (error) + SET_ERROR ("Unexpected end of file on TERM chunk") + } + else + SET_ERROR ("TERM chunk must be 10 bytes when term action is 3") + } + else + SET_ERROR ("TERM chunk must have at least 1 byte") + break; + case MNG_UINT_BACK: + // TODO: + break; + case MNG_UINT_IDAT: + case MNG_UINT_IEND: + if (loader != NULL) + SET_ERROR ("Corrupted PNG chunk closures") + break; + case MNG_UINT_MEND: + default: + break; + } + } + + if (error) + break; + + // loading a PNG stream + if (loader) + { + fseek (file, -8, SEEK_CUR); + if (!read_data (file, chunk_size+8+4, loader, error_msg)) + error = TRUE; + else if (chunk_id == MNG_UINT_IEND) + { + if (!gdk_pixbuf_loader_close (loader, error_msg)) + { + error = TRUE; + break; + } + loader = NULL; + } + } + + fseek (file, offset, SEEK_SET); + first_read = FALSE; + } while (chunk_id != MNG_UINT_MEND && !error); + + if (error) + { + g_object_unref (G_OBJECT (mng_pixbuf)); + return NULL; + } + #undef SET_ERROR + + return GDK_PIXBUF_ANIMATION (mng_pixbuf); +} + +gboolean ygdk_mng_pixbuf_is_static_image (GdkPixbufAnimation *anim) +{ + return FALSE; +} + +GdkPixbuf *ygdk_mng_pixbuf_get_static_image (GdkPixbufAnimation *anim) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + return g_list_nth_data (mng_anim->frames, 0); +} + +void ygdk_mng_pixbuf_get_size (GdkPixbufAnimation *anim, int *width, int *height) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + if (width) *width = mng_anim->frame_width; + if (height) *height = mng_anim->frame_height; +} + +GdkPixbufAnimationIter *ygdk_mng_pixbuf_get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + YGdkMngPixbufIter *iter = g_object_new (YGDK_TYPE_MNG_PIXBUF_ITER, NULL); + iter->mng_pixbuf = YGDK_MNG_PIXBUF( anim ); + iter->cur_frame = 0; + return GDK_PIXBUF_ANIMATION_ITER( iter ); +} + +static void ygdk_mng_pixbuf_class_init (YGdkMngPixbufClass *klass) +{ + ygdk_mng_pixbuf_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationClass *pixbuf_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + pixbuf_class->is_static_image = ygdk_mng_pixbuf_is_static_image; + pixbuf_class->get_static_image = ygdk_mng_pixbuf_get_static_image; + pixbuf_class->get_size = ygdk_mng_pixbuf_get_size; + pixbuf_class->get_iter = ygdk_mng_pixbuf_get_iter; +} + +//** YGdkMngPixbufIter + +G_DEFINE_TYPE (YGdkMngPixbufIter, ygdk_mng_pixbuf_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER) + +static void ygdk_mng_pixbuf_iter_init (YGdkMngPixbufIter *iter) +{ +} + +GdkPixbuf *ygdk_mng_pixbuf_iter_get_pixbuf (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + return g_list_nth_data (mng_iter->mng_pixbuf->frames, mng_iter->cur_frame); +} + +gboolean ygdk_mng_pixbuf_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + return FALSE; +} + +int ygdk_mng_pixbuf_iter_get_delay_time (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + int delay = mng_iter->mng_pixbuf->ticks_per_second; + if (mng_iter->cur_frame == g_list_length (mng_iter->mng_pixbuf->frames)-1) + delay += mng_iter->mng_pixbuf->last_frame_delay; + return delay; +} + +gboolean ygdk_mng_pixbuf_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + YGdkMngPixbuf *mng_pixbuf = mng_iter->mng_pixbuf; + if (!mng_pixbuf->frames) + return FALSE; + + gboolean can_advance = TRUE; + int frames_len = g_list_length (mng_pixbuf->frames); + if (mng_iter->cur_frame+1 == frames_len) + { + if (mng_pixbuf->iteration_max == 0x7fffffff || + mng_iter->cur_iteration < mng_pixbuf->iteration_max) + mng_iter->cur_iteration++; + else + can_advance = FALSE; + } + + if (can_advance) + mng_iter->cur_frame = (mng_iter->cur_frame+1) % frames_len; + return can_advance; +} + +static void ygdk_mng_pixbuf_iter_class_init (YGdkMngPixbufIterClass *klass) +{ + ygdk_mng_pixbuf_iter_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationIterClass *iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + iter_class->get_delay_time = ygdk_mng_pixbuf_iter_get_delay_time; + iter_class->get_pixbuf = ygdk_mng_pixbuf_iter_get_pixbuf; + iter_class->on_currently_loading_frame = ygdk_mng_pixbuf_iter_on_currently_loading_frame; + iter_class->advance = ygdk_mng_pixbuf_iter_advance; +} + Added: trunk/gtk/unstable/src/mng-loader.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/mng-loader.h?rev... ============================================================================== --- trunk/gtk/unstable/src/mng-loader.h (added) +++ trunk/gtk/unstable/src/mng-loader.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,72 @@ +/* GdkPixbuf doesn't support MNG files... MNG is a wrapper around PNG + that adds movie playback capabilities. + This code doesn't even cover MNG-VLC (smallest subset of the format), + but is hopefully enough for common uses. */ + +#ifndef YGDK_MNG_PIXBUF_H +#define YGDK_MNG_PIXBUF_H + +#define GDK_PIXBUF_ENABLE_BACKEND +#include <gdk-pixbuf/gdk-pixbuf-animation.h> + +G_BEGIN_DECLS +#define YGDK_TYPE_MNG_PIXBUF (ygdk_mng_pixbuf_get_type ()) +#define YGDK_MNG_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGDK_TYPE_MNG_PIXBUF, YGdkMngPixbuf)) +#define YGDK_MNG_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGDK_TYPE_MNG_PIXBUF, YGdkMngPixbufClass)) +#define YGDK_IS_MNG_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGDK_TYPE_MNG_PIXBUF)) +#define YGDK_IS_MNG_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGDK_TYPE_MNG_PIXBUF)) +#define YGDK_MNG_PIXBUF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGK_TYPE_MNG_PIXBUF, YGdkMngPixbufClass)) + +typedef struct YGdkMngPixbuf +{ + GdkPixbufAnimation parent; + + // private: (use GdkPixbufAnimation API) + GList *frames; // of GdkPixbufs + // MHDR header + guint32 frame_width, frame_height, ticks_per_second; + // TERM header + guint32 last_frame_delay, iteration_max; +} YGdkMngPixbuf; + +typedef struct YGdkMngPixbufClass +{ + GdkPixbufAnimationClass parent_class; +} YGdkMngPixbufClass; + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, GError **error_msg); + +GType ygdk_mng_pixbuf_get_type (void) G_GNUC_CONST; + +#define YGDK_TYPE_MNG_PIXBUF_ITER (ygdk_mng_pixbuf_iter_get_type ()) +#define YGDK_MNG_PIXBUF_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIter)) +#define YGDK_MNG_PIXBUF_ITER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIterClass)) +#define YGDK_IS_MNG_PIXBUF_ITER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), YGDK_TYPE_MNG_PIXBUF_ITER)) +#define YGDK_MNG_PIXBUF_ITER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIterClass)) + +typedef struct YGdkMngPixbufIter { + GdkPixbufAnimationIter parent; + + // private: + YGdkMngPixbuf *mng_pixbuf; + int cur_frame, cur_iteration; +} YGdkMngPixbufIter; + +typedef struct YGdkMngPixbufIterClass { + GdkPixbufAnimationIterClass parent_class; +} YGdkMngPixbufIterClass; + +GType ygdk_mng_pixbuf_iter_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /*YGDK_MNG_PIXBUF_H*/ + Added: trunk/gtk/unstable/src/test.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/test.cc?rev=4251... ============================================================================== --- trunk/gtk/unstable/src/test.cc (added) +++ trunk/gtk/unstable/src/test.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,186 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +#include <config.h> +#include <stdio.h> +#include <YUI.h> +#include <gtk/gtk.h> +#include <YGUtils.h> + +bool testMapKBAccel() +{ + fprintf (stderr, "Test map KB accels\t"); + struct { + const char *in; + const char *out; + } aTests[] = { + { "Foo&", "Foo_" }, + { "B&aa", "B_aa" }, + { "&Foo", "_Foo" }, + { "_Foo", "__Foo" }, +// FIXME - unfortunately it seems yast has noescaping policy +// for labels (hmm) at least judging from the code at +// ncurses/src/NCstring.cc (getHotKey) +// { "&&Foo", "&Foo" }, + { NULL, NULL } + }; + for (int i = 0; aTests[i].in; i++) { + string mapped = YGUtils::mapKBAccel(aTests[i].in); + if (mapped != aTests[i].out) { + fprintf (stderr, "Mis-mapped accel '%s' vs '%s'\n", + mapped.c_str(), aTests[i].out); + return false; + } + fprintf (stderr, "%d ", i); + } + fprintf (stderr, "\n"); + return true; +} + +bool testFilterText () +{ + fprintf (stderr, "Test filter text\t"); + struct { + const char *in; + const char *valid; + const char *out; + } aTests[] = { + { "Foo", "F", "F" }, + { "Foo", "Fo", "Foo" }, + { "Baa", "a", "aa" }, + { "Kuckles", "Ks", "Ks" }, + { NULL, NULL } + }; + for (int i = 0; aTests[i].in; i++) { + string filtered = YGUtils::filterText + (aTests[i].in, strlen (aTests[i].in), aTests[i].valid); + if (filtered != aTests[i].out) { + fprintf (stderr, "Mis-filtered text '%s' vs '%s'\n", + filtered.c_str(), aTests[i].out); + return false; + } + fprintf (stderr, "%d ", i); + } + fprintf (stderr, "\n"); + return true; +} + +bool testXHtmlConvert() +{ + fprintf (stderr, "Test HTML->XML rewrite \t"); + struct { + const char *in; + const char *out; + } aTests[] = { + // preservation + { "<p>foo</p>", "<body><p>foo</p></body>" }, + // product substitution + { "&product;", "<body>foo</body>" }, + { " <p>&product;</p>", "<body><p>foo</p></body>" }, + // outer tag + { "some text", "<body>some text</body>" }, + // unquoted attributes + { "<foo baa=Foo></foo>", "<body><foo baa=\"Foo\"></foo></body>" }, + // break tags + { "<br>", "<body><br/></body>" }, + { "<hr>", "<body><hr/></body>" }, + // unclosed tags + { "<p>", "<body><p></p></body>" }, + { "<b>unclosed", "<body><b>unclosed</b></body>" }, + { "<b><i>bold</i>", "<body><b><i>bold</i></b></body>" }, + { "<i><i>bold</i>", "<body><i><i>bold</i></i></body>" }, + { "<unclosed foo=baa>", + "<body><unclosed foo=\"baa\"></unclosed></body>" }, + // unclosed 'early close' tags + { "<i>Some<p>text<p> here<p></i>", + "<body><i>Some<p>text</p><p> here</p><p></p></i></body>" }, + { "<ul><li>foo<li>baa", + "<body><ul><li>foo</li><li>baa</li></ul></body>" }, + { "no outer<p>unclosed<p>several<b>unclosed bold", + "<body>no outer<p>unclosed</p><p>several<b>unclosed bold</b></p></body>" }, + // multiple white spacing -- proper HTML would had collapsed those multiple + // spaces -- not important anyway + { "one day I will do", "<body>one day I will do</body>" }, + // comment + { "we need <b>to <!-- really need to? --> do something</b> about it.", + "<body>we need <b>to do something</b> about it.</body>" }, + { NULL, NULL } + }; + for (int i = 0; aTests[i].in; i++) { + gchar *out = ygutils_convert_to_xhmlt_and_subst (aTests[i].in, "foo"); + if (strcmp (out, aTests[i].out)) { + fprintf (stderr, "Mis-converted entry %d XML '%s' should be '%s'\n", + i, out, aTests[i].out); + return false; + } + fprintf (stderr, "%d ", i); + g_free (out); + } + fprintf (stderr, "\n"); + return true; +} + +bool testStrCmp() +{ + fprintf (stderr, "Test our strcmp\t"); + struct { + const char *in1, *in2; + int out; + } aTests[] = { + { "aaa", "aaaa", 1 }, + { "29", "235", -1 }, + { "aA", "Aa", 0 }, + { "200rt9", "200rT9", 0 }, + { NULL, NULL } + }; + for (int i = 0; aTests[i].in1; i++) { + int ret = YGUtils::strcmp(aTests[i].in1, aTests[i].in2); + if (ret * aTests[i].out < 0 || (ret && !aTests[i].out) || (!ret && aTests[i].out)) { + fprintf (stderr, "Mis-mapped str comp '%d' vs '%d' ('%s' to '%s')\n", + ret, aTests[i].out, aTests[i].in1, aTests[i].in2); + return false; + } + fprintf (stderr, "%d ", i); + } + fprintf (stderr, "\n"); + return true; +} + +bool testMarkupEscape() +{ + fprintf (stderr, "Test markup escape\t"); + struct { + const char *in; + const char *out; + bool escape_br; + } aTests[] = { + { "< text />", "< text />" }, + { "um\ndois\ntres", "um\ndois\ntres" }, + { NULL, NULL } + }; + for (int i = 0; aTests[i].in; i++) { + string out = YGUtils::escape_markup (aTests[i].in); + if (out != aTests[i].out) { + fprintf (stderr, "Mis-converted entry %d XML '%s' should be '%s'\n", + i, out.c_str(), aTests[i].out); + return false; + } + fprintf (stderr, "%d ", i); + } + fprintf (stderr, "\n"); + return true; +} + +int main (int argc, char **argv) +{ + bool bSuccess = true; + + bSuccess &= testMapKBAccel(); + bSuccess &= testFilterText(); + bSuccess &= testXHtmlConvert(); + bSuccess &= testStrCmp(); + bSuccess &= testMarkupEscape(); + + return !bSuccess; +} Added: trunk/gtk/unstable/src/ygdkmngloader.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygdkmngloader.c?... ============================================================================== --- trunk/gtk/unstable/src/ygdkmngloader.c (added) +++ trunk/gtk/unstable/src/ygdkmngloader.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,410 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGdkMngLoader image loader */ +// check the header file for information about this loader + +#include "ygdkmngloader.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include <sys/mman.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> + +/* A few chunks ids */ +#define MNG_UINT_MHDR 0x4d484452L +#define MNG_UINT_BACK 0x4241434bL +#define MNG_UINT_PLTE 0x504c5445L +#define MNG_UINT_tRNS 0x74524e53L +#define MNG_UINT_IHDR 0x49484452L +#define MNG_UINT_IDAT 0x49444154L +#define MNG_UINT_IEND 0x49454e44L +#define MNG_UINT_MEND 0x4d454e44L +#define MNG_UINT_FRAM 0x4652414dL +#define MNG_UINT_LOOP 0x4c4f4f50L +#define MNG_UINT_ENDL 0x454e444cL +#define MNG_UINT_TERM 0x5445524dL + +//** Utilities to read the MNG file + +typedef struct DataStream { + const guint8 *data; + const long size; + long offset; +} DataStream; +static DataStream data_stream_constructor (const guint8 *raw_data, long size) +{ + DataStream data = { raw_data, size, 0 }; + return data; +} + +static gboolean read_signature (DataStream *data) +{ + if (data->offset+8 > data->size) + return FALSE; + data->offset += 8; + return memcmp (data->data + data->offset-8, "\212MNG\r\n\032\n", 8) == 0; +} + +static gboolean read_uint8 (DataStream *data, guint8 *value) +{ + if (data->offset+1 > data->size) + return FALSE; + *value = data->data [data->offset++]; + return TRUE; +} + +static gboolean read_uint32 (DataStream *data, guint32 *value) +{ + if (data->offset+4 > data->size) + return FALSE; + *value = data->data[data->offset+0] << 24; + *value |= data->data[data->offset+1] << 16; + *value |= data->data[data->offset+2] << 8; + *value |= data->data[data->offset+3]; + data->offset += 4; + return TRUE; +} + +static gboolean read_data (DataStream *data, guint32 size, GdkPixbufLoader *loader, + GError **error) +{ + if (data->offset+size > data->size) + { + g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + "Unexpected end of file when reading PNG chunk"); + return FALSE; + } + gboolean ret; + ret = gdk_pixbuf_loader_write (loader, data->data + data->offset, size, error); + data->offset += size; + return ret; +} + +static void image_prepared_cb (GdkPixbufLoader *loader, YGdkMngPixbuf *mng_pixbuf) +{ + GdkPixbuf *pix = gdk_pixbuf_loader_get_pixbuf (loader); + mng_pixbuf->frames = g_list_append (mng_pixbuf->frames, pix); +} + +//** YGdkMngPixbuf + +G_DEFINE_TYPE (YGdkMngPixbuf, ygdk_mng_pixbuf, GDK_TYPE_PIXBUF_ANIMATION) + +static void ygdk_mng_pixbuf_init (YGdkMngPixbuf *pixbuf) +{ +} + +gboolean ygdk_mng_pixbuf_is_file_mng (const gchar *filename) +{ + FILE *file = fopen (filename, "rb"); + if (!file) + goto is_file_mng_failed; + + guchar raw_data [8]; + if (fread (raw_data, 1, 8, file) < 8) + goto is_file_mng_failed; + + gboolean ret = ygdk_mng_pixbuf_is_data_mng (raw_data, 8); + fclose (file); + return ret; + +is_file_mng_failed: + fclose (file); + return FALSE; +} + +gboolean ygdk_mng_pixbuf_is_data_mng (const guint8 *raw_data, long size) +{ + DataStream data = data_stream_constructor (raw_data, size); + return read_signature (&data); +} + +#define SET_ERROR(msg) { error = TRUE; \ + g_set_error (error_msg, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, msg); } + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, + GError **error_msg) +{ + gboolean error = FALSE; + FILE *file = fopen (filename, "rb"); + if (!file) + { + SET_ERROR ("Could not open specified file") + return NULL; + } + + fseek (file, 0, SEEK_END); + long file_size = ftell (file); + fseek (file, 0, SEEK_SET); + + GdkPixbufAnimation *mng_pixbuf = 0; + guchar *data = mmap (NULL, file_size, PROT_READ, MAP_PRIVATE, + fileno (file), 0); + if (data == MAP_FAILED) + SET_ERROR ("Could not map file") + else + { + mng_pixbuf = ygdk_mng_pixbuf_new_from_data (data, file_size, error_msg); + munmap (data, file_size); + } + fclose (file); + return mng_pixbuf; +} + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_data (const guint8 *raw_data, long size, + GError **error_msg) +{ + DataStream data = data_stream_constructor (raw_data, size); + + gboolean error = FALSE; + if (!read_signature (&data)) + { + SET_ERROR ("Not a MNG file") + return NULL; + } + + YGdkMngPixbuf *mng_pixbuf = g_object_new (YGDK_TYPE_MNG_PIXBUF, NULL); + mng_pixbuf->iteration_max = 0x7fffffff; + + guint32 chunk_size, chunk_id; + long chunk_offset; + GdkPixbufLoader *loader = NULL; /* currently loading... */ + gboolean first_read = TRUE; + + do { + error = !read_uint32 (&data, &chunk_size); + error = error || !read_uint32 (&data, &chunk_id); + if (error) + { + SET_ERROR ("Unexpected end of file on new chunk") + break; + } + chunk_offset = data.offset + chunk_size + 4/*CRC*/; + + if (first_read && chunk_id != MNG_UINT_MHDR) + { + SET_ERROR ("MHDR chunk must come first") + break; + } + + // not currently reading a PNG stream + if (!loader) + { + switch (chunk_id) + { + case MNG_UINT_MHDR: + if (!first_read) + { + SET_ERROR ("Only one MHDR chunk allowed") + break; + } + + if (chunk_size == 7*4) + { + // Read MHDR chunk data + error = !read_uint32 (&data, &mng_pixbuf->frame_width); + error = error || !read_uint32 (&data, &mng_pixbuf->frame_height); + error = error || !read_uint32 (&data, &mng_pixbuf->ticks_per_second); + if (error) + SET_ERROR ("Unexpected end of file on MHDR chunk") + /* Next atttributes: Nominal_layer_count, Nominal_frame_count, + Nominal_play_time, Simplicity_profile */ + else if (mng_pixbuf->frame_width <= 0 || + mng_pixbuf->frame_height <= 0 || + mng_pixbuf->ticks_per_second < 0) + SET_ERROR ("Invalid MHDR parameter") +//fprintf(stderr, "ticks per second: %d\n", mng_pixbuf->ticks_per_second); + } + else + SET_ERROR ("MHDR chunk must be 28 bytes long") + break; + case MNG_UINT_IHDR: + loader = gdk_pixbuf_loader_new_with_type ("png", NULL); + g_signal_connect (G_OBJECT (loader), "area-prepared", + G_CALLBACK (image_prepared_cb), mng_pixbuf); + gdk_pixbuf_loader_set_size (loader, mng_pixbuf->frame_width, + mng_pixbuf->frame_height); + + { + const guchar sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + if(!gdk_pixbuf_loader_write (loader, sig, 8, error_msg)) + { + error = TRUE; + break; + } + } + break; + case MNG_UINT_TERM: + if (chunk_size > 1) + { + // Read TERM chunk data + guint8 t; + error = !read_uint8 (&data, &t); // term action + if (t == 3 && chunk_size == 2+8) + { + error = error || !read_uint8 (&data, &t); // after term action + error = error || !read_uint32 (&data, &mng_pixbuf->last_frame_delay); + error = error || !read_uint32 (&data, &mng_pixbuf->iteration_max); + if (error) + SET_ERROR ("Unexpected end of file on TERM chunk") + } + else + SET_ERROR ("TERM chunk must be 10 bytes when term action is 3") + } + else + SET_ERROR ("TERM chunk must have at least 1 byte") + break; + case MNG_UINT_BACK: + // TODO: + break; + case MNG_UINT_IDAT: + case MNG_UINT_IEND: + if (loader != NULL) + SET_ERROR ("Corrupted PNG chunk closures") + break; + case MNG_UINT_MEND: + default: + break; + } + } + + if (error) + break; + + // loading a PNG stream + if (loader) + { + data.offset -= 8; + if (!read_data (&data, chunk_size+8+4, loader, error_msg)) + error = TRUE; + else if (chunk_id == MNG_UINT_IEND) + { + if (!gdk_pixbuf_loader_close (loader, error_msg)) + { + error = TRUE; + break; + } + loader = NULL; + } + } + + data.offset = chunk_offset; + first_read = FALSE; + } while (chunk_id != MNG_UINT_MEND && !error); + + if (error) + { + g_object_unref (G_OBJECT (mng_pixbuf)); + return NULL; + } + return GDK_PIXBUF_ANIMATION (mng_pixbuf); +} + +#undef SET_ERROR + +static gboolean ygdk_mng_pixbuf_is_static_image (GdkPixbufAnimation *anim) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + return g_list_length (mng_anim->frames) == 1; +} + +static GdkPixbuf *ygdk_mng_pixbuf_get_static_image (GdkPixbufAnimation *anim) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + return g_list_nth_data (mng_anim->frames, 0); +} + +static void ygdk_mng_pixbuf_get_size (GdkPixbufAnimation *anim, int *width, int *height) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + if (width) *width = mng_anim->frame_width; + if (height) *height = mng_anim->frame_height; +} + +static GdkPixbufAnimationIter *ygdk_mng_pixbuf_get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + YGdkMngPixbufIter *iter = g_object_new (YGDK_TYPE_MNG_PIXBUF_ITER, NULL); + iter->mng_pixbuf = YGDK_MNG_PIXBUF( anim ); + iter->cur_frame = 0; + return GDK_PIXBUF_ANIMATION_ITER( iter ); +} + +static void ygdk_mng_pixbuf_class_init (YGdkMngPixbufClass *klass) +{ + ygdk_mng_pixbuf_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationClass *pixbuf_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + pixbuf_class->is_static_image = ygdk_mng_pixbuf_is_static_image; + pixbuf_class->get_static_image = ygdk_mng_pixbuf_get_static_image; + pixbuf_class->get_size = ygdk_mng_pixbuf_get_size; + pixbuf_class->get_iter = ygdk_mng_pixbuf_get_iter; +} + +//** YGdkMngPixbufIter + +G_DEFINE_TYPE (YGdkMngPixbufIter, ygdk_mng_pixbuf_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER) + +static void ygdk_mng_pixbuf_iter_init (YGdkMngPixbufIter *iter) +{ +} + +static GdkPixbuf *ygdk_mng_pixbuf_iter_get_pixbuf (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + return g_list_nth_data (mng_iter->mng_pixbuf->frames, mng_iter->cur_frame); +} + +static gboolean ygdk_mng_pixbuf_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + return FALSE; +} + +static int ygdk_mng_pixbuf_iter_get_delay_time (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + int delay = 1000.0 / mng_iter->mng_pixbuf->ticks_per_second; + if (mng_iter->cur_frame == g_list_length (mng_iter->mng_pixbuf->frames)-1) + delay += mng_iter->mng_pixbuf->last_frame_delay; + return delay; +} + +static gboolean ygdk_mng_pixbuf_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + YGdkMngPixbuf *mng_pixbuf = mng_iter->mng_pixbuf; + if (!mng_pixbuf->frames) + return FALSE; + + gboolean can_advance = TRUE; + int frames_len = g_list_length (mng_pixbuf->frames); + if (mng_iter->cur_frame+1 == frames_len) + { + if (mng_pixbuf->iteration_max == 0x7fffffff || + mng_iter->cur_iteration < mng_pixbuf->iteration_max) + mng_iter->cur_iteration++; + else + can_advance = FALSE; + } + + if (can_advance) + mng_iter->cur_frame = (mng_iter->cur_frame+1) % frames_len; + return can_advance; +} + +static void ygdk_mng_pixbuf_iter_class_init (YGdkMngPixbufIterClass *klass) +{ + ygdk_mng_pixbuf_iter_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationIterClass *iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + iter_class->get_delay_time = ygdk_mng_pixbuf_iter_get_delay_time; + iter_class->get_pixbuf = ygdk_mng_pixbuf_iter_get_pixbuf; + iter_class->on_currently_loading_frame = ygdk_mng_pixbuf_iter_on_currently_loading_frame; + iter_class->advance = ygdk_mng_pixbuf_iter_advance; +} + Added: trunk/gtk/unstable/src/ygdkmngloader.c-old URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygdkmngloader.c-... ============================================================================== --- trunk/gtk/unstable/src/ygdkmngloader.c-old (added) +++ trunk/gtk/unstable/src/ygdkmngloader.c-old Thu Nov 29 18:22:01 2007 @@ -0,0 +1,382 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGdkMngLoader image loader */ +// check the header file for information about this loader + +#include "ygdkmngloader.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include <sys/mman.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> + +/* A few chunks ids */ +#define MNG_UINT_MHDR 0x4d484452L +#define MNG_UINT_BACK 0x4241434bL +#define MNG_UINT_PLTE 0x504c5445L +#define MNG_UINT_tRNS 0x74524e53L +#define MNG_UINT_IHDR 0x49484452L +#define MNG_UINT_IDAT 0x49444154L +#define MNG_UINT_IEND 0x49454e44L +#define MNG_UINT_MEND 0x4d454e44L +#define MNG_UINT_FRAM 0x4652414dL +#define MNG_UINT_LOOP 0x4c4f4f50L +#define MNG_UINT_ENDL 0x454e444cL +#define MNG_UINT_TERM 0x5445524dL + +//** Utilities to read the MNG file + +struct DataStream { + guint8 *data; + long offset, size; +}; + +static gboolean read_signature (DataStream *data) +{ + if (data->offset+8 > data->size) + return FALSE; + data->offset += 8; + return memcmp (data->data + data->offset-8, "\212MNG\r\n\032\n", 8); +} + +static gboolean read_uint8 (DataStream *data, guint8 *value) +{ + if (data->offset+1 > data->size) + return FALSE; + data->offset++; + return data->data [data->offset-1]; +} + +static gboolean read_uint32 (FILE *file, guint32 *value) +{ + if (data->offset+4 > data->size) + return FALSE; + guint8 buffer[4]; + if (fread (buffer, 1, 4, file) < 4) + return FALSE; + *value = buffer[0] << 24; *value |= buffer[1] << 16; + *value |= buffer[2] << 8; *value |= buffer[3]; + return TRUE; +} + +static gboolean read_data (FILE *file, guint32 size, GdkPixbufLoader *loader, + GError **error) +{ + guchar data [size]; + if (fread (data, 1, size, file) < size) + { + g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + "Unexpected end of file when reading PNG chunk"); + return FALSE; + } + return gdk_pixbuf_loader_write (loader, data, size, error); +} + +static void image_prepared_cb (GdkPixbufLoader *loader, YGdkMngPixbuf *mng_pixbuf) +{ + GdkPixbuf *pix = gdk_pixbuf_loader_get_pixbuf (loader); + mng_pixbuf->frames = g_list_append (mng_pixbuf->frames, pix); +} + +//** YGdkMngPixbuf + +G_DEFINE_TYPE (YGdkMngPixbuf, ygdk_mng_pixbuf, GDK_TYPE_PIXBUF_ANIMATION) + +static void ygdk_mng_pixbuf_init (YGdkMngPixbuf *pixbuf) +{ +} + +gboolean ygdk_mng_pixbuf_is_file_mng (const gchar *filename) +{ + FILE *file = fopen (filename, "rb"); + if (!file) + return FALSE; + return read_signature (file); +} + +#define SET_ERROR(msg) { error = TRUE; \ + g_set_error (error_msg, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, msg); } + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, + GError **error_msg) +{ + gboolean error = FALSE; + FILE *file = fopen (filename, "rb"); + if (!file) + { + SET_ERROR ("Could not open specified file") + return NULL; + } + + fseek (file, 0, SEEK_END); + long file_size = ftell (file); + fseek (file, 0, SEEK_START); + + GdkPixbufAnimation *mng_pixbuf; + guchar *data = mmap (NULL, file_size, PROT_READ, MAP_PRIVATE, + fileno (file), 0); + if (data == MAP_FAILED) + { + SET_ERROR ("Could not map file") + return NULL; + } + mng_pixbuf = ygdk_mng_pixbuf_new_from_data (data, error_msg); + munmap (data, file_size); + return mng_pixbuf; +} + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_data (const guint8 *data, + GError **error_msg) +{ + gboolean error = FALSE; + long offset = 0; + if (!read_signature (data, &offset)) + { + SET_ERROR ("Not a MNG file") + return NULL; + } + + YGdkMngPixbuf *mng_pixbuf = g_object_new (YGDK_TYPE_MNG_PIXBUF, NULL); + mng_pixbuf->iteration_max = 0x7fffffff; + + guint32 chunk_size, chunk_id; + long chunk_offset; + GdkPixbufLoader *loader = NULL; /* currently loading... */ + gboolean first_read = TRUE; + + do { + error = !read_uint32 (data, &offset, &chunk_size); + error = error || !read_uint32 (data, &offset, &chunk_id); + if (error) + { + SET_ERROR ("Unexpected end of file on new chunk") + break; + } + chunk_offset = offset + chunk_size + 4/*CRC*/; + + if (first_read && chunk_id != MNG_UINT_MHDR) + { + SET_ERROR ("MHDR chunk must come first") + break; + } + + // not currently reading a PNG stream + if (!loader) + { + switch (chunk_id) + { + case MNG_UINT_MHDR: + if (!first_read) + { + SET_ERROR ("Only one MHDR chunk allowed") + break; + } + + if (chunk_size == 7*4) + { + // Read MHDR chunk data + error = !read_uint32 (data, &offset, &mng_pixbuf->frame_width); + error = error || !read_uint32 (data, &offset, &mng_pixbuf->frame_height); + error = error || !read_uint32 (data, &offset, &mng_pixbuf->ticks_per_second); + if (error) + SET_ERROR ("Unexpected end of file on MHDR chunk") + /* Next atttributes: Nominal_layer_count, Nominal_frame_count, + Nominal_play_time, Simplicity_profile */ + else if (mng_pixbuf->frame_width <= 0 || + mng_pixbuf->frame_height <= 0 || + mng_pixbuf->ticks_per_second < 0) + SET_ERROR ("Invalid MHDR parameter") +//fprintf(stderr, "ticks per second: %d\n", mng_pixbuf->ticks_per_second); + } + else + SET_ERROR ("MHDR chunk must be 28 bytes long") + break; + case MNG_UINT_IHDR: + loader = gdk_pixbuf_loader_new_with_type ("png", NULL); + g_signal_connect (G_OBJECT (loader), "area-prepared", + G_CALLBACK (image_prepared_cb), mng_pixbuf); + gdk_pixbuf_loader_set_size (loader, mng_pixbuf->frame_width, + mng_pixbuf->frame_height); + + { + const guchar sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + if(!gdk_pixbuf_loader_write (loader, sig, 8, error_msg)) + { + error = TRUE; + break; + } + } + break; + case MNG_UINT_TERM: + if (chunk_size > 1) + { + // Read TERM chunk data + guint8 t; + error = !read_uint8 (file, &t); // term action + if (t == 3 && chunk_size == 2+8) + { + error = error || !read_uint8 (file, &t); // after term action + error = error || !read_uint32 (file, &mng_pixbuf->last_frame_delay); + error = error || !read_uint32 (file, &mng_pixbuf->iteration_max); + if (error) + SET_ERROR ("Unexpected end of file on TERM chunk") + } + else + SET_ERROR ("TERM chunk must be 10 bytes when term action is 3") + } + else + SET_ERROR ("TERM chunk must have at least 1 byte") + break; + case MNG_UINT_BACK: + // TODO: + break; + case MNG_UINT_IDAT: + case MNG_UINT_IEND: + if (loader != NULL) + SET_ERROR ("Corrupted PNG chunk closures") + break; + case MNG_UINT_MEND: + default: + break; + } + } + + if (error) + break; + + // loading a PNG stream + if (loader) + { + fseek (file, -8, SEEK_CUR); + if (!read_data (file, chunk_size+8+4, loader, error_msg)) + error = TRUE; + else if (chunk_id == MNG_UINT_IEND) + { + if (!gdk_pixbuf_loader_close (loader, error_msg)) + { + error = TRUE; + break; + } + loader = NULL; + } + } + + fseek (file, offset, SEEK_SET); + first_read = FALSE; + } while (chunk_id != MNG_UINT_MEND && !error); + + if (error) + { + g_object_unref (G_OBJECT (mng_pixbuf)); + return NULL; + } + return GDK_PIXBUF_ANIMATION (mng_pixbuf); +} + +#undef SET_ERROR + +static gboolean ygdk_mng_pixbuf_is_static_image (GdkPixbufAnimation *anim) +{ + return FALSE; +} + +static GdkPixbuf *ygdk_mng_pixbuf_get_static_image (GdkPixbufAnimation *anim) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + return g_list_nth_data (mng_anim->frames, 0); +} + +static void ygdk_mng_pixbuf_get_size (GdkPixbufAnimation *anim, int *width, int *height) +{ + YGdkMngPixbuf *mng_anim = YGDK_MNG_PIXBUF (anim); + if (width) *width = mng_anim->frame_width; + if (height) *height = mng_anim->frame_height; +} + +static GdkPixbufAnimationIter *ygdk_mng_pixbuf_get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + YGdkMngPixbufIter *iter = g_object_new (YGDK_TYPE_MNG_PIXBUF_ITER, NULL); + iter->mng_pixbuf = YGDK_MNG_PIXBUF( anim ); + iter->cur_frame = 0; + return GDK_PIXBUF_ANIMATION_ITER( iter ); +} + +static void ygdk_mng_pixbuf_class_init (YGdkMngPixbufClass *klass) +{ + ygdk_mng_pixbuf_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationClass *pixbuf_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + pixbuf_class->is_static_image = ygdk_mng_pixbuf_is_static_image; + pixbuf_class->get_static_image = ygdk_mng_pixbuf_get_static_image; + pixbuf_class->get_size = ygdk_mng_pixbuf_get_size; + pixbuf_class->get_iter = ygdk_mng_pixbuf_get_iter; +} + +//** YGdkMngPixbufIter + +G_DEFINE_TYPE (YGdkMngPixbufIter, ygdk_mng_pixbuf_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER) + +static void ygdk_mng_pixbuf_iter_init (YGdkMngPixbufIter *iter) +{ +} + +static GdkPixbuf *ygdk_mng_pixbuf_iter_get_pixbuf (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + return g_list_nth_data (mng_iter->mng_pixbuf->frames, mng_iter->cur_frame); +} + +static gboolean ygdk_mng_pixbuf_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + return FALSE; +} + +static int ygdk_mng_pixbuf_iter_get_delay_time (GdkPixbufAnimationIter *iter) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + int delay = 1000.0 / mng_iter->mng_pixbuf->ticks_per_second; + if (mng_iter->cur_frame == g_list_length (mng_iter->mng_pixbuf->frames)-1) + delay += mng_iter->mng_pixbuf->last_frame_delay; + return delay; +} + +static gboolean ygdk_mng_pixbuf_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + YGdkMngPixbufIter *mng_iter = YGDK_MNG_PIXBUF_ITER (iter); + YGdkMngPixbuf *mng_pixbuf = mng_iter->mng_pixbuf; + if (!mng_pixbuf->frames) + return FALSE; + + gboolean can_advance = TRUE; + int frames_len = g_list_length (mng_pixbuf->frames); + if (mng_iter->cur_frame+1 == frames_len) + { + if (mng_pixbuf->iteration_max == 0x7fffffff || + mng_iter->cur_iteration < mng_pixbuf->iteration_max) + mng_iter->cur_iteration++; + else + can_advance = FALSE; + } + + if (can_advance) + mng_iter->cur_frame = (mng_iter->cur_frame+1) % frames_len; + return can_advance; +} + +static void ygdk_mng_pixbuf_iter_class_init (YGdkMngPixbufIterClass *klass) +{ + ygdk_mng_pixbuf_iter_parent_class = g_type_class_peek_parent (klass); + + GdkPixbufAnimationIterClass *iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + iter_class->get_delay_time = ygdk_mng_pixbuf_iter_get_delay_time; + iter_class->get_pixbuf = ygdk_mng_pixbuf_iter_get_pixbuf; + iter_class->on_currently_loading_frame = ygdk_mng_pixbuf_iter_on_currently_loading_frame; + iter_class->advance = ygdk_mng_pixbuf_iter_advance; +} + Added: trunk/gtk/unstable/src/ygdkmngloader.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygdkmngloader.h?... ============================================================================== --- trunk/gtk/unstable/src/ygdkmngloader.h (added) +++ trunk/gtk/unstable/src/ygdkmngloader.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,80 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* GdkPixbuf doesn't support MNG files... MNG extends PNG adding movie playback + capabilities. + This code aims for MNG-VLC (smallest subset of the format), though + it isn't completely compliable. +*/ + +#ifndef YGDK_MNG_PIXBUF_H +#define YGDK_MNG_PIXBUF_H + +#define GDK_PIXBUF_ENABLE_BACKEND +#include <gdk-pixbuf/gdk-pixbuf-animation.h> +G_BEGIN_DECLS + +#define YGDK_TYPE_MNG_PIXBUF (ygdk_mng_pixbuf_get_type ()) +#define YGDK_MNG_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGDK_TYPE_MNG_PIXBUF, YGdkMngPixbuf)) +#define YGDK_MNG_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGDK_TYPE_MNG_PIXBUF, YGdkMngPixbufClass)) +#define YGDK_IS_MNG_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGDK_TYPE_MNG_PIXBUF)) +#define YGDK_IS_MNG_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGDK_TYPE_MNG_PIXBUF)) +#define YGDK_MNG_PIXBUF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGK_TYPE_MNG_PIXBUF, YGdkMngPixbufClass)) + +typedef struct YGdkMngPixbuf +{ + GdkPixbufAnimation parent; + + // private: (use GdkPixbufAnimation API) + GList *frames; // of GdkPixbufs + // MHDR header + guint32 frame_width, frame_height, ticks_per_second; + // TERM header + guint32 last_frame_delay, iteration_max; +} YGdkMngPixbuf; + +typedef struct YGdkMngPixbufClass +{ + GdkPixbufAnimationClass parent_class; +} YGdkMngPixbufClass; + +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_file (const gchar *filename, GError **error); +GdkPixbufAnimation *ygdk_mng_pixbuf_new_from_data (const guint8 *data, long size, GError **error); +gboolean ygdk_mng_pixbuf_is_file_mng (const gchar *filename); +gboolean ygdk_mng_pixbuf_is_data_mng (const guint8 *data, long size); + +GType ygdk_mng_pixbuf_get_type (void) G_GNUC_CONST; + +#define YGDK_TYPE_MNG_PIXBUF_ITER (ygdk_mng_pixbuf_iter_get_type ()) +#define YGDK_MNG_PIXBUF_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIter)) +#define YGDK_MNG_PIXBUF_ITER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIterClass)) +#define YGDK_IS_MNG_PIXBUF_ITER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), YGDK_TYPE_MNG_PIXBUF_ITER)) +#define YGDK_MNG_PIXBUF_ITER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), YGDK_TYPE_MNG_PIXBUF_ITER, YGdkMngPixbufIterClass)) + +typedef struct YGdkMngPixbufIter { + GdkPixbufAnimationIter parent; + + // private: + YGdkMngPixbuf *mng_pixbuf; + int cur_frame, cur_iteration; +} YGdkMngPixbufIter; + +typedef struct YGdkMngPixbufIterClass { + GdkPixbufAnimationIterClass parent_class; +} YGdkMngPixbufIterClass; + +GType ygdk_mng_pixbuf_iter_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /*YGDK_MNG_PIXBUF_H*/ + Added: trunk/gtk/unstable/src/ygtkbargraph.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkbargraph.c?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkbargraph.c (added) +++ trunk/gtk/unstable/src/ygtkbargraph.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,196 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkBarGraph widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkbargraph.h" +#include <gtk/gtklabel.h> +#include <gtk/gtkframe.h> +#include <gtk/gtkeventbox.h> + +G_DEFINE_TYPE (YGtkBarGraph, ygtk_bar_graph, YGTK_TYPE_RATIO_HBOX) + +static void ygtk_bar_graph_init (YGtkBarGraph *bar) +{ +// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (bar), TRUE); + + bar->m_tooltips = gtk_tooltips_new(); + gtk_container_set_border_width (GTK_CONTAINER (bar), 12); +} + +/* Just to avoid the size getting too big, when we have little bars. */ +static void ygtk_bar_graph_size_request (GtkWidget *widget, GtkRequisition *requisition) +{ + GTK_WIDGET_CLASS (ygtk_bar_graph_parent_class)->size_request (widget, requisition); + const int max_width = 250; + if (requisition->width > max_width) + requisition->width = max_width; + requisition->height += 6; +} + +GtkWidget *ygtk_bar_graph_new (void) +{ + return g_object_new (YGTK_TYPE_BAR_GRAPH, NULL); +} + +void ygtk_bar_graph_create_entries (YGtkBarGraph *bar, guint entries) +{ + // Remove the ones in excess + guint i; + for (i = entries; i < g_list_length (YGTK_RATIO_BOX (bar)->children); i++) + gtk_container_remove (GTK_CONTAINER (bar), + (GtkWidget*) g_list_nth_data (YGTK_RATIO_BOX (bar)->children, i)); + + // Add new ones, if missing + for (i = g_list_length (YGTK_RATIO_BOX (bar)->children); i < entries; i++) { + GtkWidget *label = ygtk_colored_label_new(); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); + + YGtkColoredLabel *color_label = YGTK_COLORED_LABEL (label); + ygtk_colored_label_set_shadow_type (color_label, GTK_SHADOW_OUT); + + // we need a GtkEventBox or something, so we may assign a tooltip to it + GtkWidget *box = gtk_event_box_new(); + gtk_container_add (GTK_CONTAINER (box), label); + gtk_container_add (GTK_CONTAINER (bar), box); + + gtk_widget_show_all (box); + } +} + +void ygtk_bar_graph_setup_entry (YGtkBarGraph *bar, int index, + const gchar *label_entry, int value) +{ + YGtkRatioBoxChild *box_child = (YGtkRatioBoxChild *) + g_list_nth_data (YGTK_RATIO_BOX (bar)->children, index); + + g_return_if_fail (box_child); + GtkWidget *box = box_child->widget; + GtkWidget *label = gtk_bin_get_child (GTK_BIN (box)); + + if (value < 0) + value = 0; + + // Reading label text + if (label_entry) { + GString *label_text = g_string_new (label_entry); + { // Replace %1 by value(i) + guint i; + for (i = 0; i < label_text->len; i++) + if (label_text->str[i] == '%' && label_text->str[i+1] == '1') { + gchar *value_str = g_strdup_printf ("%d", value); + label_text = g_string_erase (label_text, i, 2); + label_text = g_string_insert (label_text, i, value_str); + g_free (value_str); + } + } + gtk_label_set_label (GTK_LABEL (label), label_text->str); + + // Tooltip with the label -- useful if the bar entry gets too small + gtk_tooltips_set_tip (bar->m_tooltips, box, label_text->str, NULL); + } + + // Set proportion + gtk_widget_set_size_request (box, 10, -1); // for homogeneous... + ygtk_ratio_box_set_child_packing (YGTK_RATIO_BOX (bar), box, MAX (value, 1), + TRUE, TRUE, 0); + + // Set background color + // The Tango palette + const guint palette [][3] = { + { 138, 226, 52 }, // Chameleon 1 + { 252, 175, 62 }, // Orange 1 + { 114, 159, 207 }, // Sky Blue 1 + { 233, 185, 110 }, // Chocolate 1 + { 239, 41, 41 }, // Scarlet Red 1 + { 252, 233, 79 }, // Butter 1 + { 173, 127, 168 }, // Plum 1 + { 115, 210, 22 }, // Chameleon 2 + { 245, 121, 0 }, // Orange 2 + { 52, 101, 164 }, // Sky Blue 2 + { 193, 125, 17 }, // Chocolate 2 + { 204, 0, 0 }, // Scarlet Red 2 + { 237, 212, 0 }, // Butter 2 + { 117, 80, 123 }, // Plum 2 + { 78, 154, 6 }, // Chameleon 3 + { 206, 92, 0 }, // Orange 3 + { 32, 74, 135 }, // Sky Blue 3 + { 143, 89, 2 }, // Chocolate 3 + { 164, 0, 0 }, // Scarlet Red 3 + { 196, 160, 0 }, // Butter 3 + { 92, 53, 102 }, // Plum 3 + { 238, 238, 236 }, // Aluminium 1 + { 211, 215, 207 }, // Aluminium 2 + { 186, 189, 182 }, // Aluminium 3 + { 136, 138, 133 }, // Aluminium 4 + { 85, 87, 83 }, // Aluminium 5 + { 46, 52, 54 }, // Aluminium 6 + }; + + const guint *color = palette [index % G_N_ELEMENTS (palette)]; + + YGtkColoredLabel *color_label = YGTK_COLORED_LABEL (label); + ygtk_colored_label_set_background (color_label, color[0], color[1], color[2]); +} + +static void ygtk_bar_graph_class_init (YGtkBarGraphClass *klass) +{ + ygtk_bar_graph_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->size_request = ygtk_bar_graph_size_request; +} + +//** YGtkColoredLabel + +G_DEFINE_TYPE (YGtkColoredLabel, ygtk_colored_label, GTK_TYPE_LABEL) + +static void ygtk_colored_label_init (YGtkColoredLabel *label) +{ + label->shadow = GTK_SHADOW_NONE; +} + +static gboolean ygtk_colored_label_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + GtkStyle *style = gtk_widget_get_style (widget); + GtkAllocation *alloc = &widget->allocation; + gtk_paint_box (style, widget->window, GTK_STATE_NORMAL, + YGTK_COLORED_LABEL (widget)->shadow, &event->area, + widget, NULL, alloc->x, alloc->y, alloc->width, alloc->height); + + GTK_WIDGET_CLASS (ygtk_colored_label_parent_class)->expose_event (widget, event); + return FALSE; +} + +GtkWidget *ygtk_colored_label_new (void) +{ return g_object_new (YGTK_TYPE_COLORED_LABEL, NULL); } + +void ygtk_colored_label_set_foreground (YGtkColoredLabel *label, guint red, + guint green, guint blue) +{ + GdkColor color = { 0, red << 8, green << 8, blue << 8 }; + gtk_widget_modify_fg (GTK_WIDGET (label), GTK_STATE_NORMAL, &color); +} + +void ygtk_colored_label_set_background (YGtkColoredLabel *label, guint red, + guint green, guint blue) +{ + GdkColor color = { 0, red << 8, green << 8, blue << 8 }; + gtk_widget_modify_bg (GTK_WIDGET (label), GTK_STATE_NORMAL, &color); +} + +void ygtk_colored_label_set_shadow_type (YGtkColoredLabel *label, GtkShadowType type) +{ + label->shadow = type; +} + +static void ygtk_colored_label_class_init (YGtkColoredLabelClass *klass) +{ + ygtk_colored_label_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->expose_event = ygtk_colored_label_expose_event; +} Added: trunk/gtk/unstable/src/ygtkbargraph.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkbargraph.h?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkbargraph.h (added) +++ trunk/gtk/unstable/src/ygtkbargraph.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,101 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkBarGraph is just a simple graph of bars that may be + changed during run-time (see ygtk_bar_graph_setup_entry()). +*/ + +#ifndef YGTK_BAR_GRAPH_H +#define YGTK_BAR_GRAPH_H + +#include "ygtkratiobox.h" +#include <gtk/gtktooltips.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_BAR_GRAPH (ygtk_bar_graph_get_type ()) +#define YGTK_BAR_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_BAR_GRAPH, YGtkBarGraph)) +#define YGTK_BAR_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_BAR_GRAPH, YGtkBarGraphClass)) +#define YGTK_IS_BAR_GRAPH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_BAR_GRAPH)) +#define YGTK_IS_BAR_GRAPH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_BAR_GRAPH)) +#define YGTK_BAR_GRAPH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_BAR_GRAPH, YGtkBarGraphClass)) + +typedef struct _YGtkBarGraph YGtkBarGraph; +typedef struct _YGtkBarGraphClass YGtkBarGraphClass; + +struct _YGtkBarGraph +{ + YGtkRatioHBox parent; + + // private + GtkTooltips *m_tooltips; +}; + +struct _YGtkBarGraphClass +{ + YGtkRatioBoxClass parent_class; +}; + +GtkWidget *ygtk_bar_graph_new (void); +GType ygtk_bar_graph_get_type (void) G_GNUC_CONST; + +void ygtk_bar_graph_create_entries (YGtkBarGraph *bar, guint entries); +void ygtk_bar_graph_setup_entry (YGtkBarGraph *bar, int index, + const gchar *label_entry, int value); + +G_END_DECLS +#endif /*YGTK_BAR_GRAPH_H*/ + +#ifndef YGTK_COLORED_LABEL_H +#define YGTK_COLORED_LABEL_H + +#include <gtk/gtklabel.h> +G_BEGIN_DECLS + +/* YGtkColoredLabel is a GtkLabel where gtk_modify_bg() can be used. It also + allows a frame around it. */ + +#define YGTK_TYPE_COLORED_LABEL (ygtk_colored_label_get_type ()) +#define YGTK_COLORED_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_COLORED_LABEL, YGtkColoredLabel)) +#define YGTK_COLORED_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_COLORED_LABEL, YGtkColoredLabelClass)) +#define YGTK_IS_COLORED_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_COLORED_LABEL)) +#define YGTK_IS_COLORED_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_COLORED_LABEL)) +#define YGTK_COLORED_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_COLORED_LABEL, YGtkColoredLabelClass)) + +typedef struct _YGtkColoredLabel +{ + GtkLabel parent; + + // private + GtkShadowType shadow; +} YGtkColoredLabel; + +typedef struct _YGtkColoredLabelClass +{ + GtkLabelClass parent_class; +} YGtkColoredLabelClass; + +GtkWidget *ygtk_colored_label_new (void); +GType ygtk_colored_label_get_type (void) G_GNUC_CONST; + +// A convenience function (you may use gtk_widget_modify_fg() and +// gtk_widget_modify_bg() instead), where colors range is [0, 255] +void ygtk_colored_label_set_foreground (YGtkColoredLabel *label, guint red, + guint green, guint blue); +void ygtk_colored_label_set_background (YGtkColoredLabel *label, guint red, + guint green, guint blue); + +void ygtk_colored_label_set_shadow_type (YGtkColoredLabel *label, GtkShadowType type); + +G_END_DECLS +#endif /*YGTK_COLORED_LABEL*/ Added: trunk/gtk/unstable/src/ygtkfieldentry.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkfieldentry.c... ============================================================================== --- trunk/gtk/unstable/src/ygtkfieldentry.c (added) +++ trunk/gtk/unstable/src/ygtkfieldentry.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,222 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkFieldEntry widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkfieldentry.h" +#include <gtk/gtk.h> +#include <string.h> + +//** YGtkFilterEntry + +static void ygtk_filter_entry_editable_init (GtkEditableClass *iface); + +G_DEFINE_TYPE_WITH_CODE (YGtkFilterEntry, ygtk_filter_entry, GTK_TYPE_ENTRY, + G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, ygtk_filter_entry_editable_init)) + +static void ygtk_filter_entry_init (YGtkFilterEntry *entry) +{ +} + +static void ygtk_filter_entry_insert_text (GtkEditable *editable, const gchar *new_text, + gint new_text_length, gint *pos) +{ + const gchar *valid_chars = YGTK_FILTER_ENTRY (editable)->valid_chars; + if (valid_chars) { + const gchar *i, *j; + for (i = new_text; *i; i++) { + for (j = valid_chars; *j; j++) { + if (*i == *j) + break; + } + if (!*j) { + // not valid text + gdk_beep(); + return; + } + } + } + + GtkEditableClass *parent_editable_iface = g_type_interface_peek + (ygtk_filter_entry_parent_class, GTK_TYPE_EDITABLE); + parent_editable_iface->insert_text (editable, new_text, new_text_length, pos); +} + +static void ygtk_filter_entry_destroy (GtkObject *object) +{ + YGtkFilterEntry *entry = YGTK_FILTER_ENTRY (object); + if (entry->valid_chars) + g_free (entry->valid_chars); + entry->valid_chars = NULL; + + GTK_OBJECT_CLASS (ygtk_filter_entry_parent_class)->destroy (object); +} + +GtkWidget *ygtk_filter_entry_new (void) +{ + return g_object_new (YGTK_TYPE_FILTER_ENTRY, NULL); +} + +void ygtk_filter_entry_set_valid_chars (YGtkFilterEntry *entry, const gchar *valid_chars) +{ + if (entry->valid_chars) + g_free (entry->valid_chars); + entry->valid_chars = g_strdup (valid_chars); +} + +static void ygtk_filter_entry_class_init (YGtkFilterEntryClass *klass) +{ + ygtk_filter_entry_parent_class = g_type_class_peek_parent (klass); + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_filter_entry_destroy; +} + +static void ygtk_filter_entry_editable_init (GtkEditableClass *iface) +{ + iface->insert_text = ygtk_filter_entry_insert_text; +} + +//** YGtkFieldEntry + +static guint filter_entry_signal; +G_DEFINE_TYPE (YGtkFieldEntry, ygtk_field_entry, GTK_TYPE_HBOX) + +static void ygtk_field_entry_init (YGtkFieldEntry *entry) +{ + gtk_box_set_spacing (GTK_BOX (entry), 4); +} + +static YGtkFilterEntry *ygtk_field_entry_focus_next_entry (YGtkFieldEntry *fields, + YGtkFilterEntry *current_entry, + gint side) +{ + GList *children = gtk_container_get_children (GTK_CONTAINER (fields)); + gint pos = g_list_index (children, current_entry); + + YGtkFilterEntry *next_entry = g_list_nth_data (children, pos + (2 * side)); + g_list_free (children); + + if (next_entry) + gtk_widget_grab_focus (GTK_WIDGET (next_entry)); + return next_entry; +} + +// If max characters reached, jump to next field +static void ygtk_field_entry_insert_text (GtkEditable *editable, const gchar *new_text, + gint new_text_length, gint *position, YGtkFieldEntry *fields) +{ + if (*position == gtk_entry_get_max_length (GTK_ENTRY (editable))) { + YGtkFilterEntry *next_entry = ygtk_field_entry_focus_next_entry (fields, + YGTK_FILTER_ENTRY (editable), 1); + if (next_entry) { + gint pos = 0; + gtk_editable_insert_text (GTK_EDITABLE (next_entry), new_text, + new_text_length, &pos); + gtk_editable_set_position (GTK_EDITABLE (next_entry), pos); + + // it would not insert the text anyway, but to avoid the beep + g_signal_stop_emission_by_name (editable, "insert_text"); + } + } +} + +static void ygtk_field_entry_move_cursor (GtkEntry *entry, GtkMovementStep move, + gint count, gboolean selection, YGtkFieldEntry *fields) +{ + if (move == GTK_MOVEMENT_VISUAL_POSITIONS) { + if (count > 0) + ygtk_field_entry_focus_next_entry (fields, YGTK_FILTER_ENTRY (entry), 1); + else + ygtk_field_entry_focus_next_entry (fields, YGTK_FILTER_ENTRY (entry), -1); + } +} + +static void ygtk_field_entry_entry_changed (GtkEditable *editable, YGtkFieldEntry *fields) +{ + GList *children = gtk_container_get_children (GTK_CONTAINER (fields)); + gint nb = g_list_index (children, YGTK_FILTER_ENTRY (editable)) / 2; + g_list_free (children); + + g_signal_emit (fields, filter_entry_signal, 0, nb); +} + +GtkWidget *ygtk_field_entry_new (void) +{ + return g_object_new (YGTK_TYPE_FIELD_ENTRY, NULL); +} + +void ygtk_field_entry_add_field (YGtkFieldEntry *fields, gchar separator, + guint max_length, const gchar *valid_chars) +{ + GtkWidget *label = 0, *entry; + if (fields->use_separator) { + const gchar str[2] = { separator, '\0' }; + label = gtk_label_new (str); + } + entry = ygtk_filter_entry_new(); + gtk_entry_set_max_length (GTK_ENTRY (entry), max_length); + gtk_entry_set_width_chars (GTK_ENTRY (entry), (max_length == 0) ? -1 : max_length); + ygtk_filter_entry_set_valid_chars (YGTK_FILTER_ENTRY (entry), valid_chars); + + g_signal_connect (G_OBJECT (entry), "insert-text", + G_CALLBACK (ygtk_field_entry_insert_text), fields); + g_signal_connect (G_OBJECT (entry), "move-cursor", + G_CALLBACK (ygtk_field_entry_move_cursor), fields); + + g_signal_connect (G_OBJECT (entry), "changed", + G_CALLBACK (ygtk_field_entry_entry_changed), fields); + + GtkBox *box = GTK_BOX (fields); + if (label) + gtk_box_pack_start (box, label, FALSE, FALSE, 0); + gtk_box_pack_start (box, entry, TRUE, TRUE, 0); + + fields->use_separator = TRUE; +} + +static YGtkFilterEntry *ygtk_field_entry_get_field (YGtkFieldEntry *fields, guint nb) +{ + YGtkFilterEntry *entry; + + GList *children = gtk_container_get_children (GTK_CONTAINER (fields)); + entry = g_list_nth_data (children, nb * 2); + g_list_free (children); + + return entry; +} + +void ygtk_field_entry_set_field_text (YGtkFieldEntry *fields, guint nb, const gchar *text) +{ + YGtkFilterEntry *entry = ygtk_field_entry_get_field (fields, nb); + g_signal_handlers_block_by_func (entry, + (gpointer) ygtk_field_entry_entry_changed, fields); + g_signal_handlers_block_by_func (entry, + (gpointer) ygtk_field_entry_insert_text, fields); + + gtk_entry_set_text (GTK_ENTRY (entry), text); + + g_signal_handlers_unblock_by_func (entry, + (gpointer) ygtk_field_entry_entry_changed, fields); + g_signal_handlers_unblock_by_func (entry, + (gpointer) ygtk_field_entry_insert_text, fields); +} + +const gchar *ygtk_field_entry_get_field_text (YGtkFieldEntry *fields, guint nb) +{ + YGtkFilterEntry *entry = ygtk_field_entry_get_field (fields, nb); + return gtk_entry_get_text (GTK_ENTRY (entry)); +} + +static void ygtk_field_entry_class_init (YGtkFieldEntryClass *klass) +{ + ygtk_field_entry_parent_class = g_type_class_peek_parent (klass); + + filter_entry_signal = g_signal_new ("field_entry_changed", + G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (YGtkFieldEntryClass, filter_entry_changed), + NULL, NULL, gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); +} Added: trunk/gtk/unstable/src/ygtkfieldentry.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkfieldentry.h... ============================================================================== --- trunk/gtk/unstable/src/ygtkfieldentry.h (added) +++ trunk/gtk/unstable/src/ygtkfieldentry.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,102 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkFieldEntry is an extension of GtkEntry with the added + functionality of being able to define fields (useful for when + you need the user to set a IP address or time/date). The number + of fields, their individual range and separation character + is all customizable. + + YGtkFilterEntry is an extension to GtkEntry that only accepts + input that is specified in an array of valid characters +*/ + +#ifndef YGTK_FILTER_ENTRY_H +#define YGTK_FILTER_ENTRY_H + +#include <gtk/gtkentry.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_FILTER_ENTRY (ygtk_filter_entry_get_type ()) +#define YGTK_FILTER_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_FILTER_ENTRY, YGtkFilterEntry)) +#define YGTK_FILTER_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_FILTER_ENTRY, YGtkFilterEntryClass)) +#define YGTK_IS_FILTER_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_FILTER_ENTRY)) +#define YGTK_IS_FILTER_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_FILTER_ENTRY)) +#define YGTK_FILTER_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_FILTER_ENTRY, YGtkFilterEntryClass)) + +typedef struct _YGtkFilterEntry +{ + GtkEntry parent; + + // private: + gchar *valid_chars; +} YGtkFilterEntry; + +typedef struct _YGtkFilterEntryClass +{ + GtkEntryClass parent_class; +} YGtkFilterEntryClass; + +GtkWidget* ygtk_filter_entry_new (void); +GType ygtk_filter_entry_get_type (void) G_GNUC_CONST; + +void ygtk_filter_entry_set_valid_chars (YGtkFilterEntry *entry, + const gchar *valid_chars); + +G_END_DECLS +#endif /*YGTK_FILTER_ENTRY_H*/ + +#ifndef YGTK_FIELD_ENTRY_H +#define YGTK_FIELD_ENTRY_H + +#include <gtk/gtkhbox.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_FIELD_ENTRY (ygtk_field_entry_get_type ()) +#define YGTK_FIELD_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_FIELD_ENTRY, YGtkFieldEntry)) +#define YGTK_FIELD_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_FIELD_ENTRY, YGtkFieldEntryClass)) +#define IS_YGTK_FIELD_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_FIELD_ENTRY)) +#define IS_YGTK_FIELD_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_FIELD_ENTRY)) +#define YGTK_FIELD_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_FIELD_ENTRY, YGtkFieldEntryClass)) + +typedef struct _YGtkFieldEntry +{ + GtkHBox parent; + + // private: + // used to disable separator for the first field + gboolean use_separator; +} YGtkFieldEntry; + +typedef struct _YGtkFieldEntryClass +{ + GtkHBoxClass parent_class; + + void (* filter_entry_changed) (YGtkFieldEntry *entry, gint field_nb); +} YGtkFieldEntryClass; + +GtkWidget* ygtk_field_entry_new (void); +GType ygtk_field_entry_get_type (void) G_GNUC_CONST; + +// if this is the first field, separator will be ignored. max_length can be 0 to +// disable it. valids_chars can be NULL to disable it. +void ygtk_field_entry_add_field (YGtkFieldEntry *entry, gchar separator, + guint max_length, const gchar *valid_chars); + +// convinience +void ygtk_field_entry_set_field_text (YGtkFieldEntry *entry, guint nb, const gchar *text); +const gchar *ygtk_field_entry_get_field_text (YGtkFieldEntry *entry, guint nb); + +G_END_DECLS +#endif /*YGTK_FIELD_ENTRY_H*/ Added: trunk/gtk/unstable/src/ygtkfindentry.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkfindentry.c?... ============================================================================== --- trunk/gtk/unstable/src/ygtkfindentry.c (added) +++ trunk/gtk/unstable/src/ygtkfindentry.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,517 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkExtEntry widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkfindentry.h" +#include <gtk/gtk.h> + +G_DEFINE_TYPE (YGtkExtEntry, ygtk_ext_entry, GTK_TYPE_ENTRY) + +static void ygtk_ext_entry_init (YGtkExtEntry *entry) +{ +} + +static void ygtk_ext_entry_destroy (GtkObject *object) +{ + GTK_OBJECT_CLASS (ygtk_ext_entry_parent_class)->destroy (object); + + YGtkExtEntry *entry = YGTK_EXT_ENTRY (object); + ygtk_ext_entry_set_border_window_size (entry, YGTK_EXT_ENTRY_LEFT_WIN, 0); + ygtk_ext_entry_set_border_window_size (entry, YGTK_EXT_ENTRY_RIGHT_WIN, 0); +} + +static void ygtk_ext_entry_map (GtkWidget *widget) +{ + if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_MAPPED (widget)) { + GTK_WIDGET_CLASS (ygtk_ext_entry_parent_class)->map (widget); + + YGtkExtEntry *entry = YGTK_EXT_ENTRY (widget); + if (entry->left_window) + gdk_window_show (entry->left_window); + if (entry->right_window) + gdk_window_show (entry->right_window); + } +} + +static void ygtk_ext_entry_unmap (GtkWidget *widget) +{ + if (GTK_WIDGET_MAPPED (widget)) { + YGtkExtEntry *entry = YGTK_EXT_ENTRY (widget); + if (entry->left_window) + gdk_window_hide (entry->left_window); + if (entry->right_window) + gdk_window_hide (entry->right_window); + + GTK_WIDGET_CLASS (ygtk_ext_entry_parent_class)->unmap (widget); + } +} + +static void ygtk_ext_entry_sync_color (YGtkExtEntry *entry) +{ + /* We don't use gtk_style_set_background() since we want to reflect + gtk_widget_modify_base() color, if changed. */ + + GtkWidget *widget = GTK_WIDGET (entry); + GdkColor color = widget->style->base [GTK_STATE_NORMAL]; + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &color); + + if (entry->left_window) + gdk_window_set_background (entry->left_window, &color); + if (entry->right_window) + gdk_window_set_background (entry->right_window, &color); +} + +static void ygtk_ext_entry_style_set (GtkWidget *widget, GtkStyle *prev_style) +{ + GTK_WIDGET_CLASS (ygtk_ext_entry_parent_class)->style_set (widget, prev_style); + ygtk_ext_entry_sync_color (YGTK_EXT_ENTRY (widget)); +} + +GdkWindow *ygtk_ext_entry_get_window (YGtkExtEntry *entry, + YGtkExtEntryWindowType type) +{ + switch (type) { + case YGTK_EXT_ENTRY_WIDGET_WIN: + return gtk_widget_get_parent_window (GTK_WIDGET (entry)); + case YGTK_EXT_ENTRY_TEXT_WIN: + return GTK_ENTRY (entry)->text_area; + case YGTK_EXT_ENTRY_LEFT_WIN: + return entry->left_window; + case YGTK_EXT_ENTRY_RIGHT_WIN: + return entry->right_window; + } + return NULL; +} + +void ygtk_ext_entry_set_border_window_size (YGtkExtEntry *entry, + YGtkExtEntryWindowType type, gint size) +{ + GtkWidget *widget = GTK_WIDGET (entry); + g_return_if_fail (type == YGTK_EXT_ENTRY_LEFT_WIN || type == YGTK_EXT_ENTRY_RIGHT_WIN); + + GdkWindow **window; + if (type == YGTK_EXT_ENTRY_LEFT_WIN) + window = &entry->left_window; + else + window = &entry->right_window; + + if (size) { + if (!*window) { + // must be realized to create a window + GdkWindowAttr attributes; + gint attributes_mask; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK + | GDK_ENTER_NOTIFY_MASK | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK; + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + // this will be tuned on size_allocate + if (type == YGTK_EXT_ENTRY_LEFT_WIN) + attributes.x = 0; + else + attributes.x = widget->allocation.width - size; + attributes.y = widget->allocation.y; + attributes.width = size; + attributes.height = widget->allocation.height; + + *window = gdk_window_new (widget->window, + &attributes, attributes_mask); + gdk_window_set_user_data (*window, widget); + // set background style + ygtk_ext_entry_sync_color (entry); + + if (GTK_WIDGET_MAPPED (widget)) + gdk_window_show (*window); + gtk_widget_queue_resize (widget); + } + else { + gint width, height; + gdk_drawable_get_size (GDK_DRAWABLE (*window), &width, &height); + if (width != size) { + gdk_window_resize (*window, size, height); + gtk_widget_queue_resize (widget); + } + } + } + else { // remove the window + if (*window) { + gdk_window_set_user_data (*window, NULL); + gdk_window_destroy (*window); + *window = NULL; + gtk_widget_queue_resize (widget); + } + } +} + +gint ygtk_ext_entry_get_border_window_size (YGtkExtEntry *entry, + YGtkExtEntryWindowType type) +{ + g_return_val_if_fail (type == YGTK_EXT_ENTRY_LEFT_WIN || type == YGTK_EXT_ENTRY_RIGHT_WIN, 0); + GdkWindow *window = ygtk_ext_entry_get_window (entry, type); + gint size = 0; + if (window && gdk_window_is_visible (window)) + gdk_drawable_get_size (GDK_DRAWABLE (window), &size, NULL); + return size; +} + +static void ygtk_ext_entry_size_request (GtkWidget *widget, GtkRequisition *req) +{ + GTK_WIDGET_CLASS (ygtk_ext_entry_parent_class)->size_request (widget, req); + + YGtkExtEntry *entry = YGTK_EXT_ENTRY (widget); + req->width += ygtk_ext_entry_get_border_window_size (entry, + YGTK_EXT_ENTRY_LEFT_WIN); + req->width += ygtk_ext_entry_get_border_window_size (entry, + YGTK_EXT_ENTRY_RIGHT_WIN); +} + +static void ygtk_ext_entry_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GTK_WIDGET_CLASS (ygtk_ext_entry_parent_class)->size_allocate + (widget, allocation); + if (!GTK_WIDGET_REALIZED (widget)) + return; + + YGtkExtEntry *entry = YGTK_EXT_ENTRY (widget); + gint left_border, right_border; + left_border = ygtk_ext_entry_get_border_window_size (entry, + YGTK_EXT_ENTRY_LEFT_WIN); + right_border = ygtk_ext_entry_get_border_window_size (entry, + YGTK_EXT_ENTRY_RIGHT_WIN); + + GdkWindow *window; + gint _x, _y, _w, _h, x, w; + + // text window + window = ygtk_ext_entry_get_window (entry, YGTK_EXT_ENTRY_TEXT_WIN); + gdk_window_get_geometry (window, &_x, &_y, &_w, &_h, NULL); + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + x = _x + left_border; + else + x = _x + right_border; + w = _w - (left_border + right_border); + gdk_window_move_resize (window, x, _y, w, _h); + + // left window + window = ygtk_ext_entry_get_window (entry, YGTK_EXT_ENTRY_LEFT_WIN); + if (window && gdk_window_is_visible (window)) { + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + x = _x; + else + x = _x + _w - left_border; + w = left_border; + gdk_window_move_resize (window, x, _y, w, _h); + } + + // right window + window = ygtk_ext_entry_get_window (entry, YGTK_EXT_ENTRY_RIGHT_WIN); + if (window && gdk_window_is_visible (window)) { + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + x = _x + _w - right_border; + else + x = _x; + w = right_border; + gdk_window_move_resize (window, x, _y, w, _h); + } +} + +GtkWidget *ygtk_ext_entry_new (void) +{ + return g_object_new (YGTK_TYPE_EXT_ENTRY, NULL); +} + +static void ygtk_ext_entry_class_init (YGtkExtEntryClass *klass) +{ + GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->map = ygtk_ext_entry_map; + gtkwidget_class->unmap = ygtk_ext_entry_unmap; + gtkwidget_class->style_set = ygtk_ext_entry_style_set; + gtkwidget_class->size_request = ygtk_ext_entry_size_request; + gtkwidget_class->size_allocate = ygtk_ext_entry_size_allocate; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_ext_entry_destroy; +} + +/* YGtkFindEntry widget */ +// check the header file for information about this widget + +#include <string.h> +#define ARROW_SIZE 7 + +static void ygtk_find_entry_editable_init (GtkEditableClass *iface); + +G_DEFINE_TYPE_WITH_CODE (YGtkFindEntry, ygtk_find_entry, YGTK_TYPE_EXT_ENTRY, + G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, ygtk_find_entry_editable_init)) + +static void ygtk_find_entry_init (YGtkFindEntry *entry) +{ +} + +static void ygtk_find_entry_destroy (GtkObject *object) +{ + GTK_OBJECT_CLASS (ygtk_find_entry_parent_class)->destroy (object); + + YGtkFindEntry *entry = YGTK_FIND_ENTRY (object); + +#define DESTROY_ICON(icon) \ + if (icon) { g_object_unref (G_OBJECT (icon)); icon = NULL; } + + DESTROY_ICON (entry->find_icon) + DESTROY_ICON (entry->find_hover_icon) + DESTROY_ICON (entry->clear_icon) + DESTROY_ICON (entry->clear_hover_icon) +#undef DESTROY_ICON +} + +// Code from Banshee: shades a pixbuf a bit, used to provide the hover effect +static inline guchar pixel_clamp (int val) +{ return MAX (0, MIN (255, val)); } +static GdkPixbuf *pixbuf_color_shift (const GdkPixbuf *src, int shift) +{ + if (!src) + return NULL; + + int width = gdk_pixbuf_get_width (src), height = gdk_pixbuf_get_height (src); + gboolean has_alpha = gdk_pixbuf_get_has_alpha (src); + + GdkPixbuf *dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), + has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height); + + guchar *src_pixels_orig = gdk_pixbuf_get_pixels (src); + guchar *dest_pixels_orig = gdk_pixbuf_get_pixels (dest); + + int src_rowstride = gdk_pixbuf_get_rowstride (src); + int dest_rowstride = gdk_pixbuf_get_rowstride (dest); + int i, j; + for (i = 0; i < height; i++) { + guchar *src_pixels = src_pixels_orig + (i * src_rowstride); + guchar *dest_pixels = dest_pixels_orig + (i * dest_rowstride); + for (j = 0; j < width; j++) { + *(dest_pixels++) = pixel_clamp (*(src_pixels++) + shift); + *(dest_pixels++) = pixel_clamp (*(src_pixels++) + shift); + *(dest_pixels++) = pixel_clamp (*(src_pixels++) + shift); + if (has_alpha) + *(dest_pixels++) = *(src_pixels++); + } + } + return dest; +} + +static void ygtk_find_entry_set_borders (YGtkFindEntry *entry) +{ + YGtkExtEntry *eentry = YGTK_EXT_ENTRY (entry); + int left_border = 0, right_border = 0; + if (entry->find_icon) { + left_border = gdk_pixbuf_get_width (entry->find_icon) + 2; + if (entry->context_menu) + left_border += ARROW_SIZE - 1; + } + if (entry->clear_icon) + right_border = gdk_pixbuf_get_width (entry->clear_icon) + 2; + + ygtk_ext_entry_set_border_window_size (eentry, + YGTK_EXT_ENTRY_LEFT_WIN, left_border); + ygtk_ext_entry_set_border_window_size (eentry, + YGTK_EXT_ENTRY_RIGHT_WIN, right_border); + gtk_widget_queue_resize (GTK_WIDGET (entry)); +} + +static void ygtk_find_entry_realize (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->realize (widget); + + YGtkExtEntry *eentry = YGTK_EXT_ENTRY (widget); + YGtkFindEntry *fentry = YGTK_FIND_ENTRY (widget); + fentry->find_icon = gtk_widget_render_icon (widget, GTK_STOCK_FIND, + GTK_ICON_SIZE_MENU, NULL); + fentry->clear_icon = gtk_widget_render_icon (widget, GTK_STOCK_CLEAR, + GTK_ICON_SIZE_MENU, NULL); + + fentry->find_hover_icon = pixbuf_color_shift (fentry->find_icon, 30); + fentry->clear_hover_icon = pixbuf_color_shift (fentry->clear_icon, 30); + + ygtk_find_entry_set_borders (fentry); + + GdkDisplay *display = gtk_widget_get_display (widget); + GdkCursor *cursor = gdk_cursor_new_for_display (display, GDK_HAND1); + + gdk_window_set_cursor (eentry->left_window, cursor); + gdk_window_set_cursor (eentry->right_window, cursor); + gdk_cursor_unref (cursor); +} + +static void ygtk_find_entry_map (GtkWidget *widget) +{ + if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_MAPPED (widget)) { + GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->map (widget); + // only show clear icon when the entry has text + GdkWindow *clear_win = YGTK_EXT_ENTRY (widget)->right_window; + if (clear_win) + gdk_window_hide (clear_win); + } +} + +static gboolean ygtk_find_entry_expose (GtkWidget *widget, GdkEventExpose *event) +{ + YGtkExtEntry *eentry = YGTK_EXT_ENTRY (widget); + YGtkFindEntry *fentry = YGTK_FIND_ENTRY (widget); + + GdkWindow *hover_window = gdk_display_get_window_at_pointer ( + gtk_widget_get_display (widget), NULL, NULL); + + if (event->window == eentry->left_window || + event->window == eentry->right_window) { + gboolean hover = hover_window == event->window; + GdkPixbuf *pixbuf; + if (event->window == eentry->left_window) + pixbuf = hover ? fentry->find_hover_icon : fentry->find_icon; + else + pixbuf = hover ? fentry->clear_hover_icon : fentry->clear_icon; + + int pix_height = gdk_pixbuf_get_height (pixbuf), win_width, win_height, y; + gdk_drawable_get_size (event->window, &win_width, &win_height); + y = (win_height - pix_height) / 2; + + gdk_draw_pixbuf (event->window, widget->style->fg_gc[0], pixbuf, + 0, 0, 1, y, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + + if (fentry->context_menu && event->window == eentry->left_window) + gtk_paint_arrow (widget->style, event->window, GTK_STATE_NORMAL, + GTK_SHADOW_NONE, &event->area, widget, NULL, + GTK_ARROW_DOWN, FALSE, + win_width - ARROW_SIZE - 1, win_height - ARROW_SIZE, + ARROW_SIZE, ARROW_SIZE); + } + else + GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->expose_event (widget, event); + return TRUE; +} + +/* Re-draw find/clear windows on mouse hover. */ +static gboolean ygtk_find_entry_enter_leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event) +{ + if (widget == gtk_get_event_widget ((GdkEvent*) event)) { + YGtkExtEntry *eentry = YGTK_EXT_ENTRY (widget); + if (event->window == eentry->left_window || + event->window == eentry->right_window) + gdk_window_invalidate_rect (event->window, NULL, FALSE); + } + return FALSE; +} + +static void ygtk_find_entry_actual_popup_menu (GtkWidget *widget, guint button, + guint32 time) +{ + GtkMenu *menu = YGTK_FIND_ENTRY (widget)->context_menu; + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, time); +} + +static gboolean ygtk_find_entry_popup_menu (GtkWidget *widget) +{ + if (YGTK_FIND_ENTRY (widget)->context_menu) { + ygtk_find_entry_actual_popup_menu (widget, 0, gtk_get_current_event_time()); + return TRUE; + } + return GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->popup_menu (widget); +} + +static gboolean ygtk_find_entry_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + YGtkFindEntry *fentry = YGTK_FIND_ENTRY (widget); + YGtkExtEntry *eentry = YGTK_EXT_ENTRY (widget); + if (event->window == eentry->left_window) { + // If the entry has an associated context menu, use it. + // Otherwise, find icon selects entry's text. + gtk_widget_grab_focus (widget); + if (fentry->context_menu) + ygtk_find_entry_actual_popup_menu (widget, event->button, event->time); + else + gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1); + } + else if (event->window == eentry->right_window) { + gtk_editable_delete_text (GTK_EDITABLE (widget), 0, -1); + gtk_widget_grab_focus (widget); + } + else + return GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->button_press_event + (widget, event); + return TRUE; +} + +static void ygtk_find_entry_insert_text (GtkEditable *editable, + const gchar *new_text, gint new_text_len, gint *pos) +{ + GtkEditableClass *parent_editable_iface = g_type_interface_peek + (ygtk_find_entry_parent_class, GTK_TYPE_EDITABLE); + parent_editable_iface->insert_text (editable, new_text, new_text_len, pos); + + GdkWindow *clear_win = YGTK_EXT_ENTRY (editable)->right_window; + if (clear_win) + gdk_window_show (clear_win); +} + +static void ygtk_find_entry_delete_text (GtkEditable *editable, gint start_pos, + gint end_pos) +{ + GtkEditableClass *parent_editable_iface = g_type_interface_peek + (ygtk_find_entry_parent_class, GTK_TYPE_EDITABLE); + parent_editable_iface->delete_text (editable, start_pos, end_pos); + + int has_text = strlen (gtk_entry_get_text (GTK_ENTRY (editable))); + if (!has_text) { + /* Set or delete text may be called while the widget has not yet been + realized. */ + GdkWindow *clear_win = YGTK_EXT_ENTRY (editable)->right_window; + if (clear_win) + gdk_window_hide (clear_win); + } +} + +void ygtk_find_entry_attach_menu (YGtkFindEntry *entry, GtkMenu *menu) +{ + if (entry->context_menu) + gtk_menu_detach (entry->context_menu); + entry->context_menu = menu; + if (menu) + gtk_menu_attach_to_widget (menu, GTK_WIDGET (entry), NULL); + ygtk_find_entry_set_borders (entry); +} + +GtkWidget *ygtk_find_entry_new (void /*gboolean will_use_find_icon */) +{ + return g_object_new (YGTK_TYPE_FIND_ENTRY, NULL); +} + +static void ygtk_find_entry_class_init (YGtkFindEntryClass *klass) +{ + GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->realize = ygtk_find_entry_realize; + gtkwidget_class->map = ygtk_find_entry_map; + gtkwidget_class->expose_event = ygtk_find_entry_expose; + gtkwidget_class->enter_notify_event = ygtk_find_entry_enter_leave_notify_event; + gtkwidget_class->leave_notify_event = ygtk_find_entry_enter_leave_notify_event; + gtkwidget_class->button_press_event = ygtk_find_entry_button_press_event; + gtkwidget_class->popup_menu = ygtk_find_entry_popup_menu; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_find_entry_destroy; +} + +static void ygtk_find_entry_editable_init (GtkEditableClass *iface) +{ + iface->insert_text = ygtk_find_entry_insert_text; + iface->delete_text = ygtk_find_entry_delete_text; +} Added: trunk/gtk/unstable/src/ygtkfindentry.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkfindentry.h?... ============================================================================== --- trunk/gtk/unstable/src/ygtkfindentry.h (added) +++ trunk/gtk/unstable/src/ygtkfindentry.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,99 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkExtEntry extends GtkEntry adding two optional GdkWindows, at each + horizontal corner, which are created at demand. Very useful to create + a panel, an icon or something inside of it. + GtkTextView provides something similar and would be nice to have this + right on GtkEntry; in fact, GtkSpinButton could be simplified if it + were for this. + Right-to-left is supported at this level (borders are mirrored, if it + is set). If you don't want that, use gtk_widget_set_direction(). + + YGtkFindEntry is a convinience widget that has a find icon, with an + optional menu, at the left, and an erase icon at the right. +*/ + +#ifndef YGTK_FIND_ENTRY_H +#define YGTK_FIND_ENTRY_H + +#include <gtk/gtkentry.h> +G_BEGIN_DECLS + +//** YGtkExtEntry + +#define YGTK_TYPE_EXT_ENTRY (ygtk_ext_entry_get_type ()) +#define YGTK_EXT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_EXT_ENTRY, YGtkExtEntry)) +#define YGTK_EXT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_EXT_ENTRY, YGtkExtEntryClass)) +#define YGTK_IS_EXT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_EXT_ENTRY)) +#define YGTK_IS_EXT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_EXT_ENTRY)) +#define YGTK_EXT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_EXT_ENTRY, YGtkExtEntryClass)) + +typedef struct _YGtkExtEntry +{ + GtkEntry parent; + // members: + GdkWindow *left_window, *right_window; +} YGtkExtEntry; + +typedef struct _YGtkExtEntryClass +{ + GtkEntryClass parent_class; +} YGtkExtEntryClass; + +GtkWidget* ygtk_ext_entry_new (void); +GType ygtk_ext_entry_get_type (void) G_GNUC_CONST; + +// API based on that of GtkTextView -- limited to our needs +typedef enum +{ YGTK_EXT_ENTRY_WIDGET_WIN, YGTK_EXT_ENTRY_TEXT_WIN, + YGTK_EXT_ENTRY_LEFT_WIN, YGTK_EXT_ENTRY_RIGHT_WIN +} YGtkExtEntryWindowType; + +GdkWindow *ygtk_ext_entry_get_window (YGtkExtEntry *entry, + YGtkExtEntryWindowType type); +void ygtk_ext_entry_set_border_window_size (YGtkExtEntry *entry, + YGtkExtEntryWindowType type, gint size); +gint ygtk_ext_entry_get_border_window_size (YGtkExtEntry *entry, + YGtkExtEntryWindowType type); + +//** YGtkFindEntry + +#define YGTK_TYPE_FIND_ENTRY (ygtk_find_entry_get_type ()) +#define YGTK_FIND_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_FIND_ENTRY, YGtkFindEntry)) +#define YGTK_FIND_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_FIND_ENTRY, YGtkFindEntryClass)) +#define YGTK_IS_FIND_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_FIND_ENTRY)) +#define YGTK_IS_FIND_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_FIND_ENTRY)) +#define YGTK_FIND_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_FIND_ENTRY, YGtkFindEntryClass)) + +typedef struct _YGtkFindEntry +{ + YGtkExtEntry parent; + // members + GdkPixbuf *find_icon, *clear_icon, *find_hover_icon, *clear_hover_icon; + GtkMenu *context_menu; +} YGtkFindEntry; + +typedef struct _YGtkFindEntryClass +{ + YGtkExtEntryClass parent_class; +} YGtkFindEntryClass; + +GtkWidget* ygtk_find_entry_new (void); +GType ygtk_find_entry_get_type (void) G_GNUC_CONST; + +void ygtk_find_entry_attach_menu (YGtkFindEntry *entry, GtkMenu *popup_menu); + +G_END_DECLS +#endif /*YGTK_FIND_ENTRY_H*/ Added: trunk/gtk/unstable/src/ygtkhtmlwrap.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkhtmlwrap.c?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkhtmlwrap.c (added) +++ trunk/gtk/unstable/src/ygtkhtmlwrap.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,170 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkHtmlWrap widget */ +// check the header file for information about this widget + +#include <config.h> +#include <gtk/gtkversion.h> +#include <string.h> +#include "ygtkhtmlwrap.h" + +GtkWidget *ygtk_html_wrap_new (void) +{ + return g_object_new (ygtk_html_wrap_get_type(), NULL); +} + + +// Utilities +static inline void adjust_scroll (GtkAdjustment *vadj, gboolean top) +{ + g_assert (vadj != 0); + if (top) + gtk_adjustment_set_value (vadj, vadj->lower); + else /* bottom */ + gtk_adjustment_set_value (vadj, vadj->upper - vadj->page_size); +} + +static void gdkwindow_set_background (GdkWindow *window, const char *image) +{ + if (image) { + GError *error = 0; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (image, &error); + if (!pixbuf) { + g_warning ("ygtkrichtext: could not open background image: '%s'" + " - %s", image, error->message); + return; + } + + GdkPixmap *pixmap; + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, + gdk_drawable_get_colormap (GDK_DRAWABLE (window)), &pixmap, NULL, 0); + g_object_unref (G_OBJECT (pixbuf)); + + gdk_window_set_back_pixmap (window, pixmap, FALSE); + } + else + gdk_window_clear (window); +} + +// GtkHTML +#ifdef USE_GTKHTML +#include <libgtkhtml-3.14/gtkhtml/gtkhtml.h> +#include <libgtkhtml-3.14/gtkhtml/gtkhtml-stream.h> +#include <libgtkhtml-3.14/gtkhtml/gtkhtml-search.h> + +GType ygtk_html_wrap_get_type (void) +{ + return GTK_TYPE_HTML; +} + +static void gtkhtml_url_requested_cb (GtkHTML *html, const gchar *url, GtkHTMLStream *stream) +{ // to load images (and possibly other external embed files) + FILE *file = fopen (url, "rb"); + + fseek (file, 0, SEEK_END); + size_t file_size = ftell (file); + rewind (file); + + gboolean error; + gchar *data = g_new (gchar, file_size); + error = fread (data, 1, file_size, file) < file_size; + fclose (file); + + if (!error) + gtk_html_stream_write (stream, data, file_size); + g_free (data); +} + +void ygtk_html_wrap_init (GtkWidget *widget) +{ + gtk_html_set_editable (GTK_HTML (widget), FALSE); + g_signal_connect (G_OBJECT (widget), "url-requested", + G_CALLBACK (gtkhtml_url_requested_cb), NULL); +} + +void ygtk_html_wrap_set_text (GtkWidget *widget, const gchar* text) +{ + GtkHTMLStream *stream = gtk_html_begin (GTK_HTML (widget)); + gtk_html_write (GTK_HTML (widget), stream, text, strlen (text)); + gtk_html_end (GTK_HTML (widget), stream, GTK_HTML_STREAM_OK); +} + +void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top) +{ + adjust_scroll (GTK_LAYOUT (widget)->vadjustment, top); +} + +gboolean ygtk_html_wrap_search (GtkWidget *widget, const gchar *text) +{ +/* if (*text == '\0') + return TRUE;*/ + return gtk_html_engine_search (GTK_HTML (widget), text, FALSE, TRUE, FALSE); +} + +gboolean ygtk_html_wrap_search_next (GtkWidget *widget, const gchar *text) +{ + return gtk_html_engine_search_next (GTK_HTML (widget)); +} + +void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data) +{ + g_signal_connect (G_OBJECT (widget), "link-clicked", callback, data); +} + +void ygtk_html_wrap_set_background (GtkWidget *widget, const char *image) +{ + // TODO +} + +// YGtkRichText +#else +#include "ygtkrichtext.h" + +GType ygtk_html_wrap_get_type() +{ + return YGTK_TYPE_RICH_TEXT; +} + +void ygtk_html_wrap_init (GtkWidget *widget) +{ +} + +void ygtk_html_wrap_set_text (GtkWidget *widget, const gchar* text) +{ + ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), text, TRUE); +} + +void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top) +{ + adjust_scroll (GTK_TEXT_VIEW (widget)->vadjustment, top); +} + +gboolean ygtk_html_wrap_search (GtkWidget *widget, const gchar *text) +{ + gboolean ret = ygtk_rich_text_mark_text (YGTK_RICH_TEXT (widget), text); + ygtk_rich_text_forward_mark (YGTK_RICH_TEXT (widget), text); + return ret; +} + +gboolean ygtk_html_wrap_search_next (GtkWidget *widget, const gchar *text) +{ + return ygtk_rich_text_forward_mark (YGTK_RICH_TEXT (widget), text); +} + +void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data) +{ + g_signal_connect (G_OBJECT (widget), "link-clicked", callback, data); +} + +void ygtk_html_wrap_set_background (GtkWidget *widget, const char *image) +{ + g_return_if_fail (GTK_WIDGET_REALIZED (widget)); + GdkWindow *window = gtk_text_view_get_window + (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_TEXT); + gdkwindow_set_background (window, image); +} + +#endif + Added: trunk/gtk/unstable/src/ygtkhtmlwrap.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkhtmlwrap.h?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkhtmlwrap.h (added) +++ trunk/gtk/unstable/src/ygtkhtmlwrap.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,37 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkHtmlWrap is a wrapper around either GtkHtml and YGtkRichText, as + set at compilation time. GtkHtml is superior, but to avoid dependencies, + we use our customized in case it isn't installed. + If you flag it as plain_text, it will simply wrap GtkTextView. +*/ + +#ifndef YGTK_HTML_WRAP_H +#define YGTK_HTML_WRAP_H + +#include <gtk/gtkwidget.h> +G_BEGIN_DECLS + +GtkWidget *ygtk_html_wrap_new (void); + +GType ygtk_html_wrap_get_type (void); +void ygtk_html_wrap_init (GtkWidget *widget); // if you use g_object_new(), call this + +void ygtk_html_wrap_set_text (GtkWidget *widget, const gchar* text); +void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top /* or bottom */); + +// callback of type: void (GtkWidget *htmlwrap, const gchar *url, gpointer data) +void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data); + +// not supported on plain text +gboolean ygtk_html_wrap_search (GtkWidget *widget, const gchar *text); +gboolean ygtk_html_wrap_search_next (GtkWidget *widget, const gchar *text); // F3 + +// set a background image -- to be done on (or after) realize +void ygtk_html_wrap_set_background (GtkWidget *widget, const char *image); + +G_END_DECLS +#endif /* YGTK_HTML_WRAP_H */ + Added: trunk/gtk/unstable/src/ygtkmenubutton.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkmenubutton.c... ============================================================================== --- trunk/gtk/unstable/src/ygtkmenubutton.c (added) +++ trunk/gtk/unstable/src/ygtkmenubutton.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,247 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkMenuButton widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkmenubutton.h" +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> + +//** YGtkPopupWindow + +G_DEFINE_TYPE (YGtkPopupWindow, ygtk_popup_window, GTK_TYPE_WINDOW) + +static void ygtk_popup_window_init (YGtkPopupWindow *popup) +{ + GtkWindow *window = GTK_WINDOW (popup); + gtk_window_set_resizable (window, FALSE); + + GtkWidget *frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); + gtk_widget_show (frame); + gtk_container_add (GTK_CONTAINER (window), frame); +} + +static void ygtk_popup_window_hide (GtkWidget *widget) +{ + gtk_grab_remove (widget); + GTK_WIDGET_CLASS (ygtk_popup_window_parent_class)->hide (widget); +} + +static gboolean ygtk_popup_window_key_press_event (GtkWidget *widget, GdkEventKey *event) +{ + if (event->keyval == GDK_Escape) { + gtk_widget_hide (widget); + return TRUE; + } + return GTK_WIDGET_CLASS (ygtk_popup_window_parent_class)->key_press_event + (widget, event); +} + +static gboolean ygtk_popup_window_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + // NOTE: You can't rely on events x and y since the event may take place + // outside of the window. + // So, we'll check if this widget (or any of its kids) got the event + // If that's not the case, close the menu + + GtkWidget *child = gtk_get_event_widget ((GdkEvent *) event); + if (child != widget) + while (child) { + if (child == widget) + return FALSE; + child = child->parent; + } + gtk_widget_hide (widget); + return TRUE; +} + +GtkWidget *ygtk_popup_window_new (GtkWidget *child) +{ + GtkWidget *widget = g_object_new (YGTK_TYPE_POPUP_WINDOW, + "type", GTK_WINDOW_POPUP, NULL); + GtkWidget *frame = gtk_bin_get_child (GTK_BIN (widget)); + gtk_container_add (GTK_CONTAINER (frame), child); + return widget; +} + +void ygtk_popup_window_popup (GtkWidget *widget, gint x, gint y, guint activate_time) +{ + gtk_grab_add (widget); + gtk_window_move (GTK_WINDOW (widget), x, y); + gtk_widget_grab_focus (widget); + gtk_widget_show (widget); + + // grab this with your teeth + if (gdk_pointer_grab (widget->window, TRUE, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + NULL, NULL, activate_time) == 0) + if (gdk_keyboard_grab (widget->window, TRUE, activate_time) != 0) + gdk_pointer_ungrab(activate_time); +} + +static void ygtk_popup_window_class_init (YGtkPopupWindowClass *klass) +{ + ygtk_popup_window_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + widget_class->key_press_event = ygtk_popup_window_key_press_event; + widget_class->button_press_event = ygtk_popup_window_button_press_event; + widget_class->hide = ygtk_popup_window_hide; +} + +//** YGtkMenuButton + +G_DEFINE_TYPE (YGtkMenuButton, ygtk_menu_button, GTK_TYPE_TOGGLE_BUTTON) + +static void ygtk_menu_button_init (YGtkMenuButton *button) +{ + button->popup = NULL; + button->label = gtk_label_new (""); + + GtkWidget *hbox, *arrow; + hbox = gtk_hbox_new (FALSE, 0); + arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN); + + if (gtk_widget_get_direction (arrow) == GTK_TEXT_DIR_LTR) { + gtk_container_add (GTK_CONTAINER (hbox), button->label); + gtk_container_add (GTK_CONTAINER (hbox), arrow); + } + else { + gtk_container_add (GTK_CONTAINER (hbox), arrow); + gtk_container_add (GTK_CONTAINER (hbox), button->label); + } + + gtk_box_set_child_packing (GTK_BOX (hbox), arrow, FALSE, FALSE, + 5, GTK_PACK_START); + + gtk_widget_show_all (hbox); + gtk_container_add (GTK_CONTAINER (button), hbox); +} + +static void ygtk_menu_button_free_popup (YGtkMenuButton *button) +{ + if (button->popup) { + gtk_widget_destroy (GTK_WIDGET (button->popup)); + g_object_unref (G_OBJECT (button->popup)); + button->popup = NULL; + } +} + +static void ygtk_menu_button_finalize (GObject *object) +{ + ygtk_menu_button_free_popup (YGTK_MENU_BUTTON (object)); + G_OBJECT_CLASS (ygtk_menu_button_parent_class)->finalize (object); +} + +static void ygtk_menu_button_get_menu_pos (GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, gpointer pointer) +{ + GtkWidget *widget = (GtkWidget*) pointer; + gdk_window_get_origin (widget->window, x, y); + *x += widget->allocation.x; + *y += widget->allocation.y + widget->allocation.height; + *push_in = TRUE; +} + +static void ygtk_menu_button_show_popup (YGtkMenuButton *button) +{ + GtkWidget *widget = GTK_WIDGET (button); + GtkWidget *popup = button->popup; + if (!popup) + return; + + guint activate_time = gtk_get_current_event_time(); + + if (GTK_IS_MENU (popup)) + gtk_menu_popup (GTK_MENU (popup), NULL, NULL, ygtk_menu_button_get_menu_pos, + widget, 0, activate_time); + else { // GTK_IS_WINDOW + gint x, y; + gdk_window_get_origin (GDK_WINDOW (widget->window), &x, &y); + x += widget->allocation.x; + y += widget->allocation.y + widget->allocation.height; + + ygtk_popup_window_popup (popup, x, y, activate_time); + } + + if (widget->allocation.width > popup->allocation.width) + gtk_widget_set_size_request (popup, widget->allocation.width, -1); +} + +static void ygtk_menu_button_hide_popup (YGtkMenuButton *button) +{ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); +} + +static void ygtk_menu_button_button_toggle (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) + ygtk_menu_button_show_popup (YGTK_MENU_BUTTON (button)); + else + ygtk_menu_button_hide_popup (YGTK_MENU_BUTTON (button)); +} + +static gint ygtk_menu_button_button_press (GtkWidget *widget, GdkEventButton *event) +{ + if (event->type == GDK_BUTTON_PRESS && event->button == 1) { + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); + ygtk_menu_button_show_popup (YGTK_MENU_BUTTON (widget)); + } + else + ygtk_menu_button_hide_popup (YGTK_MENU_BUTTON (widget)); + return TRUE; + } + return FALSE; +} + +GtkWidget *ygtk_menu_button_new (void) +{ + return g_object_new (YGTK_TYPE_MENU_BUTTON, NULL); +} + +void ygtk_menu_button_set_label (YGtkMenuButton *button, const gchar *label) +{ + gtk_label_set_text_with_mnemonic (GTK_LABEL (button->label), label); + gtk_widget_show (button->label); +} + +static void menu_button_hide_popup (GtkWidget *widget, YGtkMenuButton *button) +{ ygtk_menu_button_hide_popup (button); } + +void ygtk_menu_button_set_popup (YGtkMenuButton *button, GtkWidget *popup) +{ + ygtk_menu_button_free_popup (button); + + if (!GTK_IS_MENU (popup) && !IS_YGTK_POPUP_WINDOW (popup)) { + // install widget on a YGtkPopupMenu + button->popup = ygtk_popup_window_new (popup); + } + else + button->popup = popup; + + g_object_ref (G_OBJECT (button->popup)); + gtk_object_sink (GTK_OBJECT (button->popup)); + + g_signal_connect (G_OBJECT (popup), "hide", + G_CALLBACK (menu_button_hide_popup), button); +} + +static void ygtk_menu_button_class_init (YGtkMenuButtonClass *klass) +{ + ygtk_menu_button_parent_class = g_type_class_peek_parent (klass); + + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ygtk_menu_button_finalize; + + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + widget_class->button_press_event = ygtk_menu_button_button_press; + + GtkToggleButtonClass *toggle_button_class = GTK_TOGGLE_BUTTON_CLASS (klass); + toggle_button_class->toggled = ygtk_menu_button_button_toggle; +} Added: trunk/gtk/unstable/src/ygtkmenubutton.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkmenubutton.h... ============================================================================== --- trunk/gtk/unstable/src/ygtkmenubutton.h (added) +++ trunk/gtk/unstable/src/ygtkmenubutton.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,90 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkMenuButton is a button that displays a widget when pressed. + This widget can either be of type GtkMenu or another, like a + GtkCalendar and we'll do the proper "emulation" (the work of + the YGtkPopupWindow widget). +*/ + +#ifndef YGTK_POPUP_WINDOW_H +#define YGTK_POPUP_WINDOW_H + +#include <gtk/gtkwindow.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_POPUP_WINDOW (ygtk_popup_window_get_type ()) +#define YGTK_POPUP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_POPUP_WINDOW, YGtkPopupWindow)) +#define YGTK_POPUP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_POPUP_WINDOW, YGtkPopupWindowClass)) +#define IS_YGTK_POPUP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_POPUP_WINDOW)) +#define IS_YGTK_POPUP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_POPUP_WINDOW)) +#define YGTK_POPUP_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_POPUP_WINDOW, YGtkPopupWindowClass)) + +typedef struct _YGtkPopupWindow +{ + GtkWindow parent; +} YGtkPopupWindow; + +typedef struct _YGtkPopupWindowClass +{ + GtkWindowClass parent_class; +} YGtkPopupWindowClass; + +// don't forget to use gtk_widget_show() on the child! +GtkWidget* ygtk_popup_window_new (GtkWidget *child); +GType ygtk_popup_window_get_type (void) G_GNUC_CONST; + +void ygtk_popup_window_popup (GtkWidget *widget, gint x, gint y, guint activate_time); + +G_END_DECLS +#endif /*YGTK_POPUP_WINDOW_H*/ + +#ifndef YGTK_MENU_BUTTON_H +#define YGTK_MENU_BUTTON_H + +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkmenu.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_MENU_BUTTON (ygtk_menu_button_get_type ()) +#define YGTK_MENU_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_MENU_BUTTON, YGtkMenuButton)) +#define YGTK_MENU_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_MENU_BUTTON, YGtkMenuButtonClass)) +#define IS_YGTK_MENU_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_MENU_BUTTON)) +#define IS_YGTK_MENU_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_MENU_BUTTON)) +#define YGTK_MENU_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_MENU_BUTTON, YGtkMenuButtonClass)) + +typedef struct _YGtkMenuButton +{ + GtkToggleButton parent; + + // private: + GtkWidget *label, *popup; +} YGtkMenuButton; + +typedef struct _YGtkMenuButtonClass +{ + GtkToggleButtonClass parent_class; +} YGtkMenuButtonClass; + +GtkWidget* ygtk_menu_button_new (void); +GType ygtk_menu_button_get_type (void) G_GNUC_CONST; + +void ygtk_menu_button_set_label (YGtkMenuButton *button, const gchar *label); + +/* Popup must be either a GtkMenu or a YGtkPopupWindow. */ +// You may hide your popup "manually" issueing a gtk_widget_hide() on it +void ygtk_menu_button_set_popup (YGtkMenuButton *button, GtkWidget *popup); + +G_END_DECLS +#endif /*YGTK_MENU_BUTTON_H*/ Added: trunk/gtk/unstable/src/ygtkratiobox.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkratiobox.c?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkratiobox.c (added) +++ trunk/gtk/unstable/src/ygtkratiobox.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,585 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkRatioBox widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkratiobox.h" + +G_DEFINE_ABSTRACT_TYPE (YGtkRatioBox, ygtk_ratio_box, GTK_TYPE_CONTAINER) + +static void ygtk_ratio_box_init (YGtkRatioBox *box) +{ + GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW); + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE); +} + +static GType ygtk_ratio_box_child_type (GtkContainer* container) +{ return GTK_TYPE_WIDGET; } + +void ygtk_ratio_box_pack (YGtkRatioBox *box, GtkWidget *child, + gfloat ratio, gboolean xfill, gboolean yfill, + guint padding) +{ + YGtkRatioBoxChild* child_info; + child_info = g_new (YGtkRatioBoxChild, 1); + child_info->widget = child; + child_info->ratio = ratio; + child_info->padding = padding; + child_info->xfill = xfill; + child_info->yfill = yfill; + child_info->expand = 0; + + box->children = g_list_append (box->children, child_info); + + gtk_widget_freeze_child_notify (child); + gtk_widget_set_parent (child, GTK_WIDGET (box)); + gtk_widget_thaw_child_notify (child); +} + +static YGtkRatioBoxChild *ygtk_ratio_get_child_info (YGtkRatioBox *box, GtkWidget *child) +{ + YGtkRatioBoxChild *i = NULL; + GList *list; + for (list = box->children; list; list = list->next) { + i = (YGtkRatioBoxChild*) list->data; + if (i->widget == child) + break; + } + if (!list) + return NULL; + return i; +} + +static void ygtk_ratio_box_add (GtkContainer *container, GtkWidget *child) +{ + ygtk_ratio_box_pack (YGTK_RATIO_BOX (container), child, 1.0, TRUE, TRUE, 0); +} + +static void ygtk_ratio_box_remove (GtkContainer *container, GtkWidget *widget) +{ + YGtkRatioBox* box = YGTK_RATIO_BOX (container); + + GList* child = box->children; + for (child = box->children; child; child = child->next) { + YGtkRatioBoxChild *box_child = (YGtkRatioBoxChild*) child->data; + if (box_child->widget == widget) { + gboolean was_visible = GTK_WIDGET_VISIBLE (widget); + gtk_widget_unparent (widget); + + box->children = g_list_remove_link (box->children, child); + g_list_free (child); + g_free (box_child); + + if (was_visible) + gtk_widget_queue_resize (GTK_WIDGET (container)); + break; + } + } +} + +static void ygtk_ratio_box_forall (GtkContainer *container, gboolean include_internals, + GtkCallback callback, gpointer callback_data) +{ + g_return_if_fail (callback != NULL); + + YGtkRatioBox* box = YGTK_RATIO_BOX (container); + + GList* children = box->children; + while (children) { + YGtkRatioBoxChild* child = (YGtkRatioBoxChild*) children->data; + children = children->next; + (* callback) (child->widget, callback_data); + } +} + +/* We put size_request and _allocate in the same functions for both + orientations because it's just easier to maintain having the + logic in the same place. */ + +static void ygtk_ratio_box_size_request (GtkWidget *widget, + GtkRequisition *requisition, + GtkOrientation orientation) +{ + YGtkRatioBox* box = YGTK_RATIO_BOX (widget); + gfloat ratios_sum = 0; + box->has_must_expand = FALSE; + GList* child; + for (child = box->children; child; child = child->next) { + YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; + if (!GTK_WIDGET_VISIBLE (box_child->widget)) + continue; + if (box_child->ratio) + ratios_sum += box_child->ratio; + if (box_child->must_expand) + box->has_must_expand = TRUE; + } + + // If we want to calculate horizontal size, primary_req would be horizontal + // length, while secondary the height. Idem for the inverse. + guint primary_req = 0, secondary_req = 0; + box->weight_length = 0; // biggest ratio of widget-size / widget-ratio + + for (child = box->children; child; child = child->next) { + YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; + if (!GTK_WIDGET_VISIBLE (box_child->widget)) + continue; + + GtkRequisition child_req; + gtk_widget_size_request (box_child->widget, &child_req); + + guint prim_length, sec_length; + if (orientation == GTK_ORIENTATION_HORIZONTAL) { + prim_length = child_req.width; + sec_length = child_req.height; + } + else { + prim_length = child_req.height; + sec_length = child_req.width; + } + + if (box_child->ratio) + { + int length = (prim_length * ratios_sum) / box_child->ratio; + box->weight_length = MAX (box->weight_length, length); + } + else + primary_req += prim_length; + primary_req += box_child->padding + box->spacing; + secondary_req = MAX (secondary_req, sec_length); + } + + primary_req += box->weight_length; + + guint border = GTK_CONTAINER (widget)->border_width * 2; + primary_req += border*2; secondary_req += border*2; + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { + requisition->width = primary_req; + requisition->height = secondary_req; + } + else { + requisition->width = secondary_req; + requisition->height = primary_req; + } +} + +static void ygtk_ratio_box_size_allocate (GtkWidget *widget, + GtkAllocation *allocation, + GtkOrientation orientation) +{ + YGtkRatioBox* box = YGTK_RATIO_BOX (widget); + guint border = GTK_CONTAINER (widget)->border_width; + + // a first loop to get some data for expansibles (ie. childs with weight) + gfloat ratios_sum = 0; + gint expand_num = 0, max_ratio = 0; + gint expansable_length; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + expansable_length = allocation->width - border*2; + else + expansable_length = allocation->height - border*2; + + GList* child; + for (child = box->children; child; child = child->next) { + YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; + if (!GTK_WIDGET_VISIBLE (box_child->widget)) + continue; + + if (box_child->expand) + expand_num++; + if (box_child->ratio) + { + ratios_sum += box_child->ratio; + max_ratio = MAX (max_ratio, box_child->ratio); + } + + if (!box_child->ratio) + { + GtkRequisition child_req; + gtk_widget_get_child_requisition (box_child->widget, &child_req); + if (orientation == GTK_ORIENTATION_HORIZONTAL) + expansable_length -= child_req.width; + else + expansable_length -= child_req.height; + } + expansable_length -= box->spacing - box_child->padding; + } + expansable_length -= box->weight_length; + + gint child_pos = 0; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + child_pos = allocation->x + border; + else + child_pos = allocation->y + border; + + gboolean right_to_left = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL; + for (child = box->children; child; child = child->next) { + YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; + if (!GTK_WIDGET_VISIBLE (box_child->widget)) + continue; + + GtkAllocation child_alloc; + gint length; + + GtkRequisition child_req; + gtk_widget_get_child_requisition (box_child->widget, &child_req); + + if (!box_child->ratio) + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + length = child_req.width; + else + length = child_req.height; + } + + // give extra size (honor stretch order) + if (box_child->ratio) + { + int available_length = box->weight_length; + if (!box->has_must_expand) + available_length += expansable_length; + length = (box_child->ratio * available_length) / ratios_sum; + } + else if (box_child->expand && (ratios_sum == 0 || box_child->must_expand)) + { + // FIXME: something is wrong for expansable_length being < 0 at times + // we aren't asking for enough size! + if (expansable_length > 0) + length += expansable_length / expand_num; + } + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { + child_alloc.x = child_pos; + child_alloc.y = allocation->y + border; + child_alloc.width = length; + child_alloc.height = allocation->height - border*2; + } + else { // GTK_ORIENTATION_VERTICAL + child_alloc.x = allocation->x + border; + child_alloc.y = child_pos; + child_alloc.width = allocation->width - border*2; + child_alloc.height = length; + } + + if (!box_child->xfill) { + // we also need to center the widget + gint width = MIN (child_alloc.width, child_req.width); + child_alloc.x += MAX ((child_alloc.width - width) / 2, 0); + child_alloc.width = width; + } + if (!box_child->yfill) { + gint height = MIN (child_alloc.height, child_req.height); + child_alloc.y += MAX ((child_alloc.height - height) / 2, 0); + child_alloc.height = height; + } + + if (right_to_left) + child_alloc.x = allocation->width - child_alloc.x - child_alloc.width; + + gtk_widget_size_allocate (box_child->widget, &child_alloc); + child_pos += length + box->spacing + box_child->padding; + } +} + +void ygtk_ratio_box_set_child_packing (YGtkRatioBox *box, GtkWidget *child, + gfloat ratio, gboolean xfill, gboolean yfill, + guint padding) +{ + YGtkRatioBoxChild *child_info; + child_info = ygtk_ratio_get_child_info (box, child); + + if (child_info) { + gtk_widget_freeze_child_notify (child); + + child_info->ratio = ratio; + child_info->xfill = xfill; + child_info->yfill = yfill; + child_info->padding = padding; + child_info->expand = 0; + child_info->must_expand = 0; + + if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box)) + gtk_widget_queue_resize (child); + + gtk_widget_thaw_child_notify (child); + } +} + +void ygtk_ratio_box_get_child_packing (YGtkRatioBox *box, GtkWidget *child, + gfloat *ratio, gboolean *xfill, + gboolean *yfill, guint *padding, + gboolean *expand) +{ + YGtkRatioBoxChild *child_info; + child_info = ygtk_ratio_get_child_info (box, child); + + if (child_info) { + gtk_widget_freeze_child_notify (child); + + if (ratio) *ratio = child_info->ratio; + if (xfill) *xfill = child_info->xfill; + if (yfill) *yfill = child_info->yfill; + if (padding) *padding = child_info->padding; + if (expand) *expand = child_info->expand; + } +} + +void ygtk_ratio_box_set_child_expand (YGtkRatioBox *box, GtkWidget *child, + gboolean expand, gboolean must_expand) +{ + YGtkRatioBoxChild *child_info; + child_info = ygtk_ratio_get_child_info (box, child); + if (child_info) + { + child_info->expand = expand; + if (expand) + child_info->must_expand = must_expand; + } +} + +void ygtk_ratio_box_set_child_ratio (YGtkRatioBox *box, GtkWidget *child, + gfloat ratio) +{ + YGtkRatioBoxChild *child_info; + child_info = ygtk_ratio_get_child_info (box, child); + if (child_info) + child_info->ratio = ratio; +} + +void ygtk_ratio_box_set_spacing (YGtkRatioBox *box, gint spacing) +{ + box->spacing = spacing; +} + +static void ygtk_ratio_box_class_init (YGtkRatioBoxClass *klass) +{ + ygtk_ratio_box_parent_class = (GtkContainerClass*) g_type_class_peek_parent (klass); + + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + container_class->add = ygtk_ratio_box_add; + container_class->remove = ygtk_ratio_box_remove; + container_class->forall = ygtk_ratio_box_forall; + container_class->child_type = ygtk_ratio_box_child_type; +} + +//** RatioHBox + +G_DEFINE_TYPE (YGtkRatioHBox, ygtk_ratio_hbox, YGTK_TYPE_RATIO_BOX) + +static void ygtk_ratio_hbox_init (YGtkRatioHBox *box) +{ +} + +static void ygtk_ratio_hbox_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + ygtk_ratio_box_size_request (widget, requisition, GTK_ORIENTATION_HORIZONTAL); +} + +static void ygtk_ratio_hbox_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + ygtk_ratio_box_size_allocate (widget, allocation, GTK_ORIENTATION_HORIZONTAL); +} + +GtkWidget* ygtk_ratio_hbox_new (gint spacing) +{ + YGtkRatioBox* box = (YGtkRatioBox*) g_object_new (YGTK_TYPE_RATIO_HBOX, NULL); + box->spacing = spacing; + return GTK_WIDGET (box); +} + +static void ygtk_ratio_hbox_class_init (YGtkRatioHBoxClass *klass) +{ + ygtk_ratio_hbox_parent_class = (YGtkRatioBoxClass*) g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->size_request = ygtk_ratio_hbox_size_request; + widget_class->size_allocate = ygtk_ratio_hbox_size_allocate; +} + +//** RatioVBox + +G_DEFINE_TYPE (YGtkRatioVBox, ygtk_ratio_vbox, YGTK_TYPE_RATIO_BOX) + +static void ygtk_ratio_vbox_init (YGtkRatioVBox *box) +{ +} + +static void ygtk_ratio_vbox_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + ygtk_ratio_box_size_request (widget, requisition, GTK_ORIENTATION_VERTICAL); +} + +static void ygtk_ratio_vbox_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + ygtk_ratio_box_size_allocate (widget, allocation, GTK_ORIENTATION_VERTICAL); +} + +GtkWidget* ygtk_ratio_vbox_new (gint spacing) +{ + YGtkRatioBox* box = (YGtkRatioBox*) g_object_new (YGTK_TYPE_RATIO_VBOX, NULL); + box->spacing = spacing; + return GTK_WIDGET (box); +} + +static void ygtk_ratio_vbox_class_init (YGtkRatioVBoxClass *klass) +{ + ygtk_ratio_vbox_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->size_request = ygtk_ratio_vbox_size_request; + widget_class->size_allocate = ygtk_ratio_vbox_size_allocate; +} + +//** YGtkAdjSize + +G_DEFINE_TYPE (YGtkAdjSize, ygtk_adj_size, GTK_TYPE_BIN) + +static void ygtk_adj_size_init (YGtkAdjSize *adj_size) +{ + GTK_WIDGET_SET_FLAGS (adj_size, GTK_NO_WINDOW); + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (adj_size), FALSE); +} + +static void ygtk_adj_size_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkWidget *child = GTK_BIN (widget)->child; + requisition->width = requisition->height = 0; + if (child && GTK_WIDGET_VISIBLE (child)) { + gtk_widget_size_request (child, requisition); + guint border = GTK_CONTAINER (widget)->border_width; + requisition->width += border * 2; + requisition->height += border * 2; + + YGtkAdjSize *adj_size = YGTK_ADJ_SIZE (widget); + requisition->width = MAX (requisition->width, adj_size->min_width); + requisition->height = MAX (requisition->height, adj_size->min_height); + + if (adj_size->max_width) + requisition->width = MIN (requisition->width, adj_size->max_width); + if (adj_size->max_height) + requisition->height = MIN (requisition->height, adj_size->max_height); + + if (adj_size->only_expand) { + adj_size->min_width = requisition->width; + adj_size->min_height = requisition->height; + } + } +} + +static void ygtk_adj_size_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkWidget *child = GTK_BIN (widget)->child; + if (child && GTK_WIDGET_VISIBLE (child)) { + GtkAllocation child_alloc = *allocation; + guint border = GTK_CONTAINER (widget)->border_width; + child_alloc.x += border; + child_alloc.y += border; + child_alloc.width -= border * 2; + child_alloc.height -= border * 2; + gtk_widget_size_allocate (child, &child_alloc); + } + GTK_WIDGET_CLASS (ygtk_adj_size_parent_class)->size_allocate (widget, allocation); +} + +GtkWidget* ygtk_adj_size_new (void) +{ + return GTK_WIDGET (g_object_new (YGTK_TYPE_ADJ_SIZE, NULL)); +} + +void ygtk_adj_size_set_min (YGtkAdjSize *adj_size, guint min_width, guint min_height) +{ + adj_size->min_width = min_width; + adj_size->min_height = min_height; +} + +void ygtk_adj_size_set_max (YGtkAdjSize *adj_size, guint max_width, guint max_height) +{ + adj_size->max_width = max_width; + adj_size->max_height = max_height; +} + +void ygtk_adj_size_set_only_expand (YGtkAdjSize *adj_size, gboolean only_expand) +{ + adj_size->only_expand = only_expand; +} + +static void ygtk_adj_size_class_init (YGtkAdjSizeClass *klass) +{ + ygtk_adj_size_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->size_request = ygtk_adj_size_size_request; + widget_class->size_allocate = ygtk_adj_size_size_allocate; +} + +//** YGtkScrolledWindow + +G_DEFINE_TYPE (YGtkScrolledWindow, ygtk_scrolled_window, GTK_TYPE_SCROLLED_WINDOW) + +static void ygtk_scrolled_window_init (YGtkScrolledWindow *scroll) +{ +} + +static void ygtk_scrolled_window_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + YGtkScrolledWindow *scroll = YGTK_SCROLLED_WINDOW (widget); + + GtkRequisition child_req; + GtkWidget *child = GTK_BIN (widget)->child; + gtk_widget_size_request (child, &child_req); + + GtkScrolledWindow *gscroll = GTK_SCROLLED_WINDOW (widget); + GtkPolicyType hpolicy, vpolicy; + gtk_scrolled_window_get_policy (gscroll, &hpolicy, &vpolicy); + + if (scroll->max_width) { + if (child_req.width < scroll->max_width) + gscroll->hscrollbar_policy = GTK_POLICY_NEVER; + else + gscroll->hscrollbar_policy = GTK_POLICY_AUTOMATIC; + } + if (scroll->max_height) { + if (child_req.height < scroll->max_height) + gscroll->vscrollbar_policy = GTK_POLICY_NEVER; + else + gscroll->vscrollbar_policy = GTK_POLICY_AUTOMATIC; + } + + GTK_WIDGET_CLASS (ygtk_scrolled_window_parent_class)->size_request (widget, requisition); + // to avoid disruptions: + requisition->width = MIN (requisition->width, scroll->max_width); + requisition->height = MIN (requisition->height, scroll->max_height); +} + +GtkWidget* ygtk_scrolled_window_new (GtkWidget *child) +{ + YGtkScrolledWindow *scroll = g_object_new (YGTK_TYPE_SCROLLED_WINDOW, NULL); + if (child) + gtk_container_add (GTK_CONTAINER (scroll), child); + return GTK_WIDGET (scroll); +} + +void ygtk_scrolled_window_set_auto_policy (YGtkScrolledWindow *scroll, + guint max_width, guint max_height) +{ + scroll->max_width = max_width; + scroll->max_height = max_height; +} + +static void ygtk_scrolled_window_class_init (YGtkScrolledWindowClass *klass) +{ + ygtk_scrolled_window_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->size_request = ygtk_scrolled_window_size_request; +} Added: trunk/gtk/unstable/src/ygtkratiobox.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkratiobox.h?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkratiobox.h (added) +++ trunk/gtk/unstable/src/ygtkratiobox.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,239 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkRatioBox is an improvement over the GtkBox container that + allows the programmer to set stretch weights to containees. + + It is similar to GtkBox in usage but instead of feeding an + expand boolean, a weight is given instead. In fact, it should + behave just the same as a GtkBox if you give 0 for not expand + and 1 to. +*/ +/* + Quirks (cause of yast-core): + if one of the children has certain special properties, then only widgets with + the same properties will be expanded. These are, by order: + both stretch and rubber-band + both stretch and weight + weight + stretch + + We use different naming: + stretch = expand + rubber-band or layout-stretch = must expand + weight = ratio +*/ + +#ifndef YGTK_RATIO_BOX_H +#define YGTK_RATIO_BOX_H + +#include <gdk/gdk.h> +#include <gtk/gtkcontainer.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_RATIO_BOX (ygtk_ratio_box_get_type ()) +#define YGTK_RATIO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_RATIO_BOX, YGtkRatioBox)) +#define YGTK_RATIO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_RATIO_BOX, YGtkRatioBoxClass)) +#define YGTK_IS_RATIO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_RATIO_BOX)) +#define YGTK_IS_RATIO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_RATIO_BOX)) +#define YGTK_RATIO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_RATIO_BOX, YGtkRatioBoxClass)) + +typedef struct _YGtkRatioBox +{ + GtkContainer parent; + + // private (read-only): + GList *children; + gint16 spacing; + guint weight_length; // min-length for weight widgets + guint has_must_expand : 1; // cache +} YGtkRatioBox; + +typedef struct _YGtkRatioBoxClass +{ + GtkContainerClass parent_class; +} YGtkRatioBoxClass; + +typedef struct _YGtkRatioBoxChild +{ + GtkWidget *widget; + // members + guint16 padding; + gfloat ratio; + guint xfill : 1; + guint yfill : 1; + guint expand : 1; // twilight zone flag; use ratio + guint must_expand : 1; // higher order expand +} YGtkRatioBoxChild; + +GType ygtk_ratio_box_get_type (void) G_GNUC_CONST; + +void ygtk_ratio_box_set_spacing (YGtkRatioBox *box, gint spacing); + +void ygtk_ratio_box_pack (YGtkRatioBox *box, GtkWidget *child, gfloat ratio, + gboolean xfill, gboolean yfill, guint padding); + +// If you don't want to use ratios, you can use the ordinary expand flag. NOTE: +// If some other child has ratio > 0, this one won't expand. +// All this mess is so we can conform with yast-core. +void ygtk_ratio_box_set_child_expand (YGtkRatioBox *box, GtkWidget *child, + gboolean expand, gboolean must_expand); +void ygtk_ratio_box_set_child_ratio (YGtkRatioBox *box, GtkWidget *child, + gfloat ratio); + +void ygtk_ratio_box_set_child_packing (YGtkRatioBox *box, GtkWidget *child, + gfloat ratio, gboolean xfill, + gboolean yfill, guint padding); + +void ygtk_ratio_box_get_child_packing (YGtkRatioBox *box, GtkWidget *child, + gfloat *ratio, gboolean *xfill, + gboolean *yfill, guint *padding, + gboolean *expandable); + +/* RatioHBox */ + +#define YGTK_TYPE_RATIO_HBOX (ygtk_ratio_hbox_get_type ()) +#define YGTK_RATIO_HBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_RATIO_HBOX, YGtkRatioHBox)) +#define YGTK_RATIO_HBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_RATIO_HBOX, YGtkRatioHBoxClass)) +#define YGTK_IS_RATIO_HBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_RATIO_HBOX)) +#define YGTK_IS_RATIO_HBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_RATIO_HBOX)) +#define YGTK_RATIO_HBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_RATIO_HBOX, YGtkRatioHBoxClass)) + +typedef struct _YGtkRatioHBox +{ + YGtkRatioBox parent; +} YGtkRatioHBox; + +typedef struct _YGtkRatioHBoxClass +{ + YGtkRatioBoxClass parent_class; +} YGtkRatioHBoxClass; + +GtkWidget* ygtk_ratio_hbox_new (gint spacing); +GType ygtk_ratio_hbox_get_type (void) G_GNUC_CONST; + +/* RatioVBox */ + +#define YGTK_TYPE_RATIO_VBOX (ygtk_ratio_vbox_get_type ()) +#define YGTK_RATIO_VBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_RATIO_VBOX, YGtkRatioVBox)) +#define YGTK_RATIO_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_RATIO_VBOX, YGtkRatioVBoxClass)) +#define YGTK_IS_RATIO_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_RATIO_VBOX)) +#define YGTK_IS_RATIO_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_RATIO_VBOX)) +#define YGTK_RATIO_VBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_RATIO_VBOX, YGtkRatioVBoxClass)) + +typedef struct _YGtkRatioVBox +{ + YGtkRatioBox parent; +} YGtkRatioVBox; + +typedef struct _YGtkRatioVBoxClass +{ + YGtkRatioBoxClass parent_class; +} YGtkRatioVBoxClass; + +GtkWidget* ygtk_ratio_vbox_new (gint spacing); +GType ygtk_ratio_vbox_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /* YGTK_RATIO_BOX_H */ + +/* YGtkAdjSize container allows for better fine grained size constrains. */ +#ifndef YGTK_ADJ_SIZE_H +#define YGTK_ADJ_SIZE_H + +#include <gtk/gtkbin.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_ADJ_SIZE (ygtk_adj_size_get_type ()) +#define YGTK_ADJ_SIZE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_ADJ_SIZE, YGtkAdjSize)) +#define YGTK_ADJ_SIZE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_ADJ_SIZE, YGtkAdjSizeClass)) +#define YGTK_IS_ADJ_SIZE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_ADJ_SIZE)) +#define YGTK_IS_ADJ_SIZE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_ADJ_SIZE)) +#define YGTK_ADJ_SIZE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_ADJ_SIZE, YGtkAdjSizeClass)) + +typedef struct _YGtkAdjSize +{ + GtkBin parent; + // members + guint min_width, min_height, max_width, max_height; + gboolean only_expand; +} YGtkAdjSize; + +typedef struct _YGtkAdjSizeClass +{ + GtkBinClass parent_class; +} YGtkAdjSizeClass; + +GType ygtk_adj_size_get_type (void) G_GNUC_CONST; +GtkWidget* ygtk_adj_size_new (void); + +void ygtk_adj_size_set_min (YGtkAdjSize *adj_size, guint min_width, guint min_height); +void ygtk_adj_size_set_max (YGtkAdjSize *adj_size, guint max_width, guint max_height); + +/* Only allow the child to grow (ie. to ask for bigger sizes). */ +void ygtk_adj_size_set_only_expand (YGtkAdjSize *adj_size, gboolean only_expand); + +G_END_DECLS +#endif /*YGTK_ADJ_SIZE_H*/ + +/* YGtkScrolledWindow gives some a more fine-grained automatic scroll policy. + It allows the user to specify from which size scrolling should be applied. */ +#ifndef YGTK_SCROLLED_WIDOW_H +#define YGTK_SCROLLED_WIDOW_H + +#include <gtk/gtkscrolledwindow.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_SCROLLED_WINDOW (ygtk_scrolled_window_get_type ()) +#define YGTK_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindow)) +#define YGTK_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) +#define YGTK_IS_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW)) +#define YGTK_IS_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_SCROLLED_WINDOW)) +#define YGTK_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) + +typedef struct _YGtkScrolledWindow +{ + GtkScrolledWindow parent; + // members + guint max_width, max_height; +} YGtkScrolledWindow; + +typedef struct _YGtkScrolledWindowClass +{ + GtkScrolledWindowClass parent_class; +} YGtkScrolledWindowClass; + +GType ygtk_scrolled_window_get_type (void) G_GNUC_CONST; +GtkWidget* ygtk_scrolled_window_new (GtkWidget *child /*or NULL*/); + +void ygtk_scrolled_window_set_auto_policy (YGtkScrolledWindow *scroll, + guint max_width, guint max_height); + +G_END_DECLS +#endif /*YGTK_SCROLLED_WIDOW_H*/ Added: trunk/gtk/unstable/src/ygtkrichtext.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkrichtext.c?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkrichtext.c (added) +++ trunk/gtk/unstable/src/ygtkrichtext.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,716 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkRichText widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkrichtext.h" +#include <gtk/gtkversion.h> +#include <string.h> + +#define IDENT_MARGIN 20 +#define PARAGRAPH_SPACING 12 + +//#define PRINT_WARNINGS + +// Sucky - but we mix C & C++ so ... +/* Convert html to xhtml (or at least try) */ +gchar *ygutils_convert_to_xhmlt_and_subst (const char *instr, const char *product); + +G_DEFINE_TYPE (YGtkRichText, ygtk_rich_text, GTK_TYPE_TEXT_VIEW) + +static GdkCursor *hand_cursor, *regular_cursor; +static guint ref_cursor = 0; +static guint link_clicked_signal; +static GdkColor link_color = { 0, 0, 0, 0xeeee }; + +// utilities +// Looks at all tags covering the position of iter in the text view, +// and returns the link the text points to, in case that text is a link. +static const char* get_link (GtkTextView *text_view, gint x, gint y) +{ + GtkTextIter iter; + gtk_text_view_get_iter_at_location (text_view, &iter, x, y); + + char *link = NULL; + GSList *tags = gtk_text_iter_get_tags (&iter), *tagp; + for (tagp = tags; tagp != NULL; tagp = tagp->next) { + GtkTextTag *tag = (GtkTextTag*) tagp->data; + link = (char*) g_object_get_data (G_OBJECT (tag), "link"); + if (link) + break; + } + + if (tags) + g_slist_free (tags); + return link; +} + +// callbacks +// Links can also be activated by clicking. +static gboolean event_after (GtkWidget *text_view, GdkEvent *ev) +{ + GtkTextIter start, end; + GtkTextBuffer *buffer; + GdkEventButton *event; + gint x, y; + + if (ev->type != GDK_BUTTON_RELEASE) + return FALSE; + + event = (GdkEventButton *)ev; + if (event->button != 1) + return FALSE; + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); + + // We shouldn't follow a link if the user is selecting something. + gtk_text_buffer_get_selection_bounds (buffer, &start, &end); + if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) + return FALSE; + + gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), + GTK_TEXT_WINDOW_WIDGET, (gint) event->x, (gint) event->y, &x, &y); + + const char *link = get_link (GTK_TEXT_VIEW (text_view), x, y); + if (link) // report link + g_signal_emit (YGTK_RICH_TEXT (text_view), link_clicked_signal, 0, link); + return FALSE; +} + +#include <stdlib.h> +static int mystrcmp(void *a, void *b) +{ return g_ascii_strcasecmp (*(char **)a, *(char **)b); } + +static gboolean isBlockTag (const char *tag) +{ + static const char *Tags[] = + { "blockquote", "h1", "h2", "h3", "h4", "h5", "li", "p", "pre" }; + void *ret; + ret = bsearch (&tag, Tags, sizeof (Tags)/sizeof(char*), sizeof(char *), (void*)mystrcmp); + return ret != 0; +} +static gboolean isIdentTag (const char *tag) +{ + static const char *Tags[] = + { "blockquote", "ol", "ul" }; + void *ret; + ret = bsearch (&tag, Tags, sizeof (Tags)/sizeof(char*), sizeof(char *), (void*)mystrcmp); + return ret != 0; +} + +void ygtk_rich_text_init (YGtkRichText *rtext) +{ + rtext->prodname = NULL; + + GtkTextView *tview = GTK_TEXT_VIEW (rtext); + gtk_text_view_set_wrap_mode (tview, GTK_WRAP_WORD_CHAR); + gtk_text_view_set_editable (tview, FALSE); + gtk_text_view_set_cursor_visible (tview, FALSE); + gtk_text_view_set_pixels_below_lines (tview, 4); + + // Init link support + if (!ref_cursor) { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (rtext)); + hand_cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + regular_cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + } + ref_cursor++; + +#if GTK_CHECK_VERSION(2,10,0) + gtk_widget_style_get (GTK_WIDGET (rtext), "link_color", &link_color, NULL); +#endif + + g_signal_connect (tview, "event-after", + G_CALLBACK (event_after), NULL); + + // Create a few tags like 'h3', 'b', 'i'. others need to be created as we parse + GtkTextBuffer *buffer = gtk_text_view_get_buffer (tview); + PangoFontDescription *font_desc = GTK_WIDGET (rtext)->style->font_desc; + int size = pango_font_description_get_size (font_desc); + if (pango_font_description_get_size_is_absolute (font_desc)) + size /= PANGO_SCALE; + + gtk_text_buffer_create_tag (buffer, "h1", "weight", PANGO_WEIGHT_HEAVY, + "size", (int)(size * PANGO_SCALE_XX_LARGE), "pixels-below-lines", 16, NULL); + gtk_text_buffer_create_tag (buffer, "h2", "weight", PANGO_WEIGHT_ULTRABOLD, + "size", (int)(size * PANGO_SCALE_X_LARGE), "pixels-below-lines", 15, NULL); + gtk_text_buffer_create_tag (buffer, "h3", "weight", PANGO_WEIGHT_BOLD, + "size", (int)(size * PANGO_SCALE_LARGE), "pixels-below-lines", 14, NULL); + gtk_text_buffer_create_tag (buffer, "h4", "weight", PANGO_WEIGHT_SEMIBOLD, + "size", (int)(size * PANGO_SCALE_LARGE), "pixels-below-lines", 13, NULL); + gtk_text_buffer_create_tag (buffer, "h5", + "size", (int)(size * PANGO_SCALE_LARGE), NULL); + gtk_text_buffer_create_tag (buffer, "p", "pixels-below-lines", 12, NULL); + gtk_text_buffer_create_tag (buffer, "big", + "size", (int)(size * PANGO_SCALE_LARGE), NULL); + gtk_text_buffer_create_tag (buffer, "small", + "size", (int)(size * PANGO_SCALE_SMALL), NULL); + gtk_text_buffer_create_tag (buffer, "tt", "family", "monospace", NULL); + gtk_text_buffer_create_tag (buffer, "pre", "family", "monospace", NULL); + gtk_text_buffer_create_tag (buffer, "b", "weight", PANGO_WEIGHT_BOLD, NULL); + gtk_text_buffer_create_tag (buffer, "i", "style", PANGO_STYLE_ITALIC, NULL); + gtk_text_buffer_create_tag (buffer, "u", "underline", PANGO_UNDERLINE_SINGLE, NULL); + gtk_text_buffer_create_tag (buffer, "center", "justification", GTK_JUSTIFY_CENTER, + NULL); + // helpers + gtk_text_buffer_create_tag (buffer, "keyword", "background", "yellow", NULL); +} + +static void ygtk_rich_text_destroy (GtkObject *object) +{ + YGtkRichText *rtext = YGTK_RICH_TEXT (object); + + if (rtext->prodname) + // destroy can be called multiple times, and we must ref only once + if (ref_cursor > 0 && (--ref_cursor == 0)) { + gdk_cursor_unref (hand_cursor); + gdk_cursor_unref (regular_cursor); + } + + if (rtext->prodname) + g_free (rtext->prodname); + rtext->prodname = NULL; + + GTK_OBJECT_CLASS (ygtk_rich_text_parent_class)->destroy (object); +} + +// Change the cursor to the "hands" cursor typically used by web browsers, +// if there is a link in the given position. +static void set_cursor_if_appropriate (GtkTextView *text_view, gint x, gint y) + { + static gboolean hovering_over_link = FALSE; + gboolean hovering = get_link (text_view, x, y) != NULL; + + if (hovering != hovering_over_link) { + hovering_over_link = hovering; + + if (hovering_over_link) + gdk_window_set_cursor (gtk_text_view_get_window + (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor); + else + gdk_window_set_cursor (gtk_text_view_get_window + (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor); + } +} + +// Update the cursor image if the pointer moved. +static gboolean ygtk_rich_text_motion_notify_event (GtkWidget *text_view, + GdkEventMotion *event) +{ + gint x, y; + gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), + GTK_TEXT_WINDOW_WIDGET, + (gint) event->x, (gint) event->y, + &x, &y); + set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y); + + gdk_window_get_pointer (text_view->window, NULL, NULL, NULL); + return TRUE; +} + +// Also update the cursor image if the window becomes visible +// (e.g. when a window covering it got iconified). +static gboolean ygtk_rich_text_visibility_notify_event (GtkWidget *text_view, + GdkEventVisibility *event) +{ + gint wx, wy, bx, by; + + gdk_window_get_pointer (text_view->window, &wx, &wy, NULL); + gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), + GTK_TEXT_WINDOW_WIDGET, + wx, wy, &bx, &by); + set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by); + return TRUE; +} + +/* Rich Text parsing methods. */ + +typedef struct _HTMLList +{ + gboolean ordered; + char enumeration; +} HTMLList; + +static void HTMLList_init (HTMLList *list, gboolean ordered) +{ + list->ordered = ordered; + list->enumeration = 1; +} + +typedef struct GRTPTag { + GtkTextMark *mark; + GtkTextTag *tag; +} GRTPTag; +typedef struct GRTParseState { + GtkTextBuffer *buffer; + GtkTextTagTable *tags; + GList *htags; // of GRTPTag + + // Attributes for tags that affect their children + gboolean pre_mode; + gboolean default_color; + int left_margin; + GList *html_list; // of HTMLList +} GRTParseState; + +static void GRTParseState_init (GRTParseState *state, GtkTextBuffer *buffer) +{ + state->buffer = buffer; + state->pre_mode = FALSE; + state->default_color = TRUE; + state->left_margin = 0; + state->tags = gtk_text_buffer_get_tag_table (buffer); + state->html_list = NULL; + state->htags = NULL; +} + +static void free_list (GList *list) +{ + GList *i; + for (i = g_list_first (list); i; i = i->next) + g_free (i->data); + g_list_free (list); +} + +static void GRTParseState_free (GRTParseState *state) +{ + // NOTE: some elements might not have been freed because of bad html + free_list (state->html_list); + free_list (state->htags); +} + +static char *elide_whitespace (const char *instr, int len); + +// Tags to support: <p> and not </p>: +// either 'elide' \ns (turn off with <pre> I guess +static void +rt_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ // Called for open tags <foo bar="baz"> + if (!g_ascii_strcasecmp (element_name, "body")) + return; + + GRTParseState *state = (GRTParseState*) user_data; + GRTPTag *tag = g_malloc (sizeof (GRTPTag)); + GtkTextIter iter; + gtk_text_buffer_get_end_iter (state->buffer, &iter); + tag->mark = gtk_text_buffer_create_mark (state->buffer, NULL, &iter, TRUE); + + if (!g_ascii_strcasecmp (element_name, "pre")) + state->pre_mode = TRUE; + + // Check if this is a block tag + if (isBlockTag (element_name)) { + // make sure this opens a new paragraph + if (!gtk_text_iter_starts_line (&iter)) + { + gtk_text_buffer_insert (state->buffer, &iter, "\n", -1); + gtk_text_buffer_get_end_iter (state->buffer, &iter); + } + } + + char *lower = g_ascii_strdown (element_name, -1); + tag->tag = gtk_text_tag_table_lookup (state->tags, lower); + + // Special tags that must be inserted manually + if (!tag->tag) { + if (!g_ascii_strcasecmp (element_name, "font")) { + if (attribute_names[0] && + !g_ascii_strcasecmp (attribute_names[0], "color")) { + tag->tag = gtk_text_buffer_create_tag (state->buffer, NULL, + "foreground", attribute_values[0], + NULL); + state->default_color = FALSE; + } +#ifdef PRINT_WARNINGS + else + g_warning ("Unknown font attribute: '%s'", attribute_names[0]); +#endif + } + else if (!g_ascii_strcasecmp (element_name, "a")) { + if (attribute_names[0] && + !g_ascii_strcasecmp (attribute_names[0], "href")) { + tag->tag = gtk_text_buffer_create_tag (state->buffer, NULL, + "underline", PANGO_UNDERLINE_SINGLE, + NULL); + if (state->default_color) + g_object_set (tag->tag, "foreground-gdk", &link_color, NULL); + g_object_set_data (G_OBJECT (tag->tag), "link", g_strdup (attribute_values[0])); + } +#ifdef PRINT_WARNINGS + else + g_warning ("Unknown a attribute: '%s'", attribute_names[0]); +#endif + } + else if (!g_ascii_strcasecmp (element_name, "li")) { + HTMLList *front_list; + + if (state->html_list && + (front_list = g_list_first (state->html_list)->data) && + (front_list->ordered)) {; + gchar *str = g_strdup_printf ("%d. ", front_list->enumeration++); + gtk_text_buffer_insert (state->buffer, &iter, str, -1); + g_free (str); + } + else { // \\u25cf for bigger bullets + gtk_text_buffer_insert (state->buffer, &iter, "\u2022 ", -1); + } + } + // Tags that affect the margin + else if (!g_ascii_strcasecmp (element_name, "ul") || + !g_ascii_strcasecmp (element_name, "ol")) { + HTMLList *list = g_malloc (sizeof (HTMLList)); + HTMLList_init (list, !g_ascii_strcasecmp (element_name, "ol")); + state->html_list = g_list_append (state->html_list, list); + } + + else if (!g_ascii_strcasecmp (element_name, "img")) { + if (attribute_names[0] && + !g_ascii_strcasecmp (attribute_names[0], "src")) { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (attribute_values[0], NULL); + if (pixbuf) { + gtk_text_buffer_insert_pixbuf (state->buffer, &iter, pixbuf); + g_object_unref (G_OBJECT (pixbuf)); + } + } +#ifdef PRINT_WARNINGS + else + g_warning ("Unknown img attribute: '%s'", attribute_names[0]); +#endif + } + + // for tags like <br/>, GMarkup will pass them through the end + // tag callback too, so we'll deal with them there + else if (!g_ascii_strcasecmp (element_name, "br")) + ; + + else + { +#ifdef PRINT_WARNINGS + if (isBlockTag (element_name)) + ; + else + g_warning ("Unknown tag '%s'", element_name); +#endif + } + } + + if (!tag->tag && isIdentTag (element_name)) { + state->left_margin += IDENT_MARGIN; + tag->tag = gtk_text_buffer_create_tag (state->buffer, NULL, + "left-margin", state->left_margin, NULL); + } + + g_free (lower); + state->htags = g_list_append (state->htags, tag); +} + +static void +rt_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ // Called for close tags </foo> + if (!g_ascii_strcasecmp (element_name, "body")) + return; + + GRTParseState *state = (GRTParseState*) user_data; + + if (g_list_length (state->htags) == 0) { + g_warning ("Urgh - empty tag queue closing '%s'", element_name); + return; + } + + g_return_if_fail (state->htags != NULL); + GRTPTag *tag = g_list_last (state->htags)->data; + state->htags = g_list_remove (state->htags, tag); + + GtkTextIter start, end; + gtk_text_buffer_get_iter_at_mark (state->buffer, &start, tag->mark); + gtk_text_buffer_get_end_iter (state->buffer, &end); + + gint appendLines = 0; + + if (isIdentTag (element_name)) + state->left_margin -= IDENT_MARGIN; + + if (!g_ascii_strcasecmp (element_name, "ul") || + !g_ascii_strcasecmp (element_name, "ol")) { + HTMLList *last_list = g_list_last (state->html_list)->data; + state->html_list = g_list_remove (state->html_list, last_list); + g_free (last_list); + } + else if (!g_ascii_strcasecmp (element_name, "font")) + state->default_color = TRUE; + + else if (!g_ascii_strcasecmp (element_name, "pre")) { + state->pre_mode = FALSE; +/* + // \n must be inserted as <br> + char *txt = gtk_text_buffer_get_text (state->buffer, + &start, &end, TRUE); + char endc = txt ? txt[strlen(txt) - 1] : '\0'; + appendLines = (endc != '\r' && endc != '\n') ? 1 : 0; + g_free (txt);*/ + } + + else if (!g_ascii_strcasecmp (element_name, "br")) + appendLines = 1; + + if (isBlockTag (element_name)) + { +// appendLines = 2; +// if (!g_ascii_strcasecmp (element_name, "li")) + appendLines = 1; + } + + + if (appendLines) { + gtk_text_buffer_insert (state->buffer, &end, + appendLines == 1 ? "\n" : "\n\n", -1); + gtk_text_buffer_get_iter_at_mark (state->buffer, &start, tag->mark); + gtk_text_buffer_get_end_iter (state->buffer, &end); + } + + if (tag->tag) + gtk_text_buffer_apply_tag (state->buffer, tag->tag, &start, &end); + + gtk_text_buffer_delete_mark (state->buffer, tag->mark); + g_free (tag); +} + +static void +rt_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ // Called for character data, NB. text NOT nul-terminated + GRTParseState *state = (GRTParseState*) user_data; + GtkTextIter start, end; + gtk_text_buffer_get_end_iter (state->buffer, &start); + if (state->pre_mode) + gtk_text_buffer_insert_with_tags (state->buffer, &start, + text, text_len, NULL, NULL); + else { + char *real = elide_whitespace (text, text_len); + gtk_text_buffer_insert_with_tags (state->buffer, &start, + real, -1, NULL, NULL); + g_free (real); + } + gtk_text_buffer_get_end_iter (state->buffer, &end); +} + +static void +rt_passthrough (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error) +{ + // ignore comments etc. +} + +static void +rt_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ +} + +static GMarkupParser rt_parser = { + rt_start_element, + rt_end_element, + rt_text, + rt_passthrough, + rt_error +}; + +GtkWidget *ygtk_rich_text_new (void) +{ + return g_object_new (YGTK_TYPE_RICH_TEXT, NULL); +} + +/* String preparation methods. */ + +#define IS_WHITE(c) (g_ascii_isspace (c) || (c) == '\t') + +static char *elide_whitespace (const char *instr, int len) +{ + GString *dest = g_string_new (""); + if (len < 0) + len = strlen (instr); + gboolean last_white = FALSE; + int i; +// FIXME: whitespace elision needs to happen across tags [urk] +// FIXME: perhaps post-process non-pre sections when they are complete ? + for (i = 0; i < len; i++) + { + char ch = instr[i]; + if (ch == '\r' || ch == '\n') + continue; + if (ch == '\t') + ch = ' '; + gboolean cur_white = IS_WHITE (ch); + if (!cur_white || !last_white) + g_string_append_c (dest, ch); + last_white = cur_white; + } + + return g_string_free (dest, FALSE); +} + +void ygtk_richttext_set_prodname (YGtkRichText *rtext, const char *prodname) +{ + rtext->prodname = g_strdup (prodname); +} + +void ygtk_rich_text_set_text (YGtkRichText* rtext, const gchar* text, + gboolean rich_text) +{ + GtkTextBuffer *buffer; + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext)); + + if (!rich_text) { + gtk_text_buffer_set_text (buffer, text, -1); + return; + } + + // remove any possible existing text + gtk_text_buffer_set_text (buffer, "", 0); + + GRTParseState state; + GRTParseState_init (&state, buffer); + + GMarkupParseContext *ctx; + ctx = g_markup_parse_context_new (&rt_parser, (GMarkupParseFlags)0, &state, NULL); + + char *xml = ygutils_convert_to_xhmlt_and_subst (text, rtext->prodname); + GError *error = NULL; + if (!g_markup_parse_context_parse (ctx, xml, -1, &error)) { +#ifdef PRINT_WARNINGS + g_warning ("Markup parse error '%s'", error ? error->message : "Unknown"); +#endif + } + g_free (xml); + + g_markup_parse_context_free (ctx); + GRTParseState_free (&state); + + // remove last empty line, if any + GtkTextIter end_it, before_end_it; + gtk_text_buffer_get_end_iter (buffer, &end_it); + before_end_it = end_it; + if (gtk_text_iter_backward_char (&before_end_it) && + gtk_text_iter_get_char (&before_end_it) == '\n') + gtk_text_buffer_delete (buffer, &before_end_it, &end_it); +} + +/* gtk_text_iter_forward_search() is case-sensitive so we roll our own. + The idea is to keep use get_text and strstr there, but to be more + efficient we check per line. */ +static gboolean ygtk_rich_text_forward_search (const GtkTextIter *begin, + const GtkTextIter *end, const gchar *_key, GtkTextIter *match_start, + GtkTextIter *match_end) +{ + if (*_key == 0) + return FALSE; + + /* gtk_text_iter_get_char() returns a gunichar (ucs4 coding), so we + convert the given string (which is utf-8, like anyhting in gtk+) */ + gunichar *key = g_utf8_to_ucs4 (_key, -1, NULL, NULL, NULL); + if (!key) // conversion error -- should not happen + return FALSE; + + // convert key to lower case, to avoid work later + gunichar *k; + for (k = key; *k; k++) + *k = g_unichar_tolower (*k); + + GtkTextIter iter = *begin, iiter; + while (!gtk_text_iter_is_end (&iter) && gtk_text_iter_compare (&iter, end) <= 0) { + iiter = iter; + for (k = key; *k == g_unichar_tolower (gtk_text_iter_get_char (&iiter)) && (*k); + k++, gtk_text_iter_forward_char (&iiter)) + ; + if (!*k) { + *match_start = iter; + *match_end = iiter; + return TRUE; + } + gtk_text_iter_forward_char (&iter); + } + return FALSE; +} + +gboolean ygtk_rich_text_mark_text (YGtkRichText *rtext, const gchar *text) +{ + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext)); + GtkTextIter iter, end, match_start, match_end; + + gtk_text_buffer_get_bounds (buffer, &iter, &end); + gtk_text_buffer_remove_tag_by_name (buffer, "keyword", &iter, &end); + + gtk_text_buffer_select_range (buffer, &iter, &iter); // unselect text + if (!text || *text == '\0') + return TRUE; + + gboolean found = FALSE; + while (ygtk_rich_text_forward_search (&iter, &end, text, + &match_start, &match_end)) { + found = TRUE; + gtk_text_buffer_apply_tag_by_name (buffer, "keyword", &match_start, &match_end); + iter = match_end; + gtk_text_iter_forward_char (&iter); + } + return found; +} + +gboolean ygtk_rich_text_forward_mark (YGtkRichText *rtext, const gchar *text) +{ + GtkTextIter start_iter, end_iter; + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext)); + gtk_text_buffer_get_iter_at_mark (buffer, &start_iter, + gtk_text_buffer_get_selection_bound (buffer)); + gtk_text_buffer_get_end_iter (buffer, &end_iter); + + gboolean found; + found = ygtk_rich_text_forward_search (&start_iter, &end_iter, text, + &start_iter, &end_iter); + if (!found) { + gtk_text_buffer_get_start_iter (buffer, &start_iter); + found = ygtk_rich_text_forward_search (&start_iter, &end_iter, text, + &start_iter, &end_iter); + } + + if (found) { + gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (rtext), &start_iter, 0.10, + FALSE, 0, 0); + gtk_text_buffer_select_range (buffer, &start_iter, &end_iter); + return TRUE; + } + return FALSE; +} + +void ygtk_rich_text_class_init (YGtkRichTextClass *klass) +{ + GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->motion_notify_event = ygtk_rich_text_motion_notify_event; + gtkwidget_class->visibility_notify_event = ygtk_rich_text_visibility_notify_event; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_rich_text_destroy; + + link_clicked_signal = g_signal_new ("link-clicked", + G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (YGtkRichTextClass, link_clicked), NULL, NULL, + g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); +} + Added: trunk/gtk/unstable/src/ygtkrichtext.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkrichtext.h?r... ============================================================================== --- trunk/gtk/unstable/src/ygtkrichtext.h (added) +++ trunk/gtk/unstable/src/ygtkrichtext.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,59 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkRichText is a very simple widget that displays HTML code. + It was done, since GTK+ doesn't offer one out of box, and to + avoid dependencies. +*/ + +#ifndef YGTK_RICH_TEXT_H +#define YGTK_RICH_TEXT_H + +#include <gtk/gtktextview.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_RICH_TEXT (ygtk_rich_text_get_type ()) +#define YGTK_RICH_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_RICH_TEXT, YGtkRichText)) +#define YGTK_RICH_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_RICH_TEXT, YGtkRichTextClass)) +#define YGTK_IS_RICH_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_RICH_TEXT)) +#define YGTK_IS_RICH_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_RICH_TEXT)) +#define YGTK_RICH_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_RICH_TEXT, YGtkRichTextClass)) + +typedef struct _YGtkRichText +{ + GtkTextView parent; + // private: + char *prodname; +} YGtkRichText; + +typedef struct _YGtkRichTextClass +{ + GtkTextViewClass parent_class; + + // signals: + void (*link_clicked) (YGtkRichText *rich_text, const gchar *link); +} YGtkRichTextClass; + +GtkWidget* ygtk_rich_text_new (void); +GType ygtk_rich_text_get_type (void) G_GNUC_CONST; + +/* Sets some text to YGtkRichText, may be HTML or plain text, as indicated by + rich_text. */ +void ygtk_rich_text_set_text (YGtkRichText* rtext, const gchar* text, + gboolean rich_text); + +void ygtk_richttext_set_prodname (YGtkRichText *rtext, const char *prodname); + +// To be used together with an entry box to search for text +gboolean ygtk_rich_text_mark_text (YGtkRichText *rtext, const gchar *text); +gboolean ygtk_rich_text_forward_mark (YGtkRichText *rtext, const gchar *text); // F3 + +G_END_DECLS +#endif /* YGTK_RICH_TEXT_H */ + Added: trunk/gtk/unstable/src/ygtksteps.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtksteps.c?rev=... ============================================================================== --- trunk/gtk/unstable/src/ygtksteps.c (added) +++ trunk/gtk/unstable/src/ygtksteps.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,324 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkSteps widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtksteps.h" +#include <gtk/gtkhbox.h> +#include <gtk/gtkalignment.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkimage.h> +#include <string.h> + +#define BORDER 6 +#define STEPS_HEADER_SPACING 8 +#define STEPS_SPACING 2 +#define STEPS_IDENTATION 30 +#define CURRENT_MARK_ANIMATION_TIME 250 +#define CURRENT_MARK_ANIMATION_OFFSET 3 +#define CURRENT_MARK_FRAMES_NB (CURRENT_MARK_ANIMATION_OFFSET*2) + +G_DEFINE_TYPE (YGtkSteps, ygtk_steps, GTK_TYPE_WIDGET) + +static void ygtk_steps_init (YGtkSteps *steps) +{ + GTK_WIDGET_SET_FLAGS (steps, GTK_NO_WINDOW); + + PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET (steps)); + steps->check_mark_layout = pango_layout_new (context); + steps->current_mark_layout = pango_layout_new (context); + pango_layout_set_markup (steps->check_mark_layout, "\u2714", -1); + pango_layout_set_markup (steps->current_mark_layout, "<b>\u2192</b>", -1); + steps->current_mark_timeout_id = steps->current_mark_frame = 0; +} + +static void ygtk_steps_destroy (GtkObject *object) +{ + YGtkSteps *steps = YGTK_STEPS (object); + + if (steps->current_mark_timeout_id) { + g_source_remove (steps->current_mark_timeout_id); + steps->current_mark_timeout_id = 0; + } + + g_object_unref (steps->check_mark_layout); + steps->check_mark_layout = NULL; + + g_object_unref (steps->current_mark_layout); + steps->current_mark_layout = NULL; + + ygtk_steps_clear (steps); + GTK_OBJECT_CLASS (ygtk_steps_parent_class)->destroy (object); +} + + +static inline YGtkSingleStep *ygtk_steps_get_step (YGtkSteps *steps, guint step_nb) +{ + return g_list_nth_data (steps->steps, step_nb); +} + +static void ygtk_step_invalidate_layout (YGtkSingleStep *step) +{ + if (step->layout) { + g_object_unref (G_OBJECT (step->layout)); + step->layout = NULL; + } + if (step->layout_bold) { + g_object_unref (G_OBJECT (step->layout_bold)); + step->layout_bold = NULL; + } +} + +// should be called rather than accessing step->layout +static PangoLayout *ygtk_steps_get_step_layout (YGtkSteps *steps, guint step_nb) +{ + YGtkSingleStep *step = ygtk_steps_get_step (steps, step_nb); + + if (!step->layout) { + step->layout = gtk_widget_create_pango_layout (GTK_WIDGET (steps), NULL); + + gchar *text, *text_bold = 0; + if (step->is_heading) { + text = g_strdup_printf ("<span size=\"x-large\" weight=\"heavy\">%s</span>", + step->text); + pango_layout_set_spacing (step->layout, STEPS_HEADER_SPACING * PANGO_SCALE); + } + else { + if (!step->layout_bold) + step->layout_bold = gtk_widget_create_pango_layout (GTK_WIDGET (steps), NULL); + g_assert (step->layout_bold); + text = g_strdup (step->text); + text_bold = g_strdup_printf ("<b>%s</b>", step->text); + pango_layout_set_indent (step->layout, STEPS_IDENTATION * PANGO_SCALE); + pango_layout_set_indent (step->layout_bold, STEPS_IDENTATION * PANGO_SCALE); + pango_layout_set_spacing (step->layout, STEPS_SPACING * PANGO_SCALE); + pango_layout_set_spacing (step->layout_bold, STEPS_SPACING * PANGO_SCALE); + } + + pango_layout_set_markup (step->layout, text, -1); + g_free (text); + if (step->layout_bold) + { + pango_layout_set_markup (step->layout_bold, text_bold, -1); + g_free (text_bold); + } + } + + if (steps->current_step == step_nb) + return step->layout_bold; + return step->layout; +} + +// If PangoContext got invalidated (eg. system language change), re-compute it! +static void ygtk_steps_recompute_layout (YGtkSteps *steps) +{ + GList *it; + for (it = steps->steps; it; it = it->next) { + YGtkSingleStep *step = it->data; + if (step->layout) + pango_layout_context_changed (step->layout); + if (step->layout_bold) + pango_layout_context_changed (step->layout_bold); + } +} + +static void ygtk_steps_direction_changed (GtkWidget *widget, GtkTextDirection dir) +{ + ygtk_steps_recompute_layout (YGTK_STEPS (widget)); + GTK_WIDGET_CLASS (ygtk_steps_parent_class)->direction_changed (widget, dir); +} + +static void ygtk_steps_style_set (GtkWidget *widget, GtkStyle *style) +{ + ygtk_steps_recompute_layout (YGTK_STEPS (widget)); + GTK_WIDGET_CLASS (ygtk_steps_parent_class)->style_set (widget, style); +} + +static void ygtk_steps_size_request (GtkWidget *widget, GtkRequisition *requisition) +{ + requisition->width = requisition->height = 0; + + YGtkSteps *steps = YGTK_STEPS (widget); + int i; + for (i = 0; i < ygtk_steps_total (steps); i++) { + PangoLayout *layout = ygtk_steps_get_step_layout (steps, i); + YGtkSingleStep *step = ygtk_steps_get_step (steps, i); + if (!step->is_heading) + layout = step->layout_bold; + + int w, h; + pango_layout_get_pixel_size (layout, &w, &h); + w += PANGO_PIXELS (pango_layout_get_indent (layout)); + h += PANGO_PIXELS (pango_layout_get_spacing (layout)) * 2; + + requisition->width = MAX (w, requisition->width); + requisition->height += h; + } + + requisition->width += BORDER * 2; + requisition->height += BORDER * 2; +} + +static gboolean ygtk_steps_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + int x = widget->allocation.x + BORDER, y = widget->allocation.y + BORDER; + GtkStyle *style = gtk_widget_get_style (widget); + + YGtkSteps *steps = YGTK_STEPS (widget); + int i; + for (i = 0; i < ygtk_steps_total (steps); i++) { + PangoLayout *layout = ygtk_steps_get_step_layout (steps, i); + + // as opposite to identation, we need to apply spacing ourselves, since we aren't + // really using paragraphs + y += PANGO_PIXELS (pango_layout_get_spacing (layout)); + + gtk_paint_layout (style, widget->window, GTK_STATE_NORMAL, TRUE, + NULL, /*event->area,*/ widget, NULL, x, y, layout); + + if (i <= steps->current_step && !ygtk_steps_get_step (steps, i)->is_heading) { + PangoLayout *mark = (i == steps->current_step) ? steps->current_mark_layout + : steps->check_mark_layout; + int x_; + pango_layout_get_pixel_size (mark, &x_, NULL); + x_ = x + STEPS_IDENTATION - x_ - 6; + if (i == steps->current_step) { + if (steps->current_mark_frame < CURRENT_MARK_FRAMES_NB/2) + x_ -= steps->current_mark_frame * CURRENT_MARK_ANIMATION_OFFSET; + else + x_ -= (CURRENT_MARK_FRAMES_NB - steps->current_mark_frame) * + CURRENT_MARK_ANIMATION_OFFSET; + } + + gtk_paint_layout (style, widget->window, GTK_STATE_NORMAL, TRUE, + NULL, /*event->area,*/ widget, NULL, x_, y, mark); + } + + int h; + pango_layout_get_pixel_size (layout, NULL, &h); + // we need spacing for both sides + y += h + PANGO_PIXELS (pango_layout_get_spacing (layout)); + } + return FALSE; +} + +GtkWidget* ygtk_steps_new (void) +{ + return g_object_new (YGTK_TYPE_STEPS, NULL); +} + +guint ygtk_steps_append (YGtkSteps *steps, const gchar *step_text) +{ + gint steps_nb; + + g_return_val_if_fail (YGTK_IS_STEPS (steps), 0); + + steps_nb = ygtk_steps_total (steps); + + // check if the text is the same as the previous... + if (steps_nb) { + YGtkSingleStep *last_step = g_list_last (steps->steps)->data; + if (!g_strcasecmp (last_step->text, step_text)) { + last_step->strength++; + return steps_nb-1; + } + } + + // New step + YGtkSingleStep *step = g_new0 (YGtkSingleStep, 1); + step->is_heading = FALSE; + step->text = g_strdup (step_text); + step->strength = 1; + step->layout = step->layout_bold = NULL; + + steps->steps = g_list_append (steps->steps, step); + gtk_widget_queue_resize (GTK_WIDGET (steps)); + return steps_nb; +} + +void ygtk_steps_append_heading (YGtkSteps *steps, const gchar *heading) +{ + YGtkSingleStep *step; + + g_return_if_fail (YGTK_IS_STEPS (steps)); + + step = g_new0 (YGtkSingleStep, 1); + step->is_heading = TRUE; + step->text = g_strdup (heading); + step->strength = 1; // not important anyway + step->layout = step->layout_bold = NULL; + + steps->steps = g_list_append (steps->steps, step); + gtk_widget_queue_resize (GTK_WIDGET (steps)); +} + +void ygtk_steps_advance (YGtkSteps *steps) +{ + if (steps->current_step + 1 < ygtk_steps_total (steps)) + ygtk_steps_set_current (steps, steps->current_step + 1); +} + +static gboolean current_mark_animation_cb (void *steps_ptr) +{ + YGtkSteps *steps = steps_ptr; + + // ugly -- should use gtk_widget_queue_draw_area (widget, x, y, w, h) + // but we need to iterate through all steps to get current location and + // all, so... + gtk_widget_queue_draw (GTK_WIDGET (steps)); + + if (++steps->current_mark_frame == CURRENT_MARK_FRAMES_NB) { + steps->current_mark_frame = 0; + return FALSE; + } + return TRUE; +} + +void ygtk_steps_set_current (YGtkSteps *steps, guint step) +{ + guint old_step = steps->current_step; + steps->current_step = step; + + // update step icons + ygtk_step_invalidate_layout (ygtk_steps_get_step (steps, old_step)); + ygtk_step_invalidate_layout (ygtk_steps_get_step (steps, step)); + + steps->current_mark_frame = 0; + steps->current_mark_timeout_id = g_timeout_add + (CURRENT_MARK_ANIMATION_TIME / CURRENT_MARK_FRAMES_NB, + current_mark_animation_cb, steps); +} + +guint ygtk_steps_total (YGtkSteps *steps) +{ + return g_list_length (steps->steps); +} + +void ygtk_steps_clear (YGtkSteps *steps) +{ + GList *it; + for (it = steps->steps; it; it = it->next) { + YGtkSingleStep *step = it->data; + ygtk_step_invalidate_layout (step); + g_free (step->text); + g_free (step); + } + g_list_free (steps->steps); + steps->steps = NULL; +} + +static void ygtk_steps_class_init (YGtkStepsClass *klass) +{ + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->expose_event = ygtk_steps_expose_event; + widget_class->size_request = ygtk_steps_size_request; + widget_class->direction_changed = ygtk_steps_direction_changed; + widget_class->style_set = ygtk_steps_style_set; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_steps_destroy; +} + Added: trunk/gtk/unstable/src/ygtksteps.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtksteps.h?rev=... ============================================================================== --- trunk/gtk/unstable/src/ygtksteps.h (added) +++ trunk/gtk/unstable/src/ygtksteps.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,82 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkSteps is a widget that displays a list of steps, useful + to show the progress of some configuration tool as it does + the work of updating files or services or whatever. + + You use the append functions to initializate the steps. If, + for some reason, you want one step to count as more than one + (ie. so that a ygtk_steps_advance() needs to be called more than + once to actually advance for a given step), you may append a + step with the same name of the previous, that they'll be collapsed. + (Internally, we call that the 'strength' of the step.) + + TODO: the PangoLayout usage is getting a bit hacky. We may want to + replace it with Cairo methods. +*/ + +#ifndef YGTK_STEPS_H +#define YGTK_STEPS_H + +#include <gdk/gdk.h> +#include <gtk/gtkwidget.h> + +G_BEGIN_DECLS + +#define YGTK_TYPE_STEPS (ygtk_steps_get_type ()) +#define YGTK_STEPS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_STEPS, YGtkSteps)) +#define YGTK_STEPS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_STEPS, YGtkStepsClass)) +#define YGTK_IS_STEPS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_STEPS)) +#define YGTK_IS_STEPS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_STEPS)) +#define YGTK_STEPS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_STEPS, YGtkStepsClass)) + +typedef struct _YGtkSteps +{ + GtkWidget parent; + + // private: + GList *steps; // of YGtkSingleStep + guint current_step; + PangoLayout *check_mark_layout, *current_mark_layout; + // for current_mark little animation + guint current_mark_timeout_id, current_mark_frame; + +} YGtkSteps; + +typedef struct _YGtkStepsClass +{ + GtkWidgetClass parent_class; +} YGtkStepsClass; + +typedef struct _YGtkSingleStep +{ + gboolean is_heading; + gchar *text; + guint strength; // check the text at top + + // private -- don't access it, call ygtk_step_get_layout() instead + PangoLayout *layout, *layout_bold; // cache +} YGtkSingleStep; + +GtkWidget* ygtk_steps_new (void); +GType ygtk_steps_get_type (void) G_GNUC_CONST; + +guint ygtk_steps_append (YGtkSteps *steps, const gchar *label); +void ygtk_steps_append_heading (YGtkSteps *steps, const gchar *heading); + +void ygtk_steps_advance (YGtkSteps *steps); +void ygtk_steps_set_current (YGtkSteps *steps, guint step); +guint ygtk_steps_total (YGtkSteps *steps); + +void ygtk_steps_clear (YGtkSteps *steps); + +G_END_DECLS + +#endif /* YGTK_STEPS_H */ Added: trunk/gtk/unstable/src/ygtkwizard.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkwizard.c?rev... ============================================================================== --- trunk/gtk/unstable/src/ygtkwizard.c (added) +++ trunk/gtk/unstable/src/ygtkwizard.c Thu Nov 29 18:22:01 2007 @@ -0,0 +1,1270 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkWizard widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkwizard.h" +#include <atk/atk.h> +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> +#include <string.h> +#include "ygtkhtmlwrap.h" +#include "ygtksteps.h" +#include "ygtkfindentry.h" + +#define BUTTONS_SPACING 12 +#define BORDER 4 +#define CHILD_BORDER 6 + +// YGUtils bridge +extern void ygutils_setWidgetFont (GtkWidget *widget, PangoWeight weight, + double scale); +extern void ygutils_setStockIcon (GtkWidget *button, const char *ycp_str); + +//** YGtkHelpDialog + +G_DEFINE_TYPE (YGtkHelpDialog, ygtk_help_dialog, GTK_TYPE_WINDOW) + +// callbacks +static void ygtk_help_dialog_find_next (YGtkHelpDialog *dialog) +{ + const gchar *text = gtk_entry_get_text (GTK_ENTRY (dialog->search_entry)); + ygtk_html_wrap_search_next (dialog->help_text, text); +} + +static void search_entry_modified_cb (GtkEditable *editable, YGtkHelpDialog *dialog) +{ + gchar *key = gtk_editable_get_chars (editable, 0, -1); + if (!ygtk_html_wrap_search (dialog->help_text, key)) { + GdkColor red = { 0, 255 << 8, 102 << 8, 102 << 8 }, + white = { 0, 255 << 8, 255 << 8, 255 << 8 }; + gtk_widget_modify_base (dialog->search_entry, GTK_STATE_NORMAL, &red); + gtk_widget_modify_text (dialog->search_entry, GTK_STATE_NORMAL, &white); + gdk_beep(); + } + else { + gtk_widget_modify_base (dialog->search_entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text (dialog->search_entry, GTK_STATE_NORMAL, NULL); + } + g_free (key); +} +static void search_entry_activated_cb (GtkEntry *entry, YGtkHelpDialog *dialog) +{ ygtk_help_dialog_find_next (dialog); } +static void close_button_clicked_cb (GtkButton *button, YGtkHelpDialog *dialog) +{ gtk_widget_hide (GTK_WIDGET (dialog)); } + +static void ygtk_help_dialog_init (YGtkHelpDialog *dialog) +{ + gtk_container_set_border_width (GTK_CONTAINER (dialog), 6); + gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + + + gtk_window_set_title (GTK_WINDOW (dialog), "Help"); + gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 350); + + // title + GtkStockItem help_item; + gtk_stock_lookup (GTK_STOCK_HELP, &help_item); + + dialog->title_box = gtk_hbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (dialog->title_box), 6); + dialog->title_image = gtk_image_new_from_stock (GTK_STOCK_HELP, + GTK_ICON_SIZE_LARGE_TOOLBAR); + dialog->title_label = gtk_label_new ("Help"); + gtk_widget_modify_fg (dialog->title_label, GTK_STATE_NORMAL, + &dialog->title_label->style->fg [GTK_STATE_SELECTED]); + ygutils_setWidgetFont (dialog->title_label, PANGO_WEIGHT_ULTRABOLD, + PANGO_SCALE_LARGE); + gtk_box_pack_start (GTK_BOX (dialog->title_box), dialog->title_image, + FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (dialog->title_box), dialog->title_label, + FALSE, FALSE, 0); + + // help text + dialog->help_box = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dialog->help_box), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (dialog->help_box), + GTK_SHADOW_IN); + dialog->help_text = ygtk_html_wrap_new(); + gtk_container_add (GTK_CONTAINER (dialog->help_box), dialog->help_text); + + // bottom part (search entry + close button) + GtkWidget *bottom_box; + bottom_box = gtk_hbox_new (FALSE, 0); + dialog->search_entry = ygtk_find_entry_new(); + gtk_widget_set_size_request (dialog->search_entry, 140, -1); + dialog->close_button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); + GTK_WIDGET_SET_FLAGS (dialog->close_button, GTK_CAN_DEFAULT); + + gtk_box_pack_start (GTK_BOX (bottom_box), dialog->search_entry, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (bottom_box), dialog->close_button, FALSE, FALSE, 0); + + g_signal_connect (G_OBJECT (dialog->search_entry), "changed", + G_CALLBACK (search_entry_modified_cb), dialog); + g_signal_connect (G_OBJECT (dialog->search_entry), "activate", + G_CALLBACK (search_entry_activated_cb), dialog); + + // glue it + dialog->vbox = gtk_vbox_new (FALSE, 12); + gtk_box_pack_start (GTK_BOX (dialog->vbox), dialog->title_box, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), dialog->help_box, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), bottom_box, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox); + gtk_widget_show_all (dialog->vbox); + + g_signal_connect (G_OBJECT (dialog->close_button), "clicked", + G_CALLBACK (close_button_clicked_cb), dialog); + g_signal_connect (G_OBJECT (dialog), "delete-event", + G_CALLBACK (gtk_widget_hide_on_delete), NULL); +} + +static void ygtk_help_dialog_realize (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (ygtk_help_dialog_parent_class)->realize (widget); + YGtkHelpDialog *dialog = YGTK_HELP_DIALOG (widget); + + // set help text background + gtk_widget_realize (dialog->help_text); + ygtk_html_wrap_set_background (dialog->help_text, THEMEDIR "/wizard/help-background.png"); + + // set close as default widget + gtk_widget_grab_default (dialog->close_button); + gtk_widget_grab_focus (dialog->close_button); +} + +static gboolean ygtk_help_dialog_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + YGtkHelpDialog *dialog = YGTK_HELP_DIALOG (widget); + + // draw rect on title + int x, y, w, h; + x = dialog->title_box->allocation.x; + y = dialog->title_box->allocation.y; + w = dialog->title_box->allocation.width; + h = dialog->title_box->allocation.height; + if (x + w >= event->area.x && x <= event->area.x + event->area.width && + y + h >= event->area.y && x <= event->area.y + event->area.height) { + cairo_t *cr = gdk_cairo_create (widget->window); + gdk_cairo_set_source_color (cr, &widget->style->bg [GTK_STATE_SELECTED]); + cairo_rectangle (cr, x, y, w, h); + cairo_fill (cr); + + cairo_destroy (cr); + } + + gtk_container_propagate_expose (GTK_CONTAINER (dialog), dialog->vbox, event); + return FALSE; +} + +static void ygtk_help_dialog_close (YGtkHelpDialog *dialog) +{ gtk_widget_hide (GTK_WIDGET (dialog)); } + +GtkWidget *ygtk_help_dialog_new (GtkWindow *parent) +{ + GtkWidget *dialog = g_object_new (YGTK_TYPE_HELP_DIALOG, NULL); + if (parent) + gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); + return dialog; +} + +void ygtk_help_dialog_set_text (YGtkHelpDialog *dialog, const gchar *text) +{ + gtk_editable_delete_text (GTK_EDITABLE (dialog->search_entry), 0, -1); + ygtk_html_wrap_set_text (dialog->help_text, text); +} + +static void ygtk_help_dialog_class_init (YGtkHelpDialogClass *klass) +{ + klass->find_next = ygtk_help_dialog_find_next; + klass->close = ygtk_help_dialog_close; + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + widget_class->expose_event = ygtk_help_dialog_expose_event; + widget_class->realize = ygtk_help_dialog_realize; + + // key bindings (F3 for next word, Esc to close the window) + g_signal_new ("find_next", G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (YGtkHelpDialogClass, find_next), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + g_signal_new ("close", G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (YGtkHelpDialogClass, close), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + GtkBindingSet *binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, GDK_F3, 0, "find_next", 0); + gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0); +} + +//** YGtkWizard + +static gint get_header_padding (GtkWidget *widget) +{ +#if 0 +// TODO: read GtkAssistance style_rc attributes + gint padding; + gtk_widget_style_get (widget, "header-padding", &padding, NULL); + return padding; +#else + return 6; +#endif +} + +static gint get_content_padding (GtkWidget *widget) +{ +#if 0 + gint padding; + gtk_widget_style_get (widget, "content-padding", &padding, NULL); + return padding; +#else + return 1; +#endif +} + +// callbacks +static void destroy_tree_path (gpointer data) +{ + GtkTreePath *path = data; + gtk_tree_path_free (path); +} + +// signals +static guint action_triggered_signal; + +static void ygtk_marshal_VOID__POINTER_INT (GClosure *closure, + GValue *return_value, guint n_param_values, const GValue *param_values, + gpointer invocation_hint, gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_INT) (gpointer data1, gpointer arg_1, + gint arg_2, gpointer data2); + register GMarshalFunc_VOID__POINTER_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_INT) + (marshal_data ? marshal_data : cc->callback); + + callback (data1, g_value_get_pointer (param_values + 1), + g_value_get_int (param_values + 2), data2); +} + +static void button_clicked_cb (GtkButton *button, YGtkWizard *wizard) +{ + gpointer id = g_object_get_data (G_OBJECT (button), "id"); + g_signal_emit (wizard, action_triggered_signal, 0, id, G_TYPE_POINTER); +} + +static GtkWidget *button_new (YGtkWizard *wizard) +{ + GtkWidget *button = gtk_button_new_with_mnemonic (""); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (button_clicked_cb), wizard); + return button; +} + +static void ygtk_wizard_popup_help (YGtkWizard *wizard) +{ + if (!wizard->m_help_dialog) { + GtkWindow *window = (GtkWindow *) gtk_widget_get_ancestor ( + GTK_WIDGET (wizard), GTK_TYPE_WINDOW); + wizard->m_help_dialog = ygtk_help_dialog_new (window); + ygtk_help_dialog_set_text (YGTK_HELP_DIALOG (wizard->m_help_dialog), + wizard->m_help); + } + gtk_widget_show (wizard->m_help_dialog); +} + +static void help_button_clicked_cb (GtkWidget *button, YGtkWizard *wizard) +{ ygtk_wizard_popup_help (wizard); } + +G_DEFINE_TYPE (YGtkWizard, ygtk_wizard, GTK_TYPE_BIN) + +static void ygtk_wizard_init (YGtkWizard *wizard) +{ + wizard->menu_ids = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + wizard->tree_ids = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, destroy_tree_path); + wizard->steps_ids = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + + gtk_container_set_border_width (GTK_CONTAINER (wizard), BORDER); + + //** Title + wizard->m_title = gtk_hbox_new (FALSE, 0); + + wizard->m_title_image = gtk_image_new(); + wizard->m_title_label = gtk_label_new(""); + gtk_label_set_ellipsize (GTK_LABEL (wizard->m_title_label), PANGO_ELLIPSIZE_END); + gtk_misc_set_alignment (GTK_MISC (wizard->m_title_label), 0, 0); + + // setup label look + gtk_widget_modify_fg (wizard->m_title_label, GTK_STATE_NORMAL, + &wizard->m_title_label->style->fg [GTK_STATE_SELECTED]); + // set a strong font to the heading label + ygutils_setWidgetFont (wizard->m_title_label, PANGO_WEIGHT_ULTRABOLD, + PANGO_SCALE_XX_LARGE); + + gtk_box_pack_start (GTK_BOX (wizard->m_title), wizard->m_title_label, + TRUE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (wizard->m_title), wizard->m_title_image, + FALSE, FALSE, 0); + + gtk_widget_set_parent (wizard->m_title, GTK_WIDGET (wizard)); + gtk_widget_show_all (wizard->m_title); + + //** Adding the bottom buttons + wizard->m_next_button = button_new (wizard); + wizard->m_back_button = button_new (wizard); + wizard->m_abort_button = button_new (wizard); + wizard->m_release_notes_button = button_new (wizard); + + wizard->m_help_button = gtk_button_new_from_stock (GTK_STOCK_HELP); + GTK_WIDGET_SET_FLAGS (wizard->m_help_button, GTK_CAN_DEFAULT); + g_signal_connect (G_OBJECT (wizard->m_help_button), "clicked", + G_CALLBACK (help_button_clicked_cb), wizard); + + // we need to protect this button against insensitive in some cases + // this is a flag to enable that + ygtk_wizard_protect_next_button (wizard, FALSE); + + wizard->m_buttons = gtk_hbox_new (FALSE, 12); + + gtk_box_pack_start (GTK_BOX (wizard->m_buttons), wizard->m_help_button, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (wizard->m_buttons), wizard->m_release_notes_button, + FALSE, TRUE, 0); + + gtk_box_pack_end (GTK_BOX (wizard->m_buttons), wizard->m_next_button, FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (wizard->m_buttons), wizard->m_back_button, FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (wizard->m_buttons), wizard->m_abort_button, FALSE, TRUE, 0); + + gtk_widget_set_parent (wizard->m_buttons, GTK_WIDGET (wizard)); + gtk_widget_show (wizard->m_buttons); + + // make buttons all having the same size + GtkSizeGroup *buttons_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH); + gtk_size_group_add_widget (buttons_group, wizard->m_help_button); + gtk_size_group_add_widget (buttons_group, wizard->m_release_notes_button); + gtk_size_group_add_widget (buttons_group, wizard->m_next_button); + gtk_size_group_add_widget (buttons_group, wizard->m_back_button); + gtk_size_group_add_widget (buttons_group, wizard->m_abort_button); + g_object_unref (G_OBJECT (buttons_group)); + + //** The menu and the navigation widgets will be created when requested. + //** Help dialog will be build on realize so we can give it a parent window. +} + +static void ygtk_wizard_realize (GtkWidget *widget) +{ + YGtkWizard *wizard = YGTK_WIZARD (widget); + + GTK_WIDGET_CLASS (ygtk_wizard_parent_class)->realize (widget); + + gtk_widget_grab_default (wizard->m_next_button); + gtk_widget_grab_focus (wizard->m_next_button); +} + +static void destroy_hash (GHashTable **hash) +{ + if (*hash) + g_hash_table_destroy (*hash); + *hash = NULL; +} + +static void ygtk_wizard_destroy (GtkObject *object) +{ + YGtkWizard *wizard = YGTK_WIZARD (object); + + destroy_hash (&wizard->menu_ids); + destroy_hash (&wizard->tree_ids); + destroy_hash (&wizard->steps_ids); + + if (wizard->m_help) { + g_free (wizard->m_help); + wizard->m_help = NULL; + } + +/* We must unparent these widgets from the wizard as they would try + to use gtk_container_remove() on it. We ref them since we still + want to call destroy on them so they children die. */ +#define DESTROY_WIDGET(widget) \ + if (widget) { \ + g_object_ref (G_OBJECT (widget)); \ + gtk_widget_unparent (widget); \ + gtk_widget_destroy (widget); \ + widget = NULL; \ + } + DESTROY_WIDGET (wizard->m_title) + DESTROY_WIDGET (wizard->m_buttons) + DESTROY_WIDGET (wizard->m_menu) + DESTROY_WIDGET (wizard->m_steps) + DESTROY_WIDGET (wizard->m_title) + DESTROY_WIDGET (wizard->m_pane) +#undef DESTROY_WIDGET + + if (wizard->m_help_dialog) { + gtk_widget_destroy (wizard->m_help_dialog); + wizard->m_help_dialog = NULL; + } + + GTK_OBJECT_CLASS (ygtk_wizard_parent_class)->destroy (object); +} + +GtkWidget *ygtk_wizard_new (void) +{ + return g_object_new (YGTK_TYPE_WIZARD, NULL); +} + +static void selected_menu_item_cb (GtkMenuItem *item, const char *id) +{ + YGtkWizard *wizard = g_object_get_data (G_OBJECT (item), "wizard"); + g_signal_emit (wizard, action_triggered_signal, 0, id, G_TYPE_STRING); +} + +static void tree_item_selected_cb (GtkTreeView *tree_view, YGtkWizard *wizard) +{ + const gchar *id = ygtk_wizard_get_tree_selection (wizard); + if (id) + g_signal_emit (wizard, action_triggered_signal, 0, id, G_TYPE_STRING); +} + +void ygtk_wizard_enable_steps (YGtkWizard *wizard) +{ + g_return_if_fail (wizard->m_steps == NULL); + + wizard->m_steps = ygtk_steps_new(); + gtk_widget_modify_text (wizard->m_steps, GTK_STATE_NORMAL, + &wizard->m_steps->style->fg [GTK_STATE_SELECTED]); + + gtk_widget_set_parent (wizard->m_steps, GTK_WIDGET (wizard)); + gtk_widget_show (wizard->m_steps); + gtk_widget_queue_resize (GTK_WIDGET (wizard)); +} + +void ygtk_wizard_enable_tree (YGtkWizard *wizard) +{ + g_return_if_fail (wizard->m_tree == NULL); + + wizard->m_tree_view = gtk_tree_view_new_with_model + (GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING))); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (wizard->m_tree_view), + 0, "", gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (wizard->m_tree_view), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( + GTK_TREE_VIEW (wizard->m_tree_view)), GTK_SELECTION_BROWSE); + + g_signal_connect (G_OBJECT (wizard->m_tree_view), "cursor-changed", + G_CALLBACK (tree_item_selected_cb), wizard); + + wizard->m_tree = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wizard->m_tree), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (wizard->m_tree), + GTK_SHADOW_IN); + + gtk_container_add (GTK_CONTAINER (wizard->m_tree), wizard->m_tree_view); + gtk_widget_set_size_request (wizard->m_tree, 180, -1); + + GtkWidget *child = wizard->m_child, *pane; + pane = gtk_hpaned_new(); + gtk_paned_pack1 (GTK_PANED (pane), wizard->m_tree, TRUE, TRUE); + gtk_widget_show_all (pane); + ygtk_wizard_set_child (wizard, pane); + wizard->m_pane = pane; + if (child) + gtk_container_add (GTK_CONTAINER (wizard), child); +} + +static void ygtk_wizard_add_child (GtkContainer *container, GtkWidget *child) +{ + YGtkWizard *wizard = YGTK_WIZARD (container); + wizard->m_child = child; + if (wizard->m_pane) + gtk_paned_pack2 (GTK_PANED (wizard->m_pane), child, TRUE, FALSE); + else + GTK_CONTAINER_CLASS (ygtk_wizard_parent_class)->add (container, child); +} + +static void ygtk_wizard_remove_child (GtkContainer *container, GtkWidget *child) +{ + YGtkWizard *wizard = YGTK_WIZARD (container); + wizard->m_child = NULL; + if (wizard->m_pane) + gtk_container_remove (GTK_CONTAINER (wizard->m_pane), child); + else + GTK_CONTAINER_CLASS (ygtk_wizard_parent_class)->remove (container, child); +} + +void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *new_child) +{ + if (wizard->m_child) + gtk_container_remove (GTK_CONTAINER (wizard), wizard->m_child); + if (new_child) + gtk_container_add (GTK_CONTAINER (wizard), new_child); +} + +#define ENABLE_WIDGET(enable, widget) \ + (enable ? gtk_widget_show (widget) : gtk_widget_hide (widget)) +#define ENABLE_WIDGET_STR(str, widget) \ + (str && str[0] ? gtk_widget_show (widget) : gtk_widget_hide (widget)) + +/* Commands */ + +void ygtk_wizard_set_help_text (YGtkWizard *wizard, const gchar *text) +{ + if (wizard->m_help) + g_free (wizard->m_help); + wizard->m_help = g_strdup (text); + if (wizard->m_help_dialog) + ygtk_help_dialog_set_text (YGTK_HELP_DIALOG (wizard->m_help_dialog), text); + ENABLE_WIDGET_STR (text, wizard->m_help_button); +} + +gboolean ygtk_wizard_add_tree_item (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id) +{ + GtkTreeModel *model = gtk_tree_view_get_model + (GTK_TREE_VIEW (wizard->m_tree_view)); + GtkTreeIter iter; + + if (!parent_id || !*parent_id) + gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL); + else { + GtkTreePath *path = g_hash_table_lookup (wizard->tree_ids, parent_id); + if (path == NULL) + return FALSE; + GtkTreeIter parent_iter; + gtk_tree_model_get_iter (model, &parent_iter, path); + gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent_iter); + } + + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, text, -1); + g_hash_table_insert (wizard->tree_ids, g_strdup (id), + gtk_tree_model_get_path (model, &iter)); + return TRUE; +} + +/* this is g_hash_table_remove_all in new glib */ +static gboolean hash_table_clear_cb (gpointer key, gpointer value, gpointer data) +{ + return TRUE; +} +static void yg_hash_table_remove_all (GHashTable *hash_table) +{ + g_hash_table_foreach_remove (hash_table, hash_table_clear_cb, NULL); +} + +void ygtk_wizard_clear_tree (YGtkWizard *wizard) +{ + GtkTreeView *tree = GTK_TREE_VIEW (wizard->m_tree_view); + gtk_tree_store_clear (GTK_TREE_STORE (gtk_tree_view_get_model (tree))); + yg_hash_table_remove_all (wizard->tree_ids); +} + +gboolean ygtk_wizard_select_tree_item (YGtkWizard *wizard, const char *id) +{ + GtkTreePath *path = g_hash_table_lookup (wizard->tree_ids, id); + if (path == NULL) + return FALSE; + + g_signal_handlers_block_by_func (wizard->m_tree_view, + (gpointer) tree_item_selected_cb, wizard); + + GtkWidget *widget = wizard->m_tree_view; + gtk_tree_view_expand_to_path (GTK_TREE_VIEW (widget), path); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, + NULL, FALSE); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (widget), path, NULL, + TRUE, 0.5, 0.5); + + g_signal_handlers_unblock_by_func (wizard->m_tree_view, + (gpointer) tree_item_selected_cb, wizard); + return TRUE; +} + +void ygtk_wizard_set_header_text (YGtkWizard *wizard, GtkWindow *window, + const char *text) +{ + gtk_label_set_text (GTK_LABEL (wizard->m_title_label), text); + if (window) { + char *title = g_strdup_printf ("%s - YaST", text); + gtk_window_set_title (window, title); + g_free (title); + } +} + +gboolean ygtk_wizard_set_header_icon (YGtkWizard *wizard, GtkWindow *window, + const char *icon) +{ + GError *error = 0; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (icon, &error); + if (!pixbuf) + return FALSE; + + gtk_image_set_from_pixbuf (GTK_IMAGE (wizard->m_title_image), pixbuf); + if (window) + gtk_window_set_icon (window, pixbuf); + g_object_unref (G_OBJECT (pixbuf)); + return TRUE; +} + +void ygtk_wizard_set_abort_button_label (YGtkWizard *wizard, const char *text) +{ + gtk_button_set_label (GTK_BUTTON (wizard->m_abort_button), text); + ENABLE_WIDGET_STR (text, wizard->m_abort_button); + ygutils_setStockIcon (wizard->m_abort_button, text); +} + +void ygtk_wizard_set_back_button_label (YGtkWizard *wizard, const char *text) +{ + gtk_button_set_label (GTK_BUTTON (wizard->m_back_button), text); + ENABLE_WIDGET_STR (text, wizard->m_back_button); + ygutils_setStockIcon (wizard->m_back_button, text); +} + +void ygtk_wizard_set_next_button_label (YGtkWizard *wizard, const char *text) +{ + gtk_button_set_label (GTK_BUTTON (wizard->m_next_button), text); + ENABLE_WIDGET_STR (text, wizard->m_next_button); + ygutils_setStockIcon (wizard->m_next_button, text); +} + +void ygtk_wizard_set_back_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb) +{ + g_object_set_data_full (G_OBJECT (wizard->m_back_button), "id", id, destroy_cb); +} + +void ygtk_wizard_set_next_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb) +{ + g_object_set_data_full (G_OBJECT (wizard->m_next_button), "id", id, destroy_cb); +} + +void ygtk_wizard_set_abort_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb) +{ + g_object_set_data_full (G_OBJECT (wizard->m_abort_button), "id", id, destroy_cb); +} + +void ygtk_wizard_set_release_notes_button_label (YGtkWizard *wizard, + const gchar *text, gpointer id, + GDestroyNotify destroy_cb) +{ + gtk_button_set_label (GTK_BUTTON (wizard->m_release_notes_button), text); + g_object_set_data_full (G_OBJECT (wizard->m_release_notes_button), "id", + id, destroy_cb); + gtk_widget_show (wizard->m_release_notes_button); +} + +void ygtk_wizard_show_release_notes_button (YGtkWizard *wizard, gboolean enable) +{ + ENABLE_WIDGET (enable, wizard->m_release_notes_button); +} + +void ygtk_wizard_enable_back_button (YGtkWizard *wizard, gboolean enable) +{ + gtk_widget_set_sensitive (GTK_WIDGET (wizard->m_back_button), enable); +} + +void ygtk_wizard_enable_next_button (YGtkWizard *wizard, gboolean enable) +{ + if (enable || !ygtk_wizard_is_next_button_protected (wizard)) + gtk_widget_set_sensitive (GTK_WIDGET (wizard->m_next_button), enable); +} + +void ygtk_wizard_enable_abort_button (YGtkWizard *wizard, gboolean enable) +{ + gtk_widget_set_sensitive (GTK_WIDGET (wizard->m_abort_button), enable); +} + +gboolean ygtk_wizard_is_next_button_protected (YGtkWizard *wizard) +{ + return GPOINTER_TO_INT (g_object_get_data ( + G_OBJECT (wizard->m_next_button), "protect")); +} + +void ygtk_wizard_protect_next_button (YGtkWizard *wizard, gboolean protect) +{ + g_object_set_data (G_OBJECT (wizard->m_abort_button), "protect", + GINT_TO_POINTER (protect)); +} + +void ygtk_wizard_focus_next_button (YGtkWizard *wizard) +{ + gtk_widget_grab_focus (wizard->m_next_button); +} + +void ygtk_wizard_focus_back_button (YGtkWizard *wizard) +{ + gtk_widget_grab_focus (wizard->m_back_button); +} + +void ygtk_wizard_add_menu (YGtkWizard *wizard, const char *text, + const char *id) +{ + if (!wizard->m_menu) { + wizard->m_menu = gtk_menu_bar_new(); + gtk_widget_set_parent (wizard->m_menu, GTK_WIDGET (wizard)); + gtk_widget_queue_draw (GTK_WIDGET (wizard)); + } + + GtkWidget *entry = gtk_menu_item_new_with_mnemonic (text); + gtk_menu_shell_append (GTK_MENU_SHELL (wizard->m_menu), entry); + + GtkWidget *submenu = gtk_menu_new(); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry), submenu); + + g_hash_table_insert (wizard->menu_ids, g_strdup (id), submenu); + gtk_widget_show_all (wizard->m_menu); +} + +gboolean ygtk_wizard_add_menu_entry (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id) +{ + GtkWidget *parent = g_hash_table_lookup (wizard->menu_ids, parent_id); + if (!parent) + return FALSE; + + GtkWidget *entry = gtk_menu_item_new_with_mnemonic (text); + gtk_menu_shell_append (GTK_MENU_SHELL (parent), entry); + gtk_widget_show (entry); + + // we need to get YGtkWizard to send signal + g_object_set_data (G_OBJECT (entry), "wizard", wizard); + g_signal_connect_data (G_OBJECT (entry), "activate", + G_CALLBACK (selected_menu_item_cb), g_strdup (id), + (GClosureNotify) g_free, 0); + return TRUE; +} + +gboolean ygtk_wizard_add_sub_menu (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id) +{ + GtkWidget *parent = g_hash_table_lookup (wizard->menu_ids, parent_id); + if (!parent) + return FALSE; + + GtkWidget *entry = gtk_menu_item_new_with_mnemonic (text); + gtk_menu_shell_append (GTK_MENU_SHELL (parent), entry); + + GtkWidget *submenu = gtk_menu_new(); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry), submenu); + + g_hash_table_insert (wizard->menu_ids, g_strdup (id), submenu); + gtk_widget_show_all (entry); + return TRUE; +} + +gboolean ygtk_wizard_add_menu_separator (YGtkWizard *wizard, const char *parent_id) +{ + GtkWidget *parent = g_hash_table_lookup (wizard->menu_ids, parent_id); + if (!parent) + return FALSE; + + GtkWidget *separator = gtk_separator_menu_item_new(); + gtk_menu_shell_append (GTK_MENU_SHELL (parent), separator); + gtk_widget_show (separator); + return TRUE; +} + +void ygtk_wizard_add_step_header (YGtkWizard *wizard, const char *text) +{ + g_return_if_fail (wizard->m_steps != NULL); + ygtk_steps_append_heading (YGTK_STEPS (wizard->m_steps), text); +} + +void ygtk_wizard_add_step (YGtkWizard *wizard, const char* text, const char *id) +{ + guint step_nb; + g_return_if_fail (wizard->m_steps != NULL); + step_nb = ygtk_steps_append (YGTK_STEPS (wizard->m_steps), text); + g_hash_table_insert (wizard->steps_ids, g_strdup (id), GINT_TO_POINTER (step_nb)); +} + +gboolean ygtk_wizard_set_current_step (YGtkWizard *wizard, const char *id) +{ + gpointer step_nb = g_hash_table_lookup (wizard->steps_ids, id); + if (!step_nb) + return FALSE; + ygtk_steps_set_current (YGTK_STEPS (wizard->m_steps), GPOINTER_TO_INT (step_nb)); + return TRUE; +} + +void ygtk_wizard_clear_steps (YGtkWizard *wizard) +{ + ygtk_steps_clear (YGTK_STEPS (wizard->m_steps)); + yg_hash_table_remove_all (wizard->steps_ids); +} + +static const gchar *found_key; +static void hash_lookup_tree_path_value (gpointer _key, gpointer _value, + gpointer user_data) +{ + gchar *key = _key; + GtkTreePath *value = _value; + GtkTreePath *needle = user_data; + + if (gtk_tree_path_compare (value, needle) == 0) + found_key = key; +} + +const gchar *ygtk_wizard_get_tree_selection (YGtkWizard *wizard) +{ + GtkTreePath *path; + gtk_tree_view_get_cursor (GTK_TREE_VIEW (wizard->m_tree_view), + &path, NULL); + if (path == NULL) + return NULL; + + /* A more elegant solution would be using a crossed hash table, but there + is none out of box, so we'll just iterate the hash table. */ + found_key = 0; + g_hash_table_foreach (wizard->tree_ids, hash_lookup_tree_path_value, path); + + gtk_tree_path_free (path); + return found_key; +} + +void ygtk_wizard_set_sensitive (YGtkWizard *wizard, gboolean sensitive) +{ + // TODO: check if this chains through + gtk_widget_set_sensitive (GTK_WIDGET (wizard), sensitive); + + if (ygtk_wizard_is_next_button_protected (wizard)) + gtk_widget_set_sensitive (wizard->m_next_button, TRUE); +} + +static void ygtk_wizard_size_request (GtkWidget *widget, GtkRequisition *requisition) +{ + YGtkWizard *wizard = YGTK_WIZARD (widget); + + gint border = GTK_CONTAINER (wizard)->border_width; + gint header_padding = get_header_padding (GTK_WIDGET (wizard)); + gint content_padding = get_content_padding (GTK_WIDGET (wizard)); + GtkRequisition req; // temp usage + + requisition->width = 0; + requisition->height = border * 2; + + if (wizard->m_menu) { + gtk_widget_size_request (wizard->m_menu, &req); + requisition->width = MAX (requisition->width, req.width); + requisition->height += req.height; + } + + // title + gtk_widget_size_request (wizard->m_title, &req); + req.width += header_padding * 2 + border*2; + req.height += header_padding * 2; + + requisition->width = MAX (MIN (req.width, 40), requisition->width); + requisition->height += req.height; + + // body + { + GtkRequisition nav_req, child_req; + + if (wizard->m_steps) { + gtk_widget_size_request (wizard->m_steps, &nav_req); + nav_req.width += content_padding * 2; + nav_req.height += content_padding * 2; + } + else + nav_req.width = nav_req.height = 0; + + GtkWidget *child = GTK_BIN (wizard)->child; + if (child && GTK_WIDGET_VISIBLE (child)) + gtk_widget_size_request (child, &child_req); + else + child_req.width = child_req.height = 0; + child_req.width += content_padding * 2 + CHILD_BORDER*2; + child_req.height += content_padding * 2 + CHILD_BORDER*2; + + req.width = nav_req.width + child_req.width + border*2; + req.height = MAX (nav_req.height, child_req.height); + + requisition->width = MAX (requisition->width, req.width); + requisition->height += req.height; + } + + // buttons + gtk_widget_size_request (wizard->m_buttons, &req); + req.width += border*2; + req.height += BUTTONS_SPACING + border; + + requisition->width = MAX (requisition->width, req.width); + requisition->height += req.height; +} + +// helper -- applies padding to a GtkAllocation +static inline void apply_allocation_padding (GtkAllocation *alloc, gint padding) +{ + alloc->x += padding; + alloc->y += padding; + alloc->width -= padding * 2; + alloc->height -= padding * 2; +} + +static void ygtk_wizard_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + YGtkWizard *wizard = YGTK_WIZARD (widget); + + gint border = GTK_CONTAINER (wizard)->border_width; + gint header_padding = get_header_padding (widget); + gint content_padding = get_content_padding (widget); + GtkRequisition req; // temp usage + // we use "areas" because we need to do some tweaking when doing the actual + // allocation and this makes it easier to place the other widgets. + GtkAllocation menu_area, title_area, nav_area, child_area, buttons_area; + + // menu + menu_area.x = allocation->x; + menu_area.y = allocation->y; + if (wizard->m_menu) { + gtk_widget_get_child_requisition (wizard->m_menu, &req); + menu_area.width = allocation->width; + menu_area.height = req.height; + } + else + menu_area.width = menu_area.height = 0; + + // title + gtk_widget_get_child_requisition (wizard->m_title, &req); + title_area.x = allocation->x + border; + title_area.y = menu_area.y + menu_area.height + border; + title_area.width = allocation->width - border*2; + title_area.height = req.height + header_padding*2; + + // buttons + gtk_widget_get_child_requisition (wizard->m_buttons, &req); + buttons_area.x = title_area.x; + buttons_area.y = (allocation->y + allocation->height) - req.height - border; + buttons_area.width = title_area.width; + buttons_area.height = req.height; + + // child (aka content aka containee) + child_area.x = title_area.x; + child_area.y = title_area.y + title_area.height; + child_area.width = title_area.width; + child_area.height = allocation->height - menu_area.height - title_area.height - + buttons_area.height - border*2 - BUTTONS_SPACING; + + // navigation pane + nav_area.x = child_area.x; + nav_area.y = child_area.y; + nav_area.height = child_area.height; + if (wizard->m_steps) { + gtk_widget_get_child_requisition (wizard->m_steps, &req); + nav_area.width = req.width + content_padding*2; + + child_area.x += nav_area.width; + child_area.width -= nav_area.width; + /* // align to child + title_area.x += nav_area.width; + title_area.width -= nav_area.width;*/ + } + else + nav_area.width = 0; + + // Actual allocations + // menu + if (wizard->m_menu) + gtk_widget_size_allocate (wizard->m_menu, &menu_area); + + // title + apply_allocation_padding (&title_area, header_padding); + gtk_widget_size_allocate (wizard->m_title, &title_area); + + // child + GtkWidget *child = GTK_BIN (wizard)->child; + if (child && GTK_WIDGET_VISIBLE (child)) { + apply_allocation_padding (&child_area, content_padding + CHILD_BORDER); + gtk_widget_size_allocate (child, &child_area); + } + + // navigation pane + if (wizard->m_steps) { + apply_allocation_padding (&nav_area, content_padding); + gtk_widget_size_allocate (wizard->m_steps, &nav_area); + } + + // buttons + gtk_widget_size_allocate (wizard->m_buttons, &buttons_area); + + GTK_WIDGET_CLASS (ygtk_wizard_parent_class)->size_allocate (widget, allocation); +} + +static gboolean ygtk_wizard_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + if (!GTK_WIDGET_DRAWABLE (widget)) + return FALSE; + YGtkWizard *wizard = YGTK_WIZARD (widget); + + gint border = GTK_CONTAINER (wizard)->border_width; + gint header_padding = get_header_padding (widget); + gint content_padding = get_content_padding (widget); + + // paint a colored box + cairo_t *cr = gdk_cairo_create (widget->window); + int x, y, w, h; + + // (outer rectangle) + x = border; + y = border; + w = widget->allocation.width - border*2; + h = wizard->m_buttons->allocation.y - border - BUTTONS_SPACING; + if (wizard->m_menu) { + y += wizard->m_menu->allocation.height; + h -= wizard->m_menu->allocation.height; + } + + gdk_cairo_set_source_color (cr, &widget->style->bg [GTK_STATE_SELECTED]); + cairo_rectangle (cr, x, y, w, h); + cairo_fill (cr); + + // (inner rectangle) + x += content_padding; + w -= content_padding*2; + y += wizard->m_title->allocation.height + header_padding*2 + content_padding; + h -= wizard->m_title->allocation.height + header_padding*2 + content_padding*2; + if (wizard->m_steps) { + int steps_w = wizard->m_steps->allocation.width; + x += steps_w + content_padding; + w -= steps_w + content_padding; + } + + gdk_cairo_set_source_color (cr, &widget->style->bg [GTK_STATE_NORMAL]); + cairo_rectangle (cr, x, y, w, h); + cairo_fill (cr); + + cairo_destroy (cr); + + // propagate expose + GtkContainer *container = GTK_CONTAINER (wizard); + if (wizard->m_menu) + gtk_container_propagate_expose (container, wizard->m_menu, event); + gtk_container_propagate_expose (container, wizard->m_title, event); + if (wizard->m_steps) + gtk_container_propagate_expose (container, wizard->m_steps, event); + gtk_container_propagate_expose (container, wizard->m_buttons, event); + if (GTK_BIN (container)->child) + gtk_container_propagate_expose (container, GTK_BIN (container)->child, event); + return TRUE; +} + +static void ygtk_wizard_forall (GtkContainer *container, gboolean include_internals, + GtkCallback callback, gpointer callback_data) +{ + YGtkWizard *wizard = YGTK_WIZARD (container); + if (include_internals) { + (*callback) (wizard->m_title, callback_data); + (*callback) (wizard->m_buttons, callback_data); + if (wizard->m_menu) + (*callback) (wizard->m_menu, callback_data); + if (wizard->m_steps) + (*callback) (wizard->m_steps, callback_data); + } + + GtkWidget *containee = GTK_BIN (container)->child; + if (containee) + (*callback) (containee, callback_data); +} + +/* Accessibility support */ + +static gint ygtk_wizard_accessible_get_n_children (AtkObject *accessible) +{ + return 1 /* content*/ + 5 /* buttons*/; +} + +static AtkObject *ygtk_wizard_accessible_ref_child (AtkObject *accessible, + gint index) +{ + GtkWidget *widget = GTK_ACCESSIBLE (accessible)->widget; + if (!widget) + return NULL; + YGtkWizard *wizard = YGTK_WIZARD (widget); + + if (index == 0) { + GtkWidget *child = GTK_BIN (wizard)->child; + if (child) + return g_object_ref (G_OBJECT (child)); + return NULL; + } + + if (index >= 1 && index <= 5) { + GtkWidget *buttons[5] = { wizard->m_back_button, wizard->m_abort_button, + wizard->m_next_button, wizard->m_help_button, + wizard->m_release_notes_button }; + GtkWidget *button = buttons [index-1]; + + if (GTK_WIDGET_VISIBLE (button)) + return g_object_ref (G_OBJECT (button)); + return NULL; + } + // out of range + return NULL; +} + +static void ygtk_wizard_accessible_class_init (AtkObjectClass *class) +{ + class->get_n_children = ygtk_wizard_accessible_get_n_children; + class->ref_child = ygtk_wizard_accessible_ref_child; +} + +static GType ygtk_wizard_accessible_get_type (void) +{ + static GType type = 0; + if (!type) { + AtkObjectFactory *factory; + GType derived_type; + GTypeQuery query; + GType derived_atk_type; + + derived_type = g_type_parent (YGTK_TYPE_WIZARD); + factory = atk_registry_get_factory (atk_get_default_registry (), derived_type); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + g_type_query (derived_atk_type, &query); + + GTypeInfo type_info = { 0 }; + type_info.class_size = query.class_size; + type_info.class_init = (GClassInitFunc) ygtk_wizard_accessible_class_init; + type_info.instance_size = query.instance_size; + + type = g_type_register_static (derived_atk_type, "YGtkWizardAccessible", + &type_info, 0); + +/* + type = g_type_register_static_simple (derived_atk_type, + "YGtkWizardAccessible", query.class_size, + (GClassInitFunc) ygtk_wizard_accessible_class_init, + query.instance_size, NULL, 0); +*/ + } + return type; +} + +static AtkObject *ygtk_wizard_accessible_new (GObject *obj) +{ + AtkObject *accessible; + g_return_val_if_fail (YGTK_IS_WIZARD (obj), NULL); + + accessible = g_object_new (ygtk_wizard_accessible_get_type (), NULL); + atk_object_initialize (accessible, obj); + return accessible; +} + +static GType ygtk_wizard_accessible_factory_get_accessible_type() +{ + return ygtk_wizard_accessible_get_type (); +} + +static AtkObject*ygtk_wizard_accessible_factory_create_accessible (GObject *obj) +{ + return ygtk_wizard_accessible_new (obj); +} + +static void ygtk_wizard_accessible_factory_class_init (AtkObjectFactoryClass *class) +{ + class->create_accessible = ygtk_wizard_accessible_factory_create_accessible; + class->get_accessible_type = ygtk_wizard_accessible_factory_get_accessible_type; +} + +static GType ygtk_wizard_accessible_factory_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo type_info = { 0 }; + type_info.class_size = sizeof (AtkObjectFactoryClass); + type_info.class_init = (GClassInitFunc) ygtk_wizard_accessible_factory_class_init; + type_info.instance_size = sizeof (AtkObjectFactory); + + type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, + "YGtkWizardAccessibleFactory", &type_info, 0); + +/* + type = g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY, + "YGtkWizardAccessibleFactory", sizeof (AtkObjectFactoryClass), + (GClassInitFunc) ygtk_wizard_accessible_factory_class_init, + sizeof (AtkObjectFactory), NULL, 0); +*/ + } + return type; +} + +static AtkObject *ygtk_wizard_get_accessible (GtkWidget *widget) +{ + static gboolean first_time = TRUE; + if (first_time) { + AtkObjectFactory *factory; + AtkRegistry *registry; + GType derived_type; + GType derived_atk_type; + + derived_type = g_type_parent (YGTK_TYPE_WIZARD); + registry = atk_get_default_registry (); + factory = atk_registry_get_factory (registry, derived_type); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE)) { + atk_registry_set_factory_type (registry, YGTK_TYPE_WIZARD, + ygtk_wizard_accessible_factory_get_type ()); + } + first_time = FALSE; + } + return GTK_WIDGET_CLASS (ygtk_wizard_parent_class)->get_accessible (widget); +} + +static void ygtk_wizard_class_init (YGtkWizardClass *klass) +{ + ygtk_wizard_parent_class = g_type_class_peek_parent (klass); + + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); + //** Get expose, so we can draw line border + widget_class->expose_event = ygtk_wizard_expose_event; + widget_class->realize = ygtk_wizard_realize; + widget_class->size_request = ygtk_wizard_size_request; + widget_class->size_allocate = ygtk_wizard_size_allocate; + widget_class->get_accessible = ygtk_wizard_get_accessible; + + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + container_class->forall = ygtk_wizard_forall; + container_class->add = ygtk_wizard_add_child; + container_class->remove = ygtk_wizard_remove_child; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_wizard_destroy; + + action_triggered_signal = g_signal_new ("action-triggered", + G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (YGtkWizardClass, action_triggered), + NULL, NULL, ygtk_marshal_VOID__POINTER_INT, G_TYPE_NONE, + 2, G_TYPE_POINTER, G_TYPE_INT); + + // on F1, popup the help box + klass->popup_help = ygtk_wizard_popup_help; + g_signal_new ("popup_help", G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (YGtkWizardClass, popup_help), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + GtkBindingSet *binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, GDK_F1, 0, "popup_help", 0); +} + Added: trunk/gtk/unstable/src/ygtkwizard.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkwizard.h?rev... ============================================================================== --- trunk/gtk/unstable/src/ygtkwizard.h (added) +++ trunk/gtk/unstable/src/ygtkwizard.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,175 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkWizard is a widget based on GtkAssistant, which we couldn't + use (for starters, GtkAssistant comes from GtkWindow and we need + a widget, not a window). +*/ + +#ifndef YGTK_WIZARD_H +#define YGTK_WIZARD_H + +#include <gdk/gdk.h> +#include <gtk/gtkbin.h> +#include <gtk/gtkwindow.h> +G_BEGIN_DECLS + +// YGtkHelpDialog (for showing help text) +/* Shows help text. It is GtkWindow-inherited, rather than GtkDialog, because + we want to place a search entry next to the buttons. */ + +#define YGTK_TYPE_HELP_DIALOG (ygtk_help_dialog_get_type ()) +#define YGTK_HELP_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_HELP_DIALOG, YGtkHelpDialog)) +#define YGTK_HELP_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_HELP_DIALOG, YGtkHelpDialogClass)) +#define YGTK_IS_HELP_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_HELP_DIALOG)) +#define YGTK_IS_HELP_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_HELP_DIALOG)) +#define YGTK_HELP_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_HELP_DIALOG, YGtkHelpDialogClass)) + +typedef struct _YGtkHelpDialog +{ + GtkWindow parent; + + // parent: + GtkWidget *title_box, *title_label, *title_image; + GtkWidget *help_box, *help_text; + GtkWidget *search_entry, *close_button; + GtkWidget *vbox; +} YGtkHelpDialog; + +typedef struct _YGtkHelpDialogClass +{ + GtkWindowClass parent_class; + + // signals + void (*find_next) (YGtkHelpDialog *dialog); + void (*close) (YGtkHelpDialog *dialog); +} YGtkHelpDialogClass; + +GtkWidget *ygtk_help_dialog_new (GtkWindow *parent); +GType ygtk_help_dialog_get_type (void) G_GNUC_CONST; + +void ygtk_help_dialog_set_text (YGtkHelpDialog *dialog, const char *text); + +// YGtkWizard + +#define YGTK_TYPE_WIZARD (ygtk_wizard_get_type ()) +#define YGTK_WIZARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_WIZARD, YGtkWizard)) +#define YGTK_WIZARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_WIZARD, YGtkWizardClass)) +#define YGTK_IS_WIZARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_WIZARD)) +#define YGTK_IS_WIZARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_WIZARD)) +#define YGTK_WIZARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_WIZARD, YGtkWizardClass)) + +typedef struct _YGtkWizard +{ + GtkBin bin; + + // private: + /* Hash tables to assign Yast Ids to Gtk entries. */ + GHashTable *menu_ids; /* gchar* -> GtkWidget* */ + GHashTable *tree_ids; /* gchar* -> GtkTreePath* */ + GHashTable *steps_ids; /* gchar* -> guint */ + + /* Widgets for layout. */ + GtkWidget *m_menu, *m_title, *m_steps, *m_tree, *m_buttons; + GtkWidget *m_child, *m_pane; + // containee can be accessed via GTK_BIN (wizard)->child + + /* Widgets we need to have access to. */ + GtkWidget *m_title_label, *m_title_image, *m_tree_view, + *m_back_button, *m_abort_button, *m_next_button, *m_help_button, + *m_release_notes_button; + + /* The help text. */ + gchar *m_help; + GtkWidget *m_help_dialog; +} YGtkWizard; + +typedef struct _YGtkWizardClass +{ + GtkBinClass parent_class; + + // signals: + void (*action_triggered) (YGtkWizard *wizard, gpointer id, gint id_type); + void (*popup_help) (YGtkWizard *dialog); +} YGtkWizardClass; + +GtkWidget *ygtk_wizard_new (void); +GType ygtk_wizard_get_type (void) G_GNUC_CONST; + +// Enable a steps or tree pane widget -- should be called right after +// initilization and only _one_ of them +void ygtk_wizard_enable_steps (YGtkWizard *wizard); +void ygtk_wizard_enable_tree (YGtkWizard *wizard); + +// convinience method that removes the current child, if set, and swaps it by +// the given one (you may pass NULL to just remove current child) +void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *widget); + +// commands +// (commands that may fail return a sucess boolean.) +void ygtk_wizard_set_help_text (YGtkWizard *wizard, const gchar *text); + +// you may pass a window widget if you want the title/icon to be set on it as well +void ygtk_wizard_set_header_text (YGtkWizard *wizard, GtkWindow *window, + const char *text); +gboolean ygtk_wizard_set_header_icon (YGtkWizard *wizard, GtkWindow *window, + const char *icon); + +void ygtk_wizard_set_back_button_label (YGtkWizard *wizard, const char *text); +void ygtk_wizard_set_abort_button_label (YGtkWizard *wizard, const char *text); +void ygtk_wizard_set_next_button_label (YGtkWizard *wizard, const char *text); +void ygtk_wizard_set_back_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb); +void ygtk_wizard_set_next_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb); +void ygtk_wizard_set_abort_button_id (YGtkWizard *wizard, gpointer id, + GDestroyNotify destroy_cb); +void ygtk_wizard_enable_back_button (YGtkWizard *wizard, gboolean enable); +void ygtk_wizard_enable_next_button (YGtkWizard *wizard, gboolean enable); +void ygtk_wizard_enable_abort_button (YGtkWizard *wizard, gboolean enable); +gboolean ygtk_wizard_is_next_button_protected (YGtkWizard *wizard); +void ygtk_wizard_protect_next_button (YGtkWizard *wizard, gboolean protect); +void ygtk_wizard_focus_next_button (YGtkWizard *wizard); +void ygtk_wizard_focus_back_button (YGtkWizard *wizard); + +void ygtk_wizard_add_menu (YGtkWizard *wizard, const char *text, + const char *id); +gboolean ygtk_wizard_add_menu_entry (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id); +gboolean ygtk_wizard_add_sub_menu (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id); +gboolean ygtk_wizard_add_menu_separator (YGtkWizard *wizard, const char *parent_id); + +void ygtk_wizard_add_step_header (YGtkWizard *wizard, const char *text); +void ygtk_wizard_add_step (YGtkWizard *wizard, const char* text, const char *id); +gboolean ygtk_wizard_set_current_step (YGtkWizard *wizard, const char *id); +void ygtk_wizard_clear_steps (YGtkWizard *wizard); + +gboolean ygtk_wizard_add_tree_item (YGtkWizard *wizard, const char *parent_id, + const char *text, const char *id); +void ygtk_wizard_clear_tree (YGtkWizard *wizard); +gboolean ygtk_wizard_select_tree_item (YGtkWizard *wizard, const char *id); +const gchar *ygtk_wizard_get_tree_selection (YGtkWizard *wizard); + +void ygtk_wizard_set_release_notes_button_label (YGtkWizard *wizard, + const gchar *text, gpointer id, + GDestroyNotify destroy_cb); +void ygtk_wizard_show_release_notes_button (YGtkWizard *wizard, gboolean enable); + +// You should call this method rather than GtkWidget's if you want +// to honor next_button protect flag +void ygtk_wizard_set_sensitive (YGtkWizard *wizard, gboolean sensitive); + +G_END_DECLS +#endif /* YGTK_WIZARD_H */ Added: trunk/gtk/unstable/src/ygtkzyppwrapper.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkzyppwrapper.... ============================================================================== --- trunk/gtk/unstable/src/ygtkzyppwrapper.cc (added) +++ trunk/gtk/unstable/src/ygtkzyppwrapper.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,333 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkZyppWrapper, gtk+ hooks for zypp wrapper */ +// check the header file for information about these hooks + +#include <config.h> +#include "ygtkzyppwrapper.h" +#include "YGUtils.h" + +#include "icons/pkg-installed.xpm" +#include "icons/pkg-installed-upgradable.xpm" +#include "icons/pkg-installed-upgradable-locked.xpm" +#include "icons/pkg-installed-locked.xpm" +#include "icons/pkg-available.xpm" +#include "icons/pkg-available-locked.xpm" +#include "icons/pkg-install.xpm" +#include "icons/pkg-remove.xpm" +#include "icons/pkg-install-auto.xpm" +#include "icons/pkg-remove-auto.xpm" +#include "icons/pkg-3D.xpm" + +// bridge as we don't want to mix c++ class polymorphism and gobject +struct YGtkZyppModel::PoolNotify : public Ypp::Pool::Listener { +YGtkZyppModel *model; + virtual void entryChanged (Ypp::Pool::Iter iter, Ypp::Package *package) + { ygtk_zypp_model_entry_changed (model, iter); } + virtual void entryInserted (Ypp::Pool::Iter iter, Ypp::Package *package) + { ygtk_zypp_model_entry_inserted (model, iter); } + virtual void entryDeleted (Ypp::Pool::Iter iter, Ypp::Package *package) + { ygtk_zypp_model_entry_deleted (model, iter); } +}; + +// Icons resources +struct PackageIcons { + GdkPixbuf *installed, *installed_upgradable, *installed_locked, + *installed_upgradable_locked, *available, *available_locked, + *to_install, *to_remove, *to_auto_install, *to_auto_remove, + *is_3D; + PackageIcons() { + installed = gdk_pixbuf_new_from_xpm_data (pkg_installed_xpm); + installed_upgradable = + gdk_pixbuf_new_from_xpm_data (pkg_installed_upgradable_xpm); + installed_locked = gdk_pixbuf_new_from_xpm_data (pkg_installed_locked_xpm); + installed_upgradable_locked = + gdk_pixbuf_new_from_xpm_data (pkg_installed_upgradable_locked_xpm); + available = gdk_pixbuf_new_from_xpm_data (pkg_available_xpm); + available_locked = gdk_pixbuf_new_from_xpm_data (pkg_available_locked_xpm); + to_install = gdk_pixbuf_new_from_xpm_data (pkg_install_xpm); + to_remove = gdk_pixbuf_new_from_xpm_data (pkg_remove_xpm); + to_auto_install = gdk_pixbuf_new_from_xpm_data (pkg_install_auto_xpm); + to_auto_remove = gdk_pixbuf_new_from_xpm_data (pkg_remove_auto_xpm); + is_3D = gdk_pixbuf_new_from_xpm_data (pkg_3D_xpm); + } + ~PackageIcons() { + g_object_unref (G_OBJECT (installed)); + g_object_unref (G_OBJECT (installed_upgradable)); + g_object_unref (G_OBJECT (installed_upgradable_locked)); + g_object_unref (G_OBJECT (installed_locked)); + g_object_unref (G_OBJECT (available)); + g_object_unref (G_OBJECT (available_locked)); + g_object_unref (G_OBJECT (to_install)); + g_object_unref (G_OBJECT (to_remove)); + g_object_unref (G_OBJECT (to_auto_install)); + g_object_unref (G_OBJECT (to_auto_remove)); + g_object_unref (G_OBJECT (is_3D)); + } +}; + +static PackageIcons *icons = NULL; +void ygtk_zypp_model_finish() +{ + delete icons; icons = NULL; + Ypp::finish(); +} + +static void ygtk_zypp_model_tree_model_init (GtkTreeModelIface *iface); + +G_DEFINE_TYPE_WITH_CODE (YGtkZyppModel, ygtk_zypp_model, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, ygtk_zypp_model_tree_model_init)) + +static void ygtk_zypp_model_init (YGtkZyppModel *zmodel) +{ + if (!icons) + icons = new PackageIcons(); +} + +static void ygtk_zypp_model_finalize (GObject *object) +{ + YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (object); + delete zmodel->notify; + zmodel->notify = NULL; + delete zmodel->pool; + zmodel->pool = NULL; + G_OBJECT_CLASS (ygtk_zypp_model_parent_class)->finalize (object); +} + +static GtkTreeModelFlags ygtk_zypp_model_get_flags (GtkTreeModel *) +{ + return GtkTreeModelFlags (GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY); +} + +static gboolean ygtk_zypp_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, + GtkTreePath *path) +{ + YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (model); + gint row = gtk_tree_path_get_indices (path)[0]; + + iter->user_data = (gpointer) zmodel->pool->getIter (row); + return iter->user_data != NULL; +} + +static GtkTreePath *ygtk_zypp_model_get_path (GtkTreeModel *model, GtkTreeIter *iter) +{ + YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (model); + int row = zmodel->pool->getIndex (iter->user_data); +fprintf (stderr, "get index: %d\n", row); + + GtkTreePath *path = gtk_tree_path_new(); + gtk_tree_path_append_index (path, row); + return path; +} + +static gboolean ygtk_zypp_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter) +{ + YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (model); + iter->user_data = zmodel->pool->getNext (iter->user_data); + return iter->user_data != NULL; +} + +void ygtk_zypp_model_entry_changed (YGtkZyppModel *model, Ypp::Pool::Iter it) +{ + GtkTreeIter iter; + iter.user_data = it; + GtkTreePath *path = ygtk_zypp_model_get_path (GTK_TREE_MODEL (model), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); + gtk_tree_path_free (path); +} + +void ygtk_zypp_model_entry_inserted (YGtkZyppModel *model, Ypp::Pool::Iter it) +{ +fprintf (stderr, "inserted row\n"); + GtkTreeIter iter; + iter.user_data = it; + GtkTreePath *path = ygtk_zypp_model_get_path (GTK_TREE_MODEL (model), &iter); +fprintf (stderr, "signal\n"); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); +fprintf (stderr, "done\n"); + gtk_tree_path_free (path); +} + +void ygtk_zypp_model_entry_deleted (YGtkZyppModel *model, Ypp::Pool::Iter it) +{ + GtkTreeIter iter; + iter.user_data = it; + GtkTreePath *path = ygtk_zypp_model_get_path (GTK_TREE_MODEL (model), &iter); + gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); + gtk_tree_path_free (path); +} + +static gint ygtk_zypp_model_get_n_columns (GtkTreeModel *model) +{ + return YGtkZyppModel::TOTAL_COLUMNS; +} + +static GType ygtk_zypp_model_get_column_type (GtkTreeModel *tree_model, gint column) +{ + switch (column) + { + case YGtkZyppModel::ICON_COLUMN: + return GDK_TYPE_PIXBUF; + case YGtkZyppModel::NAME_COLUMN: + case YGtkZyppModel::NAME_DESCRIPTION_COLUMN: + return G_TYPE_STRING; + case YGtkZyppModel::PTR_COLUMN: + return G_TYPE_POINTER; + case YGtkZyppModel::SPECIAL_ICON_COLUMN: + return GDK_TYPE_PIXBUF; + } + return 0; +} + +static void ygtk_zypp_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, + gint column, GValue *value) +{ + YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (model); + Ypp::Package *package = zmodel->pool->get (iter->user_data); + + g_value_init (value, ygtk_zypp_model_get_column_type (model, column)); + switch (column) + { + case YGtkZyppModel::ICON_COLUMN: + { + GdkPixbuf *pixbuf; + bool locked = package->isLocked(); + bool auto_ = package->isAuto(); + if (package->toInstall()) { + if (auto_) + pixbuf = icons->to_auto_install; + else + pixbuf = icons->to_install; + } + else if (package->toRemove()) { + if (auto_) + pixbuf = icons->to_auto_remove; + else + pixbuf = icons->to_remove; + } + else if (package->hasUpgrade()) { + if (locked) + pixbuf = icons->installed_upgradable_locked; + else + pixbuf = icons->installed_upgradable; + } + else if (package->isInstalled()) { + if (locked) + pixbuf = icons->installed_locked; + else + pixbuf = icons->installed; + } + else { + if (locked) + pixbuf = icons->available_locked; + else + pixbuf = icons->available; + } + g_value_set_object (value, (GObject *) pixbuf); + break; + } + case YGtkZyppModel::NAME_COLUMN: + { + std::string name = package->name(); + const unsigned int max_width = 15; + if (name.size() > max_width) { + name.erase (max_width-3); + name += "..."; + } + g_value_set_string (value, g_strdup (name.c_str())); + break; + } + case YGtkZyppModel::NAME_DESCRIPTION_COLUMN: + { + std::string str = package->name(); + std::string summary = package->summary(); + if (!summary.empty()) { + YGUtils::escapeMarkup (summary); + str += "\n<small>" + summary + "</small>"; + } + g_value_set_string (value, g_strdup (str.c_str())); + break; + } + case YGtkZyppModel::PTR_COLUMN: + { + void *ptr; + ptr = (void *) package; + g_value_set_pointer (value, ptr); + break; + } + case YGtkZyppModel::SPECIAL_ICON_COLUMN: + { + if (package->is3D()) + g_value_set_object (value, (GObject *) icons->is_3D); + else + g_value_set_object (value, NULL); + break; + } + default: + g_warning ("YGtkZyppModel column %d doesn't exist.", column); + break; + } +} + +static gboolean ygtk_zypp_model_iter_children (GtkTreeModel *model, GtkTreeIter *iter, + GtkTreeIter *parent) +{ + return FALSE; +} + +static gboolean ygtk_zypp_model_iter_has_child (GtkTreeModel *model, GtkTreeIter *iter) +{ + return FALSE; +} + +static gint ygtk_zypp_model_iter_n_children (GtkTreeModel *model, GtkTreeIter *iter) +{ + return 0; +} + +static gboolean ygtk_zypp_model_iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter, + GtkTreeIter *parent, gint n) +{ + return FALSE; +} + +static gboolean ygtk_zypp_model_iter_parent (GtkTreeModel *model, GtkTreeIter *iter, + GtkTreeIter *child) +{ + return FALSE; +} + +YGtkZyppModel *ygtk_zypp_model_new (Ypp::Query *query) +{ + YGtkZyppModel *zmodel = (YGtkZyppModel *) g_object_new (YGTK_TYPE_ZYPP_MODEL, NULL); + zmodel->notify = new YGtkZyppModel::PoolNotify(); + zmodel->notify->model = zmodel; + zmodel->pool = new Ypp::Pool (query); + zmodel->pool->setListener (zmodel->notify); + return zmodel; +} + +static void ygtk_zypp_model_class_init (YGtkZyppModelClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ygtk_zypp_model_finalize; +} + +static void ygtk_zypp_model_tree_model_init (GtkTreeModelIface *iface) +{ + iface->get_flags = ygtk_zypp_model_get_flags; + iface->get_n_columns = ygtk_zypp_model_get_n_columns; + iface->get_column_type = ygtk_zypp_model_get_column_type; + iface->get_iter = ygtk_zypp_model_get_iter; + iface->get_path = ygtk_zypp_model_get_path; + iface->get_value = ygtk_zypp_model_get_value; + iface->iter_next = ygtk_zypp_model_iter_next; + iface->iter_children = ygtk_zypp_model_iter_children; + iface->iter_has_child = ygtk_zypp_model_iter_has_child; + iface->iter_n_children = ygtk_zypp_model_iter_n_children; + iface->iter_nth_child = ygtk_zypp_model_iter_nth_child; + iface->iter_parent = ygtk_zypp_model_iter_parent; +} + Added: trunk/gtk/unstable/src/ygtkzyppwrapper.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/ygtkzyppwrapper.... ============================================================================== --- trunk/gtk/unstable/src/ygtkzyppwrapper.h (added) +++ trunk/gtk/unstable/src/ygtkzyppwrapper.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,54 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* Contains ZyppWrapper query results in a GtkTreeModel. +*/ + +#ifndef YGTK_ZYPP_WRAPPER_H +#define YGTK_ZYPP_WRAPPER_H + +#include "yzyppwrapper.h" +#include <gtk/gtktreemodel.h> + +#define YGTK_TYPE_ZYPP_MODEL (ygtk_zypp_model_get_type ()) +#define YGTK_ZYPP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_ZYPP_MODEL, YGtkZyppModel)) +#define YGTK_ZYPP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_ZYPP_MODEL, YGtkZyppModelClass)) +#define YGTK_IS_ZYPP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YGTK_TYPE_ZYPP_MODEL)) +#define YGTK_IS_ZYPP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YGTK_TYPE_ZYPP_MODEL)) +#define YGTK_ZYPP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_ZYPP_MODEL, YGtkZyppModelClass)) + +struct YGtkZyppModel +{ + GObject parent; + + enum Columns { + ICON_COLUMN, NAME_COLUMN, NAME_DESCRIPTION_COLUMN, PTR_COLUMN, + SPECIAL_ICON_COLUMN, TOTAL_COLUMNS + }; + + Ypp::Pool *pool; + + struct PoolNotify; + PoolNotify *notify; +}; + +struct YGtkZyppModelClass +{ + GObjectClass parent_class; +}; + +YGtkZyppModel *ygtk_zypp_model_new (Ypp::Query *query); +GType ygtk_zypp_model_get_type (void) G_GNUC_CONST; +// besides calling Ypp for cleaning, it also cleans the icons of this hook +void ygtk_zypp_model_finish(); + +void ygtk_zypp_model_entry_changed (YGtkZyppModel *model, Ypp::Pool::Iter iter); +void ygtk_zypp_model_entry_inserted (YGtkZyppModel *model, Ypp::Pool::Iter iter); +void ygtk_zypp_model_entry_deleted (YGtkZyppModel *model, Ypp::Pool::Iter iter); + +#endif /*YGTK_ZYPP_WRAPPER_H*/ + Added: trunk/gtk/unstable/src/yzyppwrapper.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/yzyppwrapper.cc?... ============================================================================== --- trunk/gtk/unstable/src/yzyppwrapper.cc (added) +++ trunk/gtk/unstable/src/yzyppwrapper.cc Thu Nov 29 18:22:01 2007 @@ -0,0 +1,1435 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* Ypp, zypp wrapper */ +// check the header file for information about this wrapper + +#include <config.h> +#include "YGi18n.h" +#include "yzyppwrapper.h" + +#include <ycp/y2log.h> +#include <zypp/ZYppFactory.h> +#include <zypp/ResObject.h> +#include <zypp/ResPoolProxy.h> +#include <zypp/ui/Selectable.h> +#include <zypp/Patch.h> +#include <zypp/Selection.h> +#include <zypp/Package.h> +#include <zypp/Pattern.h> +#include <zypp/Language.h> +#include <zypp/Product.h> +#include <zypp/Repository.h> +#include <zypp/RepoManager.h> + +#include <glib/gslist.h> +#include "YGUtils.h" + +//** Zypp shortcuts + +typedef zypp::ResPoolProxy ZyppPool; +inline ZyppPool zyppPool() { return zypp::getZYpp()->poolProxy(); } +typedef zypp::ui::Selectable::Ptr ZyppSelectable; +typedef zypp::ui::Selectable* ZyppSelectablePtr; +typedef zypp::ResObject::constPtr ZyppObject; +typedef zypp::ResObject* ZyppObjectPtr; +typedef zypp::Package::constPtr ZyppPackage; +typedef zypp::Patch::constPtr ZyppPatch; +typedef zypp::Pattern::constPtr ZyppPattern; +typedef zypp::Language::constPtr ZyppLanguage; +inline ZyppPackage tryCastToZyppPkg (ZyppObject obj) +{ return zypp::dynamic_pointer_cast <const zypp::Package> (obj); } +inline ZyppPatch tryCastToZyppPatch (ZyppObject obj) +{ return zypp::dynamic_pointer_cast <const zypp::Patch> (obj); } +inline ZyppPattern tryCastToZyppPattern (ZyppObject obj) +{ return zypp::dynamic_pointer_cast <const zypp::Pattern> (obj); } +inline ZyppLanguage tryCastToZyppLanguage (ZyppObject obj) +{ return zypp::dynamic_pointer_cast <const zypp::Language> (obj); } + +//** Utilities + +// converts a set of tree representation in a form of a strings to a tree structure. +// String tree representations are, for instance, filenames: /dir1/dir2/file +struct StringTree { + typedef int (*Compare)(const char *, const char *); + Compare compare; + char delim; + GNode *root; + + StringTree (Compare compare, char delim) + : compare (compare), delim (delim) + { + // the root is a dummy node to keep GNode happy + root = g_node_new (NULL); + } + + ~StringTree() + { + struct inner { + static void free (GNode *node, void *_data) + { delete ((Ypp::Node *) node->data); } + }; + g_node_children_foreach (root, G_TRAVERSE_ALL, inner::free, NULL); + g_node_destroy (root); + } + + Ypp::Node *getFirst() + { + return (Ypp::Node *) root->children->data; + } + + Ypp::Node *add (const std::string &tree_str) + { + const std::list <std::string> nodes_str = YGUtils::splitString (tree_str, delim); + GNode *parent = root, *sibling = 0; + Ypp::Node *ret = 0; + + std::list <std::string>::const_iterator it; + for (it = nodes_str.begin(); it != nodes_str.end(); it++) { + bool found = false; + for (sibling = parent->children; sibling; sibling = sibling->next) { + Ypp::Node *yNode = (Ypp::Node *) sibling->data; + int cmp = (*compare) (it->c_str(), yNode->name.c_str()); + if (cmp == 0) { + found = true; + ret = yNode; + break; + } + else if (cmp < 0) + break; + } + if (!found) + break; + parent = sibling; + } + + for (; it != nodes_str.end(); it++) { + Ypp::Node *yNode = new Ypp::Node(); + GNode *n = g_node_new ((void *) yNode); + yNode->name = *it; + yNode->impl = (void *) n; + g_node_insert_before (parent, sibling, n); + parent = n; + sibling = NULL; + ret = yNode; + } + return ret; + } +}; + +//** Singleton + +static Ypp *ypp = 0; + +Ypp *Ypp::get() +{ + if (!ypp) + ypp = new Ypp(); + return ypp; +} + +void Ypp::finish() +{ + delete ypp; ypp = NULL; +} + +// Ypp::Impl declaration, to expose some methods for usage +struct Ypp::Impl +{ +public: + Impl(); + ~Impl(); + + const Repository *getRepository (int nb); + int getRepository (const std::string &zyppId); + Disk *getDisk(); + + // for Packages + bool acceptLicense (Ypp::Package *package, const std::string &license); + void packageModified (Ypp::Package *package); + + // for Pools + void addPool (Pool::Impl *pool); + void removePool (Pool::Impl *pool); + GSList *getPackages (Package::Type type); + +private: + bool resolveProblems(); + Node *addCategory (Package::Type type, const std::string &str, Package *package); + void polishCategories (Ypp::Package::Type type); + + void startTransactions(); + void finishTransactions(); + + friend class Ypp; + GSList *packages [Package::TOTAL_TYPES]; // primitive pools + StringTree *categories [Package::TOTAL_TYPES]; + GSList *repos; + Disk *disk; + Interface *interface; + GSList *pools; + bool inTransaction; + GSList *transactions; +}; + +//** Package + +struct Ypp::Package::Impl +{ + Impl (ZyppSelectable sel) + : zyppSel (sel), index (-1), availableVersions (NULL), installedVersion (NULL), is3D (false) + { + // don't use getAvailableVersion(0) for hasUpgrade() has its inneficient. + // let's just cache candidate() at start, which should point to the newest version. + hasUpgrade = false; + ZyppObject candidate = zyppSel->candidateObj(); + ZyppObject installed = zyppSel->installedObj(); + if (!!candidate && !!installed) + hasUpgrade = zypp::Edition::compare (candidate->edition(), installed->edition()) > 0; + } + + ~Impl() + { + delete installedVersion; + for (GSList *i = availableVersions; i; i = i->next) + delete ((Version *) i->data); + g_slist_free (availableVersions); + } + + std::string name, summary; + ZyppSelectable zyppSel; + int index; // used for Pools syncing + Type type; + Ypp::Node *category; + GSList *availableVersions; + Version *installedVersion; + bool hasUpgrade; + bool is3D; +}; + +Ypp::Package::Package (Ypp::Package::Impl *impl) +: impl (impl) +{} +Ypp::Package::~Package() +{ delete impl; } + +Ypp::Package::Type Ypp::Package::type() +{ return impl->type; } + +const std::string &Ypp::Package::name() +{ + std::string &ret = impl->name; + if (ret.empty()) { + ZyppSelectable sel = impl->zyppSel; + ZyppObject obj = sel->theObj(); + switch (impl->type) { + case PATTERN_TYPE: + ret = obj->summary(); + case LANGUAGE_TYPE: + ret = obj->description(); + default: + ret = sel->name(); + } + } + return ret; +} + +const std::string &Ypp::Package::summary() +{ + std::string &ret = impl->summary; + if (ret.empty()) { + if (impl->type == PACKAGE_TYPE) + ret = impl->zyppSel->theObj()->summary(); + } + return ret; +} + +std::string Ypp::Package::description() +{ + ZyppObject object = impl->zyppSel->theObj(); + std::string text = object->description(), br = "<br>"; + if (impl->type == PACKAGE_TYPE) { + // if it has this header, then it is HTML + const char *header = "<!-- DT:Rich -->", header_len = 16; + if (!text.compare (0, header_len, header, header_len)) + text.erase (0, header_len); + else { + // add breakline for every double one... + YGUtils::replace (text, "\n\n", 2, "<br>"); +/* std::string::size_type i = 0; + while ((i = text.find ("\n\n", i)) < std::string::npos) { + text.erase (i, 2); // remove it, so we don't trip on it again + text.insert (i, "<br>"); + }*/ + } + + ZyppPackage package = tryCastToZyppPkg (object); + std::string url = package->url(), license = package->license(); + if (!url.empty()) + text += br + _("Website: ") + url; + if (!license.empty()) + text += br + _("License: ") + license; + } + text += br + _("Size: ") + object->size().asString(); + return text; +} + +std::string Ypp::Package::filelist() +{ + std::string text; + ZyppObject object = impl->zyppSel->installedObj(); + ZyppPackage package = tryCastToZyppPkg (object); + if (package) { + StringTree tree (YGUtils::strcmp, '/'); + + const std::list <std::string> &filesList = package->filenames(); + for (std::list <std::string>::const_iterator it = filesList.begin(); + it != filesList.end(); it++) + tree.add (*it); + + struct inner { + static std::string getPath (GNode *node) + { + Node *yNode = (Node *) node->data; + if (!yNode) + return std::string(); + return getPath (node->parent) + "/" + yNode->name; + } + static bool hasNextLeaf (GNode *node) + { + GNode *i; + for (i = node->next; i; i = i->next) + if (!i->children) + return true; + return false; + } + static bool hasPrevLeaf (GNode *node) + { + GNode *i; + for (i = node->prev; i; i = i->prev) + if (!i->children) + return true; + return false; + } + static gboolean traverse (GNode *node, void *_data) + { + Node *yNode = (Node *) node->data; + if (yNode) { + std::string *str = (std::string *) _data; + if (!hasPrevLeaf (node)) { + std::string path = getPath (node->parent); + *str += "<a href=" + path + ">" + path + "</a>"; + *str += "<blockquote>"; + } + else + *str += ", "; + *str += yNode->name; + + if (!hasNextLeaf (node)) + *str += "</blockquote>"; + } + return FALSE; + } + }; + g_node_traverse (tree.root, G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, + inner::traverse, (void *) &text); + } + return text; +} + +std::string Ypp::Package::changelog() +{ + string text; + ZyppObject object = impl->zyppSel->installedObj(); + ZyppPackage package = tryCastToZyppPkg (object); + if (package) { + const std::list <zypp::ChangelogEntry> &changelogList = package->changelog(); + for (std::list <zypp::ChangelogEntry>::const_iterator it = changelogList.begin(); + it != changelogList.end(); it++) { + std::string author = it->author(), changes = it->text(); + YGUtils::escapeMarkup (author); + YGUtils::escapeMarkup (changes); + YGUtils::replace (changes, "\n", 1, "<br>"); + text += it->date().asString() + author + ":<br>" + + "<blockquote>" + changes + "</blockqute>"; + } + } + return text; +} + +std::string Ypp::Package::authors() +{ +fprintf (stderr, "authors %s\n", name().c_str()); + std::string text; + ZyppObject object = impl->zyppSel->theObj(); + ZyppPackage package = tryCastToZyppPkg (object); + if (package) { + std::string packager = package->packager(), authors; + YGUtils::escapeMarkup (packager); + const std::list <std::string> &authorsList = package->authors(); + for (std::list <std::string>::const_iterator it = authorsList.begin(); + it != authorsList.end(); it++) { + std::string author = *it; + YGUtils::escapeMarkup (author); + if (!authors.empty()) + authors += "<br>"; + authors += author; +fprintf (stderr, "\t add author %s\n", author.c_str()); + } + // Some packagers put Authors over the Descriptions field. This seems to be rare + // on, so I'm not even going to bother. + + if (!packager.empty()) + text += _("Packaged by:") + ("<blockquote>" + packager) + "</blockquote>"; + if (!authors.empty()) + text += _("Developed by:") + ("<blockquote>" + authors) + "</blockquote>"; + } + return text; +} + +std::string Ypp::Package::provides() +{ + std::string text; + ZyppObject object = impl->zyppSel->theObj(); + const zypp::CapSet &capSet = object->dep (zypp::Dep::PROVIDES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + if (!text.empty()) + text += "\n"; + text += it->asString(); + } + return text; +} + +std::string Ypp::Package::requires() +{ + std::string text; + ZyppObject object = impl->zyppSel->theObj(); + const zypp::CapSet &capSet = object->dep (zypp::Dep::REQUIRES); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + if (!text.empty()) + text += "\n"; + text += it->asString(); + } + return text; +} + +Ypp::Node *Ypp::Package::category() +{ + return impl->category; +} + +bool Ypp::Package::is3D() +{ + return impl->is3D; +} + + +bool Ypp::Package::isInstalled() +{ + return impl->zyppSel->hasInstalledObj(); +} + +bool Ypp::Package::hasUpgrade() +{ + return impl->hasUpgrade; +} + +bool Ypp::Package::isLocked() +{ + zypp::ui::Status status = impl->zyppSel->status(); + return status == zypp::ui::S_Taboo || status == zypp::ui::S_Protected; +} + +bool Ypp::Package::toInstall (int *nb) +{ + if (nb) { + ZyppObject candidate = impl->zyppSel->candidateObj(); + for (int i = 0; getAvailableVersion (i); i++) { + const Version *version = getAvailableVersion (i); + ZyppObject i_obj = (ZyppObjectPtr) version->impl; + if (i_obj == candidate) { + *nb = i; + break; + } + } + } + return impl->zyppSel->toInstall(); +} + +bool Ypp::Package::toRemove() +{ + return impl->zyppSel->toDelete(); +} + +bool Ypp::Package::isModified() +{ + return impl->zyppSel->toModify(); +} + +bool Ypp::Package::isAuto() +{ + zypp::ui::Status status = impl->zyppSel->status(); + return status == zypp::ui::S_AutoInstall || status == zypp::ui::S_AutoUpdate || + status == zypp::ui::S_AutoDel; +} + +void Ypp::Package::install (int nb) +{ + if (isLocked()) + return; + if (!impl->zyppSel->hasLicenceConfirmed()) + { + const std::string &license = impl->zyppSel->candidateObj()->licenseToConfirm(); + if (!license.empty()) + if (!ypp->impl->acceptLicense (this, license)) + return; + impl->zyppSel->setLicenceConfirmed(); + } + + zypp::ui::Status status = impl->zyppSel->status(); + switch (status) { + // not applicable + case zypp::ui::S_Protected: + case zypp::ui::S_Taboo: + case zypp::ui::S_Install: + case zypp::ui::S_Update: + break; + // undo + case zypp::ui::S_Del: + status = zypp::ui::S_KeepInstalled; + break; + // nothing to do about it + case zypp::ui::S_AutoDel: + break; + // action + case zypp::ui::S_NoInst: + case zypp::ui::S_AutoInstall: + status = zypp::ui::S_Install; + break; + case zypp::ui::S_KeepInstalled: + case zypp::ui::S_AutoUpdate: + status = zypp::ui::S_Update; + break; + } + + impl->zyppSel->set_status (status); + if (toInstall()) { + const Version *version = getAvailableVersion (nb); + ZyppObject candidate = (ZyppObjectPtr) version->impl; + if (!impl->zyppSel->setCandidate (candidate)) { + y2warning ("Error: Could not set package '%s' candidate to '%s'\n", + name().c_str(), version->number.c_str()); + return; + } + } + + ypp->impl->packageModified (this); +} + +void Ypp::Package::remove() +{ + zypp::ui::Status status = impl->zyppSel->status(); + switch (status) { + // not applicable + case zypp::ui::S_Protected: + case zypp::ui::S_Taboo: + case zypp::ui::S_NoInst: + case zypp::ui::S_Del: + break; + // undo + case zypp::ui::S_Install: + status = zypp::ui::S_NoInst; + break; + // nothing to do about it + case zypp::ui::S_AutoInstall: + case zypp::ui::S_AutoUpdate: + break; + case zypp::ui::S_Update: + status = zypp::ui::S_KeepInstalled; + break; + // action + case zypp::ui::S_KeepInstalled: + case zypp::ui::S_AutoDel: + status = zypp::ui::S_Del; + break; + } + + impl->zyppSel->set_status (status); + ypp->impl->packageModified (this); +} + +void Ypp::Package::undo() +{ + if (isModified()) { + if (toInstall()) + remove(); + else + install (0); + } +} + +void Ypp::Package::lock (bool lock) +{ + undo(); + + zypp::ui::Status status; + if (lock) + status = isInstalled() ? zypp::ui::S_Protected : zypp::ui::S_Taboo; + else + status = isInstalled() ? zypp::ui::S_KeepInstalled : zypp::ui::S_NoInst; + + impl->zyppSel->set_status (status); + ypp->impl->packageModified (this); +} + +static Ypp::Package::Version *constructVersion (ZyppObject object) +{ + Ypp::Package::Version *version = new Ypp::Package::Version(); + version->number = object->edition().version(); + version->repo = ypp->impl->getRepository (object->repository().info().alias()); + version->cmp = 0; + version->impl = (void *) get_pointer (object); + return version; +} + +const Ypp::Package::Version *Ypp::Package::getInstalledVersion() +{ + if (!impl->installedVersion) { + const ZyppObject installedObj = impl->zyppSel->installedObj(); + if (installedObj) + impl->installedVersion = constructVersion (installedObj); + } + return impl->installedVersion; +} + +const Ypp::Package::Version *Ypp::Package::getAvailableVersion (int nb) +{ + if (!impl->availableVersions) { + const ZyppObject installedObj = impl->zyppSel->installedObj(); + for (zypp::ui::Selectable::available_iterator it = impl->zyppSel->availableBegin(); + it != impl->zyppSel->availableEnd(); it++) { + Version *version = constructVersion (*it); + if (installedObj) + version->cmp = zypp::Edition::compare ((*it)->edition(), installedObj->edition()); + impl->availableVersions = g_slist_append (impl->availableVersions, version); + } + struct inner { + static gint version_compare (gconstpointer pa, gconstpointer pb) + { + ZyppObjectPtr a = (ZyppObjectPtr) ((Version *) pa)->impl; + ZyppObjectPtr b = (ZyppObjectPtr) ((Version *) pb)->impl; + // swapped arguments, as we want them sorted from newer to older + return zypp::Edition::compare (b->edition(), a->edition()); + } + }; + impl->availableVersions = g_slist_sort (impl->availableVersions, + inner::version_compare); + } + return (Version *) g_slist_nth_data (impl->availableVersions, nb); +} + +bool Ypp::Package::isOnRepository (int repo_nb) +{ + int i; + for (i = 0; getAvailableVersion (i); i++) + if (getAvailableVersion (i)->repo == repo_nb) + return true; + // if there are no availables, answer yes to all repos + return i == 0; +} + +//** Query + +struct Ypp::Query::Impl +{ + template <typename T> + struct Key + { + Key() + : defined (false) + {} + void define (T v) + { + defined = true; + value = v; + } + bool is (const T &v) const + { +// if (!defined) return true; + return value == v; + } + bool defined; + T value; + }; + + Key <Ypp::Package::Type> type; + Key <std::list <std::string> > name; + Key <Ypp::Node *> category; + Key <bool> isInstalled; + Key <bool> hasUpgrade; + Key <bool> isModified; + Key <std::list <int> > onRepositories; + + Impl() + {} + + bool match (Package *package) + { + bool match = true; +// we must avoid passing values by copy, as well as zypp calls + if (match && type.defined) + match = type.is (package->type()); + if (match && isInstalled.defined) + match = isInstalled.is (package->isInstalled()); + if (match && hasUpgrade.defined) + match = hasUpgrade.is (package->hasUpgrade()); + if (match && isModified.defined) + match = isModified.is (package->isModified()); + if (match && name.defined) { + const std::list <std::string> &names = name.value; + std::list <std::string>::const_iterator it; + for (it = names.begin(); it != names.end(); it++) + if (YGUtils::contains (package->name(), *it) || + YGUtils::contains (package->summary(), *it) || + YGUtils::contains (package->provides(), *it)) + break; + match = it != names.end(); + } + if (match && category.defined) { + Ypp::Node *query_category = category.value; + Ypp::Node *pkg_category = package->category(); + GNode *node = (GNode *) query_category->impl; + if (!g_node_find (node, G_PRE_ORDER, G_TRAVERSE_ALL, pkg_category)) + match = false; + } + if (match && onRepositories.defined) { + const std::list <int> &repos = onRepositories.value; + std::list <int>::const_iterator it; + for (it = repos.begin(); it != repos.end(); it++) + if (package->isOnRepository (*it)) + break; + match = it != repos.end(); + } + return match; + } +}; + +Ypp::Query::Query (Ypp::Package::Type type) +{ + impl = new Impl(); + impl->type.define (type); +} +Ypp::Query::~Query() +{ delete impl; } + +void Ypp::Query::setName (std::string value) +{ impl->name.define (YGUtils::splitString (value, ' ')); } +void Ypp::Query::setCategory (Ypp::Node *value) +{ impl->category.define (value); } +void Ypp::Query::setIsInstalled (bool value) +{ impl->isInstalled.define (value); } +void Ypp::Query::setHasUpgrade (bool value) +{ impl->hasUpgrade.define (value); } +void Ypp::Query::setIsModified (bool value) +{ impl->isModified.define (value); } +void Ypp::Query::setRepositories (std::list <int> value) +{ impl->onRepositories.define (value); } + +//** Pool + +struct Ypp::Pool::Impl +{ +Query *query; +GSList *packages; +Pool::Listener *listener; + + Impl (Query *query) + : query (query), listener (NULL) + { + packages = buildPool (query); +fprintf (stderr, "created pool, adding to Ypp\n"); + ypp->impl->addPool (this); + } + + ~Impl() + { +fprintf (stderr, "destroyed pool, removing from Ypp\n"); + ypp->impl->removePool (this); + delete query; + g_slist_free (packages); + } + + void packageModified (Package *package) + { + bool match = query->impl->match (package); + int cmp = 1; + GSList *i; + for (i = packages; i; i = i->next) { + Package *pkg = (Package *) i->data; + if (pkg->impl->index == package->impl->index) + cmp = 0; + if (pkg->impl->index >= package->impl->index) + break; + } + if (cmp == 0) { + if (match) { // modified + if (listener) + listener->entryChanged ((Iter) i, package); + } + else { // removed + if (listener) + listener->entryDeleted ((Iter) i, package); + packages = g_slist_delete_link (packages, i); + } + } + else { + if (match) { // inserted + if (i == NULL) { +fprintf (stderr, "i null -- append it\n"); +fprintf (stderr, "before packages: %p\n", packages); + packages = g_slist_append (packages, (gpointer) package); + i = g_slist_last (packages); +//fprintf (stderr, "index: \n", getIndexOf (package)); +fprintf (stderr, "after packages: %p\n", packages); +} + else { + packages = g_slist_insert_before (packages, i, (gpointer) package); + int index = g_slist_position (packages, i) - 1; + i = g_slist_nth (packages, index); + } + if (listener) + listener->entryInserted ((Iter) i, package); + } + } + } + +private: + static GSList *buildPool (Query *query) // at construction + { +long time1 = time(NULL); +fprintf (stderr, "build pool...\n"); + GSList *pool = NULL; + GSList *entire_pool = ypp->impl->getPackages (query->impl->type.value); + int index = 0; + for (GSList *i = entire_pool; i; i = i->next) { + Package *pkg = (Package *) i->data; + if (query->impl->match (pkg)) + pool = g_slist_append (pool, i->data); + if (pkg->impl->index == -1) + pkg->impl->index = index++; + } +fprintf (stderr, "delta time: %ld\n", time(NULL)-time1); + return pool; + } +}; + +Ypp::Pool::Pool (Query *query) +{ impl = new Impl (query); } +Ypp::Pool::~Pool() +{ delete impl; } + +Ypp::Pool::Iter Ypp::Pool::getFirst() +{ return impl->packages; } + +Ypp::Pool::Iter Ypp::Pool::getNext (Ypp::Pool::Iter iter) +{ return ((GSList *) iter)->next; } + +Ypp::Package *Ypp::Pool::get (Ypp::Pool::Iter iter) +{ return (Ypp::Package *) ((GSList *) iter)->data; } + +int Ypp::Pool::getIndex (Ypp::Pool::Iter iter) +{ return g_slist_position (impl->packages, (GSList *) iter); } + +Ypp::Pool::Iter Ypp::Pool::getIter (int index) +{ return g_slist_nth (impl->packages, index); } + +void Ypp::Pool::setListener (Ypp::Pool::Listener *listener) +{ impl->listener = listener; } + +//** Misc + +struct Ypp::Disk::Impl +{ +Ypp::Disk::Listener *listener; +GSList *partitions; + + Impl() + : partitions (NULL) + { + if (zypp::getZYpp()->diskUsage().empty()) + zypp::getZYpp()->setPartitions ( + zypp::DiskUsageCounter::detectMountPoints()); + } + + ~Impl() + { + clearPartitions(); + } + + void packageModified (Package *package) + { + clearPartitions(); + if (listener) + listener->update(); + } + + void clearPartitions() + { + for (GSList *i = partitions; i; i = i->next) + delete ((Partition *) i->data); + g_slist_free (partitions); + partitions = NULL; + } + + const Partition *getPartition (int nb) + { + if (!partitions) { + typedef zypp::DiskUsageCounter::MountPoint ZyppDu; + typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet; + typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator; + + ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage(); + for (ZyppDuSetIterator it = diskUsage.begin(); it != diskUsage.end(); it++) { + if (!it->readonly) { + // partition fields: dir, used_size, total_size (size on Kb) + Ypp::Disk::Partition *partition = new Partition(); + partition->path = it->dir; + partition->used = it->pkg_size; + partition->total = it->total_size; + partition->used_str = + zypp::ByteCount (partition->used, zypp::ByteCount::K).asString(); + partition->total_str = + zypp::ByteCount (partition->total, zypp::ByteCount::K).asString(); + partitions = g_slist_append (partitions, (gpointer) partition); + } + } + } + return (Partition *) g_slist_nth_data (partitions, nb); + } +}; + +Ypp::Disk::Disk() +{ impl = new Impl(); } +Ypp::Disk::~Disk() +{ delete impl; } + +void Ypp::Disk::setListener (Ypp::Disk::Listener *listener) +{ impl->listener = listener; } + +const Ypp::Disk::Partition *Ypp::Disk::getPartition (int nb) +{ return impl->getPartition (nb); } + +Ypp::Node *Ypp::getFirstCategory (Ypp::Package::Type type) +{ + return impl->categories[type]->getFirst(); +} + +Ypp::Node *Ypp::Node::next() +{ + GNode *ret = ((GNode *) impl)->next; + if (ret) return (Ypp::Node *) ret->data; + return NULL; +} + +Ypp::Node *Ypp::Node::child() +{ + GNode *ret = ((GNode *) impl)->children; + if (ret) return (Ypp::Node *) ret->data; + return NULL; +} + +struct CatConversor { + const char *from, *to; +}; +static const CatConversor catConversor[] = { + { "Amusements/Games/3D", "Games/Action" }, + { "Amusements/Games/Board/Puzzle", "Games/Logic" }, + { "Amusements/Games/Board/Card", "Games/Card" }, + { "Amusements/Games", "Games" }, + { "Amusements", "Games" }, + { "Applications/Publishing", "Office" }, + { "Applications/Internet", "Network" }, + { "Applications", "" }, + { "Development/C", "Development/Libraries/C and C++" }, + { "Development/Python", "Development/Libraries/Python" }, + { "Development/Libraries/C", "Development/Libraries/C and C++" }, + { "Libraries", "Development/Libraries" }, + { "Productivity/Multimedia/Player", "Multimedia/Sound/Players" }, + { "Productivity/Multimedia/Audio", "Multimedia/Sound/Players" }, + { "Video", "Multimedia/Video" }, + { "Productivity/Multimedia", "Multimedia" }, + { "Productivity/Graphics", "Multimedia/Graphics" }, + { "Productivity/Networking", "Network" }, + { "Productivity/Network", "Network" }, + { "Productivity/Office", "Office" }, + { "Productivity/Publishing", "Office/Publishing" }, + { "Productivity/Telephony", "Network/Telephony" }, + { "Productivity", "Utilities" }, + { "System/Emulators", "Emulators" }, + { "System/GUI", "Utilities/GUI" }, + { "System/Video", "Emulators" }, + { "System/Libraries", "Development/Libraries/C and C++/System" }, + { "X11/Applications/Multimedia", "Multimedia" }, + { "X11/GNOME/Multimedia", "Multimedia" }, + { "X11/Applications", "Utilities/GUI" }, +}; +#define CAT_CONVERSOR_SIZE (sizeof (catConversor)/sizeof (CatConversor)) +struct TypoConversor { + const char *from, *to, len; +}; +static const TypoConversor catTypos[] = { + { "Others", "Other", 6 }, { "Utilites", "Utilities", 8 }, + { "AOLInstantMessenge", "AOLInstantMessenger", 18 }, + { "Library", "Libraries", 7 }, { "Libs", "Libraries", 4 }, +}; +#define CAT_TYPOS_SIZE (sizeof (catTypos)/sizeof (TypoConversor)) + +Ypp::Node *Ypp::Impl::addCategory (Ypp::Package::Type type, + const std::string &category_str, Package *pkg) +{ + struct inner { + static int cmp (const char *a, const char *b) + { + // Other group should always go as last + if (!strcmp (a, "Other")) + return !strcmp (b, "Other") ? 0 : 1; + if (!strcmp (b, "Other")) + return -1; + return YGUtils::strcmp (a, b); + } + + // Package categories guide-line don't seem to be enforced, some categories + // are duplicated, or don't make much sense. Let's try to cut on that. + + static std::string treatCategory (const std::string &category, Package *pkg) + { + std::string ret (category); + + // typos (end group only) + for (unsigned int c = 0; c < CAT_TYPOS_SIZE; c++) { + const char *from = catTypos[c].from, from_len = catTypos[c].len; + int ret_index = ret.length() - from_len; + + if (ret_index >= 0 && ret.compare (ret_index, from_len, from, from_len) == 0) { + const char *to = catTypos[c].to; + ret.erase (ret_index); + ret.append (to); + break; + } + } + + for (unsigned int c = 0; c < CAT_CONVERSOR_SIZE; c++) { + const char *from = catConversor[c].from; + unsigned int i; + for (i = 0; from[i] && i < ret.length(); i++) + if (from[i] != ret[i]) + break; + if (!from[i] && (i == ret.length() || ret[i] == '/')) { + const char *to = catConversor[c].to; + ret.erase (0, i); + ret.insert (0, to); + if (c == 0 && pkg) + pkg->impl->is3D = true; + break; + } + } + return ret; + } + }; + + if (!categories[type]) + categories[type] = new StringTree (inner::cmp, '/'); + if (type == Package::PACKAGE_TYPE) + return categories[type]->add (inner::treatCategory (category_str, pkg)); + else + return categories[type]->add (category_str); +} + +void Ypp::Impl::polishCategories (Ypp::Package::Type type) +{ + // some treatment on categories + // Put all packages under a node (as opposite to packages on a leaf) to + // the Other category. + if (type == Package::PACKAGE_TYPE) { + GSList *pool = ypp->impl->getPackages (type); + for (GSList *i = pool; i; i = i->next) { + Package *pkg = (Package *) i->data; + Ypp::Node *ynode = pkg->category(); + if (ynode->child()) { + GNode *node = (GNode *) ynode->impl; + GNode *last = g_node_last_child (node); + if (((Ypp::Node *) last->data)->name == "Other") + pkg->impl->category = (Ypp::Node *) last->data; + else { + // must create a "Other" node + fprintf (stderr, "creating Other\n"); + Ypp::Node *yN = new Ypp::Node(); + GNode *n = g_node_new ((void *) yN); + yN->name = "Other"; + yN->impl = (void *) n; + g_node_insert_before (node, NULL, n); + pkg->impl->category = yN; + } + } + } + } +} + +//** Ypp top methods & internal connections + +Ypp::Impl::Impl() +: repos (NULL), disk (NULL), interface (NULL), pools (NULL), + inTransaction (false), transactions (NULL) +{ + for (int i = 0; i < Package::TOTAL_TYPES; i++) { + packages[i] = NULL; + categories[i] = NULL; + } +} + +Ypp::Impl::~Impl() +{ + struct inner { + static void free_package (void *data, void *_data) + { delete ((Package *) data); } + static void free_repo (void *data, void *_data) + { delete ((Repository *) data); } + }; + + for (int t = 0; t < Package::TOTAL_TYPES; t++) { + g_slist_foreach (packages[t], inner::free_package, NULL); + g_slist_free (packages[t]); + delete categories[t]; + } + + g_slist_foreach (repos, inner::free_repo, NULL); + g_slist_free (repos); + + // don't delete pools as they don't actually belong to Ypp, just listeners + g_slist_free (pools); + delete disk; +} + +const Ypp::Repository *Ypp::Impl::getRepository (int nb) +{ + if (!repos) { + zypp::RepoManager manager; + std::list <zypp::RepoInfo> zrepos = manager.knownRepositories(); + for (std::list <zypp::RepoInfo>::const_iterator it = zrepos.begin(); + it != zrepos.end(); it++) { + if (it->enabled()) { + Repository *repo = new Repository(); + repo->name = it->name(); + repo->alias = it->alias(); + repos = g_slist_append (repos, repo); + } + } + } + return (Repository *) g_slist_nth_data (repos, nb); +} + +int Ypp::Impl::getRepository (const std::string &alias) +{ + for (int i = 0; getRepository (i); i++) + if (getRepository (i)->alias == alias) + return i; + return -1; /*error*/ +} + +Ypp::Disk *Ypp::Impl::getDisk() +{ + if (!disk) + disk = new Disk(); + return disk; +} + +bool Ypp::Impl::acceptLicense (Ypp::Package *package, const std::string &license) +{ + if (interface) + interface->acceptLicense (package, license); + return false; +} + +Ypp::Problem::Solution *Ypp::Problem::getSolution (int nb) +{ + return (Ypp::Problem::Solution *) g_slist_nth_data ((GSList *) impl, nb); +} + +bool Ypp::Impl::resolveProblems() +{ + zypp::Resolver_Ptr zResolver = zypp::getZYpp()->resolver(); + bool resolved = false; + while (true) { + if (zResolver->resolvePool()) { + resolved = true; + break; + } + zypp::ResolverProblemList zProblems = zResolver->problems(); + if ((resolved = zProblems.empty())) + break; + + if (!interface) + break; + + std::list <Problem *> problems; + for (zypp::ResolverProblemList::iterator it = zProblems.begin(); + it != zProblems.end(); it++) { + Problem *problem = new Problem(); + problem->description = (*it)->description(); + problem->details = (*it)->details(); + GSList *solutions = NULL; + zypp::ProblemSolutionList zSolutions = (*it)->solutions(); + for (zypp::ProblemSolutionList::iterator jt = zSolutions.begin(); + jt != zSolutions.end(); jt++) { + Problem::Solution *solution = new Problem::Solution(); + solution->description = (*jt)->description(); + solution->details = (*jt)->details(); + solution->apply = false; + solution->impl = (void *) get_pointer (*jt); + solutions = g_slist_append (solutions, solution); + } + problem->impl = (void *) solutions; + problems.push_back (problem); + } + + resolved = interface->resolveProblems (problems); + + zypp::ProblemSolutionList choices; + for (std::list <Problem *>::iterator it = problems.begin(); + it != problems.end(); it++) { + for (int i = 0; (*it)->getSolution (i); i++) { + Problem::Solution *solution = (*it)->getSolution (i); + if (resolved && solution->apply) + choices.push_back ((zypp::ProblemSolution *) solution->impl); + delete solution; + } + delete *it; + } + + if (resolved) + zResolver->applySolutions (choices); + else + break; + } + + if (!resolved) + zResolver->undo(); + return resolved; +} + +void Ypp::Impl::packageModified (Ypp::Package *package) +{ + // notify listeners of package change + for (GSList *i = pools; i; i = i->next) { +fprintf (stderr, "ypp: informing pool of package modified\n"); + ((Pool::Impl *) i->data)->packageModified (package); + } + if (disk) + disk->impl->packageModified (package); + if (interface) + interface->packageModified (package); + + transactions = g_slist_append (transactions, package); + if (!inTransaction) + finishTransactions(); +} + +void Ypp::Impl::startTransactions() +{ + inTransaction = true; +} + +void Ypp::Impl::finishTransactions() +{ + inTransaction = true; + bool resolved = resolveProblems(); + if (resolved) { + // resolver won't tell us what changed -- tell pools about Auto packages + for (GSList *p = packages [Ypp::Package::PACKAGE_TYPE]; p; p = p->next) { + Ypp::Package *pkg = (Ypp::Package *) p->data; + if (pkg->isAuto()) { + for (GSList *i = pools; i; i = i->next) + ((Pool::Impl *) i->data)->packageModified (pkg); + } + } + } + else { + // user canceled resolver -- undo all + for (GSList *i = transactions; i; i = i->next) + ((Ypp::Package *) i->data)->undo(); + } + g_slist_free (transactions); + transactions = NULL; + inTransaction = false; +} + +void Ypp::Impl::addPool (Pool::Impl *pool) +{ fprintf (stderr, "ypp: adding pool\n"); pools = g_slist_append (pools, pool); } +void Ypp::Impl::removePool (Pool::Impl *pool) +{ fprintf (stderr, "ypp: removing pool\n"); pools = g_slist_remove (pools, pool); } + +#if 0 +// using auxiliary GSequence tree -- not yet shiped by Glib :X +// in any case, a sort merge is very fast, as packages are more or less +// sorted anyway... +GSList *Ypp::Impl::getPackages (Ypp::Package::Type type) +{ + if (!packages[type]) { + // auxiliary for efficient alphabetic sorting + GSequence *pool = g_sequence_new (NULL); + struct inner { + static gint compare (gconstpointer _a, gconstpointer _b, gpointer _data) + { + Package *a = (Package *) _a; + Package *b = (Package *) _b; + return YGUtils::strcmp (a->name().c_str(), b->name().c_str()); + } +/* static void pool_foreach (gpointer data, gpointer _list) + { + GSList **list = (GSList **) _list; + *list = g_slist_append (*list, data); + }*/ + }; + + ZyppPool::const_iterator it, end; + switch (type) + { + case Package::PACKAGE_TYPE: + it = zyppPool().byKindBegin <zypp::Package>(); + end = zyppPool().byKindEnd <zypp::Package>(); + break; + case Package::PATTERN_TYPE: + it = zyppPool().byKindBegin <zypp::Pattern>(); + end = zyppPool().byKindEnd <zypp::Pattern>(); + break; + case Package::LANGUAGE_TYPE: + it = zyppPool().byKindBegin <zypp::Language>(); + end = zyppPool().byKindEnd <zypp::Language>(); + break; + default: + break; + } + for (; it != end; it++) + { + Package *package = new Package (new Package::Impl (*it)); + g_sequence_insert_sorted (pool, package, inner::compare, NULL); + } + + // add stuff to the actual pool now + int index = 0; + for (GSequenceIter *it = g_sequence_get_begin_iter (pool); + !g_sequence_iter_is_end (it); it = g_sequence_iter_next (it)) { + gpointer data = g_sequence_get (it); + Package *pkg = (Package *) data; + pkg->impl->index = index++; + pkg->impl->type = type; + packages[type] = g_slist_append (packages[type], data); + } + +// g_sequence_foreach (pool, inner::pool_foreach, &); + g_sequence_free (pool); + } + return packages[type]; +} +#else +GSList *Ypp::Impl::getPackages (Ypp::Package::Type type) +{ + if (!packages[type]) { +long time1 = time(NULL); +fprintf (stderr, "creating pool of %d...\n", type); + GSList *pool = NULL; + struct inner { + static gint compare (gconstpointer _a, gconstpointer _b) + { + Package *a = (Package *) _a; + Package *b = (Package *) _b; + return YGUtils::strcmp (a->name().c_str(), b->name().c_str()); + } + }; + + ZyppPool::const_iterator it, end; + switch (type) { + case Package::PACKAGE_TYPE: + it = zyppPool().byKindBegin <zypp::Package>(); + end = zyppPool().byKindEnd <zypp::Package>(); + break; + case Package::PATTERN_TYPE: + it = zyppPool().byKindBegin <zypp::Pattern>(); + end = zyppPool().byKindEnd <zypp::Pattern>(); + break; + case Package::LANGUAGE_TYPE: + it = zyppPool().byKindBegin <zypp::Language>(); + end = zyppPool().byKindEnd <zypp::Language>(); + break; + default: + break; + } + for (; it != end; it++) { + Package *package = new Package (new Package::Impl (*it)); + Ypp::Node *category = 0; + if (type == Package::PACKAGE_TYPE) { + ZyppObject object = (*it)->theObj(); + ZyppPackage zpackage = tryCastToZyppPkg (object); + if (!zpackage) + continue; + category = addCategory (type, zpackage->group(), package); + } + else if (type == Package::PATTERN_TYPE) { + ZyppObject object = (*it)->theObj(); + ZyppPattern pattern = tryCastToZyppPattern (object); + if (!pattern || !pattern->userVisible()) + continue; + category = addCategory (type, pattern->category(), 0); + } + + package->impl->type = type; + package->impl->category = category; + pool = g_slist_prepend (pool, package); + } + // its faster to prepend then reverse, as we avoid iterating for each append + // lets reverse before sorting, as they are somewhat sorted already + pool = g_slist_reverse (pool); + // a sort merge. Don't use g_slist_insert_sorted() -- its linear + pool = g_slist_sort (pool, inner::compare); + packages[type] = pool; + + polishCategories (type); +fprintf (stderr, "delta time: %ld\n", time(NULL)-time1); + } + return packages[type]; +} +#endif + +Ypp::Ypp() +{ impl = new Impl(); } + +Ypp::~Ypp() +{ delete impl; } + +const Ypp::Repository *Ypp::getRepository (int nb) +{ return impl->getRepository (nb); } + +Ypp::Disk *Ypp::getDisk() +{ return impl->getDisk(); } + +void Ypp::setInterface (Ypp::Interface *interface) +{ impl->interface = interface; } + +bool Ypp::isModified() +{ + return zyppPool().diffState<zypp::Package >() || + zyppPool().diffState<zypp::Pattern >() || + zyppPool().diffState<zypp::Selection>() || + zyppPool().diffState<zypp::Language >() || + zyppPool().diffState<zypp::Patch >(); +} + +void Ypp::startTransactions() +{ impl->startTransactions(); } + +void Ypp::finishTransactions() +{ impl->finishTransactions(); } + Added: trunk/gtk/unstable/src/yzyppwrapper.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/src/yzyppwrapper.h?r... ============================================================================== --- trunk/gtk/unstable/src/yzyppwrapper.h (added) +++ trunk/gtk/unstable/src/yzyppwrapper.h Thu Nov 29 18:22:01 2007 @@ -0,0 +1,196 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* A simplification of libzypp's API. + + To get a list of packages, setup a Query object and create a Pool with + it. Package has a set of manipulation methods, the results of which are + then reported to Pool listeners, which you can choose to act on your + interface, if you want them reflected on the viewer. + Iterate the pool using Pool::Iter. Don't keep it around though, instead use + getIndex() and getIter(index). + + You must register an object that implements Interface, as some transactions + are bound by user decisions. Ypp is a singleton; first call to get() will + initialize it; you should call finish() when you're done to de-allocate + caches. + The only thing you should free is Pool objects. A Query will be freed by + the Pool object you pass it to. +*/ + +#ifndef ZYPP_WRAPPER_H +#define ZYPP_WRAPPER_H + +#include <string> +#include <list> + +struct Ypp +{ + // Utilities + struct Node { + std::string name; + Node *next(); + Node *child(); + void *impl; + }; + + // Entries + struct Package { + enum Type { + PACKAGE_TYPE, PATTERN_TYPE, LANGUAGE_TYPE, TOTAL_TYPES + }; + + Type type(); + const std::string &name(); + const std::string &summary(); + Node *category(); + bool is3D(); + + std::string description(); + std::string filelist(); + std::string changelog(); + std::string authors(); + + std::string provides(); + std::string requires(); + + bool isInstalled(); + bool hasUpgrade(); + bool isLocked(); + + bool toInstall (int *nb = 0); + bool toRemove(); + bool isModified(); + bool isAuto(); /* installing/removing cause of dependency */ + + void install (int nb); /* if installed, will replace it by that version */ + void remove(); + void undo(); + void lock (bool lock); + + struct Version { + std::string number; + int repo, cmp /*relatively to installed*/; + void *impl; + }; + const Version *getInstalledVersion(); + const Version *getAvailableVersion (int nb); + + // convinience -- true if any available is from the given repo + bool isOnRepository (int repo); + + struct Impl; + Impl *impl; + Package (Impl *impl); + ~Package(); + }; + + // when installing/removing/... a few packages at a time, you should use this methods, + // so that problem resolver gets only kicked after they are all queued + void startTransactions(); + void finishTransactions(); + + // Query + struct Query { + Query (Package::Type type); + void setName (std::string name); + void setCategory (Ypp::Node *category); + void setIsInstalled (bool installed); + void setHasUpgrade (bool upgradable); + void setIsModified (bool modified); + void setRepositories (std::list <int> repositories); + + ~Query(); + struct Impl; + Impl *impl; + }; + + // Pool + struct Pool { + Pool (Query *query); + + typedef void * Iter; + Iter getFirst(); + Iter getNext (Iter it); + Package *get (Iter it); + int getIndex (Iter it); + Iter getIter (int index); + + struct Listener { + virtual void entryChanged (Iter iter, Package *package) = 0; + virtual void entryInserted (Iter iter, Package *package) = 0; + virtual void entryDeleted (Iter iter, Package *package) = 0; + }; + void setListener (Listener *listener); + + ~Pool(); + struct Impl; + Impl *impl; + }; + + // Resolver + struct Problem { + std::string description, details; + struct Solution { + std::string description, details; + bool apply; + void *impl; + }; + Solution *getSolution (int nb); + void *impl; + }; + + // Module + static Ypp *get(); + static void finish(); + + struct Interface { + virtual bool acceptLicense (Package *package, const std::string &license) = 0; + // resolveProblems = false to cancel the action that had that effect + virtual bool resolveProblems (std::list <Problem *> problems) = 0; + + // FIXME: this is mostly a hack; the thing is that GtkTreeSelection doesn't + // signal when a selected row changes values. Anyway, to be done differently. + virtual void packageModified (Package *package) = 0; + }; + void setInterface (Interface *interface); + + bool isModified(); // any change made? + + // Misc + struct Repository { + std::string name, alias /*internal use*/; + }; + const Repository *getRepository (int nb); + + Node *getFirstCategory (Package::Type type); + + struct Disk + { + struct Partition { + std::string path, used_str, total_str; + long long used, total; + }; + const Partition *getPartition (int nb); + + struct Listener { + virtual void update() = 0; + }; + void setListener (Listener *listener); + + Disk(); + ~Disk(); + struct Impl; + Impl *impl; + }; + Disk *getDisk(); + + Ypp(); + ~Ypp(); + struct Impl; + Impl *impl; +}; + +#endif /*ZYPP_WRAPPER_H*/ + Added: trunk/gtk/unstable/tests/Beep.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Beep.ycp?rev=4... ============================================================================== --- trunk/gtk/unstable/tests/Beep.ycp (added) +++ trunk/gtk/unstable/tests/Beep.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,19 @@ +// Test for UI::Beep() +{ + UI::OpenDialog ( + `Label ("Doing some operations...") + ); + sleep (4000); + UI::CloseDialog(); + + UI::OpenDialog ( + `VBox ( + `Label ("Done. Now prooceed to answer the next questions."), + `PushButton ("Ok") + ) + ); + UI::Beep(); + + UI::UserInput(); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Cursor.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Cursor.ycp?rev... ============================================================================== --- trunk/gtk/unstable/tests/Cursor.ycp (added) +++ trunk/gtk/unstable/tests/Cursor.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,21 @@ +// Cursor test +{ + UI::OpenDialog ( + `VBox ( + `IntField (`id (`time), "Work for (secs):", 0, 10, 2), + `PushButton (`id (`work), "&Work!"), + `PushButton (`id (`cancel), "&Close") + ) + ); + + any ret = nil; + repeat { + ret = UI::UserInput(); + + if (ret == `work) + sleep ((integer) UI::QueryWidget (`time, `Value) * 1000); + + } until (ret == `cancel); + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/FileDialog.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/FileDialog.ycp... ============================================================================== --- trunk/gtk/unstable/tests/FileDialog.ycp (added) +++ trunk/gtk/unstable/tests/FileDialog.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,62 @@ +// Tests for file dialog calls: +// string UI::AskForExistingFile (startWith, filter, headline) +// string UI::AskForSaveFileName (startWith, filter, headline) +// string UI::AskForExistingDirectory (startWith, headline) + +{ + define void show_selected (string selected) + { + UI::OpenDialog ( + `VBox ( + `HBox ( + `Label ("You have selected:"), + `Label (`opt (`outputField), selected) + ), + `PushButton ("OK") + ) + ); + UI::UserInput(); + UI::CloseDialog(); + }; + + while (true) { + UI::OpenDialog ( + `VBox ( + `ComboBox (`id (`combo_action), "Action:", + [ + `item (`id (`open_file), "Open File"), + `item (`id (`save_file), "Save File"), + `item (`id (`select_folder), "Select Folder") + ] ), + `TextEntry (`id (`entry_path), "Some path:"), + `TextEntry (`id (`entry_filter), "Filter:", "*"), + `HBox ( + `PushButton (`id (`ok), "OK"), + `PushButton (`id (`cancel), "Cancel") + ) + ) + ); + any ret = UI::UserInput(); + + if (ret == `cancel) + break; + + string start_path = (string) UI::QueryWidget (`id (`entry_path), `Value); + string filter_str = (string) UI::QueryWidget (`id (`entry_filter), `Value); + + string ret_path = nil; + + any action = UI::QueryWidget (`id (`combo_action), `Value); + UI::CloseDialog(); + + if (action == `open_file) + ret_path = UI::AskForSaveFileName (start_path, filter_str, "Choose a File"); + else if (action == `save_file) + ret_path = UI::AskForSaveFileName (start_path, filter_str, "Choose a File"); + else if (action == `select_folder) + ret_path = UI::AskForSaveFileName (start_path, filter_str, "Choose a Folder"); + + if (ret_path != nil) + show_selected (ret_path); + } +} Added: trunk/gtk/unstable/tests/Frame.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Frame.ycp?rev=... ============================================================================== --- trunk/gtk/unstable/tests/Frame.ycp (added) +++ trunk/gtk/unstable/tests/Frame.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,27 @@ +{ +UI::OpenDialog ( + `VBox ( + `Frame ("CPU &Speed", + `VBox ( + `RadioButtonGroup( + `VBox ( + `Left(`RadioButton("Normal")), + `Left(`RadioButton("Overclocked")), + `Left(`RadioButton("Red Hot")), + `Left(`RadioButton("Melting", true)), + `Left(`TextEntry ("Delay:", "20")) + ) + ), + `Frame + ( "Exact speed", + `Slider ("CPU", 0, 100, 85) + ) + ) + ), + `PushButton("&OK") + ) + ); + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/IconButton.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/IconButton.ycp... ============================================================================== --- trunk/gtk/unstable/tests/IconButton.ycp (added) +++ trunk/gtk/unstable/tests/IconButton.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,20 @@ +// PushButton with icons (relative path) +{ + UI::OpenDialog ( + `VBox ( + `Heading( "YaST2 Mini Control Center" ), + `IconButton (`id ("keyboard "), "yast-keyboard.png", "Keyboard"), + `IconButton (`id ("mouse" ), "yast-mouse.png", "Mouse"), + `IconButton (`id ("timezone" ), "yast-timezone.png", "Time zone"), + `IconButton (`id ("lan" ), "yast-lan.png", "Network"), + `IconButton (`id ("sw_single"), "yast-software.png", "Software") + ) + ); + + string tool = (string) UI::UserInput(); + UI::CloseDialog(); + + UI::OpenDialog (`Label ("Running " + tool + "...")); + sleep (4000); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/IconItems-ComboBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/IconItems-Comb... ============================================================================== --- trunk/gtk/unstable/tests/IconItems-ComboBox.ycp (added) +++ trunk/gtk/unstable/tests/IconItems-ComboBox.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,25 @@ +// ComboBox with icons +{ + UI::OpenDialog ( + `VBox ( + `Heading( "YaST2 Mini Control Center" ), + `ComboBox (`id (`mod), `opt (`editable), "Modules", + [ "Auto-Yast", + `item(`id ("keyboard" ), `icon( "yast-keyboard.png"), "Keyboard" ), + `item(`id ("mouse" ), `icon( "yast-mouse.png" ), "Mouse" ), + `item(`id ("timezone" ), `icon( "yast-timezone.png"), "Time zone"), + `item(`id ("lan" ), `icon( "yast-lan.png" ), "Network" ), + `item(`id ("sw_single"), `icon( "yast-software.png"), "Software" ) + ] ), + `PushButton("&OK") + ) + ); + + UI::UserInput(); + string tool = (string) UI::QueryWidget (`id(`mod ), `Value); + UI::CloseDialog(); + + UI::OpenDialog (`Label ("Running " + tool + "...")); + sleep (4000); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/IconItems-MultiSelectionBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/IconItems-Mult... ============================================================================== --- trunk/gtk/unstable/tests/IconItems-MultiSelectionBox.ycp (added) +++ trunk/gtk/unstable/tests/IconItems-MultiSelectionBox.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,31 @@ +// ComboBox with icons +{ + UI::OpenDialog ( + `VBox ( + `Heading( "YaST2 Mini Control Center" ), + `MultiSelectionBox (`id (`mod), "Modules", + [ "auto-yast", + `item(`id ("keyboard" ), `icon( "yast-keyboard.png"), "Keyboard", true ), + `item(`id ("mouse" ), `icon( "yast-mouse.png" ), "Mouse", true ), + `item(`id ("timezone" ), `icon( "yast-timezone.png"), "Time zone"), + `item(`id ("lan" ), `icon( "yast-lan.png" ), "Network" ), + `item(`id ("sw_single"), `icon( "yast-software.png"), "Software" ) + ] ), + `PushButton("&OK") + ) + ); + + UI::UserInput(); + list mods = (list) UI::QueryWidget (`id(`mod ), `SelectedItems); + UI::CloseDialog(); + + string text = "Running "; + foreach (`it, mods, + ``{ text = sformat( "%1, %2", text, it); } + ); + text = text + "..."; + + UI::OpenDialog (`Label (text)); + sleep (4000); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/IconItems-SelectionBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/IconItems-Sele... ============================================================================== --- trunk/gtk/unstable/tests/IconItems-SelectionBox.ycp (added) +++ trunk/gtk/unstable/tests/IconItems-SelectionBox.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,25 @@ +// ComboBox with icons +{ + UI::OpenDialog ( + `VBox ( + `Heading( "YaST2 Mini Control Center" ), + `SelectionBox (`id (`mod), "Modules", + [ "Auto-Yast", + `item(`id ("keyboard" ), `icon( "yast-keyboard.png"), "Keyboard" ), + `item(`id ("mouse" ), `icon( "yast-mouse.png" ), "Mouse" ), + `item(`id ("timezone" ), `icon( "yast-timezone.png"), "Time zone"), + `item(`id ("lan" ), `icon( "yast-lan.png" ), "Network" ), + `item(`id ("sw_single"), `icon( "yast-software.png"), "Software" ) + ] ), + `PushButton("&OK") + ) + ); + + UI::UserInput(); + string mod = (string) UI::QueryWidget (`id(`mod ), `CurrentItem); + UI::CloseDialog(); + + UI::OpenDialog (`Label ("Running " + mod + "...")); + sleep (4000); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Image.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Image.ycp?rev=... ============================================================================== --- trunk/gtk/unstable/tests/Image.ycp (added) +++ trunk/gtk/unstable/tests/Image.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,68 @@ +// Image test +string filename = "tests/image.gif"; + +{ + UI::OpenDialog ( + `VBox ( + `ReplacePoint (`id (`replace_image), + `ColoredLabel ("Choose an image type option!", `rgb (0, 0, 0), + `rgb (255, 0, 0), 5) + ), + + `Frame ("Image type:", + `RadioButtonGroup (`id(`rb), + `VBox( + `Left (`RadioButton(`id (`static),`opt(`notify), "&Static")), + `Left (`RadioButton(`id (`animation), `opt(`notify), "&Animation")) + ) + ) + ), + + `Frame ("Image effect:", + `RadioButtonGroup (`id(`rb), + `VBox( + `Left (`RadioButton(`id (`no_effect), `opt(`notify), "&None", true)), + `Left (`RadioButton(`id (`tiled_effect),`opt(`notify), "&Tiled")), + `Left (`RadioButton(`id (`scaled_effect), `opt(`notify), "&Scaled")) + ) + ) + ), + `Right (`Label ("Resize the window!")), + `PushButton(`id (`close), "&Close") + ) + ); + + any ret = nil; + while (true) + { + ret = UI::UserInput(); + if (ret == `close || ret == `cancel) + break; + + any type_opt = nil; + if (!(boolean) UI::QueryWidget(`id(`static), `Value)) + type_opt = `animated; + + any effect_opt = nil; + if ((boolean) UI::QueryWidget(`id(`tiled_effect), `Value)) + effect_opt = `tiled; + else if ((boolean) UI::QueryWidget(`id(`scaled_effect), `Value)) + effect_opt = `scaleToFit; + + // needed for tiling (scaling sets this automatically, anyway...) + any zerowidth = nil; + any zeroheight = nil; + if (effect_opt != nil) { + zerowidth = `zeroWidth; + zeroheight = `zeroHeight; + } + + UI::ReplaceWidget (`replace_image, + `Image (`opt (type_opt, effect_opt, zerowidth, zeroheight), + filename, filename + " not found")); + + } + + UI::CloseDialog(); +} + Added: trunk/gtk/unstable/tests/ImageMng.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/ImageMng.ycp?r... ============================================================================== --- trunk/gtk/unstable/tests/ImageMng.ycp (added) +++ trunk/gtk/unstable/tests/ImageMng.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,91 @@ +// Image test +// TODO: make it getting the filename as an argument + +{ + UI::OpenDialog ( + `VBox ( + `ReplacePoint (`id (`replace_image), + `ColoredLabel ("Choose an image first!", `rgb (0, 0, 0), + `rgb (255, 0, 0), 5) + ), + + `Frame ("Which MNG file:", + `RadioButtonGroup (`id(`rb), + `VBox( + `Left (`RadioButton(`id (`movie1), `opt(`notify), "&Movie1")), + `Left (`RadioButton(`id (`movie2), `opt(`notify), "&Movie2")), + `Left (`RadioButton(`id (`movie3), `opt(`notify), "&Movie3")), + `Left (`RadioButton(`id (`movie4), `opt(`notify), "&Movie4")), + `Left (`RadioButton(`id (`movie5), `opt(`notify), "&Movie5")), + `Left (`RadioButton(`id (`movie6), `opt(`notify), "&Movie6")), + `Left (`RadioButton(`id (`movie7), `opt(`notify), "&Movie7")), + `Left (`RadioButton(`id (`movie8), `opt(`notify), "&Movie8")) + ) + ) + ), + + `Frame ("Image effect:", + `RadioButtonGroup (`id(`rb), + `VBox( + `Left (`RadioButton(`id (`no_effect), `opt(`notify), "&None", true)), + `Left (`RadioButton(`id (`tiled_effect),`opt(`notify), "&Tiled")), + `Left (`RadioButton(`id (`scaled_effect), `opt(`notify), "&Scaled")) + ) + ) + ), + `Right (`Label ("Resize the window!")), + `PushButton(`id (`close), "&Close") + ) + ); + + any ret = nil; + while (true) + { + ret = UI::UserInput(); + if (ret == `close || ret == `cancel) + break; + + any effect_opt = nil; + if ((boolean) UI::QueryWidget(`id(`tiled_effect), `Value)) + effect_opt = `tiled; + else if ((boolean) UI::QueryWidget(`id(`scaled_effect), `Value)) + effect_opt = `scaleToFit; + + // needed for tiling (scaling sets this automatically, anyway...) + any zerowidth = nil; + any zeroheight = nil; + if (effect_opt != nil) { + zerowidth = `zeroWidth; + zeroheight = `zeroHeight; + } + + string filename = ""; + if ((boolean) UI::QueryWidget(`id(`movie1), `Value)) + filename = "tests/movie1.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie2), `Value)) + filename = "tests/movie2.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie3), `Value)) + filename = "tests/movie3.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie4), `Value)) + filename = "tests/movie4.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie5), `Value)) + filename = "tests/movie5.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie6), `Value)) + filename = "tests/movie6.mng"; + else if ((boolean) UI::QueryWidget(`id(`movie7), `Value)) + filename = "tests/movie7.mng"; + else + filename = "tests/movie8.mng"; + + // to test inline images, uncomment next line and pass it to `Image + //byteblock data = (byteblock) SCR::Read (.target.byte, filename); + + UI::ReplaceWidget (`replace_image, + `Image (`opt (`animated, effect_opt, zerowidth, zeroheight), + filename, filename + " not found")); + + } + + UI::CloseDialog(); +} + Added: trunk/gtk/unstable/tests/Layout-Align-Weight.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Align-W... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Align-Weight.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Align-Weight.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,11 @@ +// alignment - weight test +{ +UI::OpenDialog( + `HBox( + `Right (`HWeight (1, `PushButton ("Left"))), + `Left (`HWeight (1, `PushButton ("Right"))) + ) +); +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-AlignStretch.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-AlignSt... ============================================================================== --- trunk/gtk/unstable/tests/Layout-AlignStretch.ycp (added) +++ trunk/gtk/unstable/tests/Layout-AlignStretch.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,15 @@ +// alignment (test case for inst_productsources bug) +{ +UI::OpenDialog( + `VBox( + `HBox( + `PushButton ("Fixed"), + `Bottom (`PushButton ("Test")) + ), + `VWeight( 1, `MultiLineEdit("Description", "bla bla") ) + ) +); +UI::UserInput(); +UI::CloseDialog(); +} + Added: trunk/gtk/unstable/tests/Layout-Expand.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Expand.... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Expand.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Expand.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,32 @@ +// Widgets expand and align +{ +// stand-alone +UI::OpenDialog( + `HBox( + `VBox ( + `MultiLineEdit ("Multi Line Edit", "some text"), + `PushButton ("Yes") + ), + `PushButton ("No") + ) + ); +UI::UserInput(); + +// on wizard +UI::OpenDialog( + `Wizard (`back, "&Back", `abort, "Ab&ort", `next, "&Next") + ); + +UI::ReplaceWidget (`id (`contents), + `HBox( + `VBox ( + `MultiLineEdit ("Multi Line Edit", "some text"), + `PushButton ("Yes") + ), + `PushButton ("No") + ) + ); + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-Frame2.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Frame2.... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Frame2.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Frame2.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,18 @@ +{ + UI::OpenDialog( `VBox( + `Frame ( `opt (`vstretch), "CPU &Speed", + `RadioButtonGroup( + `VBox( + `Left(`RadioButton("Normal" )), + `Left(`RadioButton("Overclocked" )), + `Left(`RadioButton("Red Hot" )), + `Left(`RadioButton("Melting", true )) + ) + ) + ), + `PushButton("&OK") + ) + ); + UI::UserInput(); + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-HVCenter-Align.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-HVCente... ============================================================================== --- trunk/gtk/unstable/tests/Layout-HVCenter-Align.ycp (added) +++ trunk/gtk/unstable/tests/Layout-HVCenter-Align.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,9 @@ +// HVCenter alignment test +{ +UI::OpenDialog( + `HVCenter (`ColoredLabel(`opt (`hstretch, `vstretch), "Hello, World!", `rgb (200, 0, 0), `rgb (200, 200, 50), 20)) +); + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-ReplacePoint.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Replace... ============================================================================== --- trunk/gtk/unstable/tests/Layout-ReplacePoint.ycp (added) +++ trunk/gtk/unstable/tests/Layout-ReplacePoint.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,13 @@ +// replacement stretchable test +{ +UI::OpenDialog( + `ReplacePoint (`id (`rp), `PushButton ("Push Me!")) +); + +UI::UserInput(); + +UI::ReplaceWidget (`rp, `MultiLineEdit ("", "I should be all stretched!")); + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-Split-Split.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Split-S... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Split-Split.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Split-Split.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,21 @@ +// Split in a split behavior +{ +UI::OpenDialog (`opt (`defaultsize), `HBox (`PushButton ("Okay"))); +UI::UserInput(); + +UI::OpenDialog (`opt (`defaultsize), `HBox (`PushButton ("Okay"), `VBox (`PushButton ("Nay"), `PushButton ("Pay")))); +UI::UserInput(); + +UI::OpenDialog(`opt (`defaultsize), `Wizard (`back, "&Back", `abort, "Ab&ort", `next, "&Next")); +UI::ReplaceWidget (`contents, `HBox (`VBox(`PushButton ("Okay")), `VBox (`PushButton ("Nay"), `PushButton ("Pay")))); +UI::UserInput(); + +UI::OpenDialog (`opt (`defaultsize), `VBox (`HBox (`VBox(`PushButton ("Okay")), `VBox (`PushButton ("Nay"), `PushButton ("Pay"))))); +UI::UserInput(); + +UI::OpenDialog (`opt (`defaultsize), `VBox (`HBox(`PushButton ("Okay")))); +UI::UserInput(); + +UI::OpenDialog (`opt (`defaultsize), `HBox (`VBox(`PushButton ("Okay")))); +UI::UserInput(); +} Added: trunk/gtk/unstable/tests/Layout-Truncated-Widget.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Truncat... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Truncated-Widget.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Truncated-Widget.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,43 @@ +// Let's create and destroy something + +{ + +list strings = + [ "What a long button I am :D", ":/" ]; +integer cur_string = 1; + +UI::OpenDialog + ( + `VBox + ( + `ReplacePoint(`id(`kill_replaceable), `PushButton( `id(`kill), + "I am a waste of space" )), + `PushButton( `id(`transform), select(strings, cur_string, nil) ), + `PushButton( `id(`quit), "Exit" ) + ) + ); + +any button_id = nil; + +while (true) + { + button_id = UI::UserInput(); + + if (button_id == `quit) + break; + + if (button_id == `transform) + { + cur_string = (cur_string + 1) % 2; + UI::ChangeWidget (`transform, `Label, select(strings, cur_string, nil)); + } + + if (button_id == `kill) + { + UI::ReplaceWidget (`kill_replaceable, `Empty()); + } + + + } +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-Wizard-BackgroundWidget.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Wizard-... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Wizard-BackgroundWidget.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Wizard-BackgroundWidget.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,15 @@ +// Widget with background on wizard +{ +UI::OpenDialog (`opt(`defaultsize), + `Wizard (`back, "&Back", `abort, "Ab&ort", `next, "&Next") + ); + + UI::ReplaceWidget (`contents, + `VBox ( + `HVCenter (`BackgroundPixmap ("wallpapers/welcome.jpg"), + `MultiLineEdit ("", "I should have a background around me.")) + ) + ); +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-Wizard-OneWidget.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Wizard-... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Wizard-OneWidget.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Wizard-OneWidget.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,13 @@ +// wizard, one widget test +{ +UI::OpenDialog( + `Wizard (`back, "&Back", `abort, "Ab&ort", `next, "&Next") +); + +UI::ReplaceWidget (`contents, `ColoredLabel(`opt (`hstretch, `vstretch), "Hello, World!", `rgb (200, 0, 0), `rgb (200, 200, 50), 20)); +// non-stretchable: +//UI::ReplaceWidget (`contents, `ColoredLabel("Hello, World!", `rgb (200, 0, 0), `rgb (200, 200, 50), 20)); + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Layout-Wizard3.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Layout-Wizard3... ============================================================================== --- trunk/gtk/unstable/tests/Layout-Wizard3.ycp (added) +++ trunk/gtk/unstable/tests/Layout-Wizard3.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,30 @@ +// The widget should get center aligned on wizard, but not ordinary dialogs +{ +// stand-alone +UI::OpenDialog( + `VBox( + `Heading ("Header"), + `VSpacing (0.5), + `Label ("This text should get on top") + ) + ); +UI::UserInput(); + +// on wizard +UI::OpenDialog( + `Wizard (`back, "&Back", `abort, "Ab&ort", `next, "&Next") + ); + + +UI::ReplaceWidget (`id (`contents), + `VBox( + `Heading ("Header"), + `VSpacing (0.5), + `Label ("This text should get centered") + ) + ); + + +UI::UserInput(); +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/MainDialogs.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/MainDialogs.yc... ============================================================================== --- trunk/gtk/unstable/tests/MainDialogs.ycp (added) +++ trunk/gtk/unstable/tests/MainDialogs.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,38 @@ +// This is a test for the usage of multiple main dialogs +// (that is with the defaultsize attribute). They should +// all share the same window. + +{ + UI::OpenDialog (`opt (`defaultsize), + `VBox ( + `Heading ("First dialog"), + `PushButton (`id (`next), "Next"), + `PushButton ("Close") + ) + ); + + while (UI::UserInput() == `next) { + UI::OpenDialog (`opt (`defaultsize), + `VBox ( + `Heading ("Second dialog"), + `PushButton (`id (`next), "Next"), + `PushButton ("Back") + ) + ); + + while (UI::UserInput() == `next) { + UI::OpenDialog (`opt (`defaultsize), + `VBox ( + `Heading ("Third dialog"), + `PushButton ("Close") + ) + ); + UI::UserInput(); + UI::CloseDialog(); + } + + UI::CloseDialog(); + } + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/MultiProgressMeterHuge.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/MultiProgressM... ============================================================================== --- trunk/gtk/unstable/tests/MultiProgressMeterHuge.ycp (added) +++ trunk/gtk/unstable/tests/MultiProgressMeterHuge.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,39 @@ +// Simple example for MultiProgressMeter +{ + if ( ! UI::HasSpecialWidget(`HMultiProgressMeter ) ) + { + UI::OpenDialog( + `VBox( + `Label("Error: This UI doesn't support the MultiProgressMeter widget!"), + `PushButton(`opt(`default), "&OK") + ) + ); + UI::UserInput(); + UI::CloseDialog(); + + return; + } + + + UI::OpenDialog( + `VBox( + `HMultiProgressMeter(`id(`prog), [ 10000, 200, 500, 20, 100 ] ), + `PushButton(`opt(`default), "&Ok" ) + ) + ); + + UI::ChangeWidget(`prog, `Values, [ 1000, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 800, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 500, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 200, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 200, 500, 20, 100 ] ); UI::UserInput(); + + UI::ChangeWidget(`prog, `Values, [ 0, 100, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 20, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 500, 20, 100 ] ); UI::UserInput(); + + UI::ChangeWidget(`prog, `Values, [ 0, 0, 400, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 300, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 200, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 100, 20, 100 ] ); UI::UserInput(); +} Added: trunk/gtk/unstable/tests/MultiProgressMeterVer.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/MultiProgressM... ============================================================================== --- trunk/gtk/unstable/tests/MultiProgressMeterVer.ycp (added) +++ trunk/gtk/unstable/tests/MultiProgressMeterVer.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,39 @@ +// Simple example for MultiProgressMeter +{ + if ( ! UI::HasSpecialWidget(`HMultiProgressMeter ) ) + { + UI::OpenDialog( + `VBox( + `Label("Error: This UI doesn't support the MultiProgressMeter widget!"), + `PushButton(`opt(`default), "&OK") + ) + ); + UI::UserInput(); + UI::CloseDialog(); + + return; + } + + + UI::OpenDialog( + `VBox( + `VMultiProgressMeter(`id(`prog), [ 100, 200, 500, 20, 100 ] ), + `PushButton(`opt(`default), "&Ok" ) + ) + ); + + UI::ChangeWidget(`prog, `Values, [ 1000, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 800, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 500, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 200, 200, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 200, 500, 20, 100 ] ); UI::UserInput(); + + UI::ChangeWidget(`prog, `Values, [ 0, 100, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 20, 500, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 500, 20, 100 ] ); UI::UserInput(); + + UI::ChangeWidget(`prog, `Values, [ 0, 0, 400, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 300, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 200, 20, 100 ] ); UI::UserInput(); + UI::ChangeWidget(`prog, `Values, [ 0, 0, 100, 20, 100 ] ); UI::UserInput(); +} Added: trunk/gtk/unstable/tests/MultiSelectionBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/MultiSelection... ============================================================================== --- trunk/gtk/unstable/tests/MultiSelectionBox.ycp (added) +++ trunk/gtk/unstable/tests/MultiSelectionBox.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,16 @@ +// MultiSelectionBox -- test notify flag +{ +list items = + [ "Spaghetti", "Steak Sandwich", "Chili", "Salami Baguette" ]; + +UI::OpenDialog ( + `MinSize (30, 10, + `MultiSelectionBox (`id(`list), `opt (`notify), + "Plates", items) + ) + ); + +UI::UserInput(); +UI::CloseDialog(); +} + Added: trunk/gtk/unstable/tests/ProgressPulse.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/ProgressPulse.... ============================================================================== --- trunk/gtk/unstable/tests/ProgressPulse.ycp (added) +++ trunk/gtk/unstable/tests/ProgressPulse.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,30 @@ +// Simple ProgressBar example +{ + integer max_progress = 0; + integer progress = 0; + + UI::OpenDialog( + `VBox( + `ProgressBar(`id(`pr), "Sample progress bar", max_progress, progress ), + `PushButton(`id(`next), "Next"), + `Right(`PushButton(`id(`close), "&Close" ) ) + ) + ); + + + while ( progress < 20 ) + { + symbol button = (symbol) UI::UserInput(); + + if ( button == `next ) + { + progress = progress + 1; + UI::ChangeWidget(`id(`pr), `Value, progress); + UI::ChangeWidget(`id(`pr), `Label, sformat("Progress %1 of %2", progress, max_progress )); + } + else if ( button == `close ) + break; + } + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/RichText1.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/RichText1.ycp?... ============================================================================== --- trunk/gtk/unstable/tests/RichText1.ycp (added) +++ trunk/gtk/unstable/tests/RichText1.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,26 @@ +// RichText test + +{ + UI::OpenDialog ( + `VBox ( + `RichText (`id (`rtext), ""), + `MultiLineEdit (`id (`source), `opt(`notify), "Source code", ""), + `PushButton (`id (`close), `opt(`default), "&Close") + ) + ); + + any ret = nil; + repeat + { + ret = UI::UserInput(); + + if (ret == `source) + { + UI::ChangeWidget (`id (`rtext), `Value, + (string) UI::QueryWidget(`id(`source), `Value)); + } + + } until (ret == `close || ret == `cancel); + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/RichText2.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/RichText2.ycp?... ============================================================================== --- trunk/gtk/unstable/tests/RichText2.ycp (added) +++ trunk/gtk/unstable/tests/RichText2.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,89 @@ +// RichText test (with a list of examples) +{ + list texts = [ + // simple + "<p><a href=\"nowhere\">Hello world!</a></p>", + "<h1>Operating Systems</h1><h2>Linux</h2> Suse", + + // the br & hr tags + "Drinking <u>ice</u> tea <br> <hr> is <b>good</b> for you.", + + // Broken end element + "Broken end element </ul> elided", + + // the li tags + "Things to do <li>foo <li>baa <li>baz.", + + // unclosed tags + "No outer tag<p>Unclosed paragraphs<p>several of them <b>unclosed bold</b>", + + // Some more complete text, with an image + "<center><h1><font color=blue>Super <font color=red>Man</font></font> " + + "to the rescue</h1></center><a " + + "href=http://en.wikipedia.org/wiki/Superman>Super Man</a> is a very " + + "estimated super hero in Metropolis, but he is looked down by others " + + "like mad scientists and politiceans. <img src=\"tests/image.gif\">", + + // table (from SlideShow) + "<table cellspacing=\"10\" cellpadding=\"5\">" + + "<tr>" + + "<td width =\"*\">" + + "<img src=\"/opt/gnome/share/icons/hicolor/32x32/apps/gnome-media-player.png\"" + + "width=\"100\" align=\"left\">" + + "</td>" + + "<td width=\"*\">" + + "<p><font color=\"#00007f\"><b>XMMS and JuK - Powerful Jukeboxes</b></font></p>" + + "<p>XMMS is an excellent sound player for Linux. It is easy to use and supports" + + "various formats, including audio CDs. Test the many visualization plug-ins or" + + "download your favorite XMMS skins from the web.</p>" + + "<p>New in KDE: JuK, which classifies your MP3s and organizes your music" + + "collection.</p>" + + "<p><b>Want More?</b></p>" + + "<p>The SUSE distribution features a wide range of applications for playing" + + "your CDs and MP3 songs. For example, KsCD is a user-friendly CD player. The" + + "track information for most CDs is available on the Internet. Simply activate" + + "the respective function to display the list.</p>" + + "</td>" + + "</tr>" + + "</table>" + ]; + + UI::OpenDialog ( + `VBox ( + `RichText (`id (`rtext), texts[0]:nil), + `MultiLineEdit (`id (`source), `opt(`notify), "Source code", texts[0]:nil), + `Label (`id(`link), `opt(`hstretch), ""), + `Slider (`id (`slider), `opt(`notify), "Test text case:", 0, size (texts)-1, 0), + `PushButton (`id (`close), `opt(`icon ("close")), "&Close") + ) + ); + + any ret = nil; + repeat + { + ret = UI::UserInput(); + + if (ret == `slider) + { + integer cur_text = (integer) UI::QueryWidget(`id(`slider), `Value ); + UI::ChangeWidget (`id (`source), `Value, texts[cur_text]:nil); + UI::ChangeWidget (`id (`rtext), `Value, texts[cur_text]:nil); + UI::ChangeWidget (`id(`link), `Value, ""); + } + + else if (ret == `source) + { + UI::ChangeWidget (`id (`rtext), `Value, + (string) UI::QueryWidget(`id(`source), `Value)); + } + + else + { // RichText doesn't seem to pass its id... + string url = sformat ("%1", ret); + UI::ChangeWidget (`id(`link), `Value, "You pressed: " + url); + } + + } until (ret == `close || ret == `cancel); + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/SelectionBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/SelectionBox.y... ============================================================================== --- trunk/gtk/unstable/tests/SelectionBox.ycp (added) +++ trunk/gtk/unstable/tests/SelectionBox.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,45 @@ +// SelectionBox change and lookup test +{ +list itemlist1 = + [ "Spaghetti", "Steak Sandwich", "Chili", "Salami Baguette" ]; + +list itemlist2 = + [ "Mercedes", "AUDI", "VW", "BMW", "Porsche" ]; + +list itemslists = [ itemlist1, itemlist2 ]; + +integer listnum = 0; + +UI::OpenDialog ( + `VBox ( + `MinSize (30, 10, + `SelectionBox (`id(`list), `opt (`immediate), + "Prices", itemlist1) + ), + `TextEntry (`id(`text), "Current item:", ""), + `Right ( + `HBox ( + `PushButton (`id (`next), "Change &List Contents"), + `PushButton (`id (`cancel), "&Close") + ) + ) + ) + ); + +any ret = nil; +while (ret != `cancel) { + ret = UI::UserInput(); + + if (ret == `next) { + listnum = 1 - listnum; + UI::ChangeWidget (`id(`list), `Items, select (itemslists, listnum, nil)); + } + + if (ret == `list) { + string item = (string) UI::QueryWidget(`id(`list), `CurrentItem); + UI::ChangeWidget (`id (`text), `Value, item); + } +} + +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/StockIcons.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/StockIcons.ycp... ============================================================================== --- trunk/gtk/unstable/tests/StockIcons.ycp (added) +++ trunk/gtk/unstable/tests/StockIcons.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,55 @@ +// Stock Icons test + +{ + list stock_icons = [ + "ok", + "cancel", + "abort", + "apply", + "about", + "connect", + "disconnect", + "edit", + "open", + "close", + "new", + "quit", + "print", + "save", + "save-as", + "yes", + "no", + + ]; + integer i = 0; + + UI::OpenDialog ( + `ReplacePoint (`id (`rp), + `PushButton (`opt (`icon (stock_icons[i]:nil)), stock_icons[i]:"") + ) + ); + + any ret = nil; + while (true) + { + ret = UI::TimeoutUserInput (1000); + + if (ret == `timeout) + { + i = i + 1; + if (i == size (stock_icons)) + break; + else + UI::ReplaceWidget (`rp, + `PushButton (`opt (`icon (stock_icons[i]:nil)), stock_icons[i]:"") + ); + UI::RecalcLayout(); + } + + else + break; + + }; + + UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/Table3-4.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Table3-4.ycp?r... ============================================================================== --- trunk/gtk/unstable/tests/Table3-4.ycp (added) +++ trunk/gtk/unstable/tests/Table3-4.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,68 @@ +// merge of Table3 and Table4 tests +{ +list itemlist1 = + [ `item(`id(3), "Spaghetti", 8), + `item(`id(4), "Steak Sandwich", 12), + `item(`id(1), "Chili", 6), + `item(`id(2), "Salami Baguette", nil) + ]; + +list itemlist2 = + [ `item(`id(0), "Mercedes", 60000), + `item(`id(1), "AUDI", 50000), + `item(`id(2), "VW", 40000), + `item(`id(3), "BMW", 60000), + `item(`id(3), "Porsche", 80000) + ]; + +list itemslists = [ itemlist1, itemlist2 ]; + +integer listnum = 0; + +UI::OpenDialog ( + `VBox ( + `Heading ("Prices"), + `MinSize (30, 10, + `Table (`id(`table), `header("Name", "price"), itemlist1) + ), + `Right ( + `HBox ( + `PushButton (`id (`lookup), "&Lookup"), + `PushButton (`id (`next), "Change &Table Contents"), + `PushButton (`id (`cancel), "&Close") + ) + ) + ) + ); + +any ret = nil; +while (ret != `cancel) { + ret = UI::UserInput(); + + if (ret == `next) { + listnum = 1 - listnum; + UI::ChangeWidget(`id(`table), `Items, select(itemslists, listnum, nil)); + } + + if (ret == `lookup) { + any id = UI::QueryWidget(`id(`table), `CurrentItem); + if (is(id, integer)) { + string text = sformat ( + "Line: %1", UI::QueryWidget(`id(`table), `Item(id))); + UI::OpenDialog ( + `MarginBox (1, 0.2, + `VBox ( + `Left (`Label ("Current Table Item")), + `Label(`opt(`outputField), text), + `PushButton("&OK") + ) + ) + ); + UI::UserInput(); + UI::CloseDialog(); + } + } +} + +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/TransientDialog.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/TransientDialo... ============================================================================== --- trunk/gtk/unstable/tests/TransientDialog.ycp (added) +++ trunk/gtk/unstable/tests/TransientDialog.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,24 @@ +{ + + +UI::OpenDialog (`opt (`defaultsize), `PushButton ("Button1")); +UI::TimeoutUserInput (4 * 1000); + +UI::OpenDialog (`opt (`defaultsize), `PushButton ("Button2")); +UI::TimeoutUserInput (4 * 1000); + +UI::OpenDialog (`PushButton ("Button")); +UI::TimeoutUserInput (4 * 1000); +} + +// simple +/* +{ +UI::OpenDialog (`opt (`defaultsize), `PushButton ("Button")); +UI::TimeoutUserInput (4 * 1000); + +UI::OpenDialog (`PushButton ("Button")); +UI::TimeoutUserInput (8 * 1000); +} +*/ + Added: trunk/gtk/unstable/tests/Tree3.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/Tree3.ycp?rev=... ============================================================================== --- trunk/gtk/unstable/tests/Tree3.ycp (added) +++ trunk/gtk/unstable/tests/Tree3.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,123 @@ +{ + // Build a dialog with a tree for directory selection, three + // buttons with common values and a label that directly echoes any + // selected directory. + // + // The tree in this example uses the `notify option that makes + // UI::UserInput() return immediately as soon as the user selects a + // tree item rather than the default behaviour which waits for the + // user to activate a button. + + UI::OpenDialog( + `MinWidth( 50, + `VBox( + `Tree(`id(`dest_dir), + `opt(`notify), + "Select destination directory:", + [ + `item( "/" , true, + [ + `item( "etc", + [ + `item("opt"), + `item("SuSEconfig"), + `item("X11") + ] + ), + `item( "usr", false, + [ + "bin", + "lib", + `item("share", + [ + "man", + "info", + "emacs" + ] + ), + `item( `id(`usr_local), "local" ), + `item("X11R6", + [ + "bin", + "lib", + "share", + "man", + "etc" + ] + ) + ] + ), + `item( `id(`opt), "opt", true, + [ + "kde", + "netscape", + "Office51" + ] + ), + `item("home"), + "work", + `item( "<other>") + ] + ) + ] ), + `HBox( + `PushButton(`id(`sel_opt), `opt(`hstretch), "/&opt" ), + `PushButton(`id(`sel_usr), `opt(`hstretch), "/&usr" ), + `PushButton(`id(`sel_usr_local), `opt(`hstretch), "/usr/&local" ) + ), + `HBox( + `HWeight( 2, `Label("Current Item:") ), + `HWeight( 5, `Label(`id(`echoItem), `opt(`outputField, `hstretch), "") ) + ), + `HBox( + `HWeight( 2, `Label("Current Branch:") ), + `HWeight( 5, `Label(`id(`echoBranch), `opt(`outputField, `hstretch), "") ) + ), + `HBox( + `HWeight( 2, `Label("Current Path:") ), + `HWeight( 5, `Label(`id(`echoPath), `opt(`outputField, `hstretch), "") ) + ), + `PushButton(`id(`ok), `opt(`default, `icon ("ok")), "&OK") + ) + ) + ); + + any id = nil; + + repeat + { + id = UI::UserInput(); + + if ( id == `sel_usr) UI::ChangeWidget( `id( `dest_dir ), `CurrentItem, "usr" ); + else if ( id == `sel_usr_local) UI::ChangeWidget( `id( `dest_dir ), `CurrentItem, `usr_local ); + else if ( id == `sel_opt) UI::ChangeWidget( `id( `dest_dir ), `CurrentItem, `opt ); + else if ( id == `dest_dir) + { + any current_dir = UI::QueryWidget(`dest_dir, `CurrentItem ); + + if ( current_dir != nil ) + UI::ChangeWidget( `id( `echoItem ), `Value, sformat( "%1", current_dir ) ); + + list<string> current_branch = (list<string>) UI::QueryWidget(`dest_dir, `CurrentBranch ); + + if ( current_branch != nil ) + { + UI::ChangeWidget(`echoBranch, `Value, sformat( "%1", current_branch) ); + + string current_path = mergestring( current_branch, "/" ); + if ( size( current_path ) > 2 ) + // Remove duplicate "/" at start + current_path = substring( current_path, 1, size( current_path )-1 ); + + UI::ChangeWidget(`echoPath, `Value, sformat( "%1", current_path ) ); + } + } + + } until ( id == `ok ); + + + // Close the dialog. + // Remember to read values from the dialog's widgets BEFORE closing it! + UI::CloseDialog(); + +} Added: trunk/gtk/unstable/tests/WizardList.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/WizardList.ycp... ============================================================================== --- trunk/gtk/unstable/tests/WizardList.ycp (added) +++ trunk/gtk/unstable/tests/WizardList.ycp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,33 @@ +{ +UI::OpenDialog( + `Wizard (`opt (`treeEnabled), + `back, "", `cancel, "", `cancel, "&Exit") + ); + +UI::WizardCommand (`AddTreeItem ("", "Computer", "computer")); +UI::WizardCommand (`AddTreeItem ("computer", "Hardware", "hardware")); +UI::WizardCommand (`AddTreeItem ("hardware", "CPU", "cpu@hardware")); +UI::WizardCommand (`AddTreeItem ("cpu@hardware", "MMU", "mmu")); +UI::WizardCommand (`AddTreeItem ("hardware", "RAM", "ram@hardware")); +UI::WizardCommand (`AddTreeItem ("computer", "Software", "software")); + +any ret = nil; +repeat { + ret = UI::UserInput(); + + string selected = (string) UI::QueryWidget (`id(`wizard), `CurrentItem ); + + if (selected == "mmu") { + UI::ReplaceWidget (`id (`contents), + `Label ("MMU setup") + ); + } + if (selected == "ram@hardware") { + UI::ReplaceWidget (`id (`contents), + `Label ("RAM setup") + ); + } +} until (ret == `cancel); + +UI::CloseDialog(); +} Added: trunk/gtk/unstable/tests/image.gif URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/image.gif?rev=... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie-endless.mng-old URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie-endless.... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie1.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie1.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie2.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie2.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie3.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie3.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie4.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie4.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie5.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie5.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie6.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie6.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie7.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie7.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/tests/movie8.mng URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/tests/movie8.mng?rev... ============================================================================== Binary file - no diff available. Added: trunk/gtk/unstable/ycc/Makefile URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/ycc/Makefile?rev=425... ============================================================================== --- trunk/gtk/unstable/ycc/Makefile (added) +++ trunk/gtk/unstable/ycc/Makefile Thu Nov 29 18:22:01 2007 @@ -0,0 +1,16 @@ +# Yast Control Center (Yast-GTK) + +CC = g++ +CFLAGS = -Wall `pkg-config gtk+-2.0 --cflags` +LIBS =`pkg-config gtk+-2.0 --libs` + +all: ycc-gtk + +ycc.o: ycc.cpp + $(CC) $(CFLAGS) ycc.cpp -c -o ycc.o + +ycc-gtk: ycc.o + $(CC) $(LIBS) ycc.o -o ycc-gtk + +clean: + rm -f *.o *~ ycc-gtk Added: trunk/gtk/unstable/ycc/ycc.cpp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable/ycc/ycc.cpp?rev=4251... ============================================================================== --- trunk/gtk/unstable/ycc/ycc.cpp (added) +++ trunk/gtk/unstable/ycc/ycc.cpp Thu Nov 29 18:22:01 2007 @@ -0,0 +1,269 @@ +/* Yast Control Center (Yast-GTK) */ + +#include <string> +#include <set> +#include <map> +#include <list> +#include <gtk/gtk.h> +#include <stdlib.h> +#include <string.h> + +/* Definitions */ +#define YAST_GROUPS "/usr/share/applications/YaST2/groups/" +#define YAST_ENTRIES "/usr/share/applications/YaST2/" +#define ICONS "/usr/share/YaST2/theme/current/icons/32x32/apps/" + +/* Globals */ +static GtkWidget *window; + +/* Get all names of files in a certain directory. */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> + +std::set<std::string> subfiles(const std::string& path) { + DIR *dirStructP; + struct dirent *direntp; + std::set <std::string> sfiles; + + if((dirStructP = opendir(path.c_str())) != NULL) { + while((direntp = readdir(dirStructP)) != NULL) { + std::string filename; + struct stat buf; + filename = path + "/" + direntp->d_name; + + if(std::string (direntp->d_name) == "." || + std::string (direntp->d_name) == "..") + continue; // ignore . and .. directories + + if (stat(filename.c_str(), &buf) == 0 && S_ISREG(buf.st_mode)) + sfiles.insert(direntp->d_name); + } + closedir(dirStructP); + } + return sfiles; +} + +/* Erase everything from the given characters. */ +void erase_from (std::string &str, const std::string &chars) +{ + for (unsigned int i = 0; i < chars.length(); i++) { + std::string::size_type pos; + pos = str.find (chars[i], 0); + if (pos != std::string::npos) + str.erase (pos); + } +} + +/* The widget with the icons. */ +class View { + GtkWidget *m_widget; + GtkAdjustment *adjustment; + std::map <std::string, GtkListStore*> m_stores; + std::list <std::string> sort_keys; + +public: + View() + { + m_widget = gtk_notebook_new(); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (m_widget), GTK_POS_LEFT); + } + + ~View() {} + + GtkWidget *getWidget() + { return m_widget; } + + void addGroup (const gchar *name, const gchar *icon_path, + const gchar *nick, const gchar *sort_key) + { + // calculate position + int pos; + { + std::list <std::string>::iterator it; + for (it = sort_keys.begin(), pos = 0; it != sort_keys.end(); it++, pos++) + if (strcmp (it->c_str(), sort_key) >= 0) + break; + sort_keys.insert (it, sort_key); + } + + // label widget + GtkWidget *tab_label, *image, *label; + + GdkPixbuf *icon = NULL; + if (icon_path) { + GError *error = 0; + std::string path = ICONS + std::string (icon_path) + ".png"; + icon = gdk_pixbuf_new_from_file (path.c_str(), &error); + if (!icon) + g_warning ("Could not load icon: %s.\nReason: %s", icon_path, error->message); + } + + tab_label = gtk_hbox_new (FALSE, 0); + label = gtk_label_new (name); + if (icon) + image = gtk_image_new_from_pixbuf (icon); + + if (icon) + gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, icon ? 6 : 0); + + // page widget + GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING); + m_stores [nick] = store; + + GtkWidget *icons_view; + icons_view = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_icon_view_set_text_column (GTK_ICON_VIEW (icons_view), 0); + gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icons_view), 1); + g_signal_connect(G_OBJECT (icons_view), "item-activated", + G_CALLBACK (executeCommand), this); + + GtkWidget *page; + page = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (page), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (page), icons_view); + + // add those to the notebook + gtk_widget_show_all (tab_label); + gtk_notebook_insert_page_menu (GTK_NOTEBOOK (m_widget), page, tab_label, NULL, pos); + } + + void addEntry (const gchar *group, const gchar *name, + const gchar *icon_path, const gchar *execute) + { + GtkListStore *store = m_stores [group]; + if (!store) { + g_warning ("Didn't find group '%s' for entry '%s'.", group, name); + return; + } + + GdkPixbuf *icon = NULL; + if (icon_path) { + GError *error = 0; + std::string path = ICONS + std::string (icon_path) + ".png"; + icon = gdk_pixbuf_new_from_file (path.c_str(), &error); + if (!icon) + g_warning ("Could not load icon: %s.\nReason: %s", icon_path, error->message); + } + + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, name, 1, icon, 2, execute, -1); + } + + static void executeCommand (GtkIconView *iconview, GtkTreePath *path, View *pThis) + { + GtkTreeModel *model = gtk_icon_view_get_model (iconview); + GtkTreeIter iter; + if (gtk_tree_model_get_iter (model, &iter, path)) { + gchar *command_; + gtk_tree_model_get (model, &iter, 2, &command_, -1); + + std::string command = command_; + g_free (command_); + + command += " &"; + printf ("running %s\n", command.c_str()); + system (command.c_str()); + + static GdkCursor *cursor = NULL; + if (!cursor) { + GdkDisplay *display = gtk_widget_get_display (window); + cursor = gdk_cursor_new_for_display (display, GDK_WATCH); + } + gdk_window_set_cursor (window->window, cursor); + g_timeout_add (1500, set_normal_cursor_cb, NULL); + } + } + + static gboolean set_normal_cursor_cb (gpointer data) + { + gdk_window_set_cursor (window->window, NULL); + return FALSE; + } +}; + +/* Main code */ +int main(int argc, char* argv[]) +{ + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "Suse Control Center"); + gtk_window_set_default_size (GTK_WINDOW (window), 650, 400); + g_signal_connect(G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); + + bool is_root = getuid () == 0; + + View view; + { // adding groups + GKeyFile *file = g_key_file_new(); + std::set <std::string> groups = subfiles (YAST_GROUPS); + for (std::set <std::string>::iterator it = groups.begin(); + it != groups.end(); it++) { + if (!g_key_file_load_from_file (file, (YAST_GROUPS + (*it)).c_str(), + G_KEY_FILE_NONE, NULL)) + continue; + + gchar* name = g_key_file_get_locale_string (file, "Desktop Entry", "Name", 0, NULL); + gchar *nick = g_key_file_get_string (file, "Desktop Entry", "X-SuSE-YaST-Group", NULL); + gchar *icon = g_key_file_get_string (file, "Desktop Entry", "Icon", NULL); + gchar *sort_key = g_key_file_get_string (file, "Desktop Entry", + "X-SuSE-YaST-SortKey", NULL); + if (name && nick) + view.addGroup (name, icon, nick, sort_key); + + if (name) g_free (name); + if (nick) g_free (nick); + if (icon) g_free (icon); + if (sort_key) g_free (sort_key); + } + g_key_file_free (file); + } + { // adding entries + GKeyFile *file = g_key_file_new(); + std::set <std::string> entries = subfiles (YAST_ENTRIES); + for (std::set <std::string>::iterator it = entries.begin(); + it != entries.end(); it++) { + if (!g_key_file_load_from_file (file, (YAST_ENTRIES + (*it)).c_str(), + G_KEY_FILE_NONE, NULL)) + continue; + + gchar *group = g_key_file_get_string (file, "Desktop Entry", "X-SuSE-YaST-Group", NULL); + gchar* name = g_key_file_get_locale_string (file, "Desktop Entry", "Name", 0, NULL); + gchar *icon = g_key_file_get_string (file, "Desktop Entry", "Icon", NULL); + gchar *command = g_key_file_get_string (file, "Desktop Entry", "Exec", NULL); + gboolean needs_root = g_key_file_get_boolean (file, "Desktop Entry", + "X-SuSE-YaST-RootOnly", NULL); + + if (group && name && command && (!needs_root || is_root)) + view.addEntry (group, name, icon, command); + + if (group) g_free (group); + if (name) g_free (name); + if (icon) g_free (icon); + if (command) g_free (command); + } + g_key_file_free (file); + } + + gtk_container_add (GTK_CONTAINER (window), view.getWidget()); + gtk_widget_show_all (window); + + if (!is_root) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GtkDialogFlags (0), GTK_MESSAGE_INFO, GTK_BUTTONS_OK, + "You are executing the control center as an ordinary user.\n" + "Only a few modules will be available."); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + + gtk_main(); + return 0; +} -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org