YaST Commits
Threads by month
- ----- 2024 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
November 2009
- 38 participants
- 1224 discussions
![](https://seccdn.libravatar.org/avatar/d95f774280866d45941b1365718208ff.jpg?s=120&d=mm&r=g)
[yast-commit] r59809 - in /branches/SuSE-Code-11-SP1-Branch/yast2: library/types/src/Hostname.ycp package/yast2.changes
by kmachalkova@svn.opensuse.org 26 Nov '09
by kmachalkova@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: kmachalkova
Date: Thu Nov 26 18:22:27 2009
New Revision: 59809
URL: http://svn.opensuse.org/viewcvs/yast?rev=59809&view=rev
Log:
strip trailing \n correctly
Modified:
branches/SuSE-Code-11-SP1-Branch/yast2/library/types/src/Hostname.ycp
branches/SuSE-Code-11-SP1-Branch/yast2/package/yast2.changes
Modified: branches/SuSE-Code-11-SP1-Branch/yast2/library/types/src/Hostname.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/yast2…
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/yast2/library/types/src/Hostname.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/yast2/library/types/src/Hostname.ycp Thu Nov 26 18:22:27 2009
@@ -155,9 +155,11 @@
}
else
{
- fqhostname = String::FirstChunk( hostname_data["stdout"]:"", "\n");
+ fqhostname = hostname_data["stdout"]:"";
}
+ fqhostname = String::FirstChunk( fqhostname, "\n");
+
y2debug("Current FQDN: %1", fqhostname);
return fqhostname;
}
Modified: branches/SuSE-Code-11-SP1-Branch/yast2/package/yast2.changes
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/yast2…
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/yast2/package/yast2.changes (original)
+++ branches/SuSE-Code-11-SP1-Branch/yast2/package/yast2.changes Thu Nov 26 18:22:27 2009
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Thu Nov 26 18:10:42 CET 2009 - kmachalkova(a)suse.cz
+
+- Fixed striping trailing \n from Hostname::CurrentHostname()
+ (bnc#553213)
+
+-------------------------------------------------------------------
Thu Nov 26 13:40:24 CET 2009 - locilka(a)suse.cz
- Fixed access rights for /etc/install.inf (bnc #500124)
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
Author: rpmcruz
Date: Thu Nov 26 18:22:11 2009
New Revision: 59808
URL: http://svn.opensuse.org/viewcvs/yast?rev=59808&view=rev
Log:
* Reverted to development state.
Added:
trunk/gtk/Makefile
Added: trunk/gtk/Makefile
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/Makefile?rev=59808&view=auto
==============================================================================
--- trunk/gtk/Makefile (added)
+++ trunk/gtk/Makefile Thu Nov 26 18:22:11 2009
@@ -0,0 +1,21 @@
+# Makefile meant only for convenience and to provide a nicer
+# interface for the newcomer.
+
+all:
+ make -f Makefile.cvs
+
+install:
+ make -f Makefile.cvs install
+
+clean:
+ rm -rf build
+
+package:
+ cd build ; make package_source
+ mv build/*.tar.bz2 build/package/* package
+
+test:
+ build/src/test
+
+.PHONY: all install clean package test
+
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
Author: rpmcruz
Date: Thu Nov 26 18:18:31 2009
New Revision: 59807
URL: http://svn.opensuse.org/viewcvs/yast?rev=59807&view=rev
Log:
* Reverted to development state.
Added:
trunk/gtk/CMakeLists.txt
trunk/gtk/VERSION.cmake
trunk/gtk/config.h.cmake
Removed:
trunk/gtk/NEWS
trunk/gtk/POTFILES
trunk/gtk/SUBDIRS
trunk/gtk/VERSION
trunk/gtk/autodocs-cc-base.ami
trunk/gtk/autodocs-cc-off.ami
trunk/gtk/autodocs-cc.ami
trunk/gtk/autodocs-ycp.ami
trunk/gtk/autogen.sh
trunk/gtk/configure.in.in
trunk/gtk/gtkize-iso
trunk/gtk/libtool.m4
trunk/gtk/ltoptions.m4
trunk/gtk/ltsugar.m4
trunk/gtk/ltversion.m4
trunk/gtk/lt~obsolete.m4
trunk/gtk/pluglib-bindings.ami
trunk/gtk/test.sh
trunk/gtk/ycc.sh
Modified:
trunk/gtk/ChangeLog
trunk/gtk/Makefile.cvs
trunk/gtk/README
trunk/gtk/TODO
trunk/gtk/yast2-gtk.spec.in
Added: trunk/gtk/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/CMakeLists.txt?rev=59807&vie…
==============================================================================
--- trunk/gtk/CMakeLists.txt (added)
+++ trunk/gtk/CMakeLists.txt Thu Nov 26 18:18:31 2009
@@ -0,0 +1,53 @@
+# cmake 2.6 requires this
+cmake_minimum_required (VERSION 2.4)
+
+project (yast2-gtk)
+
+## configure
+
+# we bundle our own FindGTK2.cmake while it isn't shipped with cmake
+set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/modules")
+
+find_package (GTK2 REQUIRED gtk)
+find_package (Libyui REQUIRED)
+find_package (Zypp REQUIRED)
+
+# debug while GTK2 support is shaky
+message (STATUS "GTK2 includes:" ${GTK2_INCLUDE_DIRS})
+message (STATUS "GTK2 libraries:" ${GTK2_LIBRARIES})
+
+# set libyui and libzypp versions
+execute_process (COMMAND pkg-config --modversion yast2-libyui COMMAND awk -F. "{ printf \"%d\", ($1 * 1000 + $2) * 1000 + $3;}" OUTPUT_VARIABLE YAST2_VERSION)
+if (NOT YAST2_VERSION)
+ message (FATAL_ERROR "Could not parse YaST2 (libyui) version.")
+endif (NOT YAST2_VERSION)
+
+execute_process (COMMAND pkg-config --modversion libzypp COMMAND awk -F. "{ printf \"%d\", ($1 * 1000 + $2) * 1000 + $3;}" OUTPUT_VARIABLE ZYPP_VERSION)
+if (NOT ZYPP_VERSION)
+ message (FATAL_ERROR "Could not parse Zypp version.")
+endif (NOT ZYPP_VERSION)
+
+set (CMAKE_MODULE_PATH "${CMAKE_INSTALL_PREFIX}/share/YaST2/data/devtools/cmake/modules" ${CMAKE_MODULE_PATH})
+include (YastCommon)
+set (YAST_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/include/YaST2)
+
+set (DATADIR ${CMAKE_INSTALL_PREFIX}/share/YaST2/gtk/)
+set (LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/YaST2/locale)
+set (THEMEDIR ${CMAKE_INSTALL_PREFIX}/share/YaST2/theme/current)
+
+# create config.h (see config.h.cmake)
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+## gcc flags
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Woverloaded-virtual -Wno-deprecated")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall")
+set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
+
+## make package
+
+set (RPMNAME "yast2-gtk")
+generate_packaging (${RPMNAME} ${VERSION})
+
+add_subdirectory (src)
+
Modified: trunk/gtk/ChangeLog
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/ChangeLog?rev=59807&r1=59806…
==============================================================================
--- trunk/gtk/ChangeLog (original)
+++ trunk/gtk/ChangeLog Thu Nov 26 18:18:31 2009
@@ -1,11 +1,453 @@
-2009-07-18 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+2009-10-26 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
- * src/yzyppwrapper.cc: bug fix 504424: don't crash on empty
- Package::group().
+ * Reverted to development state.
-2009-03-11 Martin Kudlvasr <mkudlvasr(a)novell.com>
+ * src/YGPackageSelector.cc: some UI changes to
+ try out.
+
+2009-10-15 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/pkg/YGPackageSelector.cc: bug fix 547075
+ (or part of): popup confirm dialog, rather than
+ having the user to double-click apply button.
+
+ * src/pkg/YGPackageSelector.cc: don't disable
+ installed tab on repositories view.
+
+ * src/pkg/YGPackageSelector.cc: removed Uncouple
+ button.
+
+ * src/pkg/YGPackageSelector.cc: disable version
+ action button if the action is already undertaken.
+
+2009-10-15 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/pkg/ygtkzyppview.cc: improved speed up fix:
+ only query libzypp when respective expander is open.
+
+ * src/pkg/yzyppwrapper.cc: don't suffix "B" to
+ size string: it seems libzypp now does that.
+
+ * src/pkg/YGPackageSelector.cc: bug fix: honor
+ GtkStyle on whether to show repositories "Edit..."
+ button icon.
+
+ * src/CMakeLists.txt & src/pkg/CMakeLists.txt:
+ changes juridiction over a few widgets used
+ exclusively by the pkg component. (to cut on
+ py2gtk.so size)
+
+ * src/ygtkhtmlwrap.h/c: changed gpointer casting
+ to proper callback definition.
+
+ * src/ygtkrichtext.h/c: split up set_text() into
+ set_plain_text().
+
+2009-10-13 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/pkg/ygtkzyppview.cc: only apply speed up fix
+ for big text streams (above 20Kb) since it may
+ cause flicker.
+
+2009-10-13 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/pkg/ygtkzyppview.cc: speed up fix: quick hack
+ so we only set file-list text (which can be very long
+ and take many seconds on some packages: e.g. kernel-*)
+ when expander is open.
+ In the future, call zypp's filelist() when needed since
+ that can take a few seconds as well.
+
+2009-10-04 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * Ported build system from autotools to cmake.
+
+2009-09-30 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/yzypptags.h/cc: bug fix: a couple mapping errors
+ of PackageKit categories.
+
+ * src/yzyppwrapper.cc: speed fix: improved startup
+ speed by both mapping categories when needed and
+ improving the mapping performance as well.
+
+2009-09-30 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.h/cc: map package text-view details
+ scrolling to the view-port they are installed on.
+
+2009-09-24 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/yzyppwrapper.cc: made compilable for 11.1 libzypp
+ version 5.24.5.
+
+2009-09-24 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.cc: bug fix: pass USERNAME for gnomesu
+ not USER.
+
+ * src/YGPackageSelector.cc & src/ygtkzyppview.cc/h: look fix:
+ reserve empty space for online_update installed tab.
+
+ * src/ygtknotebook.c: bug fix: search entry wasn't well aligned
+ under some settings.
+
+2009-09-23 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.cc: bug fix: pkg-selector dir links
+ not working.
+
+2009-09-23 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.cc: speed fix: don't load packages at
+ initialization for online_update.
+
+2009-09-23 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGDumbTab.cc: changed calling order of parent
+ class to reflect yast2-qt (to prevent any bug).
+
+ * src/YGTable.cc: bug fix: block GtkTreeSelection events not
+ only on init, but on only instances when the widget is
+ mapped. Fixes bootloader tab change misbehavior on 11.2.
+
+ * src/YGUtils.cc: bug fix: comply with desktop settings to
+ not show icons on buttons, as in 11.2.
+
+ * src/ygtknotebook.c: bug fix: delete corner child on
+ destructor. Fixes 11.2 sw_single crash on exit.
+
+ * src/yzypptags.cc: speed up sw_single initialization time.
+
+ * src/ygtkzyppview.cc: look fix: when icons on buttons are
+ disabled, show "Undo" as a label instead of as an icon.
+
+ * src/YGPackageSelector.cc: bug fix: only set Undo tab
+ to confirm when the user has not uncoupled it.
+
+ * src/YGPackageSelector.cc: give initial focus to search
+ entry.
+
+2009-09-22 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/yzypptags.h/cc: -qt PK groups was not caughting
+ documentation and productivity branches.
+
+2009-09-22 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.h/cc: fix: make double-click working on
+ remove and undo tabs.
+
+ * src/ygtkzyppview.cc: fix: refresh version control on
+ package change.
+
+ * src/yzyppwrapper.h/cc: PkgList::add/removeListener()
+ now (fake) const.
+
+2009-09-21 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * tests/Layout-Truncated-Widget.ycp: uncovered difference
+ in our layout mechanism to qt's. We may want to address this
+ in the future.
+
+ * src/YGDialog.cc: increased default size.
+
+ * src/YGDialog.cc: don't tell GTK to change cursor to the one
+ already in use.
+
+ * src/YGPackageSelector.cc, src/YGUI.h/cc: moved statment of
+ software manager default size here.
+
+ * src/ygtkbargraph.h/c: make it inherit from GtkFrame, and
+ changed frame look.
+
+ * src/ygtkratiobox.c: make use of GtkContainer's border_width
+ and make last widget take rest of the size.
+
+ * src/ygtkrichtext.c & src/ygtktextview.c: instead of
+ selecting link on right-click, make it select any word under
+ the mouse cursor.
+
+ * src/ygtksteps.h/c: look more yast2-qt: adopted qt's mark
+ glyphs and added glyphs for todo tasks.
+
+ * src/ygtkzyppview.cc: touched up run Firefox as user logic.
+
+2009-09-14 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: disable install tab when
+ searching for files.
+
+ * src/YGPackageSelector.cc: change title only when done.
+
+ * src/YGPackageSelector.cc: change expand properties to
+ Upgrade tab columns.
+
+2009-09-14 Katarina Machalkova <kmachalkova(a)suse.cz>
+
+ * src/YGUI.cc: initialize Gtk stuff in ctor if we're running
+ without threads. This enables standalone libyui, where
+ with_threads=false use Gtk interface (thanks mmeeks for help)
+
+2009-09-13 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: bug fix: repository selection not
+ unset on filter change.
+
+ * src/YGPackageSelector.cc: place startup progress-bar on the
+ same place as ycp's.
+
+2009-09-13 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: removed "filter by novelty" from
+ search (pass --novelty-filter to enable it) and moved it as
+ the Groups item "Fresh".
+
+2009-09-10 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkfindentry.c: bug fix: on resize find and erase
+ icons disapear (unrealize not implemented).
+
+2009-09-10 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkcellrendererbutton.c: look more like a button
+ when pressed.
+
+ * src/YGUI.h, src/YGMenuButton.cc & src/YGTable.cc: make
+ compilable with latest libyui.
+
+ * src/YGUI.h/cc & src/YGDialog.cc: ensure to be more generous
+ to sw_single window from the start.
+
+2009-09-10 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkcellrendererbutton.h/c: a push-button for lists.
+
+ * src/ygtkcellrenderertextpixbuf.h/c: added stock icon
+ options, and fixed x/ypadding.
+
+ * src/YGUI.h/cc & src/YGPackageSelector.cc: pass arguments for
+ PkgSelector so we can let people experiment with new looks at
+ run-time. Try:
+ /usr/lib/YaST2/bin/y2base sw_single gtk --find-pane --buttons
+
+ * src/ygtkzyppview.h/cc: added button column.
+
+2009-09-07 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
- * Version 2.17.13
+ * src/ygtknotebook.cc: handle right-to-left text flow:
+ thank Michael for the reminder.
+
+ * src/ygtkzyppview.cc: bug fix 523694: find a way to
+ fire the browser as the session's user.
+
+ * src/yzyppwrapper.cc: bug fix: online_update: was reporting
+ available patches as already installed on version box.
+
+2009-09-07 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.cc: select installed version radio
+ button for the remove tab.
+
+2009-09-06 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/yzyppwrapper.h/cc: added severity() description
+ to Package structure.
+
+ * src/YGPackageSelector.cc: split online_update list by
+ severity.
+
+ * src/ygtkzyppview.cc: bug fix: show "applies to" list.
+
+2009-09-06 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGTable.cc: bug fix 513085: block selection was too
+ ambitious.
+
+ * src/YGUtils.cc: fixed flicker from scrolling text
+ widgets like LogView.
+
+2009-09-06 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppview.h/cc & src/YGPackageSelector.cc: use
+ "xpad" instead of italic fonts for 'auto' packages.
+
+2009-09-06 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGUtils.cc: map stock icons for enable/disable.
+
+ * src/ygtkfindentry.c: look: center-align menu arrow.
+
+ * src/ygtkzyppview.cc: bug fix: "upgrade all" was alternating
+ the check boxes instead of simply setting all true.
+
+2009-09-06 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtktooltip.h/c: re-added tooltip window.
+
+ * src/ygtknotebook.h/c: sub-notebook that allows a widget to be
+ installed at the empty top-right corner.
+
+ * src/YGPackageSelector.cc: replaced find pane by a find entry
+ at the tab-book corner.
+
+ * src/yzyppwrapper.h/cc: bug fix: highlight broken for sub-queries:
+ now pass Package to highlight() instead of index.
+
+ * src/yzyppwrapper.h/cc: replaced explicit PkgList::refreshProps()
+ for an implicit call when a package in the list is modified.
+
+2009-09-04 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: fixes for online_update.
+
+ * src/ygtkzyppwrapper.cc: touched up Patch contents box.
+
+ * src/yzyppwrapper.h/cc: got rid of setPkgListener. Instead
+ use the listeners from PkgList.
+
+ * src/yzyppwrapper.cc: some fixes on support of patches:
+ installed status and version rank.
+
+2009-09-04 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: use a common pool for all tabs
+ so to make it a snap to change tabs.
+
+ * src/ygtkzyppview.h/cc: turned Package & Detail views into
+ GTK widgets so we don't have to bother with mem management.
+
+ * src/ygtkwizard.c: gtk_object_destroy() -> g_object_finalize();
+ not sure what the difference is, but latter seems more used.
+
+ * src/yzyppwrapper.h/cc: allow multiple listeners for PkgList.
+ bug fix: versions on the detail box now reflect any pkg changes.
+
+2009-09-03 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/icons/pkg-tiles-mode.xpm & pkg-list-mode.xpm:
+ removed.
+
+ * src/YGPackageSelector.cc: when exact package found,
+ highlight respective tab.
+
+ * src/YGPackageSelector.cc: replaced the undo tab by the
+ confirmation dialog widgetry.
+
+ * src/ygtkwizard.c: enlarged help window.
+
+ * src/ygtkzyppview.h/cc: switched remove tab default toggles.
+
+ * src/yzyppwrapper.h/cc: added whole_string option to
+ PkgQuery::Query.
+
+ * src/ygtkzyppview.h/cc: re-aligned description and version
+ control boxes.
+
+ * src/yzyppwrapper/cc: reduced busy tolerance from 50ms to 30ms
+ for 500 loops.
+
+ * src/YGPackageSelector.cc: set tooltips on tab labels.
+
+2009-09-02 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtktreemodel.h/cc: nice wrapper for GtkTreeModel.
+
+ * src/yzyppview.h/cc: moved PackagesView and PackageDetails
+ here. Re-worked the model: in particular, added support for
+ multiple lists and apply all entry.
+
+ * src/YGPackageSelector.cc: made use of new PackagesView
+ functionality: in particular, split out undo tab.
+
+ * src/YGPackageSelector.cc: added confirmation dialog on
+ apply.
+
+ * src/YGPackageSelector.cc: added progress bar.
+
+ * src/yzyppwrapper.h/.cc: PkgList now a vector: much nicer
+ for the multiple lists enable model.
+
+ * src/yzyppwrapper.h/.cc: added progress bar signal.
+
+ * src/ygtkwizard.c: fixed set_child().
+
+ * src/YGMenuButton.cc: implemented new YGContextMenu.
+
+ * src/YGUI.h: respective hook for YGContextMenu.
+
+ * src/YGTable.cc: respective context-menu signals.
+
+ * src/YGWidget.cc: emitEvent(): contain context-menu signals
+ to flags notifyContextMenu().
+
+ * src/YGUtils.cc: bug fix 446524: complement our label mapping
+ strategy with an array of translatable yast2 labels.
+
+ * src/ygtksteps.c: bug fix 471059: ignore style: force black
+ color on the text (since our background is white).
+
+ * src/ygtkwizard.c: use stock image for help button: copes
+ with style change.
+
+ * src/yzyppwrapper.h/.c: added canRemove() property to
+ packages, and extended PkgList.
+
+ * src/yzyppview.cc: bug fix 489016: don't show lock&remove
+ buttons for patterns.
+
+2009-08-29 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/yzyppwrapper.h/.cc: split up Package::support()
+
+ * src/YGPackageSelector.cc: touched up support expander on details.
+
+ * src/YGPackageSelector.cc: made list-details box move horizontal
+ on large widescreens.
+
+ * src/pkg-selector-help.h: touched to reflect UI changes.
+
+ * src/YGPackageSelector.cc: split selector-help in small pieces.
+
+2009-08-29 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtkzyppwrapper.h/.cc: more column properties.
+
+ * src/YGPackageSelector.cc: gray-out tabs for which the query
+ is not applicable (e.g. can't find for files on available view
+ for technical limitations).
+
+ * src/YGPackageSelector.cc: replaced old pattern suggestion tooltip
+ for a label in the search pane.
+
+2009-08-29 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/YGPackageSelector.cc: show installed and candidate versions
+ for the upgrades view.
+
+ * src/ygtkzyppwrapper.h/.cc: more column properties.
+
+ * src/yzyppwrapper.h/.cc: commented out installed and last build info
+ from the description box. (maybe show as tooltips for the versions enum?)
+
+2009-08-28 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+
+ * src/ygtktreeview.h/.c: moved from ygtkscrolledwindow.h to its
+ rightful file.
+
+ * src/yzyppwrapper.h/.cc: some big re-work: most interestingly,
+ integrated PkgList from YGPackageSelector.cc into the Pool structure.
+
+ * src/ygtkzyppwrapper.h/.cc: more column properties.
+
+ * src/YGPackageSelector.cc: preliminrary major changes to the UI as
+ discussed with the other devs. Special thanks to Christian Jager
+ <christian.jaeger(a)rub.de>.
+
+2009-03-18 Martin Kudlvasr <mkudlvasr(a)novell.com>
+
+ * tests/ButtonOrder.ycp added test to see button order heuristic
+ behaviour (bnc#479874)
2009-03-11 Martin Kudlvasr <mkudlvasr(a)novell.com>
@@ -20,22 +462,18 @@
* add tests/MultiLine.ycp for bnc#459657
* src/YGText.cc: overload doSetEnabled for YGMultiLineEdit
-2009-02-19 Martin Kudlvasr <mkudlvasr(a)novell.com>
+2009-02-26 Martin Kudlvasr <mkudlvasr(a)novell.com>
* change src/YGDialog.cc to maximize window when screen width <= 800 OR
* screen height <= 600. There was AND previously.
- * fixes bnc#462476
- * Version 2.17.12
-
-2009-02-17 Martin Kudlvasr <mkudlvasr(a)novell.com>
- * backport of mmeeks changes in trunk (r55491),
- fixes (475275)
- * Version 2.17.11
+2009-02-13 Michael Meeks <michael.meeks(a)novell.com>
-2009-02-12 Martin Kudlvasr <mkudlvasr(a)novell.com>
+ * src/YGUtils.cc (ygutils_convert_to_xhtml): handle
+ mangled entities appearing in URLs around the place:
+ bug 475275.
- * Version 2.17.10
+ * src/test.cc (testXHtmlConvert): upd. regression tests.
2009-01-26 Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
Modified: trunk/gtk/Makefile.cvs
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/Makefile.cvs?rev=59807&r1=59…
==============================================================================
--- trunk/gtk/Makefile.cvs (original)
+++ trunk/gtk/Makefile.cvs Thu Nov 26 18:18:31 2009
@@ -6,18 +6,18 @@
PREFIX = /usr
-configure: all
- ./configure --prefix=$(PREFIX) --libdir=$(PREFIX)/$(LIB)
+configure:
+ mkdir build ;\
+ cd build ;\
+ cmake -DCMAKE_INSTALL_PREFIX=$(PREFIX) -DLIB=$(LIB) .. && make
-all:
- y2tool y2autoconf
- y2tool y2automake
- autoreconf --force --install
+# use "VERBOSE=1 make" to read full gcc argument
install: configure
- make
- make install
+ cd build ;\
+ make && make install
+
+reconf:
+ cd build ;\
+ cmake rebuild_cache
-reconf: all
- ./config.status --recheck
- ./config.status
Modified: trunk/gtk/README
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/README?rev=59807&r1=59806&r2…
==============================================================================
--- trunk/gtk/README (original)
+++ trunk/gtk/README Thu Nov 26 18:18:31 2009
@@ -24,7 +24,6 @@
Building / Installing
- make -f Makefile.cvs
make && sudo make install [1]
[1] - if you want sudo not to ask you a password, add yourself to the
Modified: trunk/gtk/TODO
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/TODO?rev=59807&r1=59806&r2=5…
==============================================================================
--- trunk/gtk/TODO (original)
+++ trunk/gtk/TODO Thu Nov 26 18:18:31 2009
@@ -1,33 +1,58 @@
/* List of missing features, actual bugs and other issues */
-= Regression testing =
+Bugs
-* Setup LDTP to run through all the tests/ and provoke as many
- code-paths as possible
-
-= Look and feel =
-
-* YGRichText: should use GtkHtml when available, so that we get support for
- tables.
-
-* YGTextEntry / YGMultiLineEdit: Add undo/redo support. The backend code should
- be shared. We probably want to make an interface for it that is then implemented
- by those two GTK widgets. Work out a patch for GTK+.
-
-= Package Selector =
-(this little monster diserves a section of its own. =))
-
-* Search syntax: add proper Google syntax support. Consider also adding regex
- support when Glib ships with it (add radio boxes to entry's context menu).
-
-= Yast-Core =
-
-* Stock icons for buttons (at least the wizard ones)
- Currently the support is limited to English because it's done by comparing
- the strings to a list of stock icon ones.
-
-* Button order
- Should be possible to specify button order. eg: [Ok] [Cancel] vs [Cancel] [Ok]
- We could hack this through if we had stock images support (may depend
- on the way they are implemented).
+ tests/Layout-TruncatedWidget.ycp
+ unlike yast2-qt, we trigger recalculation events on widget property
+ changes like the label or the button text.
+ Difficulty: High - Priority: Low
+
+ Honor YDialog's YWizardDialog directive
+ see bug 457758. We also want to make multiple Wizard instances
+ share the same help window. Overall, move a bunch of YGWizard
+ stuff into YGDialog domain.
+ Difficulty: Medium - Priority: Low
+
+Enhancements
+
+ Package manager search syntax
+ add proper Google syntax support. Consider also adding regex (add
+ radio boxes to entry's context menu).
+ Difficulty: Medium - Priority: Low
+
+ YGTextEntry / YGMultiLineEdit
+ Add undo/redo support. (Possibly work out a patch for GTK+.)
+ Difficulty: Low - Priority: Medium
+
+ YGtkFindEntry
+ Deprecate YGtkFindEntry usage in favor of GTK 2.16 GtkEntry new
+ APIs. Notice the requirements for the Package Manager: change
+ icon to reflect that of the context menu, and show arrow next
+ to the search icon.
+ Difficulty: Low - Priority: Low
+
+ YGPackageSelector.cc: FlexPane class
+ Deprecate in favor of GTK 2.16 GtkOrientation API for GtkPaned.
+ Difficulty: Low - Priority: Low
+
+ Installer look
+ Port or adopt yast2-qt's installer style file.
+ Difficulty: High - Priority: Low
+
+Build procedure
+
+ YGRichText
+ should use GtkHtml when available, so that we get support for tables.
+
+ Road block: the problem here is that Webkit doesn't work well for our
+ package-selector use (outside a scrolled window). Does it make sense to
+ keep YGtkRichText for that sole purpose?
+ Difficulty: Medium - Priority: Medium
+
+Test Framework
+
+ Regression tests
+ setup LDTP to run through all the tests/ and provoke as many code-paths
+ as possible.
+ Difficulty: High (tiresome) - Priority: Low
Added: trunk/gtk/VERSION.cmake
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/VERSION.cmake?rev=59807&view…
==============================================================================
--- trunk/gtk/VERSION.cmake (added)
+++ trunk/gtk/VERSION.cmake Thu Nov 26 18:18:31 2009
@@ -0,0 +1,4 @@
+set (VERSION_MAJOR "2")
+set (VERSION_MINOR "19")
+set (VERSION_PATCH "5")
+
Added: trunk/gtk/config.h.cmake
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/config.h.cmake?rev=59807&vie…
==============================================================================
--- trunk/gtk/config.h.cmake (added)
+++ trunk/gtk/config.h.cmake Thu Nov 26 18:18:31 2009
@@ -0,0 +1,9 @@
+/* Important paths */
+#cmakedefine DATADIR "${DATADIR}"
+#cmakedefine THEMEDIR "${THEMEDIR}"
+#cmakedefine LOCALEDIR "${LOCALEDIR}"
+
+/* Version enumerations to develop backward compability */
+#cmakedefine YAST2_VERSION ${YAST2_VERSION}
+#cmakedefine ZYPP_VERSION ${ZYPP_VERSION}
+
Modified: trunk/gtk/yast2-gtk.spec.in
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/yast2-gtk.spec.in?rev=59807&…
==============================================================================
--- trunk/gtk/yast2-gtk.spec.in (original)
+++ trunk/gtk/yast2-gtk.spec.in Thu Nov 26 18:18:31 2009
@@ -1,39 +1,21 @@
-#
-# spec file for package yast2-gtk (Version 2.17.1)
-#
-# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-#
-# All modifications and additions to the file contributed by third parties
-# remain the property of their copyright owners, unless otherwise agreed
-# upon. The license for this file, and modifications and additions to the
-# file, is the same license as for the pristine package itself (unless the
-# license for the pristine package is not an Open Source License, in which
-# case the license is the MIT License). An "Open Source License" is a
-# license that conforms to the Open Source Definition (Version 1.9)
-# published by the Open Source Initiative.
-
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
-#
-
-# norootforbuild
-
-Url: http://en.opensuse.org/YaST2-GTK
-
-Name: yast2-gtk
-Version: @VERSION@
-Release: 0
-License: LGPL v2.1 or later
-Group: System/YaST
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-Source0: yast2-gtk-@VERSION@.tar.bz2
-prefix: /usr
-Source2: yast2-gtk-rpmlintrc
-BuildRequires: blocxx-devel gcc-c++ libxcrypt-devel libzypp-devel yast2-devtools gtk2-devel
-BuildRequires: yast2-core-devel >= 2.16.27
-BuildRequires: yast2-libyui-devel
-Requires: yast2-core >= 2.16.27
-Summary: YaST2 - Gtk Graphical User Interface
-Provides: yast2_ui
+@HEADERCOMMENT@
+
+
+@HEADER@
+Url: http://en.opensuse.org/YaST2-GTK
+Summary: YaST2 - GTK+ Graphical User Interface
+Group: System/YaST
+License: GPL v2.1 or later
+BuildRequires: cmake
+BuildRequires: gcc-c++ blocxx-devel libxcrypt-devel
+BuildRequires: gtk2-devel
+BuildRequires: yast2-devtools >= 2.16.3
+BuildRequires: yast2-libyui-devel >= 2.18.8
+BuildRequires: libzypp-devel >= 6.3.0
+Requires: yast2-libyui >= 2.18.8
+Requires: yast2_theme >= 2.16.1
+Requires: libzypp >= 6.3.0
+Provides: yast2_ui yast2-ui-gtk
Provides: yast2_ui_pkg
%description
@@ -44,21 +26,37 @@
Authors:
--------
- Ricardo Cruz
- Michael Meeks
-
-@PREP@
+ Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt>
+ Michael Meeks <mmeeks(a)novell.com>
-@BUILD@
+%prep
+%setup
-@INSTALL@
-rm $RPM_BUILD_ROOT%{_libdir}/YaST2/plugin/libpy2gtk.la
+%build
+mkdir build
+cd build
+export CFLAGS="$RPM_OPT_FLAGS"
+export CXXFLAGS="$CFLAGS"
+cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+ -DLIB=%{_lib} \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_SKIP_RPATH=1 \
+ ..
+make %{?jobs:-j %jobs} VERBOSE=1
+
+%install
+cd build
+make install DESTDIR=$RPM_BUILD_ROOT
+cd ..
-@CLEAN@
+%clean
+rm -rf "$RPM_BUILD_ROOT"
%files
%defattr (-, root, root)
-%doc @docdir@
-%{_libdir}/YaST2/plugin/libpy2gtk.so.*
-%{_libdir}/YaST2/plugin/libpy2gtk.so
-%{_datadir}/YaST2/gtk
+%dir %_libdir/YaST2
+%_libdir/YaST2/plugin/
+%_prefix/share/YaST2/gtk/
+
+%changelog
+
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
Author: rpmcruz
Date: Thu Nov 26 18:16:21 2009
New Revision: 59806
URL: http://svn.opensuse.org/viewcvs/yast?rev=59806&view=rev
Log:
* Reverted to development state.
* src/YGPackageSelector.cc: some UI changes to
try out.
Added:
trunk/gtk/src/pkg/
trunk/gtk/src/pkg/CMakeLists.txt
trunk/gtk/src/pkg/YGPackageSelector.cc
trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.cc
trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.h
trunk/gtk/src/pkg/pkg-selector-help.h
trunk/gtk/src/pkg/ygtkcellrendererbutton.c
trunk/gtk/src/pkg/ygtkcellrendererbutton.h
trunk/gtk/src/pkg/ygtkdetailview.cc
trunk/gtk/src/pkg/ygtkdetailview.h
trunk/gtk/src/pkg/ygtkdiskview.cc
trunk/gtk/src/pkg/ygtkdiskview.h
trunk/gtk/src/pkg/ygtknotebook.c
trunk/gtk/src/pkg/ygtknotebook.h
trunk/gtk/src/pkg/ygtkpackageview.cc
trunk/gtk/src/pkg/ygtkpackageview.h
trunk/gtk/src/pkg/ygtktooltip.c
trunk/gtk/src/pkg/ygtktooltip.h
trunk/gtk/src/pkg/ygtktreemodel.cc
trunk/gtk/src/pkg/ygtktreemodel.h
trunk/gtk/src/pkg/yzypptags.cc
trunk/gtk/src/pkg/yzypptags.h
trunk/gtk/src/pkg/yzyppwrapper.cc
trunk/gtk/src/pkg/yzyppwrapper.h
Added: trunk/gtk/src/pkg/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/CMakeLists.txt?rev=5…
==============================================================================
--- trunk/gtk/src/pkg/CMakeLists.txt (added)
+++ trunk/gtk/src/pkg/CMakeLists.txt Thu Nov 26 18:16:21 2009
@@ -0,0 +1,43 @@
+## Makefile.am
+
+set (gtk_pkg_yast_plugin_SRCS
+ YGPackageSelectorPluginImpl.cc
+ YGPackageSelector.cc
+ yzypptags.cc
+ yzyppwrapper.cc
+
+ ygtkpackageview.cc
+ ygtkdetailview.cc
+ ygtkdiskview.cc
+
+ ygtkcellrendererbutton.c
+ ygtknotebook.c
+ ygtktreemodel.cc
+ ygtktooltip.c
+ )
+
+## includes:
+
+include_directories (${ZYPP_INCLUDE_DIR})
+# we want libpy2gtk_pkg.so to link to libpy2gtk.so before install
+# and then to find it when it is installed and on its own
+link_directories (${CMAKE_BINARY_DIR}/src)
+link_directories (${UI_PLUGIN_DIR})
+
+## target:
+
+add_library (py2gtk_pkg SHARED ${gtk_pkg_yast_plugin_SRCS})
+
+## libraries:
+
+target_link_libraries (py2gtk_pkg libpy2gtk.so)
+target_link_libraries (py2gtk_pkg ${GTK2_LIBRARIES})
+target_link_libraries (py2gtk_pkg ${LIBYUI_LIBRARY})
+target_link_libraries (py2gtk_pkg ${ZYPP_LIBRARY})
+set_target_properties (py2gtk_pkg PROPERTIES SOVERSION 2)
+set_target_properties (py2gtk_pkg PROPERTIES LINK_FLAGS "--no-undefined -Wl,-rpath -Wl,${UI_PLUGIN_DIR}")
+
+## install:
+
+install (TARGETS py2gtk_pkg LIBRARY DESTINATION ${UI_PLUGIN_DIR})
+
Added: trunk/gtk/src/pkg/YGPackageSelector.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/YGPackageSelector.cc…
==============================================================================
--- trunk/gtk/src/pkg/YGPackageSelector.cc (added)
+++ trunk/gtk/src/pkg/YGPackageSelector.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,2505 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+/*
+ Textdomain "yast2-gtk"
+ */
+
+#define YUILogComponent "gtk"
+#include "config.h"
+#include <string.h>
+#include "YGUI.h"
+#include "YGUtils.h"
+#include "YGi18n.h"
+#include "YGDialog.h"
+
+#include "ygtkwizard.h"
+#include "ygtkfindentry.h"
+#include "ygtkmenubutton.h"
+#include "ygtkhtmlwrap.h"
+#include "ygtkrichtext.h"
+#include "ygtktreeview.h"
+#include "ygtktooltip.h"
+#include "ygtkpackageview.h"
+#include "ygtkdetailview.h"
+#include "ygtkdiskview.h"
+
+// experiments:
+extern bool show_find_pane, use_buttons, show_novelty_filter;
+
+//** UI components -- split up for re-usability, but mostly for readability
+
+#if 0
+class UndoView
+{
+GtkWidget *m_vbox;
+Ypp::PkgList m_changes;
+
+public:
+ GtkWidget *getWidget() { return m_vbox; }
+
+ UndoView (YGtkPackageView::Listener *listener)
+ {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->setToModify (true);
+ m_changes = Ypp::PkgQuery (Ypp::Package::PACKAGE_TYPE, query);
+
+ GtkWidget *view = createView (listener);
+
+ m_vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (m_vbox), 6);
+ gtk_box_pack_start (GTK_BOX (m_vbox), view, TRUE, TRUE, 0);
+#if 0
+// FIXME: temporarily disable uncouple button
+// issues: * too visible (also the labeling/icon are a bit off)
+// * undo window should not overlap (or at least placed at the side on start)
+ GtkWidget *uncouple_button = gtk_button_new_with_label (_("Uncouple"));
+ GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_DISCONNECT, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (uncouple_button), icon);
+ GtkWidget *uncouple_align = gtk_alignment_new (1, .5, 0, 1);
+ gtk_container_add (GTK_CONTAINER (uncouple_align), uncouple_button);
+ gtk_widget_set_tooltip_text (uncouple_button, _("Open in new window"));
+ g_signal_connect (G_OBJECT (uncouple_button), "clicked",
+ G_CALLBACK (uncouple_clicked_cb), this);
+ gtk_box_pack_start (GTK_BOX (m_vbox), uncouple_align, FALSE, TRUE, 0);
+#endif
+ gtk_widget_show_all (m_vbox);
+ g_object_ref_sink (m_vbox);
+ }
+
+ ~UndoView()
+ { g_object_unref (m_vbox); }
+
+ GtkWidget *createView (YGtkPackageView::Listener *listener)
+ {
+ GtkWidget *hbox = gtk_hbox_new (TRUE, 6);
+ for (int i = 0; i < 3; i++) {
+ const char *str = 0, *stock = 0;
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ int checkCol = 0;
+ switch (i) {
+ case 0:
+ str = _("To install:");
+ stock = GTK_STOCK_ADD;
+ query->setToInstall (true);
+ query->setIsInstalled (false);
+ checkCol = TO_INSTALL_PROP;
+ break;
+ case 1:
+ str = _("To upgrade:");
+ stock = GTK_STOCK_GO_UP;
+ query->setToInstall (true);
+ query->setIsInstalled (true);
+ checkCol = TO_UPGRADE_PROP;
+ break;
+ case 2:
+ str = _("To remove:");
+ stock = GTK_STOCK_REMOVE;
+ query->setToRemove (true);
+ checkCol = TO_REMOVE_PROP;
+ break;
+ default: break;
+ }
+ Ypp::PkgQuery list (m_changes, query);
+
+ GtkWidget *label_box, *icon, *label;
+ label = gtk_label_new (str);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
+ icon = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
+ label_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (label_box), icon, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (label_box), label, TRUE, TRUE, 0);
+ YGtkPackageView *view = ygtk_package_view_new (FALSE);
+ view->appendCheckColumn (checkCol);
+ view->appendTextColumn (NULL, NAME_PROP, -1, true);
+ view->setActivateAction (YGtkPackageView::UNDO_ACTION);
+ view->setList (list, NULL);
+ view->setListener (listener);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
+
+ GtkWidget *box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (box), label_box, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (view), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), box, TRUE, TRUE, 0);
+ }
+ return hbox;
+ }
+
+private:
+ static void uncouple_clicked_cb (GtkButton *button, UndoView *pThis)
+ {
+ gtk_widget_hide (pThis->m_vbox);
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Undo History"),
+ YGDialog::currentWindow(), GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 450);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+ g_signal_connect (G_OBJECT (dialog), "delete-event",
+ G_CALLBACK (uncouple_delete_event_cb), pThis);
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (close_response_cb), pThis);
+
+ GtkWidget *view = pThis->createView (NULL);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), view);
+ gtk_widget_show_all (dialog);
+ }
+
+ static gboolean uncouple_delete_event_cb (
+ GtkWidget *widget, GdkEvent *event, UndoView *pThis)
+ {
+ gtk_widget_show (pThis->m_vbox);
+ return FALSE;
+ }
+
+ static void close_response_cb (GtkDialog *dialog, gint response, UndoView *pThis)
+ {
+ gtk_widget_show (pThis->m_vbox);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
+};
+
+struct QueryListener {
+ virtual void queryNotify() = 0;
+ virtual void queryNotifyDelay() = 0;
+};
+
+class QueryWidget
+{
+protected:
+ QueryListener *m_listener;
+ void notify() { m_listener->queryNotify(); }
+ void notifyDelay() { m_listener->queryNotifyDelay(); }
+
+public:
+ void setListener (QueryListener *listener) { m_listener = listener; }
+ virtual GtkWidget *getWidget() = 0;
+ virtual void writeQuery (Ypp::PkgQuery::Query *query) = 0;
+
+ virtual bool availablePackagesOnly() { return false; }
+ virtual bool installedPackagesOnly() { return false; }
+ virtual ~QueryWidget() {}
+};
+
+class StoreView : public QueryWidget
+{
+protected:
+ GtkWidget *m_view, *m_scroll, *m_box;
+ enum Column { TEXT_COL, ICON_COL, ENABLED_COL, PTR_COL, TOOLTIP_COL, TOTAL_COLS };
+
+ virtual void doBuild (GtkTreeStore *store) = 0;
+ virtual void writeQuerySel (Ypp::PkgQuery::Query *query,
+ const std::list <gpointer> &ptr) = 0;
+
+ StoreView()
+ : QueryWidget()
+ {
+ m_scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_scroll),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ m_view = NULL;
+ m_box = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (m_box), m_scroll, TRUE, TRUE, 0);
+
+ // parent constructor should call build()
+ }
+
+public:
+ virtual GtkWidget *getWidget() { return m_box; }
+
+ virtual void writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ GtkTreeModel *model;
+ GList *selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ std::list <gpointer> ptrs;
+ for (GList *i = selected; i; i = i->next) {
+ GtkTreePath *path = (GtkTreePath *) i->data;
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gpointer ptr;
+ gtk_tree_model_get (model, &iter, PTR_COL, &ptr, -1);
+ if (ptr)
+ ptrs.push_back (ptr);
+ gtk_tree_path_free (path);
+ }
+ g_list_free (selected);
+ writeQuerySel (query, ptrs);
+ }
+
+protected:
+ void build (bool tree_mode, bool with_icons, bool multi_selection,
+ bool do_tooltip)
+ {
+ if (m_view)
+ gtk_container_remove (GTK_CONTAINER (m_scroll), m_view);
+
+ m_view = ygtk_tree_view_new();
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ gtk_tree_view_set_headers_visible (view, FALSE);
+ gtk_tree_view_set_search_column (view, TEXT_COL);
+ if (do_tooltip)
+ gtk_tree_view_set_tooltip_column (view, TEXT_COL);
+ gtk_tree_view_set_show_expanders (view, tree_mode);
+ gtk_tree_view_set_tooltip_column (view, TOOLTIP_COL);
+
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ if (with_icons) {
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes ("",
+ renderer, "icon-name", ICON_COL, "sensitive", ENABLED_COL, NULL);
+ gtk_tree_view_append_column (view, column);
+ }
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("",
+ renderer, "markup", TEXT_COL, "sensitive", ENABLED_COL, NULL);
+ gtk_tree_view_append_column (view, column);
+
+ GtkTreeStore *store = gtk_tree_store_new (TOTAL_COLS,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_STRING);
+ GtkTreeModel *model = GTK_TREE_MODEL (store);
+ gtk_tree_view_set_model (view, model);
+ g_object_unref (G_OBJECT (model));
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection,
+ multi_selection ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (selection_cb), this);
+ gtk_tree_selection_set_select_function (selection, can_select_cb, this, NULL);
+
+ block();
+ GtkTreeIter iter;
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, TEXT_COL, _("All"), ENABLED_COL, TRUE,
+ TOOLTIP_COL, _("No filter"), -1);
+ doBuild (store);
+
+ selectFirstItem();
+ unblock();
+
+ gtk_container_add (GTK_CONTAINER (m_scroll), m_view);
+ gtk_widget_show (m_view);
+ }
+
+private:
+ void block()
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
+ g_signal_handlers_block_by_func (selection, (gpointer) selection_cb, this);
+ }
+ void unblock()
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
+ g_signal_handlers_unblock_by_func (selection, (gpointer) selection_cb, this);
+ }
+
+ void selectFirstItem()
+ {
+ /* 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... */
+ block();
+ GtkTreePath *path = gtk_tree_path_new_first();
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (m_view), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+ unblock();
+ }
+
+ static void selection_cb (GtkTreeSelection *selection, StoreView *pThis)
+ {
+ pThis->notify();
+ // if item unselected, make sure "All" is
+ if (gtk_tree_selection_count_selected_rows (selection) == 0)
+ pThis->selectFirstItem();
+ }
+
+ static gboolean can_select_cb (GtkTreeSelection *selection, GtkTreeModel *model,
+ GtkTreePath *path, gboolean currently_selected,
+ gpointer pData)
+ {
+ gboolean ret;
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, ENABLED_COL, &ret, -1);
+ return ret;
+ }
+};
+
+struct Categories : public StoreView
+{
+ bool m_rpmGroups, m_onlineUpdate;
+
+public:
+ Categories (bool onlineUpdate)
+ : StoreView(), m_rpmGroups (false), m_onlineUpdate (onlineUpdate)
+ {
+ if (!onlineUpdate) {
+ GtkWidget *check = gtk_check_button_new_with_label (_("Detailed"));
+ YGUtils::setWidgetFont (GTK_BIN (check)->child,
+ PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_SCALE_SMALL);
+ gtk_widget_set_tooltip_text (check,
+ _("Group by the PackageKit-based filter or straight from the actual "
+ "RPM information."));
+ g_signal_connect (G_OBJECT (check), "toggled",
+ G_CALLBACK (rpm_groups_toggled_cb), this);
+ gtk_box_pack_start (GTK_BOX (m_box), check, FALSE, TRUE, 0);
+ }
+ build (m_rpmGroups, !m_rpmGroups, false, false);
+ }
+
+protected:
+ virtual void doBuild (GtkTreeStore *store)
+ {
+ struct inner {
+ static void populate (GtkTreeStore *store, GtkTreeIter *parent,
+ Ypp::Node *category, Categories *pThis)
+ {
+ if (!category)
+ return;
+ GtkTreeIter iter;
+ gtk_tree_store_append (store, &iter, parent);
+ gtk_tree_store_set (store, &iter, TEXT_COL, category->name.c_str(),
+ ICON_COL, category->icon, PTR_COL, category, ENABLED_COL, TRUE, -1);
+ populate (store, &iter, category->child(), pThis);
+ populate (store, parent, category->next(), pThis);
+ }
+ };
+
+ Ypp::Node *first_category;
+ Ypp::Package::Type type = m_onlineUpdate ?
+ Ypp::Package::PATCH_TYPE : Ypp::Package::PACKAGE_TYPE;
+ if (!m_rpmGroups && !m_onlineUpdate)
+ first_category = Ypp::get()->getFirstCategory2 (type);
+ else
+ first_category = Ypp::get()->getFirstCategory (type);
+ inner::populate (store, NULL, first_category, this);
+ if (!m_rpmGroups && !m_onlineUpdate) {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkTreeIter iter;
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_view_set_row_separator_func (view,
+ is_tree_model_iter_separator_cb, NULL, NULL);
+
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, TEXT_COL, _("Recommended"),
+ ICON_COL, GTK_STOCK_ABOUT, PTR_COL, GINT_TO_POINTER (1),
+ ENABLED_COL, TRUE, TOOLTIP_COL, _("Recommended by an installed package"), -1);
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, TEXT_COL, _("Suggested"),
+ ICON_COL, GTK_STOCK_ABOUT, PTR_COL, GINT_TO_POINTER (2),
+ ENABLED_COL, TRUE, TOOLTIP_COL, _("Suggested by an installed package"), -1);
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, TEXT_COL, _("Fresh"),
+ ICON_COL, GTK_STOCK_NEW, PTR_COL, GINT_TO_POINTER (3),
+ ENABLED_COL, TRUE, TOOLTIP_COL, _("Uploaded in the last week"), -1);
+ }
+ }
+
+ virtual void writeQuerySel (Ypp::PkgQuery::Query *query, const std::list <gpointer> &ptrs)
+ {
+ gpointer ptr = ptrs.empty() ? NULL : ptrs.front();
+ int nptr = GPOINTER_TO_INT (ptr);
+ if (nptr == 1)
+ query->setIsRecommended (true);
+ else if (nptr == 2)
+ query->setIsSuggested (true);
+ else if (nptr == 3)
+ query->setBuildAge (7);
+ else if (ptr) {
+ Ypp::Node *node = (Ypp::Node *) ptr;
+ if (m_rpmGroups || m_onlineUpdate)
+ query->addCategory (node);
+ else
+ query->addCategory2 (node);
+ }
+ }
+
+ static void rpm_groups_toggled_cb (GtkToggleButton *button, Categories *pThis)
+ {
+ pThis->m_rpmGroups = gtk_toggle_button_get_active (button);
+ pThis->build (pThis->m_rpmGroups, !pThis->m_rpmGroups, false, false);
+ pThis->notify();
+ }
+
+ static gboolean is_tree_model_iter_separator_cb (
+ GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+ {
+ gint col = data ? GPOINTER_TO_INT (data) : 0;
+ gpointer ptr;
+ gtk_tree_model_get (model, iter, col, &ptr, -1);
+ return ptr == NULL;
+ }
+};
+
+struct Repositories : public StoreView
+{
+public:
+ Repositories (bool repoMgrEnabled)
+ : StoreView()
+ {
+ if (repoMgrEnabled) {
+ GtkWidget *align, *button, *box, *image, *label;
+ box = gtk_hbox_new (FALSE, 6);
+ GtkSettings *settings = gtk_settings_get_default();
+ gboolean button_images;
+ g_object_get (settings, "gtk-button-images", &button_images, NULL);
+ if (button_images) {
+ image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (box), image, FALSE, TRUE, 0);
+ }
+ label = gtk_label_new (_("Edit..."));
+ YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_SCALE_SMALL);
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+ button = gtk_button_new();
+ gtk_container_add (GTK_CONTAINER (button), box);
+ gtk_widget_set_tooltip_text (button, _("Access the repositories manager tool."));
+ align = gtk_alignment_new (0, 0, 0, 1);
+ gtk_container_add (GTK_CONTAINER (align), button);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (setup_button_clicked_cb), this);
+ gtk_box_pack_start (GTK_BOX (m_box), align, FALSE, TRUE, 0);
+ }
+ build (false, true, true, true);
+ }
+
+ virtual ~Repositories()
+ { Ypp::get()->setFavoriteRepository (NULL); }
+
+protected:
+ virtual void doBuild (GtkTreeStore *store)
+ {
+ GtkTreeIter iter;
+ for (int i = 0; Ypp::get()->getRepository (i); i++) {
+ const Ypp::Repository *repo = Ypp::get()->getRepository (i);
+ gtk_tree_store_append (store, &iter, NULL);
+ std::string text = repo->name, url (repo->url);
+ YGUtils::escapeMarkup (url);
+ text += "\n<small>" + url + "</small>";
+ const gchar *icon;
+ if (repo->url.empty())
+ icon = GTK_STOCK_MISSING_IMAGE;
+ else if (repo->url.compare (0, 2, "cd", 2) == 0 ||
+ repo->url.compare (0, 3, "dvd", 3) == 0)
+ icon = GTK_STOCK_CDROM;
+ else if (repo->url.compare (0, 3, "iso", 3) == 0)
+ icon = GTK_STOCK_FILE;
+ else
+ icon = GTK_STOCK_NETWORK;
+ gtk_tree_store_set (store, &iter, TEXT_COL, text.c_str(),
+ ICON_COL, icon, ENABLED_COL, repo->enabled, PTR_COL, repo,
+ TOOLTIP_COL, text.c_str(), -1);
+ }
+ }
+
+ virtual void writeQuerySel (Ypp::PkgQuery::Query *query, const std::list <gpointer> &ptrs)
+ {
+ for (std::list <gpointer>::const_iterator it = ptrs.begin();
+ it != ptrs.end(); it++) {
+ Ypp::Repository *repo = (Ypp::Repository *) *it;
+ query->addRepository (repo);
+ }
+ gpointer ptr = ptrs.size() == 1 ? ptrs.front() : NULL;
+ Ypp::get()->setFavoriteRepository ((Ypp::Repository *) ptr);
+ }
+
+ static void setup_button_clicked_cb (GtkButton *button, Repositories *pThis)
+ { YGUI::ui()->sendEvent (new YMenuEvent ("repo_mgr")); }
+};
+
+struct Collection : public QueryWidget, YGtkPackageView::Listener
+{
+private:
+ YGtkPackageView *m_view;
+ GtkWidget *m_buttons_box, *m_box;
+
+public:
+ virtual GtkWidget *getWidget() { return m_box; }
+
+ Collection (Ypp::Package::Type type)
+ : QueryWidget()
+ {
+ m_view = ygtk_package_view_new (TRUE);
+ m_view->appendIconColumn (NULL, ICON_PROP);
+ m_view->appendTextColumn (NULL, NAME_SUMMARY_PROP);
+ if (type == Ypp::Package::LANGUAGE_TYPE)
+ m_view->setList (Ypp::PkgQuery (type, NULL), NULL);
+ else
+ populateView (m_view, type);
+ m_view->setListener (this);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_view), GTK_SHADOW_IN);
+
+ // control buttons
+ m_buttons_box = gtk_alignment_new (0, 0, 0, 0);
+ GtkWidget *image, *button;
+ button = gtk_button_new_with_label (_("Install All"));
+ image = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (install_cb), this);
+ gtk_container_add (GTK_CONTAINER (m_buttons_box), button);
+ gtk_widget_set_sensitive (m_buttons_box, FALSE);
+
+ // layout
+ m_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), GTK_WIDGET (m_view), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), m_buttons_box, FALSE, TRUE, 0);
+ }
+
+ static void populateView (YGtkPackageView *view, Ypp::Package::Type type)
+ { // list 1D categories intertwined with its constituent packages
+ Ypp::Node *category = Ypp::get()->getFirstCategory (type);
+ for (; category; category = category->next()) {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->addCategory (category);
+ view->appendList (category->name.c_str(), Ypp::PkgQuery (type, query), NULL);
+ }
+ }
+
+ virtual void packagesSelected (Ypp::PkgList selection)
+ {
+ gtk_widget_set_sensitive (m_buttons_box, selection.notInstalled());
+ notify();
+ }
+
+ virtual void writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ Ypp::PkgList selected = m_view->getSelected();
+ for (int i = 0; selected.get (i); i++)
+ query->addCollection (selected.get (i));
+ if (selected.size() == 0)
+ query->setClear();
+ }
+
+ void doAll (bool install /*or remove*/)
+ { // we just need to mark the collections themselves
+ Ypp::PkgList selected = m_view->getSelected();
+ install ? selected.install() : selected.remove();
+ }
+
+ static void install_cb (GtkButton *button, Collection *pThis)
+ { pThis->doAll (true); }
+ static void remove_cb (GtkButton *button, Collection *pThis)
+ { pThis->doAll (false); }
+};
+
+static const char *find_entry_tooltip =
+ _("<b>Package search:</b> Use spaces to separate your keywords. They "
+ "will be matched against RPM <i>name</i> and <i>summary</i> attributes. "
+ "Other criteria attributes are available by pressing the search icon.\n"
+ "(usage example: \"yast dhcp\" will return yast's dhcpd tool)");
+static const char *find_entry_novelty_tooltip =
+ _("Number of days since the package was built by the repository.");
+static const char *find_entry_file_tooltip =
+ _("Note: Only applicable to installed packages.");
+static std::string findPatternTooltip (const std::string &name)
+{
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->addNames (name, ' ', true, false, false, false, false, true);
+ query->setIsInstalled (false);
+ Ypp::PkgQuery pool (Ypp::Package::PATTERN_TYPE, query);
+ if (pool.size() > 0) {
+ std::string _name = pool.get (0)->name();
+ std::string text = _("Patterns are available that can "
+ "assist you in the installment of");
+ text += " <i>" + _name + "</i>.";
+ return text;
+ }
+ return "";
+}
+
+class FindPane : public QueryWidget
+{
+GtkWidget *m_box, *m_name, *m_radio[5], *m_info_box, *m_info_label;
+bool m_onlineUpdate;
+
+public:
+ virtual GtkWidget *getWidget() { return m_box; }
+
+ FindPane (bool onlineUpdate)
+ : m_onlineUpdate (onlineUpdate)
+ {
+ GtkWidget *name_box = gtk_hbox_new (FALSE, 6), *button;
+ m_name = ygtk_find_entry_new();
+ gtk_widget_set_tooltip_markup (m_name, find_entry_tooltip);
+ g_signal_connect (G_OBJECT (m_name), "changed",
+ G_CALLBACK (name_changed_cb), this);
+ button = gtk_button_new_with_label ("");
+ GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_OK, GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ gtk_widget_set_tooltip_text (button, _("Search!"));
+ gtk_box_pack_start (GTK_BOX (name_box), m_name, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (name_box), button, FALSE, TRUE, 0);
+
+ for (int i = 0; i < 5; i++) m_radio[i] = 0;
+ GtkWidget *radio_box = gtk_vbox_new (FALSE, 0);
+ m_radio[0] = gtk_radio_button_new_with_label_from_widget (NULL, _("Name & summary"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_radio[0]), TRUE);
+ GtkRadioButton *radiob = GTK_RADIO_BUTTON (m_radio[0]);
+ m_radio[1] = gtk_radio_button_new_with_label_from_widget (radiob, _("Description"));
+ if (!onlineUpdate) {
+ m_radio[2] = gtk_radio_button_new_with_label_from_widget (radiob, _("File name"));
+ gtk_widget_set_tooltip_text (m_radio[2], find_entry_file_tooltip);
+ m_radio[3] = gtk_radio_button_new_with_label_from_widget (radiob, _("Author"));
+ if (show_novelty_filter) {
+ m_radio[4] = gtk_radio_button_new_with_label_from_widget (radiob, _("Novelty (in days)"));
+ g_signal_connect (G_OBJECT (m_radio[4]), "toggled", G_CALLBACK (novelty_toggled_cb), this);
+ gtk_widget_set_tooltip_markup (m_radio[4], find_entry_novelty_tooltip);
+ }
+ }
+ for (int i = 0; i < 5; i++)
+ if (m_radio [i])
+ gtk_box_pack_start (GTK_BOX (radio_box), m_radio[i], FALSE, TRUE, 0);
+
+ GtkWidget *radio_frame = gtk_frame_new (_("Search in:"));
+ YGUtils::setWidgetFont (gtk_frame_get_label_widget (GTK_FRAME (radio_frame)),
+ PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_frame_set_shadow_type (GTK_FRAME (radio_frame), GTK_SHADOW_NONE);
+ GtkWidget *align = gtk_alignment_new (0, 0, 1, 1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 15, 0);
+ gtk_container_add (GTK_CONTAINER (align), radio_box);
+ gtk_container_add (GTK_CONTAINER (radio_frame), align);
+
+ m_info_box = gtk_hbox_new (FALSE, 6);
+ m_info_label = gtk_label_new ("");
+ gtk_label_set_line_wrap (GTK_LABEL (m_info_label), TRUE);
+ gtk_box_pack_start (GTK_BOX (m_info_box),
+ gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_MENU), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_info_box), m_info_label, TRUE, TRUE, 0);
+
+ GtkWidget *separator1 = gtk_event_box_new();
+ gtk_widget_set_size_request (separator1, -1, 12);
+ GtkWidget *separator2 = gtk_event_box_new();
+ gtk_widget_set_size_request (separator2, -1, 15);
+ GtkWidget *separator3 = gtk_event_box_new();
+ gtk_widget_set_size_request (separator3, -1, 50);
+
+ GtkWidget *box = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), separator1, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), name_box, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), separator2, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), radio_frame, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), separator3, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), m_info_box, FALSE, TRUE, 0);
+ m_box = box;
+
+ g_signal_connect (G_OBJECT (m_name), "activate", G_CALLBACK (button_clicked_cb), this);
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_clicked_cb), this);
+ }
+
+ virtual void writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ gtk_widget_hide (m_info_box);
+ const char *name = gtk_entry_get_text (GTK_ENTRY (m_name));
+ if (*name) {
+ int item;
+ for (item = 0; item < 5; item++)
+ if (m_radio[item])
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m_radio[item])))
+ break;
+ if (item >= 5) ;
+ else if (item == 4) { // novelty
+ int days = atoi (name);
+ query->setBuildAge (days);
+ }
+ else {
+ bool use_name, use_summary, use_description, use_filelist, use_authors;
+ use_name = use_summary = use_description = use_filelist = use_authors = false;
+ switch (item) {
+ case 0: // name & summary
+ default:
+ use_name = use_summary = true;
+ break;
+ case 1: // description
+ use_name = use_summary = use_description = true;
+ break;
+ case 2: // file
+ use_filelist = true;
+ break;
+ case 3: // author
+ use_authors = true;
+ break;
+ }
+ query->addNames (name, ' ', use_name, use_summary, use_description,
+ use_filelist, use_authors);
+ }
+ if (item == 0 && !m_onlineUpdate) { // tip: user may be unaware of the patterns
+ std::string text = findPatternTooltip (name);
+ if (!text.empty()) {
+ gtk_label_set_markup (GTK_LABEL (m_info_label), text.c_str());
+ // wrapping must be performed manually in GTK
+ int width;
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
+ width = getWidget()->allocation.width - width - 6;
+ gtk_widget_set_size_request (m_info_label, width, -1);
+ gtk_widget_show_all (m_info_box);
+ }
+ }
+ }
+ }
+
+ virtual bool installedPackagesOnly()
+ { return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m_radio[2])); }
+
+ const char *searchName()
+ {
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m_radio[0]))) {
+ const char *name = gtk_entry_get_text (GTK_ENTRY (m_name));
+ return *name ? name : NULL;
+ }
+ return NULL;
+ }
+
+private:
+ static void novelty_toggled_cb (GtkToggleButton *button, FindPane *pThis)
+ {
+ // novelty is weird; so show usage case
+ const gchar *text = "";
+ if (gtk_toggle_button_get_active (button))
+ text = "7";
+ g_signal_handlers_block_by_func (pThis->m_name, (gpointer) name_changed_cb, pThis);
+ gtk_entry_set_text (GTK_ENTRY (pThis->m_name), text);
+ g_signal_handlers_unblock_by_func (pThis->m_name, (gpointer) name_changed_cb, pThis);
+ gtk_editable_set_position (GTK_EDITABLE (pThis->m_name), -1);
+ ygtk_find_entry_set_state (YGTK_FIND_ENTRY (pThis->m_name), TRUE);
+ }
+
+ static void name_changed_cb (YGtkFindEntry *entry, FindPane *pThis)
+ {
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ // novelty allows only numbers
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pThis->m_radio[4]))) {
+ gboolean correct = TRUE;
+ for (const gchar *i = text; *i; i++)
+ if (!g_ascii_isdigit (*i)) {
+ correct = FALSE;
+ break;
+ }
+ ygtk_find_entry_set_state (entry, correct);
+ }
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pThis->m_radio[0])))
+ pThis->notifyDelay();
+ else if (*text == '\0')
+ pThis->notify();
+ }
+
+ static void button_clicked_cb (GtkWidget *widget, FindPane *pThis)
+ { pThis->notify(); }
+};
+
+class FindEntry : public QueryWidget
+{
+GtkWidget *m_name;
+bool m_onlineUpdate;
+GtkWidget *m_combo;
+
+public:
+ GtkWidget *getWidget() { return m_name; }
+
+ FindEntry (bool onlineUpdate, GtkWidget *combo) : QueryWidget()
+ , m_onlineUpdate (onlineUpdate), m_combo (combo)
+ {
+ m_name = ygtk_find_entry_new();
+ gtk_widget_set_size_request (m_name, 140, -1);
+ gtk_widget_set_tooltip_markup (m_name, find_entry_tooltip);
+ ygtk_find_entry_insert_item (YGTK_FIND_ENTRY (m_name),
+ _("Filter by name & summary"), GTK_STOCK_FIND, NULL);
+ ygtk_find_entry_insert_item (YGTK_FIND_ENTRY (m_name),
+ _("Filter by description"), GTK_STOCK_EDIT, NULL);
+ if (!onlineUpdate) {
+ ygtk_find_entry_insert_item (YGTK_FIND_ENTRY (m_name),
+ _("Filter by file"), GTK_STOCK_OPEN, find_entry_file_tooltip);
+ ygtk_find_entry_insert_item (YGTK_FIND_ENTRY (m_name),
+ _("Filter by author"), GTK_STOCK_ABOUT, NULL);
+ if (show_novelty_filter)
+ ygtk_find_entry_insert_item (YGTK_FIND_ENTRY (m_name),
+ _("Filter by novelty (in days)"), GTK_STOCK_NEW, find_entry_novelty_tooltip);
+ }
+ g_signal_connect (G_OBJECT (m_name), "changed",
+ G_CALLBACK (name_changed_cb), this);
+ g_signal_connect (G_OBJECT (m_name), "menu-item-selected",
+ G_CALLBACK (name_item_changed_cb), this);
+ g_signal_connect (G_OBJECT (m_name), "realize",
+ G_CALLBACK (realize_cb), this);
+ gtk_widget_show (m_name);
+ }
+
+ void clear()
+ {
+ g_signal_handlers_block_by_func (m_name, (gpointer) name_changed_cb, this);
+ g_signal_handlers_block_by_func (m_name, (gpointer) name_item_changed_cb, this);
+ gtk_entry_set_text (GTK_ENTRY (m_name), "");
+ ygtk_find_entry_select_item (YGTK_FIND_ENTRY (m_name), 0);
+ g_signal_handlers_unblock_by_func (m_name, (gpointer) name_changed_cb, this);
+ g_signal_handlers_unblock_by_func (m_name, (gpointer) name_item_changed_cb, this);
+ }
+
+ const char *searchName()
+ {
+ YGtkFindEntry *entry = YGTK_FIND_ENTRY (m_name);
+ if (ygtk_find_entry_get_selected_item (entry) == 0) {
+ const char *name = gtk_entry_get_text (GTK_ENTRY (m_name));
+ return *name ? name : NULL;
+ }
+ return NULL;
+ }
+
+ virtual void writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ const char *name = gtk_entry_get_text (GTK_ENTRY (m_name));
+ if (*name) {
+ int item = ygtk_find_entry_get_selected_item (YGTK_FIND_ENTRY (m_name));
+ if (item >= 5) ;
+ else if (item == 4) { // novelty
+ int days = atoi (name);
+ query->setBuildAge (days);
+ }
+ else {
+ bool use_name, use_summary, use_description, use_filelist, use_authors;
+ use_name = use_summary = use_description = use_filelist = use_authors = false;
+ switch (item) {
+ case 0: // name & summary
+ default:
+ use_name = use_summary = true;
+ break;
+ case 1: // description
+ use_name = use_summary = use_description = true;
+ break;
+ case 2: // file
+ use_filelist = true;
+ break;
+ case 3: // author
+ use_authors = true;
+ break;
+ }
+ query->addNames (name, ' ', use_name, use_summary, use_description,
+ use_filelist, use_authors);
+ }
+
+ if (item == 0 && !m_onlineUpdate) { // tip: user may be unaware of the patterns
+ std::string text = findPatternTooltip (name);
+ if (!text.empty())
+ ygtk_tooltip_show_at_widget (m_combo, YGTK_POINTER_UP_LEFT,
+ text.c_str(), GTK_STOCK_DIALOG_INFO);
+ }
+ }
+ }
+
+ virtual bool installedPackagesOnly()
+ { return ygtk_find_entry_get_selected_item (YGTK_FIND_ENTRY (m_name)) == 2; }
+
+private:
+ static void name_changed_cb (YGtkFindEntry *entry, FindEntry *pThis)
+ {
+ gint nb = ygtk_find_entry_get_selected_item (entry);
+ if (nb == 4) { // novelty only allows numbers
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ gboolean correct = TRUE;
+ for (const gchar *i = text; *i; i++)
+ if (!g_ascii_isdigit (*i)) {
+ correct = FALSE;
+ break;
+ }
+ ygtk_find_entry_set_state (entry, correct);
+ }
+ pThis->notifyDelay();
+ }
+
+ static void name_item_changed_cb (YGtkFindEntry *entry, gint nb, FindEntry *pThis)
+ {
+ const gchar *text = "";
+ if (nb == 4) text = "7"; // novelty is weird; show usage case
+ g_signal_handlers_block_by_func (entry, (gpointer) name_changed_cb, pThis);
+ gtk_entry_set_text (GTK_ENTRY (entry), text);
+ g_signal_handlers_unblock_by_func (entry, (gpointer) name_changed_cb, pThis);
+ gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+ ygtk_find_entry_set_state (entry, TRUE);
+ pThis->notify();
+ }
+
+ static void realize_cb (GtkWidget *widget, FindEntry *pThis)
+ { gtk_widget_grab_focus (widget); }
+};
+
+class FilterCombo : public QueryWidget
+{
+GtkWidget *m_box, *m_combo, *m_bin;
+bool m_onlineUpdate, m_repoMgrEnabled;
+QueryWidget *m_queryWidget;
+
+public:
+ virtual GtkWidget *getWidget() { return m_box; }
+ GtkWidget *getComboBox() { return m_combo; }
+
+ FilterCombo (bool onlineUpdate, bool repoMgrEnabled)
+ : QueryWidget(), m_onlineUpdate (onlineUpdate), m_repoMgrEnabled (repoMgrEnabled),
+ m_queryWidget (NULL)
+ {
+ m_combo = gtk_combo_box_new_text();
+ if (onlineUpdate)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Severity"));
+ else {
+ if (show_find_pane)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Search"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Groups"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Patterns"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Languages"));
+ gtk_widget_set_tooltip_markup (m_combo,
+ _("Packages can be organized in:\n"
+/*
+ "<b>Search:</b> find a given package by name, summary or some "
+ "other attribute.\n"
+*/
+ "<b>Groups:</b> simple categorization of packages by purpose.\n"
+ "<b>Patterns:</b> assists in installing all packages necessary "
+ "for several working environments.\n"
+ "<b>Languages:</b> adds another language to the system.\n"
+ "<b>Repositories:</b> catalogues what the several configured "
+ "repositories have available."));
+ }
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_combo), _("Repositories"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_combo), 0);
+ g_signal_connect (G_OBJECT (m_combo), "changed",
+ G_CALLBACK (combo_changed_cb), this);
+
+ m_bin = gtk_event_box_new();
+ m_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), m_combo, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), m_bin, TRUE, TRUE, 0);
+ select (0);
+ };
+
+ ~FilterCombo()
+ { delete m_queryWidget; }
+
+ virtual void writeQuery (Ypp::PkgQuery::Query *query)
+ { m_queryWidget->writeQuery (query); }
+
+ virtual bool availablePackagesOnly()
+ { return m_queryWidget->availablePackagesOnly(); }
+ virtual bool installedPackagesOnly()
+ { return m_queryWidget->installedPackagesOnly(); }
+
+ const char *searchName()
+ {
+ if (gtk_combo_box_get_active (GTK_COMBO_BOX (m_combo)) == 0)
+ return ((FindPane *) m_queryWidget)->searchName();
+ return NULL;
+ }
+
+ void select (int nb)
+ {
+ delete m_queryWidget;
+ if (m_onlineUpdate) {
+ switch (nb) {
+ case 0: m_queryWidget = new Categories (m_onlineUpdate); break;
+ case 1: m_queryWidget = new Repositories (m_repoMgrEnabled); break;
+ default: break;
+ }
+ }
+ else {
+ if (!show_find_pane) nb++;
+ switch (nb) {
+ case 0: m_queryWidget = new FindPane (m_onlineUpdate); break;
+ case 1: m_queryWidget = new Categories (m_onlineUpdate); break;
+ case 2: m_queryWidget = new Collection (Ypp::Package::PATTERN_TYPE); break;
+ case 3: m_queryWidget = new Collection (Ypp::Package::LANGUAGE_TYPE); break;
+ case 4: m_queryWidget = new Repositories (m_repoMgrEnabled); break;
+ default: break;
+ }
+ }
+ m_queryWidget->setListener (m_listener);
+ setChild (m_queryWidget->getWidget());
+ }
+
+private:
+ void setChild (GtkWidget *widget)
+ {
+ if (GTK_BIN (m_bin)->child)
+ gtk_container_remove (GTK_CONTAINER (m_bin), GTK_BIN (m_bin)->child);
+ gtk_container_add (GTK_CONTAINER (m_bin), widget);
+ gtk_widget_show_all (m_bin);
+ }
+
+ static void combo_changed_cb (GtkComboBox *combo, FilterCombo *pThis)
+ {
+ pThis->select (gtk_combo_box_get_active (combo));
+ pThis->notify();
+ }
+};
+
+#include "ygtknotebook.h"
+
+class QueryNotebook : public QueryListener, YGtkPackageView::Listener
+{
+GtkWidget *m_widget, *m_notebook;
+bool m_onlineUpdate;
+FilterCombo *m_combo;
+YGtkDetailView *m_details;
+GtkWidget *m_oldPage;
+guint m_timeout_id;
+bool m_disabledTab, m_highlightTab;
+UndoView *m_undoView;
+Ypp::PkgList m_packages, m_pool;
+FindEntry *m_find;
+
+public:
+ GtkWidget *getWidget() { return m_widget; }
+
+ QueryNotebook (bool onlineUpdate, bool repoMgrEnabled)
+ : m_onlineUpdate (onlineUpdate), m_timeout_id (0), m_disabledTab (true), m_highlightTab (false),
+ m_undoView (NULL)
+ {
+ m_notebook = ygtk_notebook_new();
+ gtk_widget_show (m_notebook);
+ appendPage (0, _("_Install"), GTK_STOCK_ADD);
+ if (!onlineUpdate)
+ appendPage (1, _("_Upgrade"), GTK_STOCK_GO_UP);
+ if (!onlineUpdate)
+ appendPage (2, _("_Remove"), GTK_STOCK_REMOVE);
+ else
+ appendPage (2, _("Installed"), GTK_STOCK_HARDDISK);
+ if (!onlineUpdate)
+ appendPage (3, _("_Undo"), GTK_STOCK_UNDO);
+
+ m_details = YGTK_DETAIL_VIEW (ygtk_detail_view_new (onlineUpdate));
+ GtkWidget *pkg_details_pane = gtk_vpaned_new();
+ gtk_paned_pack1 (GTK_PANED (pkg_details_pane), m_notebook, TRUE, FALSE);
+ gtk_paned_pack2 (GTK_PANED (pkg_details_pane), GTK_WIDGET (m_details), FALSE, TRUE);
+ gtk_paned_set_position (GTK_PANED (pkg_details_pane), 600);
+
+ m_combo = new FilterCombo (onlineUpdate, repoMgrEnabled);
+ m_combo->setListener (this);
+ m_combo->select (0);
+ GtkWidget *hpane = gtk_hpaned_new();
+ gtk_paned_pack1 (GTK_PANED (hpane), m_combo->getWidget(), FALSE, TRUE);
+ gtk_paned_pack2 (GTK_PANED (hpane), pkg_details_pane, TRUE, FALSE);
+ gtk_paned_set_position (GTK_PANED (hpane), 170);
+
+ m_widget = hpane;
+ gtk_widget_show_all (m_widget);
+ gtk_widget_hide (GTK_WIDGET (m_details));
+
+ m_find = NULL;
+ if (!show_find_pane) {
+ m_find = new FindEntry (onlineUpdate, m_combo->getComboBox());
+ ygtk_notebook_set_corner_widget (YGTK_NOTEBOOK (m_notebook), m_find->getWidget());
+ m_find->setListener (this);
+ }
+
+ Ypp::Package::Type type = Ypp::Package::PACKAGE_TYPE;
+ if (m_onlineUpdate)
+ type = Ypp::Package::PATCH_TYPE;
+ m_packages = Ypp::get()->getPackages (type);
+ queryNotify();
+ }
+
+ ~QueryNotebook()
+ {
+ if (m_timeout_id)
+ g_source_remove (m_timeout_id);
+ delete m_undoView;
+ delete m_combo;
+ delete m_find;
+ }
+
+ bool confirmChanges()
+ {
+ if (m_onlineUpdate) return true;
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (m_notebook)) == 3) return true;
+
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ "%s", _("Apply changes?"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Please review the changes to perfom."));
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
+ GTK_STOCK_APPLY, GTK_RESPONSE_YES, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 500);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+ GtkWidget *view = m_undoView->createView (NULL);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view);
+ gtk_widget_show_all (dialog);
+
+ gint response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ return response == GTK_RESPONSE_YES;
+ }
+
+private:
+ const char *getTooltip (int page)
+ {
+ if (m_onlineUpdate && page > 0)
+ page++;
+ switch (page) {
+ case 0: return _("Available for install");
+ case 1: return _("Upgrades");
+ case 2: return m_onlineUpdate ? _("Installed patches") : _("Installed packages");
+ case 3: return _("Undo history");
+ default: break;
+ }
+ return NULL;
+ }
+
+ // callbacks
+ virtual void queryNotify()
+ {
+ if (m_disabledTab) { // limit users to the tabs whose query is applicable
+ m_disabledTab = false;
+ for (int i = 0; i < 4; i++)
+ enablePage (i, true);
+ }
+ if (availablePackagesOnly()) {
+ enablePage (m_onlineUpdate ? 1 : 2, false, 0);
+ m_disabledTab = true;
+ }
+ else if (installedPackagesOnly()) {
+ int new_page = m_onlineUpdate ? 1 : 2;
+ enablePage (0, false, new_page);
+ m_disabledTab = true;
+ }
+
+ GtkNotebook *notebook = GTK_NOTEBOOK (m_notebook);
+ for (int i = 0; i < 3; i++) {
+ GtkWidget *page = gtk_notebook_get_nth_page (notebook, i);
+ if (page) YGTK_PACKAGE_VIEW (page)->clear();
+ }
+
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ if (!show_find_pane)
+ m_find->writeQuery (query);
+ m_combo->writeQuery (query);
+ m_pool = Ypp::PkgQuery (m_packages, query);
+
+ for (int i = 0; i < 3; i++) {
+ GtkWidget *page = gtk_notebook_get_nth_page (notebook, i);
+ if (page) {
+ YGtkPackageView *view = YGTK_PACKAGE_VIEW (page);
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ int n = i;
+ if (m_onlineUpdate && n > 0) n++;
+ switch (n) {
+ case 0: // available
+ if (m_onlineUpdate)
+ // special pane for patches upgrades makes little sense, so
+ // we instead list them together with availables
+ query->setHasUpgrade (true);
+ query->setIsInstalled (false);
+ break;
+ case 1: // upgrades
+ query->setHasUpgrade (true);
+ break;
+ case 2: // installed
+ query->setIsInstalled (true);
+ break;
+ default: break;
+ }
+ Ypp::PkgQuery list (m_pool, query);
+ if (!m_onlineUpdate) {
+ const char *applyAll = NULL;
+ if (!m_onlineUpdate && n == 1)
+ applyAll = _("Upgrade All");
+ view->setList (list, applyAll);
+ }
+ else {
+ for (int i = 0; i < 6; i++) {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->setSeverity (i);
+ Ypp::PkgQuery severity_list (list, query);
+ std::string str (Ypp::Package::severityStr (i));
+ view->appendList (str.c_str(), severity_list, NULL);
+ }
+ }
+ }
+ }
+
+ if (!m_onlineUpdate) {
+ // set tab label bold if there's a package there with the name
+ if (m_highlightTab) {
+ for (int i = 0; i < 3; i++)
+ highlightPage (i, false);
+ m_highlightTab = false;
+ }
+ const char *name;
+ if (show_find_pane)
+ name = m_combo->searchName();
+ else
+ name = m_find->searchName();
+ if (name) {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->addNames (name, 0, true, false, false, false, false, true, true);
+ Ypp::PkgQuery list (Ypp::Package::PACKAGE_TYPE, query);
+ if (list.size()) {
+ m_highlightTab = true;
+ Ypp::Package *pkg = list.get (0);
+ if (!pkg->isInstalled())
+ highlightPage (0, true);
+ else {
+ highlightPage (2, true);
+ if (pkg->hasUpgrade())
+ highlightPage (1, true);
+ }
+ }
+ }
+ }
+ }
+
+ virtual void queryNotifyDelay()
+ {
+ struct inner {
+ static gboolean timeout_cb (gpointer data)
+ {
+ QueryNotebook *pThis = (QueryNotebook *) data;
+ pThis->m_timeout_id = 0;
+ pThis->queryNotify();
+ return FALSE;
+ }
+ };
+ if (m_timeout_id) g_source_remove (m_timeout_id);
+ m_timeout_id = g_timeout_add (500, inner::timeout_cb, this);
+ }
+
+ virtual void packagesSelected (Ypp::PkgList packages)
+ {
+ m_details->setPackages (packages);
+ if (packages.size() > 0)
+ gtk_widget_show (GTK_WIDGET (m_details));
+ }
+
+ inline bool availablePackagesOnly()
+ { return m_combo->availablePackagesOnly(); }
+
+ inline bool installedPackagesOnly()
+ {
+ if (m_find && m_find->installedPackagesOnly())
+ return true;
+ return m_combo->installedPackagesOnly();
+ }
+
+ // utilities
+ void appendPage (int nb, const char *text, const char *stock)
+ {
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 6), *label, *icon;
+ if (stock) {
+ icon = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, TRUE, 0);
+ }
+ label = gtk_label_new (text);
+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ g_object_set_data (G_OBJECT (hbox), "label", label);
+ gtk_widget_show_all (hbox);
+
+ GtkWidget *page;
+ if (nb < 3) {
+ int col;
+ switch (nb) {
+ default:
+ case 0: col = TO_INSTALL_PROP; break;
+ case 1: col = TO_UPGRADE_PROP; break;
+ case 2: col = TO_REMOVE_PROP; break;
+ }
+ YGtkPackageView *view = ygtk_package_view_new (FALSE);
+ if (use_buttons) {
+ //view->appendIconColumn (NULL, ICON_PROP);
+ view->appendTextColumn (NULL, NAME_SUMMARY_PROP, 350);
+ view->appendButtonColumn (NULL, col);
+ view->setRulesHint (true);
+ }
+ else {
+ if (m_onlineUpdate && nb > 0)
+ view->appendEmptyColumn (25);
+ else
+ view->appendCheckColumn (col);
+ view->appendTextColumn (_("Name"), NAME_PROP, 160);
+ if (col == TO_UPGRADE_PROP) {
+ view->appendTextColumn (_("Installed"), INSTALLED_VERSION_PROP, -1);
+ view->appendTextColumn (_("Available"), AVAILABLE_VERSION_PROP, -1);
+ }
+ else
+ view->appendTextColumn (_("Summary"), SUMMARY_PROP);
+ }
+ view->setListener (this);
+ page = GTK_WIDGET (view);
+ }
+ else {
+ m_undoView = new UndoView (this);
+ page = m_undoView->getWidget();
+ }
+ gtk_notebook_append_page (GTK_NOTEBOOK (m_notebook), page, hbox);
+ }
+
+ void enablePage (int page_nb, bool enabled, int new_page_nb = -1)
+ {
+ GtkNotebook *notebook = GTK_NOTEBOOK (m_notebook);
+ GtkWidget *page = gtk_notebook_get_nth_page (notebook, page_nb);
+ if (page) {
+ GtkWidget *label = gtk_notebook_get_tab_label (notebook, page);
+ gtk_widget_set_sensitive (label, enabled);
+ const char *tooltip = getTooltip (page_nb);
+ if (!enabled)
+ tooltip = _("Query only applicable to available packages.");
+ gtk_widget_set_tooltip_text (label, tooltip);
+ if (!enabled && new_page_nb >= 0) {
+ GtkWidget *selected = gtk_notebook_get_nth_page (notebook,
+ gtk_notebook_get_current_page (notebook));
+ if (selected == page)
+ gtk_notebook_set_current_page (notebook, new_page_nb);
+ }
+ }
+ }
+
+ void highlightPage (int page_nb, bool highlight)
+ {
+ GtkNotebook *notebook = GTK_NOTEBOOK (m_notebook);
+ GtkWidget *label = gtk_notebook_get_tab_label (notebook,
+ gtk_notebook_get_nth_page (notebook, page_nb));
+ label = (GtkWidget *) g_object_get_data (G_OBJECT (label), "label");
+ YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL,
+ highlight ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, PANGO_SCALE_MEDIUM);
+ }
+};
+#endif
+
+class ToolsBox
+{
+GtkWidget *m_box;
+
+public:
+ GtkWidget *getWidget() { return m_box; }
+
+ ToolsBox()
+ {
+ GtkWidget *button, *popup, *item;
+ button = ygtk_menu_button_new_with_label (_("Tools"));
+ popup = gtk_menu_new();
+
+ item = gtk_menu_item_new_with_label (_("Import List..."));
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (G_OBJECT (item), "activate",
+ G_CALLBACK (import_file_cb), this);
+ item = gtk_menu_item_new_with_label (_("Export List..."));
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (G_OBJECT (item), "activate",
+ G_CALLBACK (export_file_cb), this);
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), gtk_separator_menu_item_new());
+ item = gtk_menu_item_new_with_label (_("Generate Dependency Testcase..."));
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+ g_signal_connect (G_OBJECT (item), "activate",
+ G_CALLBACK (create_solver_testcase_cb), this);
+
+ ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (button), popup);
+ gtk_widget_show_all (popup);
+
+ m_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), button, FALSE, TRUE, 0);
+ gtk_widget_show_all (m_box);
+ }
+
+private:
+ static void errorMsg (const std::string &header, const std::string &message)
+ {
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "%s", header.c_str());
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
+ "%s", message.c_str());
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+
+ static void import_file_cb (GtkMenuItem *item, ToolsBox *pThis)
+ {
+ GtkWidget *dialog;
+ dialog = gtk_file_chooser_dialog_new (_("Import Package List"),
+ YGDialog::currentWindow(), GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+
+ int ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (ret == GTK_RESPONSE_ACCEPT) {
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (!Ypp::get()->importList (filename)) {
+ std::string error = _("Couldn't load package list from: ");
+ error += filename;
+ errorMsg (_("Import Failed"), error);
+ }
+ g_free (filename);
+ }
+ gtk_widget_destroy (dialog);
+ }
+
+ static void export_file_cb (GtkMenuItem *item, ToolsBox *pThis)
+ {
+ GtkWidget *dialog;
+ dialog = gtk_file_chooser_dialog_new (_("Export Package List"),
+ YGDialog::currentWindow(), GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
+
+ int ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (ret == GTK_RESPONSE_ACCEPT) {
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (!Ypp::get()->exportList (filename)) {
+ std::string error = _("Couldn't save package list to: ");
+ error += filename;
+ errorMsg (_("Export Failed"), error);
+ }
+ g_free (filename);
+ }
+ gtk_widget_destroy (dialog);
+ }
+
+ static void create_solver_testcase_cb (GtkMenuItem *item)
+ {
+ const char *dirname = "/var/log/YaST2/solverTestcase";
+ std::string msg = _("Use this to generate extensive logs to help tracking down "
+ "bugs in the dependency resolver.\nThe logs will be stored in "
+ "directory: ");
+ msg += dirname;
+
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL,
+ "%s", _("Create Dependency Resolver Test Case"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", msg.c_str());
+ int ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (ret == GTK_RESPONSE_OK) {
+ if (Ypp::get()->createSolverTestcase (dirname)) {
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO, "%s", _("Success"));
+ msg = _("Dependency resolver test case written to");
+ msg += " <tt>";
+ msg += dirname;
+ msg += "</tt>\n";
+ msg += _("Prepare <tt>y2logs.tgz tar</tt> archive to attach to Bugzilla?");
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
+ "%s", msg.c_str());
+ ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (ret == GTK_RESPONSE_YES)
+ YGUI::ui()->askSaveLogs();
+ }
+ else {
+ msg = _("Failed to create dependency resolver test case.\n"
+ "Please check disk space and permissions for");
+ msg += " <tt>";
+ msg += dirname;
+ msg += "</tt>";
+ errorMsg ("Error", msg.c_str());
+ }
+ }
+ }
+};
+
+//** Dialogs
+
+static bool confirmCancel()
+{
+ if (!Ypp::get()->isModified())
+ return true;
+
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+ "%s", _("Changes not saved!"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
+ _("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;
+}
+
+bool confirmApply()
+{
+ if (!Ypp::get()->isModified())
+ return true;
+
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ "%s", _("Apply changes?"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Please review the changes to perfom."));
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
+ GTK_STOCK_APPLY, GTK_RESPONSE_YES, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 500);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+#if 0
+ GtkWidget *view = m_undoView->createView (NULL);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view);
+#endif
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
+ gtk_label_new ("TO DO\n\nTo download: xxx\nHard disk needed: xxx"));
+ gtk_widget_show_all (dialog);
+
+ gint response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ return response == GTK_RESPONSE_YES;
+}
+
+static bool confirmPkgs (const char *title, const char *message,
+ GtkMessageType icon, const Ypp::PkgList list,
+ const std::string &extraProp)
+{
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GtkDialogFlags (0), icon, GTK_BUTTONS_NONE, "%s", title);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
+ GTK_STOCK_APPLY, GTK_RESPONSE_YES, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 500);
+ gtk_widget_show_all (dialog);
+
+ YGtkPackageView *view = ygtk_package_view_new (TRUE);
+ view->setVisible (extraProp, true);
+ view->setList (list, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), GTK_WIDGET (view));
+
+ bool confirm = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES);
+ gtk_widget_destroy (dialog);
+ return confirm;
+}
+
+static bool askConfirmUnsupported()
+{
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->setIsInstalled (false);
+ query->setToModify (true);
+ query->setIsSupported (false);
+
+ Ypp::PkgQuery list (Ypp::Package::PACKAGE_TYPE, query);
+ if (list.size() > 0)
+ return confirmPkgs (_("Unsupported Packages"), _("Please realize that the following "
+ "software is either unsupported or requires an additional customer contract "
+ "for support."), GTK_MESSAGE_WARNING, list, "support");
+ return true;
+}
+
+static bool acceptText (Ypp::Package *package, const std::string &title,
+ const std::string &open, const std::string &text, bool question)
+{
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ (GtkDialogFlags) 0, question ? GTK_MESSAGE_QUESTION : GTK_MESSAGE_INFO,
+ question ? GTK_BUTTONS_YES_NO : GTK_BUTTONS_OK,
+ "%s %s", package->name().c_str(), title.c_str());
+ if (!open.empty())
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", open.c_str());
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+ GtkWidget *view = ygtk_html_wrap_new(), *scroll;
+ ygtk_html_wrap_set_text (view, text.c_str(), FALSE);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type
+ (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scroll), view);
+
+ GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox);
+ gtk_box_pack_start (vbox, scroll, TRUE, TRUE, 6);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 500);
+ gtk_widget_show_all (dialog);
+
+ gint ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ bool confirmed = (ret == GTK_RESPONSE_YES);
+ gtk_widget_destroy (dialog);
+ return confirmed;
+}
+
+static bool resolveProblems (const std::list <Ypp::Problem *> &problems)
+{
+ // we can't use ordinary radio buttons, as gtk+ enforces that in a group
+ // one must be selected...
+ #define DETAILS_PAD 25
+ enum ColumnAlias {
+ SHOW_TOGGLE_COL, ACTIVE_TOGGLE_COL, TEXT_COL, WEIGHT_TEXT_COL,
+ TEXT_PAD_COL, APPLY_PTR_COL, TOTAL_COLS
+ };
+
+ 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);
+ if (!apply)
+ return;
+
+ // 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);
+ if (apply) *apply = false;
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ enabled = !enabled;
+ *apply = enabled;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, enabled, -1);
+ }
+ 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);
+ }
+ };
+
+ // model
+ GtkTreeStore *store = gtk_tree_store_new (TOTAL_COLS,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT,
+ G_TYPE_INT, G_TYPE_POINTER);
+ for (std::list <Ypp::Problem *>::const_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, -1);
+ if (!(*it)->details.empty()) {
+ GtkTreeIter details_iter;
+ gtk_tree_store_append (store, &details_iter, &problem_iter);
+ gtk_tree_store_set (store, &details_iter, SHOW_TOGGLE_COL, FALSE,
+ TEXT_COL, (*it)->details.c_str(), TEXT_PAD_COL, DETAILS_PAD, -1);
+ }
+
+ for (int i = 0; (*it)->getSolution (i); i++) {
+ Ypp::Problem::Solution *solution = (*it)->getSolution (i);
+ GtkTreeIter solution_iter;
+ gtk_tree_store_append (store, &solution_iter, &problem_iter);
+ gtk_tree_store_set (store, &solution_iter, SHOW_TOGGLE_COL, TRUE,
+ WEIGHT_TEXT_COL, PANGO_WEIGHT_NORMAL,
+ ACTIVE_TOGGLE_COL, FALSE, TEXT_COL, solution->description.c_str(),
+ APPLY_PTR_COL, &solution->apply, -1);
+ if (!solution->details.empty()) {
+ gtk_tree_store_append (store, &solution_iter, &problem_iter);
+ gtk_tree_store_set (store, &solution_iter, SHOW_TOGGLE_COL, FALSE,
+ WEIGHT_TEXT_COL, PANGO_WEIGHT_NORMAL,
+ TEXT_COL, solution->details.c_str(), TEXT_PAD_COL, DETAILS_PAD, -1);
+ }
+ }
+ }
+
+ // interface
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GtkDialogFlags (0), GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, "%s",
+ _("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);
+ // 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();
+ g_object_set (G_OBJECT (renderer), "wrap-width", 400, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "text", TEXT_COL, "weight", WEIGHT_TEXT_COL, "xpad", TEXT_PAD_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);
+
+ 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);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 500);
+ gtk_widget_show_all (dialog);
+
+ bool apply = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_APPLY);
+ gtk_widget_destroy (dialog);
+ return apply;
+}
+
+struct _QueryListener
+{
+ virtual void refresh() = 0;
+};
+
+struct _QueryWidget
+{
+ virtual GtkWidget *getWidget() = 0;
+
+ virtual void updateType (Ypp::Package::Type type) = 0;
+ virtual void updateList (Ypp::PkgList list) = 0;
+ virtual bool begsUpdate() = 0;
+
+ virtual bool writeQuery (Ypp::PkgQuery::Query *query) = 0;
+
+ void setListener (_QueryListener *listener)
+ { m_listener = listener; }
+
+//protected:
+ _QueryWidget() : m_listener (NULL) {}
+ virtual ~_QueryWidget() {}
+
+ void notify() { if (m_listener) m_listener->refresh(); }
+
+ void notifyDelay()
+ {
+ static guint timeout_id = 0;
+ struct inner {
+ static gboolean timeout_cb (gpointer data)
+ {
+ _QueryWidget *pThis = (_QueryWidget *) data;
+ timeout_id = 0;
+ pThis->notify();
+ return FALSE;
+ }
+ };
+ if (timeout_id) g_source_remove (timeout_id);
+ timeout_id = g_timeout_add (500, inner::timeout_cb, this);
+ }
+
+private:
+ _QueryListener *m_listener;
+};
+
+class SearchEntry : public _QueryWidget
+{
+GtkWidget *m_widget, *m_entry;
+bool m_clearIcon;
+
+public:
+ SearchEntry() : _QueryWidget()
+ {
+ m_entry = gtk_entry_new();
+ g_signal_connect (G_OBJECT (m_entry), "realize",
+ G_CALLBACK (grab_focus_cb), NULL);
+ gtk_widget_set_size_request (m_entry, 50, -1);
+ GtkWidget *entry_hbox = gtk_hbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (entry_hbox), gtk_label_new (_("Find:")), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (entry_hbox), m_entry, TRUE, TRUE, 0);
+
+ m_clearIcon = false;
+ g_signal_connect (G_OBJECT (m_entry), "changed",
+ G_CALLBACK (entry_changed_cb), this);
+ g_signal_connect (G_OBJECT (m_entry), "icon-press",
+ G_CALLBACK (icon_press_cb), this);
+
+ m_widget = gtk_vbox_new (FALSE, 4);
+ GtkWidget *expander = gtk_expander_new (_("Options"));
+ gtk_container_add (GTK_CONTAINER (expander), gtk_label_new ("TO DO"));
+ gtk_box_pack_start (GTK_BOX (m_widget), entry_hbox, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_widget), expander, FALSE, TRUE, 0);
+ }
+
+ virtual GtkWidget *getWidget() { return m_widget; }
+
+ virtual void updateType (Ypp::Package::Type type) {}
+ virtual void updateList (Ypp::PkgList list) {}
+ virtual bool begsUpdate() { return false; }
+
+ virtual bool writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ const gchar *name = gtk_entry_get_text (GTK_ENTRY (m_entry));
+ if (*name) {
+ query->addNames (name, ' ');
+ return true;
+ }
+ return false;
+ }
+
+ static void entry_changed_cb (GtkEditable *editable, SearchEntry *pThis)
+ {
+ pThis->notifyDelay();
+
+ const gchar *name = gtk_entry_get_text (GTK_ENTRY (editable));
+ bool icon = *name;
+ if (pThis->m_clearIcon != icon) {
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (editable),
+ GTK_ENTRY_ICON_SECONDARY, icon ? GTK_STOCK_CLEAR : NULL);
+ gtk_entry_set_icon_activatable (GTK_ENTRY (editable),
+ GTK_ENTRY_ICON_SECONDARY, icon);
+ if (icon)
+ gtk_entry_set_icon_tooltip_text (GTK_ENTRY (editable),
+ GTK_ENTRY_ICON_SECONDARY, _("Clear"));
+ pThis->m_clearIcon = icon;
+ }
+ }
+
+ static void icon_press_cb (GtkEntry *entry, GtkEntryIconPosition pos,
+ GdkEvent *event, SearchEntry *pThis)
+ { gtk_entry_set_text (entry, ""); }
+
+ static void grab_focus_cb (GtkWidget *widget)
+ { gtk_widget_grab_focus (widget); }
+};
+
+static void selection_changed_cb (GtkTreeSelection *selection, _QueryWidget *pThis)
+{
+ if (gtk_tree_selection_get_selected (selection, NULL, NULL))
+ pThis->notify();
+}
+
+static GtkWidget *tree_view_new()
+{
+ GtkWidget *view = gtk_tree_view_new();
+ GtkTreeView *tview = GTK_TREE_VIEW (view);
+ gtk_tree_view_set_headers_visible (tview, FALSE);
+ gtk_tree_view_set_search_column (tview, 0);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (tview);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (
+ NULL, renderer, "markup", 0, NULL);
+ gtk_tree_view_append_column (tview, column);
+ return view;
+}
+
+static GtkWidget *scrolled_window_new (GtkWidget *child)
+{
+ GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scroll), child);
+ return scroll;
+}
+
+static void list_store_set_text_count (GtkListStore *store, GtkTreeIter *iter,
+ const char *text, int count)
+{
+ gchar *_text = g_strdup_printf ("%s <small>(%d)</small>", text, count);
+ gtk_list_store_set (store, iter, 0, _text, 1, count > 0, -1);
+ g_free (_text);
+}
+
+class CategoryView : public _QueryWidget
+{
+GtkWidget *m_widget, *m_view;
+GtkTreeModel *m_model;
+bool m_type2;
+
+public:
+ CategoryView() : _QueryWidget()
+ {
+ m_type2 = false;
+ m_view = tree_view_new();
+ GtkWidget *scroll = scrolled_window_new (m_view);
+
+ GtkWidget *combo = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Categories"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Repositories"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+ g_signal_connect (G_OBJECT (combo), "changed",
+ G_CALLBACK (combo_changed_cb), this);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+ m_widget = vbox;
+
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (selection_changed_cb), this);
+ }
+
+ virtual GtkWidget *getWidget()
+ { return m_widget; }
+
+ virtual void updateType (Ypp::Package::Type type)
+ {
+ m_type2 = type == Ypp::Package::PACKAGE_TYPE;
+
+ GtkListStore *store;
+ GtkTreeIter iter;
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
+ m_model = GTK_TREE_MODEL (store);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, NULL, -1);
+ Ypp::Node *category;
+ if (m_type2)
+ category = Ypp::get()->getFirstCategory2 (type);
+ else
+ category = Ypp::get()->getFirstCategory (type);
+ for (; category; category = category->next()) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, category, -1);
+ }
+ GtkTreeModel *filter_model = gtk_tree_model_filter_new (m_model, NULL);
+ gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 1);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), filter_model);
+ g_object_unref (G_OBJECT (store));
+ g_object_unref (G_OBJECT (filter_model));
+
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ g_signal_handlers_block_by_func (selection, (gpointer) selection_changed_cb, this);
+ gtk_tree_model_get_iter_first (filter_model, &iter);
+ gtk_tree_selection_select_iter (selection, &iter);
+ g_signal_handlers_unblock_by_func (selection, (gpointer) selection_changed_cb, this);
+ }
+
+ virtual void updateList (Ypp::PkgList list)
+ {
+ GtkTreeModel *model = GTK_TREE_MODEL (m_model);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first (model, &iter))
+ do {
+ Ypp::Node *category;
+ gtk_tree_model_get (model, &iter, 2, &category, -1);
+
+ GtkListStore *store = GTK_LIST_STORE (model);
+ if (category) {
+ int categoriesNb = 0;
+ for (int i = 0; i < list.size(); i++) {
+ Ypp::Package *pkg = list.get (i);
+ Ypp::Node *pkg_category = m_type2 ? pkg->category2() : pkg->category();
+ if (pkg_category == category)
+ categoriesNb++;
+ }
+ list_store_set_text_count (store, &iter, category->name.c_str(), categoriesNb);
+ }
+ else
+ list_store_set_text_count (store, &iter, _("All Categories"), list.size());
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ virtual bool begsUpdate() { return true; }
+
+ virtual bool writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ Ypp::Node *category;
+ gtk_tree_model_get (model, &iter, 2, &category, -1);
+ if (category) {
+ if (m_type2)
+ query->addCategory2 (category);
+ else
+ query->addCategory (category);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static void combo_changed_cb (GtkComboBox *combo, CategoryView *pThis)
+ {
+ }
+};
+
+class StatusView : public _QueryWidget
+{
+GtkWidget *m_widget, *m_view;
+GtkTreeModel *m_model;
+
+public:
+ StatusView() : _QueryWidget()
+ {
+ m_view = tree_view_new();
+ m_widget = scrolled_window_new (m_view);
+
+ GtkListStore *store;
+ GtkTreeIter iter;
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT);
+ m_model = GTK_TREE_MODEL (store);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, 0, -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, 1, -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, 2, -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, 3, -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 1, TRUE, 2, 4, -1);
+
+ GtkTreeModel *filter_model = gtk_tree_model_filter_new (m_model, NULL);
+ gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 1);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), filter_model);
+ g_object_unref (G_OBJECT (store));
+ g_object_unref (G_OBJECT (filter_model));
+
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ gtk_tree_model_get_iter_first (filter_model, &iter);
+ gtk_tree_selection_select_iter (selection, &iter);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (selection_changed_cb), this);
+ }
+
+ virtual GtkWidget *getWidget()
+ { return m_widget; }
+
+ virtual void updateType (Ypp::Package::Type type) {}
+
+ virtual void updateList (Ypp::PkgList list)
+ {
+ int installedNb = 0, upgradableNb = 0, notInstalledNb = 0, modifiedNb = 0;
+ for (int i = 0; i < list.size(); i++) {
+ Ypp::Package *pkg = list.get (i);
+ if (pkg->isInstalled()) {
+ installedNb++;
+ if (pkg->hasUpgrade())
+ upgradableNb++;
+ }
+ else
+ notInstalledNb++;
+ if (pkg->toModify())
+ modifiedNb++;
+ }
+
+ GtkTreeModel *model = m_model;
+ GtkTreeIter iter;
+ GtkListStore *store = GTK_LIST_STORE (model);
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, 0);
+ list_store_set_text_count (store, &iter, _("Any Status"), list.size());
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, 1);
+ list_store_set_text_count (store, &iter, _("Not Installed"), notInstalledNb);
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, 2);
+ list_store_set_text_count (store, &iter, _("Installed"), installedNb);
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, 3);
+ list_store_set_text_count (store, &iter, _("Upgradable"), upgradableNb);
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, 4);
+ list_store_set_text_count (store, &iter, _("Modified"), modifiedNb);
+ }
+
+ virtual bool begsUpdate() { return true; }
+
+ virtual bool writeQuery (Ypp::PkgQuery::Query *query)
+ {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view));
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ int status;
+ gtk_tree_model_get (model, &iter, 2, &status, -1);
+ switch (status) {
+ case 0: default: break;
+ case 1: query->setIsInstalled (false); break;
+ case 2: query->setIsInstalled (true); break;
+ case 3: query->setHasUpgrade (true); break;
+ case 4: query->setToModify (true); break;
+ }
+ if (status > 0 && status <= 4)
+ return true;
+ }
+ return false;
+ }
+};
+
+class DetailBox
+{
+GtkWidget *m_widget, *m_text, *m_pkg_view;
+
+public:
+ GtkWidget *getWidget() { return m_widget; }
+
+ DetailBox()
+ {
+ m_text = ygtk_rich_text_new();
+ YGtkPackageView *view = ygtk_package_view_new (TRUE);
+ m_pkg_view = GTK_WIDGET (view);
+ //gtk_widget_set_size_request (m_pkg_view, -1, 200);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 18);
+ gtk_box_pack_start (GTK_BOX (vbox), m_text, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), m_pkg_view, TRUE, TRUE, 0);
+
+ m_widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (m_widget), vbox);
+ }
+
+ void setPackage (Ypp::Package *package)
+ {
+ if (package) {
+ std::string text = package->description (HTML_MARKUP);
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (m_text), text.c_str());
+ gtk_widget_show (m_widget);
+ }
+ else
+ ygtk_rich_text_set_plain_text (YGTK_RICH_TEXT (m_text), "");
+
+ if (package && package->type() != Ypp::Package::PACKAGE_TYPE) {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->addCollection (package);
+ Ypp::PkgQuery list (Ypp::Package::PACKAGE_TYPE, query);
+ ((YGtkPackageView *) m_pkg_view)->setList (list, NULL);
+ gtk_widget_show (m_pkg_view);
+ }
+ else
+ gtk_widget_hide (m_pkg_view);
+ }
+};
+
+class UI : public YGtkPackageView::Listener, _QueryListener, Ypp::Disk::Listener
+{
+GtkWidget *m_widget, *m_view, *m_disk_label;
+_QueryWidget *m_query[3];
+DetailBox *m_details;
+DiskView *m_disk;
+Ypp::Package::Type m_type;
+
+public:
+ GtkWidget *getWidget() { return m_widget; }
+
+ UI() : m_type (Ypp::Package::PACKAGE_TYPE)
+ {
+ YGtkPackageView *view = ygtk_package_view_new (TRUE);
+ view->setListener (this);
+ m_view = GTK_WIDGET (view);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
+
+ GtkWidget *view_pane = gtk_vpaned_new();
+ gtk_paned_pack1 (GTK_PANED (view_pane), m_view, TRUE, FALSE);
+ m_details = new DetailBox();
+ gtk_paned_pack2 (GTK_PANED (view_pane), m_details->getWidget(), FALSE, TRUE);
+
+ GtkWidget *combo = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Package"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Pattern"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Language"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+ g_signal_connect (G_OBJECT (combo), "changed",
+ G_CALLBACK (type_changed_cb), this);
+
+ m_disk = new DiskView();
+ m_disk_label = gtk_label_new ("");
+
+ GtkWidget *type_hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (type_hbox), m_disk_label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (type_hbox), m_disk->getWidget(), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (type_hbox), gtk_event_box_new(), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (type_hbox), gtk_label_new (_("Type:")), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (type_hbox), combo, FALSE, TRUE, 0);
+
+ GtkWidget *view_vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (view_vbox), view_pane, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (view_vbox), type_hbox, FALSE, TRUE, 0);
+
+ GtkWidget *side_vbox = gtk_vbox_new (FALSE, 6);
+ m_query[0] = new SearchEntry();
+ gtk_box_pack_start (GTK_BOX (side_vbox), m_query[0]->getWidget(), FALSE, TRUE, 0);
+
+ m_query[1] = new CategoryView();
+ m_query[2] = new StatusView();
+
+ GtkWidget *cat_pane = gtk_vpaned_new();
+ gtk_paned_pack1 (GTK_PANED (cat_pane), m_query[1]->getWidget(), TRUE, FALSE);
+ gtk_paned_pack2 (GTK_PANED (cat_pane), m_query[2]->getWidget(), TRUE, FALSE);
+ gtk_box_pack_start (GTK_BOX (side_vbox), cat_pane, TRUE, TRUE, 0);
+
+ GtkWidget *side_pane = gtk_hpaned_new();
+ gtk_paned_pack1 (GTK_PANED (side_pane), side_vbox, FALSE, FALSE);
+ gtk_paned_pack2 (GTK_PANED (side_pane), view_vbox, TRUE, FALSE);
+ gtk_paned_set_position (GTK_PANED (side_pane), 150);
+
+ for (int i = 0; i < 3; i++) {
+ m_query[i]->updateType (m_type);
+ m_query[i]->setListener (this);
+ }
+ refresh();
+ updateDisk();
+ Ypp::get()->getDisk()->addListener (this);
+ m_widget = side_pane;
+ gtk_widget_show_all (m_widget);
+ gtk_widget_hide (m_details->getWidget());
+ }
+
+ ~UI()
+ {
+ for (int i = 0; i < 3; i++)
+ delete m_query[i];
+ delete m_disk;
+ }
+
+private:
+ void updateWidget (_QueryWidget *widget)
+ {
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ for (int i = 0; i < 3; i++) {
+ if (m_query[i] == widget)
+ continue;
+ m_query[i]->writeQuery (query);
+ }
+
+ Ypp::PkgQuery list (m_type, query);
+ widget->updateList (list);
+ }
+
+ virtual void refresh()
+ {
+ bool widgetModified[3] = { false };
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ for (int i = 0; i < 3; i++)
+ widgetModified[i] = m_query[i]->writeQuery (query);
+
+ Ypp::PkgQuery list (m_type, query);
+ ((YGtkPackageView *) m_view)->setList (list, NULL);
+
+ for (int i = 0; i < 3; i++)
+ if (m_query[i]->begsUpdate()) {
+ if (widgetModified[i])
+ updateWidget (m_query[i]);
+ else
+ m_query[i]->updateList (list);
+ }
+ }
+
+ virtual void packagesSelected (Ypp::PkgList packages)
+ {
+ m_details->setPackage (packages.size() ? packages.get (0) : NULL);
+ }
+
+ virtual void updateDisk()
+ {
+ Ypp::Disk *disk = Ypp::get()->getDisk();
+ const Ypp::Disk::Partition *part = 0;
+ for (int i = 0; disk->getPartition (i); i++) {
+ const Ypp::Disk::Partition *p = disk->getPartition (i);
+ if (p->path == "/usr" || p->path == "/usr/") {
+ part = p;
+ break;
+ }
+ if (p->path == "/")
+ part = p;
+ }
+ if (part) {
+ gchar *text;
+ if (part->delta)
+ text = g_strdup_printf ("Free disk space: %s (%s%s)", part->free_str.c_str(),
+ part->delta > 0 ? "+" : "", part->delta_str.c_str());
+ else
+ text = g_strdup_printf ("Free disk space: %s", part->free_str.c_str());
+ gtk_label_set_text (GTK_LABEL (m_disk_label), text);
+ g_free (text);
+ }
+ else
+ gtk_label_set_text (GTK_LABEL (m_disk_label), "");
+ }
+
+ static void type_changed_cb (GtkComboBox *combo, UI *pThis)
+ {
+ pThis->m_type = (Ypp::Package::Type) gtk_combo_box_get_active (combo);
+ for (int i = 0; i < 3; i++)
+ pThis->m_query[i]->updateType (pThis->m_type);
+ pThis->refresh();
+ }
+};
+
+#include <YPackageSelector.h>
+#include "pkg-selector-help.h"
+
+class YGPackageSelector : public YPackageSelector, public YGWidget, public Ypp::Interface
+{
+ToolsBox *m_tools;
+GtkWidget *m_progressbar;
+guint m_button_timeout_id;
+
+public:
+ YGPackageSelector (YWidget *parent, long mode)
+ : YPackageSelector (NULL, mode)
+ , YGWidget (this, parent, YGTK_TYPE_WIZARD, NULL)
+ {
+ setBorder (0);
+ bool onlineUpdate = onlineUpdateMode();
+ YGDialog *dialog = YGDialog::currentDialog();
+ dialog->setCloseCallback (confirm_cb, this);
+ dialog->setMinSize (700, 800); // enlarge
+
+ YGtkWizard *wizard = YGTK_WIZARD (getWidget());
+ ygtk_wizard_set_header_icon (wizard,
+ THEMEDIR "/icons/22x22/apps/yast-software.png");
+ const char *title = onlineUpdate ? _("Online Update") : _("Software Manager");
+ ygtk_wizard_set_header_text (wizard, title);
+ ygtk_wizard_set_help_text (wizard, _("Please wait..."));
+
+ ygtk_wizard_set_button_label (wizard, wizard->abort_button,
+ _("_Cancel"), GTK_STOCK_CANCEL);
+ ygtk_wizard_set_button_str_id (wizard, wizard->abort_button, "cancel");
+ ygtk_wizard_set_button_label (wizard, wizard->back_button, NULL, NULL);
+ ygtk_wizard_set_button_label (wizard, wizard->next_button,
+ _("A_pply"), GTK_STOCK_APPLY);
+ ygtk_wizard_set_button_str_id (wizard, wizard->next_button, "accept");
+ g_signal_connect (G_OBJECT (wizard), "action-triggered",
+ G_CALLBACK (wizard_action_cb), this);
+ ygtk_wizard_enable_button (wizard, wizard->next_button, FALSE);
+
+ m_tools = new ToolsBox();
+ ygtk_wizard_set_extra_button (YGTK_WIZARD (getWidget()), m_tools->getWidget());
+
+ m_progressbar = gtk_progress_bar_new();
+ GtkWidget *empty = gtk_event_box_new();
+ gtk_widget_set_size_request (empty, -1, 36);
+ gtk_widget_show (empty);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_end (GTK_BOX (vbox), empty, FALSE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (vbox), m_progressbar, FALSE, TRUE, 0);
+ gtk_widget_show (vbox);
+ ygtk_wizard_set_child (YGTK_WIZARD (wizard), vbox);
+ Ypp::get()->setInterface (this);
+
+/* m_notebook = new QueryNotebook (onlineUpdate, repoMgrEnabled());
+ gtk_box_pack_start (GTK_BOX (vbox), m_notebook->getWidget(), TRUE, TRUE, 0);
+*/
+ UI *ui = new UI();
+ gtk_box_pack_start (GTK_BOX (vbox), ui->getWidget(), TRUE, TRUE, 0);
+ gtk_widget_hide (empty);
+
+ const char **help = onlineUpdate ? patch_help : pkg_help;
+ std::string str;
+ str.reserve (6144);
+ for (int i = 0; help[i]; i++)
+ str.append (help [i]);
+ ygtk_wizard_set_help_text (wizard, str.c_str());
+ dialog->setTitle (title);
+ m_button_timeout_id = g_timeout_add (7500, wizard_enable_button_cb, this);
+ }
+
+ virtual ~YGPackageSelector()
+ {
+ if (m_button_timeout_id)
+ g_source_remove (m_button_timeout_id);
+// delete m_notebook;
+ delete m_tools;
+ Ypp::finish();
+ }
+
+ // (Y)Gtk callbacks
+ static gboolean wizard_enable_button_cb (gpointer data)
+ {
+ YGPackageSelector *pThis = (YGPackageSelector *) data;
+ pThis->m_button_timeout_id = 0;
+ YGtkWizard *wizard = YGTK_WIZARD (pThis->getWidget());
+ ygtk_wizard_enable_button (wizard, wizard->next_button, TRUE);
+ return FALSE;
+ }
+
+ static bool confirm_cb (void *pThis)
+ { return confirmCancel(); }
+
+ static void wizard_action_cb (YGtkWizard *wizard, gpointer id,
+ gint id_type, YGPackageSelector *pThis)
+ {
+ const gchar *action = (gchar *) id;
+ yuiMilestone() << "Closing PackageSelector with '" << action << "'\n";
+ if (!strcmp (action, "accept")) {
+ if (!pThis->onlineUpdateMode()) {
+ if (pThis->confirmUnsupported())
+ if (!askConfirmUnsupported())
+ return;
+ }
+ if (confirmApply())
+ YGUI::ui()->sendEvent (new YMenuEvent ("accept"));
+ }
+ else if (!strcmp (action, "cancel"))
+ if (confirmCancel())
+ YGUI::ui()->sendEvent (new YCancelEvent());
+ }
+
+ // Ypp callbacks
+ virtual bool acceptLicense (Ypp::Package *package, const std::string &license)
+ {
+ return acceptText (package, _("License Agreement"),
+ _("Do you accept the terms of this license?"), license, true);
+ }
+
+ virtual void notifyMessage (Ypp::Package *package, const std::string &msg)
+ { acceptText (package, _("Notification"), "", msg, false); }
+
+ virtual bool resolveProblems (const std::list <Ypp::Problem *> &problems)
+ { return ::resolveProblems (problems); }
+
+ virtual bool allowRestrictedRepo (const Ypp::PkgList list)
+ {
+ return confirmPkgs (_("Dependencies from Filtered Repositories"),
+ _("The following packages have necessary dependencies that are not provided "
+ "by the filtered repository. Install them?"), GTK_MESSAGE_WARNING, list,
+ "repository");
+ }
+
+ virtual void loading (float progress)
+ {
+ if (progress == 1) {
+ if (GTK_WIDGET_VISIBLE (m_progressbar)) {
+ gtk_widget_hide (m_progressbar);
+ while (g_main_context_iteration (NULL, FALSE)) ;
+ }
+ YGUI::ui()->normalCursor();
+ }
+ else {
+ if (progress == 0)
+ YGUI::ui()->busyCursor();
+ else { // progress=0 may be to trigger cursor only
+ gtk_widget_show (m_progressbar);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (m_progressbar), progress);
+ }
+ while (g_main_context_iteration (NULL, FALSE)) ;
+ }
+ }
+
+ YGWIDGET_IMPL_COMMON (YPackageSelector)
+};
+
+#include "pkg/YGPackageSelectorPluginImpl.h"
+
+YPackageSelector *
+YGPackageSelectorPluginImpl::createPackageSelector (YWidget *parent, long modeFlags)
+{ return new YGPackageSelector (parent, modeFlags); }
+
Added: trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/YGPackageSelectorPlu…
==============================================================================
--- trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.cc (added)
+++ trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,12 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+#include "pkg/YGPackageSelectorPluginImpl.h"
+
+extern "C"
+{
+ // Important to locate this symbol - see YGPackageSelectorPluginStub.cc
+ YGPackageSelectorPluginImpl PSP;
+}
+
Added: trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/YGPackageSelectorPlu…
==============================================================================
--- trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.h (added)
+++ trunk/gtk/src/pkg/YGPackageSelectorPluginImpl.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,22 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+#ifndef YGPACKAGE_SELECTOR_PLUGIN_IMPL_H
+#define YGPACKAGE_SELECTOR_PLUGIN_IMPL_H
+
+struct YPackageSelector;
+struct YWidget;
+
+#include "YGPackageSelectorPluginIf.h"
+
+class YGPackageSelectorPluginImpl : public YGPackageSelectorPluginIf
+{
+public:
+ virtual YPackageSelector *createPackageSelector (YWidget *parent, long modeFlags);
+ virtual YWidget *createPatternSelector (YWidget *parent, long modeFlags) { return 0; }
+ virtual YWidget *createSimplePatchSelector (YWidget *parent, long modeFlags) { return 0; }
+};
+
+#endif /*YGPACKAGE_SELECTOR_PLUGIN_IMPL_H*/
+
Added: trunk/gtk/src/pkg/pkg-selector-help.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/pkg-selector-help.h?…
==============================================================================
--- trunk/gtk/src/pkg/pkg-selector-help.h (added)
+++ trunk/gtk/src/pkg/pkg-selector-help.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,97 @@
+/*
+ Textdomain "yast2-gtk"
+ */
+
+static const char *pkg_help[] = {
+ _("<h1>Purpose</h1>"
+ "<p>This tool lets you install, remove, and update applications.</p>"
+ "<p>&product; 's software management is also called 'package management'. A package is "
+ "generally an application bundle, but multiple packages that extend the application "
+ "may be offered in order to avoid clutter (e.g. games tend to de-couple the music "
+ "data in another package, since its not essential and requires significant disk space). "
+ "The base package will get the application's name, while extra packages are suffix-ed. "
+ "Common extras are:</p>"
+ "<ul>"
+ "<li>-plugin-: extends the application with some extra functionality.</li>"
+ "<li>-devel: needed for software development.</li>"
+ "<li>-debuginfo: needed for software beta-testing.</li>"
+ "<li>-fr, -dr, -pl (language siglas): translation files (your language package will "
+ "be marked for installation automatically).</li>"
+ "</ul>"
+ "<p>You will find both packages installed on your system, and packages that are made "
+ "available through the configured repositories.</p>"
+ "<blockquote>A repository is a packages media; it can either be local (such as the "
+ "&product; CDs), or a remote internet server. You can find utilities to setup "
+ "repositories on the YaST control center.</blockquote>"),
+ _("<h1>Usage</h1>"
+ "<h2>Install, Upgrade, Remove, Undo tab pages</h2>"
+ "<p>These tabs produce listings of the different sources of packages. 'Install' "
+ "lists available packages from the configured repositories. "
+ "'Upgrade' are the subset of installed packages that have more recent versions "
+ "available. 'Remove' allows you to uninstall a package that is installed in your "
+ "system. You can review changes in the 'Undo' tab, and revoke changes individually "
+ "at any time.</p>"
+ "<p>Press the 'Apply' button when you want your changes to be performed.</p>"),
+ _("<h2>Search</h2>"
+ "<p>Enter free text into the search-field to match their names and descriptions. "
+ "(a search for 'office' will bring up the 'OpenOffice' packages as well as "
+ "AbiWord which carries the word 'office' in its description). You can also "
+ "choose to view software from a specific repository. Searching other attributes "
+ "is possible. For instance, you may perform a search on the installed package "
+ "containing a given file. Press the search icon for the filter menu.</p>"),
+ _("<h2>Groups, Patterns, Languages</h2>"
+ "<p>Software for &product; is indexed so that you can find software for a specific "
+ "task when you don't know the name of the software you are looking for. Browse "
+ "indexes of software through the Groups pane. A more detailed, hierarchical classification "
+ "of software packages, like 'Multimedia/Video' is available through the 'Detailed' check "
+ "button. 'Patterns' and 'Languages' are task-oriented collections of multiple packages that "
+ "install like one (the installation of the 'server'-pattern for example will install various "
+ "software needed for running a server). By using 'Install All' you make sure that future "
+ "collection changes, when you upgrade &product;, will be honored.</p>"),
+ _("<h2>Software details in the box below</h2>"
+ "<p>Explore the available information about the package in the box below. Note "
+ "that more information is available for installed software than that only "
+ "available from a repository.</p>"
+ "<p>You can also pick a specific version of the package to install from this "
+ "box.</p>"
+ "<p>The box will be placed to the right on large wide-screens when on fullscreen, "
+ "in order to better use the screen space.</p>"),
+ _("<h2>Lock software</h2>"
+ "<p>Advanced users may want to know that locking or unlocking a package against "
+ "automatic changes can be perfomed by right-clicking the package list entry.</p>"
+ "<p>Locking is only useful in very unusual cases: for instance, you may not want "
+ "to install a given drivers because it interferes with your system, yet you want "
+ "to install some collection that includes it.</p>"),
+ _("<h2>Apply button</h2>"
+ "<p>Changes will be performed once you decide to click the 'Apply' "
+ "button in the lower-right corner. If you want to leave the software manager "
+ "without performing any changes, simply press 'Cancel'.</p>"),
+ _("<hr/><p>Developed for &product; by:</p>"
+ "<blockquote>Ricardo Cruz <rpmcruz(a)alunos.dcc.fc.up.pt></blockquote>"
+ "<p>Co-designed by Christian Jaeger.</p>"),
+ 0
+};
+
+static const char *patch_help[] = {
+ _("<h1>Purpose</h1>"
+ "<p>This tool gives you control on overviewing and picking patches. You may also "
+ "reverse patches that have been applied to the system.</p>"
+ ""
+ "<h1>Usage</h1>"
+ "<h2>Categories</h2>"
+ "<p>Patches are grouped as follows:</p>"
+ "<ul>"
+ "<li>Security: patches a software flaw that could be exploited to gain "
+ "restricted privilege.</li>"
+ "<li>Recommended: fixes non-security related flaws (e.g. data corruption, "
+ "performance slowdown)</li>"
+ "<li>Optional: ones that only apply to few users.</li>"
+ "</ul>"
+ "<p>Only patches that apply to your system will be visible. &product; developers "
+ "are very restrained in pushing patches; you can be sure that all patches are "
+ "of signficant severity.</p>"
+ "<p>If you are looking for applications enhancements, you should check for upgrades "
+ "on the Software Manager.</p>"),
+ 0
+};
+
Added: trunk/gtk/src/pkg/ygtkcellrendererbutton.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkcellrendererbutt…
==============================================================================
--- trunk/gtk/src/pkg/ygtkcellrendererbutton.c (added)
+++ trunk/gtk/src/pkg/ygtkcellrendererbutton.c Thu Nov 26 18:16:21 2009
@@ -0,0 +1,171 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkCellRendererButton widget */
+// check the header file for information about this widget
+
+#include "ygtkcellrendererbutton.h"
+#include <gtk/gtk.h>
+
+#define INNER_BORDER 4
+#define OUTER_BORDER 1
+#define BORDER (INNER_BORDER+OUTER_BORDER)
+#define DEPRESS_PAD 2
+
+enum {
+ PROP_0,
+ PROP_ACTIVE,
+};
+
+static guint toggle_cell_signal = 0;
+
+G_DEFINE_TYPE (YGtkCellRendererButton, ygtk_cell_renderer_button, YGTK_TYPE_CELL_RENDERER_TEXT_PIXBUF)
+
+static void ygtk_cell_renderer_button_init (YGtkCellRendererButton *bcell)
+{
+ bcell->active = FALSE;
+ GtkCellRenderer *cell = GTK_CELL_RENDERER (bcell);
+ cell->xpad = BORDER;
+ cell->ypad = BORDER;
+}
+
+static void ygtk_cell_renderer_button_get_property (GObject *object,
+ guint param_id, GValue *value, GParamSpec *pspec)
+{
+ if (pspec->owner_type == YGTK_TYPE_CELL_RENDERER_BUTTON) {
+ YGtkCellRendererButton *bcell = YGTK_CELL_RENDERER_BUTTON (object);
+ switch (param_id) {
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, bcell->active);
+ break;
+ }
+ }
+ else
+ G_OBJECT_CLASS (ygtk_cell_renderer_button_parent_class)->get_property (
+ object, param_id, value, pspec);
+}
+
+static void ygtk_cell_renderer_button_set_property (GObject *object,
+ guint param_id, const GValue *value, GParamSpec *pspec)
+{
+ if (pspec->owner_type == YGTK_TYPE_CELL_RENDERER_BUTTON) {
+ YGtkCellRendererButton *bcell = YGTK_CELL_RENDERER_BUTTON (object);
+ switch (param_id) {
+ case PROP_ACTIVE:
+ bcell->active = g_value_get_boolean (value);
+ break;
+ }
+ }
+ else
+ G_OBJECT_CLASS (ygtk_cell_renderer_button_parent_class)->set_property (
+ object, param_id, value, pspec);
+}
+
+static void ygtk_cell_renderer_button_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget, GdkRectangle *cell_area, gint *xoffset, gint *yoffset,
+ gint *width, gint *height)
+{
+ GTK_CELL_RENDERER_CLASS (ygtk_cell_renderer_button_parent_class)->get_size (
+ cell, widget, NULL, NULL, NULL, width, height);
+ if (xoffset) *xoffset = 0;
+ if (yoffset) *yoffset = 0;
+}
+
+static void ygtk_cell_renderer_button_render (GtkCellRenderer *cell,
+ GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area,
+ GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags)
+{
+ YGtkCellRendererButton *bcell = YGTK_CELL_RENDERER_BUTTON (cell);
+
+ gboolean has_focus = FALSE;
+ if (flags & GTK_CELL_RENDERER_SELECTED)
+ has_focus = GTK_WIDGET_HAS_FOCUS (widget);
+
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!cell->sensitive || GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE)
+ state = GTK_STATE_INSENSITIVE;
+ else if ((flags & GTK_CELL_RENDERER_PRELIT))
+ state = GTK_STATE_PRELIGHT;
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ if (bcell->active) {
+ shadow = GTK_SHADOW_IN;
+ state = GTK_STATE_ACTIVE;
+ }
+
+ int width, height;
+ GTK_CELL_RENDERER_CLASS (ygtk_cell_renderer_button_parent_class)->get_size (
+ cell, widget, NULL, NULL, NULL, &width, &height);
+ int x = cell_area->x + OUTER_BORDER;
+ width -= OUTER_BORDER*2;
+ int y = cell_area->y + (cell_area->height - height)/2 + OUTER_BORDER;
+ height -= OUTER_BORDER*2;
+
+#if 0
+ static GtkWidget *button = 0;
+ if (!button) {
+ button = gtk_toggle_button_new();
+ GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_container_add (GTK_CONTAINER (window), button);
+ gtk_widget_show (button);
+ gtk_widget_realize (window);
+ button->allocation.x = x;
+ button->allocation.y = y;
+ button->allocation.width = width;
+ button->allocation.height = height;
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), bcell->active);
+ gtk_paint_box (button->style, window, state, shadow, expose_area, button,
+ "button", x, y, width, height);
+#else
+ gtk_paint_box (widget->style, window, state, shadow, expose_area, widget,
+ "button", x, y, width, height);
+#endif
+
+ int cell_area_x = cell_area->x, cell_area_y = cell_area->y;
+ if (bcell->active) {
+ cell_area->x += DEPRESS_PAD;
+ cell_area->y += DEPRESS_PAD;
+ }
+
+ GTK_CELL_RENDERER_CLASS (ygtk_cell_renderer_button_parent_class)->render (
+ cell, window, widget, background_area, cell_area, expose_area, 0);
+
+ cell_area->x = cell_area_x; cell_area->y = cell_area_y;
+}
+
+static gboolean ygtk_cell_renderer_button_activate (GtkCellRenderer *cell,
+ GdkEvent *event, GtkWidget *widget, const gchar *path, GdkRectangle *background_area,
+ GdkRectangle *cell_area, GtkCellRendererState flags)
+{
+ g_signal_emit (cell, toggle_cell_signal, 0, path);
+ return TRUE;
+}
+
+GtkCellRenderer *ygtk_cell_renderer_button_new (void)
+{ return g_object_new (YGTK_TYPE_CELL_RENDERER_BUTTON, NULL); }
+
+gboolean ygtk_cell_renderer_button_get_active (YGtkCellRendererButton *cell)
+{ return cell->active; }
+
+static void ygtk_cell_renderer_button_class_init (YGtkCellRendererButtonClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = ygtk_cell_renderer_button_get_property;
+ object_class->set_property = ygtk_cell_renderer_button_set_property;
+
+ GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+ cell_class->get_size = ygtk_cell_renderer_button_get_size;
+ cell_class->render = ygtk_cell_renderer_button_render;
+ cell_class->activate = ygtk_cell_renderer_button_activate;
+
+ g_object_class_install_property (object_class, PROP_ACTIVE,
+ g_param_spec_boolean ("active", "Toggle state", "The toggle state of the button",
+ FALSE, G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+ toggle_cell_signal = g_signal_new ("toggled", G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (YGtkCellRendererButtonClass, toggled),
+ NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
Added: trunk/gtk/src/pkg/ygtkcellrendererbutton.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkcellrendererbutt…
==============================================================================
--- trunk/gtk/src/pkg/ygtkcellrendererbutton.h (added)
+++ trunk/gtk/src/pkg/ygtkcellrendererbutton.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,48 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* GtkButton meets GtkCellRenderer.
+*/
+
+#ifndef YGTK_CELL_RENDERER_BUTTON_H
+#define YGTK_CELL_RENDERER_BUTTON_H
+
+#include "ygtkcellrenderertextpixbuf.h"
+G_BEGIN_DECLS
+
+#define YGTK_TYPE_CELL_RENDERER_BUTTON (ygtk_cell_renderer_button_get_type ())
+#define YGTK_CELL_RENDERER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_CELL_RENDERER_BUTTON, YGtkCellRendererButton))
+#define YGTK_CELL_RENDERER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_CELL_RENDERER_BUTTON, YGtkCellRendererButtonClass))
+#define YGTK_IS_CELL_RENDERER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ YGTK_TYPE_CELL_RENDERER_BUTTON))
+#define YGTK_IS_CELL_RENDERER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ YGTK_TYPE_CELL_RENDERER_BUTTON))
+#define YGTK_CELL_RENDERER_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_CELL_RENDERER_BUTTON, YGtkCellRendererButtonClass))
+
+typedef struct _YGtkCellRendererButton
+{
+ YGtkCellRendererTextPixbuf parent;
+
+ // private:
+ guint active : 2;
+} YGtkCellRendererButton;
+
+typedef struct _YGtkCellRendererButtonClass
+{
+ YGtkCellRendererTextPixbufClass parent_class;
+
+ void (* toggled) (YGtkCellRendererButton *renderer, const gchar *path);
+} YGtkCellRendererButtonClass;
+
+GtkCellRenderer *ygtk_cell_renderer_button_new (void);
+GType ygtk_cell_renderer_button_get_type (void) G_GNUC_CONST;
+
+gboolean ygtk_cell_renderer_button_get_active (YGtkCellRendererButton *cell);
+
+G_END_DECLS
+#endif /*YGTK_CELL_RENDERER_BUTTON_H*/
+
Added: trunk/gtk/src/pkg/ygtkdetailview.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkdetailview.cc?re…
==============================================================================
--- trunk/gtk/src/pkg/ygtkdetailview.cc (added)
+++ trunk/gtk/src/pkg/ygtkdetailview.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,765 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkZyppView, Zypp GtkTreeView implementation */
+// check the header file for information about this widget
+
+/*
+ Textdomain "yast2-gtk"
+ */
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "ygtkdetailview.h"
+#include "ygtkpackageview.h"
+#include "ygtkrichtext.h"
+#include "YGi18n.h"
+#include "YGUtils.h"
+#include "YGDialog.h"
+#include <stdlib.h>
+#include <string.h>
+#include <list>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+//** Utilities
+
+#define BROWSER_PATH "/usr/bin/firefox"
+#define GNOME_OPEN_PATH "/usr/bin/gnome-open"
+inline bool CAN_OPEN_URL()
+{ return g_file_test (BROWSER_PATH, G_FILE_TEST_IS_EXECUTABLE); }
+inline bool CAN_OPEN_DIRNAME()
+{ return g_file_test (GNOME_OPEN_PATH, G_FILE_TEST_IS_EXECUTABLE); }
+
+void run (const std::string &cmd, bool as_user)
+{
+ std::string prepend, append;
+ if (as_user && getuid() == 0) {
+ char *username = getenv ("USERNAME");
+ if (username && *username && strcmp (username, "root") != 0) {
+ prepend.reserve (64);
+ prepend = "gnomesu -u ";
+ prepend += username;
+ prepend += " -c \"";
+ append = "\"";
+ }
+ }
+ system (((prepend + cmd + append) + " &").c_str());
+}
+
+void OPEN_URL (const char *uri)
+{
+ std::string command;
+ command.reserve (256);
+ command = BROWSER_PATH " --new-window ";
+ command += uri;
+ run (command, true);
+}
+void OPEN_DIRNAME (const char *uri)
+{
+ std::string command;
+ command.reserve (256);
+ command = GNOME_OPEN_PATH " ";
+ command += uri;
+ run (command, false);
+}
+
+static const char *onlyInstalledMsg =
+ _("<i>Information only available for installed packages.</i>");
+
+//** Detail & control
+
+class YGtkDetailView::Impl
+{
+private:
+ struct Versions : public Ypp::PkgList::Listener {
+ GtkWidget *m_box, *m_versions_box, *m_button, *m_undo_button;
+ Ypp::PkgList m_packages; // we keep a copy to test against modified...
+ bool m_onlineUpdate;
+
+ GtkWidget *getWidget() { return m_box; }
+
+ Versions (bool onlineUpdate) : m_onlineUpdate (onlineUpdate)
+ {
+ GtkWidget *label = gtk_label_new (_("Versions:"));
+ YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ m_versions_box = gtk_vbox_new (FALSE, 2);
+ m_button = gtk_button_new_with_label ("");
+ g_signal_connect (G_OBJECT (m_button), "clicked", G_CALLBACK (button_clicked_cb), this);
+ GtkSettings *settings = gtk_settings_get_default();
+ gboolean show_button_images;
+ g_object_get (settings, "gtk-button-images", &show_button_images, NULL);
+ if (show_button_images) {
+ m_undo_button = gtk_button_new_with_label ("");
+ gtk_button_set_image (GTK_BUTTON (m_undo_button),
+ gtk_image_new_from_stock (GTK_STOCK_UNDO, GTK_ICON_SIZE_BUTTON));
+ gtk_widget_set_tooltip_text (m_undo_button, _("Undo"));
+ }
+ else
+ m_undo_button = gtk_button_new_with_label (_("Undo"));
+ g_signal_connect (G_OBJECT (m_undo_button), "clicked", G_CALLBACK (undo_clicked_cb), this);
+ GtkWidget *button_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (button_box), gtk_label_new(""), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (button_box), m_button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (button_box), m_undo_button, FALSE, TRUE, 0);
+
+ m_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), m_versions_box, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), button_box, FALSE, TRUE, 0);
+
+ // PkgList::addListeners() isn't currently working for ordinary PkgList
+ // other than getPackages(), thus this hack.
+ if (!m_onlineUpdate)
+ Ypp::get()->getPackages (Ypp::Package::PACKAGE_TYPE).addListener (this);
+ }
+
+ ~Versions()
+ {
+ if (!m_onlineUpdate)
+ Ypp::get()->getPackages (Ypp::Package::PACKAGE_TYPE).removeListener (this);
+ }
+
+ void setPackages (Ypp::PkgList packages)
+ {
+ m_packages = packages;
+
+ GList *children = gtk_container_get_children (GTK_CONTAINER (m_versions_box));
+ for (GList *i = children; i; i = i->next)
+ gtk_container_remove (GTK_CONTAINER (m_versions_box), (GtkWidget *) i->data);
+ g_list_free (children);
+
+ if (packages.size() == 0) {
+ gtk_widget_hide (m_box);
+ return;
+ }
+ gtk_widget_show (m_box);
+ if (packages.size() == 1) {
+ Ypp::Package *package = packages.get (0);
+
+ int children = 0;
+ GtkWidget *radio = 0;
+ const Ypp::Package::Version *version;
+ if ((version = package->getInstalledVersion())) {
+ std::string _version = YGUtils::truncate (version->number, 20, 0);
+
+ bool italic = package->toRemove();
+ char *text = g_strdup_printf ("%s%s <small>(%s)</small>\n%s%s",
+ italic ? "<i>" : "",
+ _version.c_str(), version->arch.c_str(), _("Installed"),
+ italic ? "</i>" : "");
+ radio = gtk_radio_button_new_with_label (NULL, text);
+ gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (radio)->child), TRUE);
+ if (version->number.size() > 20) {
+ char *text = g_strdup_printf ("%s <small>(%s)</small>\n%s",
+ version->number.c_str(), version->arch.c_str(), _("Installed"));
+ gtk_widget_set_tooltip_markup (radio, text);
+ g_free (text);
+ }
+ gtk_box_pack_start (GTK_BOX (m_versions_box), radio, FALSE, TRUE, 0);
+ g_free (text);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ g_object_set_data (G_OBJECT (radio), "version", (void *) version);
+ g_signal_connect (G_OBJECT (radio), "toggled",
+ G_CALLBACK (version_toggled_cb), this);
+ children++;
+ }
+ bool activeSet = package->toRemove();
+ const Ypp::Package::Version *toInstall = 0;
+ if (!package->toInstall (&toInstall))
+ toInstall = 0;
+ const Ypp::Repository *favoriteRepo = Ypp::get()->favoriteRepository();
+ for (int i = 0; (version = package->getAvailableVersion (i)); i++) {
+ std::string _version = YGUtils::truncate (version->number, 20, 0);
+ std::string repo;
+ if (version->repo)
+ repo = YGUtils::truncate (version->repo->name, 22, 0);
+
+ bool italic = toInstall == version;
+ char *text = g_strdup_printf ("%s%s <small>(%s)</small>\n%s%s",
+ italic ? "<i>" : "",
+ _version.c_str(), version->arch.c_str(), repo.c_str(),
+ italic ? "</i>" : "");
+ radio = gtk_radio_button_new_with_label_from_widget (
+ GTK_RADIO_BUTTON (radio), text);
+ gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (radio)->child), TRUE);
+ g_free (text);
+ if (version->number.size() > 20 ||
+ (version->repo && version->repo->name.size() > 22)) {
+ char *text = g_strdup_printf ("%s <small>(%s)</small>\n%s",
+ version->number.c_str(), version->arch.c_str(),
+ version->repo ? version->repo->name.c_str() : "");
+ gtk_widget_set_tooltip_markup (radio, text);
+ g_free (text);
+ }
+ gtk_box_pack_start (GTK_BOX (m_versions_box), radio, FALSE, TRUE, 0);
+ if (!activeSet) {
+ if (toInstall == version) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ activeSet = true;
+ }
+ else if (i == 0 && (!package->isInstalled() || version->cmp > 0))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ else if (version->repo == favoriteRepo) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ favoriteRepo = 0; // select only the 1st hit
+ }
+ }
+ g_object_set_data (G_OBJECT (radio), "version", (void *) version);
+ g_signal_connect (G_OBJECT (radio), "toggled",
+ G_CALLBACK (version_toggled_cb), this);
+ if ((children % 2) == 1)
+ g_signal_connect (G_OBJECT (radio), "expose-event", G_CALLBACK (draw_gray_cb), this);
+ children++;
+ }
+ gtk_widget_show_all (m_versions_box);
+ }
+
+ // is locked
+ if (packages.locked() || packages.unlocked())
+ gtk_widget_set_sensitive (m_button, !packages.locked());
+ else
+ gtk_widget_set_sensitive (m_button, TRUE);
+ syncButton();
+ }
+
+ private:
+ virtual void entryChanged (const Ypp::PkgList list, int index, Ypp::Package *package)
+ {
+ if (m_packages.contains (package))
+ setPackages (m_packages); // refresh !
+ }
+ // won't happen:
+ virtual void entryInserted (const Ypp::PkgList list, int index, Ypp::Package *package) {}
+ virtual void entryDeleted (const Ypp::PkgList list, int index, Ypp::Package *package) {}
+
+ static gboolean draw_gray_cb (GtkWidget *widget, GdkEventExpose *event, Versions *pThis)
+ {
+ GtkAllocation *alloc = &widget->allocation;
+ int x = alloc->x, y = alloc->y, w = alloc->width, h = alloc->height;
+
+ cairo_t *cr = gdk_cairo_create (widget->window);
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_set_source_rgb (cr, 245/255.0, 245/255.0, 245/255.0);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ return FALSE;
+ }
+
+ const Ypp::Package::Version *getVersion()
+ {
+ GtkWidget *radio = 0;
+ GList *children = gtk_container_get_children (GTK_CONTAINER (m_versions_box));
+ for (GList *i = children; i; i = i->next)
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (i->data))) {
+ radio = (GtkWidget *) i->data;
+ break;
+ }
+ g_list_free (children);
+ if (radio)
+ return (Ypp::Package::Version *) g_object_get_data (G_OBJECT (radio), "version");
+ return NULL;
+ }
+
+ void syncButton()
+ {
+ const char *label = 0, *stock = 0;
+ bool modified = false;
+ if (m_packages.size() == 1) {
+ Ypp::Package *package = m_packages.get (0);
+ const Ypp::Package::Version *version = getVersion();
+ const Ypp::Package::Version *installed = package->getInstalledVersion();
+ if (installed == version) {
+ label = _("Remove");
+ stock = GTK_STOCK_DELETE;
+ if (package->toRemove())
+ modified = true;
+ }
+ else {
+ if (installed) {
+ if (version->cmp > 0) {
+ label = _("Upgrade");
+ stock = GTK_STOCK_GO_UP;
+ }
+ else if (version->cmp < 0) {
+ label = _("Downgrade");
+ stock = GTK_STOCK_GO_DOWN;
+ }
+ else {
+ label = _("Re-install");
+ stock = GTK_STOCK_REFRESH;
+ }
+ }
+ else {
+ label = _("Install");
+ stock = GTK_STOCK_SAVE;
+ }
+
+ const Ypp::Package::Version *toInstall = 0;
+ if (!package->toInstall (&toInstall))
+ toInstall = 0;
+ if (toInstall == version)
+ modified = true;
+ }
+ }
+ else {
+ if (m_packages.modified())
+ modified = true;
+ if (m_packages.upgradable()) {
+ label = _("Upgrade");
+ stock = GTK_STOCK_GO_UP;
+ }
+ else if (m_packages.installed()) {
+ label = _("Remove");
+ stock = GTK_STOCK_DELETE;
+ }
+ else if (m_packages.notInstalled()) {
+ label = _("Install");
+ stock = GTK_STOCK_SAVE;
+ }
+ else if (m_packages.modified()) {
+ label = _("Undo");
+ stock = GTK_STOCK_UNDO;
+ modified = false;
+ }
+ }
+ if (label) {
+ gtk_button_set_label (GTK_BUTTON (m_button), label);
+ GtkWidget *image = gtk_image_new_from_stock (
+ stock, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (m_button), image);
+ gtk_widget_show (m_button);
+ }
+ else
+ gtk_widget_hide (m_button);
+ gtk_widget_set_sensitive (m_button, !modified);
+ modified ? gtk_widget_show (m_undo_button) : gtk_widget_hide (m_undo_button);
+ }
+
+ static void version_toggled_cb (GtkToggleButton *radio, Versions *pThis)
+ { if (gtk_toggle_button_get_active (radio)) pThis->syncButton(); }
+
+ static void button_clicked_cb (GtkButton *button, Versions *pThis)
+ {
+ if (pThis->m_packages.size() == 1) {
+ Ypp::Package *package = pThis->m_packages.get (0);
+ const Ypp::Package::Version *version = pThis->getVersion();
+ const Ypp::Package::Version *installed = package->getInstalledVersion();
+ if (installed == version)
+ pThis->m_packages.remove();
+ else
+ package->install (version);
+ }
+ else {
+ if (pThis->m_packages.upgradable())
+ pThis->m_packages.install();
+ else if (pThis->m_packages.installed())
+ pThis->m_packages.remove();
+ else if (pThis->m_packages.notInstalled())
+ pThis->m_packages.install();
+ else if (pThis->m_packages.modified())
+ pThis->m_packages.undo();
+ }
+ }
+
+ static void undo_clicked_cb (GtkButton *button, Versions *pThis)
+ {
+ pThis->m_packages.undo();
+ }
+ };
+
+GtkWidget *m_scroll, *m_icon, *m_icon_frame, *m_description, *m_filelist, *m_changelog,
+ *m_authors, *m_support, *m_requires, *m_provides, *m_contents;
+Versions *m_versions;
+bool m_verMode;
+
+public:
+ Impl (GtkWidget *scroll, bool onlineUpdate)
+ : m_verMode (false)
+ {
+ m_scroll = scroll;
+ m_versions = new Versions (onlineUpdate);
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 2);
+ setupScrollAsWhite (scroll, hbox);
+
+ GtkWidget *versions_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (versions_box),
+ createIconWidget (&m_icon, &m_icon_frame), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (versions_box), m_versions->getWidget(), FALSE, TRUE, 0);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
+ m_description = ygtk_rich_text_new();
+ g_signal_connect (G_OBJECT (m_description), "link-clicked",
+ G_CALLBACK (link_pressed_cb), this);
+ gtk_box_pack_start (GTK_BOX (vbox), m_description, FALSE, TRUE, 0);
+
+ m_filelist = m_changelog = m_authors = m_support = m_requires = m_provides = m_contents = 0;
+ if (!onlineUpdate) {
+ m_filelist = ygtk_rich_text_new();
+ if (CAN_OPEN_DIRNAME())
+ g_signal_connect (G_OBJECT (m_filelist), "link-clicked",
+ G_CALLBACK (dirname_pressed_cb), this);
+ m_changelog = ygtk_rich_text_new();
+ m_authors = ygtk_rich_text_new();
+ m_support = ygtk_rich_text_new();
+ GtkWidget *dependencies_box = gtk_hbox_new (TRUE, 0);
+ m_requires = ygtk_rich_text_new();
+ m_provides = ygtk_rich_text_new();
+ gtk_box_pack_start (GTK_BOX (dependencies_box), m_requires, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (dependencies_box), m_provides, TRUE, TRUE, 0);
+
+ appendExpander (vbox, _("File List"), m_filelist);
+ appendExpander (vbox, _("Changelog"), m_changelog);
+ appendExpander (vbox, _("Authors"), m_authors);
+ appendExpander (vbox, _("Dependencies"), dependencies_box);
+ appendExpander (vbox, "", m_support);
+ }
+ else {
+ YGtkPackageView *contents;
+ m_contents = GTK_WIDGET (contents = ygtk_package_view_new (TRUE));
+ gtk_widget_set_size_request (m_contents, -1, 150);
+ appendExpander (vbox, _("Applies to"), m_contents);
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), versions_box, FALSE, TRUE, 0);
+ gtk_widget_show_all (hbox);
+ g_signal_connect (G_OBJECT (scroll), "hierarchy-changed",
+ G_CALLBACK (hierarchy_changed_cb), this);
+ g_signal_connect (G_OBJECT (scroll), "realize",
+ G_CALLBACK (realize_cb), this);
+ }
+
+ ~Impl()
+ { delete m_versions; }
+
+ void setPackages (Ypp::PkgList packages)
+ {
+ gtk_widget_hide (m_icon_frame);
+ Ypp::Package *package = 0;
+ if (packages.size() == 1) {
+ package = packages.get (0);
+ std::string description = "<b>" + package->name() + "</b><br>";
+ description += package->description (HTML_MARKUP);
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (m_description), description.c_str());
+ if (m_support) {
+ std::string label ("<b>" + std::string (_("Supportability:")) + "</b> ");
+ label += package->support();
+ gtk_expander_set_label (GTK_EXPANDER (m_support->parent), label.c_str());
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (m_support),
+ package->supportText (HTML_MARKUP).c_str());
+ gtk_widget_show (m_support->parent);
+ }
+ gtk_image_clear (GTK_IMAGE (m_icon));
+ GtkIconTheme *icons = gtk_icon_theme_get_default();
+ GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icons,
+ package->name().c_str(), 32, GtkIconLookupFlags (0), NULL);
+ if (pixbuf) {
+ gtk_image_set_from_pixbuf (GTK_IMAGE (m_icon), pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ gtk_widget_show (m_icon_frame);
+ }
+ setPassiveUpdate (m_filelist, filelist_cb, package);
+ setPassiveUpdate (m_changelog, changelog_cb, package);
+ setPassiveUpdate (m_authors, authors_cb, package);
+ setPassiveUpdate (m_requires, requires_cb, package);
+ setPassiveUpdate (m_provides, provides_cb, package);
+ setPassiveUpdate (m_contents, contents_cb, package);
+ }
+ else {
+ std::string description;
+ if (packages.size() > 0) {
+ description = _("Selected:");
+ description += "<ul>";
+ for (int i = 0; packages.get (i); i++)
+ description += "<li>" + packages.get (i)->name() + "</li>";
+ description += "</ul>";
+ }
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (m_description), description.c_str());
+ if (m_support)
+ gtk_widget_hide (m_support->parent);
+ setPassiveUpdate (m_filelist, NULL, NULL);
+ setPassiveUpdate (m_changelog, NULL, NULL);
+ setPassiveUpdate (m_authors, NULL, NULL);
+ setPassiveUpdate (m_requires, NULL, NULL);
+ setPassiveUpdate (m_provides, NULL, NULL);
+ setPassiveUpdate (m_contents, NULL, NULL);
+ }
+
+ m_versions->setPackages (packages);
+ scrollTop();
+ }
+
+ void setPackage (Ypp::Package *package)
+ {
+ Ypp::PkgList packages;
+ packages.append (package);
+ setPackages (packages);
+ }
+
+ void setVerticalMode (bool verMode)
+ {
+ if (verMode != m_verMode) {
+ m_verMode = verMode;
+ }
+ }
+
+private:
+ void scrollTop()
+ {
+ GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (m_scroll);
+ GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment (scroll);
+ YGUtils::scrollWidget (vadj, true);
+ }
+
+ // utilities:
+ static GtkWidget *createIconWidget (GtkWidget **icon_widget, GtkWidget **icon_frame)
+ {
+ *icon_widget = gtk_image_new();
+
+ GtkWidget *box, *align, *frame;
+ box = gtk_event_box_new();
+ gtk_container_add (GTK_CONTAINER (box), *icon_widget);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 2);
+
+ frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (frame), box);
+
+ align = gtk_alignment_new (0, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), frame);
+ gtk_container_set_border_width (GTK_CONTAINER (align), 6);
+ *icon_frame = align;
+ return align;
+ }
+
+ static void setupScrollAsWhite (GtkWidget *scroll, GtkWidget *box)
+ {
+ struct inner {
+ static gboolean expose_cb (GtkWidget *widget, GdkEventExpose *event)
+ {
+ cairo_t *cr = gdk_cairo_create (widget->window);
+ GdkColor color = { 0, 255 << 8, 255 << 8, 255 << 8 };
+ gdk_cairo_set_source_color (cr, &color);
+ cairo_rectangle (cr, event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ return FALSE;
+ }
+ };
+
+ g_signal_connect (G_OBJECT (box), "expose-event",
+ G_CALLBACK (inner::expose_cb), NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), box);
+ }
+
+ static GtkWidget *appendExpander (GtkWidget *box, const char *label, GtkWidget *child)
+ {
+ std::string str = std::string ("<b>") + label + "</b>";
+ GtkWidget *expander = gtk_expander_new (str.c_str());
+ gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
+ gtk_container_add (GTK_CONTAINER (expander), child);
+ gtk_box_pack_start (GTK_BOX (box), expander, FALSE, TRUE, 0);
+ return expander;
+ }
+
+ // callbacks
+ static void link_pressed_cb (GtkWidget *text, const gchar *link, Impl *pThis)
+ {
+ if (!strncmp (link, "pkg://", 6)) {
+ const gchar *pkg_name = link + 6;
+ Ypp::Package *pkg = Ypp::get()->getPackages (Ypp::Package::PACKAGE_TYPE).find (pkg_name);
+ if (pkg)
+ pThis->setPackage (pkg);
+ else {
+ GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK, _("Package '%s' was not found."), pkg_name);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+ }
+ else
+ OPEN_URL (link);
+ }
+
+ static void dirname_pressed_cb (GtkWidget *text, const gchar *link, Impl *pThis)
+ { OPEN_DIRNAME (link); }
+
+ static void hierarchy_changed_cb (GtkWidget *widget, GtkWidget *old, Impl *pThis)
+ {
+ GtkWidget *parent = gtk_widget_get_parent (widget);
+ if (parent) {
+ bool vertical = GTK_IS_HPANED (parent) || GTK_IS_HBOX (parent);
+ pThis->setVerticalMode (vertical);
+ }
+ }
+
+ static void filelist_cb (GtkWidget *widget, gpointer pkg)
+ {
+ std::string str (((Ypp::Package *) pkg)->filelist (HTML_MARKUP));
+ if (str.empty())
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), onlyInstalledMsg);
+ else
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), str.c_str());
+ }
+
+ static void changelog_cb (GtkWidget *widget, gpointer pkg)
+ {
+ std::string str (((Ypp::Package *) pkg)->changelog());
+ if (str.empty())
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), onlyInstalledMsg);
+ else
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), str.c_str());
+ }
+
+ static void authors_cb (GtkWidget *widget, gpointer pkg)
+ {
+ std::string str (((Ypp::Package *) pkg)->authors (HTML_MARKUP));
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), str.c_str());
+ }
+
+ static void requires_cb (GtkWidget *widget, gpointer pkg)
+ {
+ std::string str = _("Requires:");
+ str += "<br><blockquote>";
+ str += ((Ypp::Package *) pkg)->requires (HTML_MARKUP);
+ YGUtils::replace (str, "\n", 1, "<br>");
+ str += "</blockquote>";
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), str.c_str());
+ }
+
+ static void provides_cb (GtkWidget *widget, gpointer pkg)
+ {
+ std::string str = _("Provides:");
+ str += "<br><blockquote>";
+ str += ((Ypp::Package *) pkg)->provides (HTML_MARKUP);
+ YGUtils::replace (str, "\n", 1, "<br>");
+ str += "</blockquote>";
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), str.c_str());
+ }
+
+ static void contents_cb (GtkWidget *widget, gpointer pkg)
+ {
+ YGtkPackageView *contents = YGTK_PACKAGE_VIEW (widget);
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ query->addCollection ((Ypp::Package *) pkg);
+ contents->setList (Ypp::PkgQuery (Ypp::Package::PACKAGE_TYPE, query), 0);
+ }
+
+ // fix cursor keys support
+ static void move_cursor_cb (GtkTextView *view, GtkMovementStep step, gint count,
+ gboolean extend_selection, Impl *pThis)
+ {
+ GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (pThis->m_scroll);
+ GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (scroll);
+ int height = pThis->m_scroll->allocation.height;
+ gdouble increment;
+ switch (step) {
+ case GTK_MOVEMENT_DISPLAY_LINES:
+ increment = height / 10.0;
+ break;
+ case GTK_MOVEMENT_PAGES:
+ increment = height * 0.9;
+ break;
+ case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+ increment = adj->upper - adj->lower;
+ break;
+ default:
+ increment = 0.0;
+ break;
+ }
+
+ gdouble value = adj->value + (count * increment);
+ value = MIN (value, adj->upper - adj->page_size);
+ value = MAX (value, adj->lower);
+ if (value != adj->value)
+ gtk_adjustment_set_value (adj, value);
+ }
+
+ static inline void fix_keybindings (Impl *pThis, GtkWidget *widget)
+ {
+ if (widget)
+ g_signal_connect (G_OBJECT (widget), "move-cursor",
+ G_CALLBACK (move_cursor_cb), pThis);
+ }
+
+ static void realize_cb (GtkWidget *widget, Impl *pThis)
+ {
+ fix_keybindings (pThis, pThis->m_description);
+ fix_keybindings (pThis, pThis->m_filelist);
+ fix_keybindings (pThis, pThis->m_changelog);
+ fix_keybindings (pThis, pThis->m_authors);
+ fix_keybindings (pThis, pThis->m_support);
+ fix_keybindings (pThis, pThis->m_requires);
+ fix_keybindings (pThis, pThis->m_provides);
+ }
+
+ // make the widget request data when/if necessary; speeds up expander children
+ typedef void (*UpdateCb) (GtkWidget *widget, gpointer data);
+
+ static void ygtk_widget_passive_update (GtkWidget *widget, UpdateCb update_cb, gpointer data)
+ {
+ g_object_set_data (G_OBJECT (widget), "update-cb", (gpointer) update_cb);
+ g_object_set_data (G_OBJECT (widget), "user-data", data);
+ if (GTK_WIDGET_MAPPED (widget) || !update_cb)
+ ygtk_widget_passive_update_cb (widget);
+ else
+ g_signal_connect (G_OBJECT (widget), "map",
+ G_CALLBACK (ygtk_widget_passive_update_cb), NULL);
+ }
+
+ static void ygtk_widget_passive_update_cb (GtkWidget *widget)
+ {
+ g_signal_handlers_disconnect_by_func (widget, (gpointer) ygtk_widget_passive_update_cb, NULL);
+ UpdateCb update_cb = (UpdateCb) g_object_get_data (G_OBJECT (widget), "update-cb");
+ gpointer data = g_object_get_data (G_OBJECT (widget), "user-data");
+ if (update_cb) // could be set to null to disable
+ update_cb (widget, data);
+ }
+
+ static void setPassiveUpdate (GtkWidget *widget, UpdateCb update_cb, Ypp::Package *pkg)
+ { // convinience method
+ if (widget) {
+ ygtk_widget_passive_update (widget, update_cb, (gpointer) pkg);
+ GtkWidget *expander = gtk_widget_get_ancestor (widget, GTK_TYPE_EXPANDER);
+ pkg ? gtk_widget_show (expander) : gtk_widget_hide (expander);
+ }
+ }
+};
+
+G_DEFINE_TYPE (YGtkDetailView, ygtk_detail_view, GTK_TYPE_SCROLLED_WINDOW)
+
+static void ygtk_detail_view_init (YGtkDetailView *view)
+{}
+
+GtkWidget *ygtk_detail_view_new (gboolean onlineUpdate)
+{
+ YGtkDetailView *view = (YGtkDetailView *) g_object_new (YGTK_TYPE_DETAIL_VIEW, NULL);
+ view->impl = new YGtkDetailView::Impl (GTK_WIDGET (view), onlineUpdate);
+ return GTK_WIDGET (view);
+}
+
+static void ygtk_detail_view_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (ygtk_detail_view_parent_class)->finalize (object);
+ YGtkDetailView *view = YGTK_DETAIL_VIEW (object);
+ delete view->impl;
+ view->impl = NULL;
+}
+
+static void ygtk_detail_view_class_init (YGtkDetailViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ygtk_detail_view_finalize;
+}
+
+void YGtkDetailView::setPackages (Ypp::PkgList packages)
+{ impl->setPackages (packages); }
+
+void YGtkDetailView::setPackage (Ypp::Package *package)
+{ impl->setPackage (package); }
+
Added: trunk/gtk/src/pkg/ygtkdetailview.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkdetailview.h?rev…
==============================================================================
--- trunk/gtk/src/pkg/ygtkdetailview.h (added)
+++ trunk/gtk/src/pkg/ygtkdetailview.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,46 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Text box information on a given package.
+*/
+
+#ifndef YGTK_DETAIL_VIEW_H
+#define YGTK_DETAIL_VIEW_H
+
+#include "yzyppwrapper.h"
+#include <gtk/gtkscrolledwindow.h>
+
+#define YGTK_TYPE_DETAIL_VIEW (ygtk_detail_view_get_type ())
+#define YGTK_DETAIL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_DETAIL_VIEW, YGtkDetailView))
+#define YGTK_DETAIL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_DETAIL_VIEW, YGtkDetailViewClass))
+#define YGTK_IS_DETAIL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ YGTK_TYPE_DETAIL_VIEW))
+#define YGTK_IS_DETAIL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ YGTK_TYPE_DETAIL_VIEW))
+#define YGTK_DETAIL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_DETAIL_VIEW, YGtkDetailViewClass))
+
+struct YGtkDetailView
+{ // use ygtk_detail_view_new() to instance the object
+ GtkScrolledWindow parent;
+
+ void setPackage (Ypp::Package *package);
+ void setPackages (Ypp::PkgList packages);
+
+ struct Impl;
+ Impl *impl;
+};
+
+struct YGtkDetailViewClass
+{
+ GtkScrolledWindowClass parent_class;
+};
+
+GtkWidget* ygtk_detail_view_new (gboolean onlineUpdate);
+GType ygtk_detail_view_get_type (void) G_GNUC_CONST;
+
+#endif /*YGTK_DETAIL_VIEW_H*/
+
Added: trunk/gtk/src/pkg/ygtkdiskview.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkdiskview.cc?rev=…
==============================================================================
--- trunk/gtk/src/pkg/ygtkdiskview.cc (added)
+++ trunk/gtk/src/pkg/ygtkdiskview.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,166 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkDiskView widget */
+// check the header file for information about this widget
+
+/*
+ Textdomain "yast2-gtk"
+ */
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "ygtkdiskview.h"
+#include "YGi18n.h"
+#include "YGUtils.h"
+#include "YGDialog.h"
+#include "ygtkmenubutton.h"
+
+static GtkWidget *DiskList_new (GtkTreeModel *model, bool framed)
+{
+ bool foreign_model = model == NULL;
+ if (model == NULL) {
+ GtkListStore *store = gtk_list_store_new (6,
+ // 0 - mount point, 1 - usage percent, 2 - usage string,
+ // (highlight warns) 3 - font weight, 4 - font color string,
+ // 5 - delta description
+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING,
+ G_TYPE_STRING);
+ model = GTK_TREE_MODEL (store);
+ }
+
+ GtkWidget *view = gtk_tree_view_new_with_model (model), *scroll = view;
+ if (foreign_model)
+ g_object_unref (G_OBJECT (model));
+ 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, "weight", 3, "foreground", 4, 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_column_set_min_width (column, 180); // SIZE_REQUEST
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "alignment", PANGO_ALIGN_RIGHT,
+ "style", PANGO_STYLE_ITALIC, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("Delta",
+ renderer, "text", 5, NULL);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+
+ if (framed) {
+ 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_container_add (GTK_CONTAINER (scroll), view);
+ }
+ else
+ g_object_set (view, "can-focus", FALSE, NULL);
+ gtk_widget_show_all (scroll);
+ return scroll;
+}
+
+static void DiskList_setup (GtkWidget *widget, int i, const std::string &path,
+ int usage_percent, int delta_percent, const std::string &description,
+ const std::string &changed, bool is_full)
+{
+ GtkTreeView *view = GTK_TREE_VIEW (widget);
+ GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+ if (i == 0)
+ gtk_list_store_clear (store);
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, path.c_str(), 1, usage_percent,
+ 2, description.c_str(), 3, PANGO_WEIGHT_NORMAL, 4, NULL,
+ 5, changed.c_str(), -1);
+ if (is_full)
+ gtk_list_store_set (store, &iter, 3, PANGO_WEIGHT_BOLD, 4, "red", -1);
+}
+
+GtkWidget *DiskView::getWidget()
+{ return m_button; }
+
+DiskView::DiskView ()
+: m_hasWarn (false)
+{
+ m_button = ygtk_menu_button_new();
+ gtk_widget_set_tooltip_text (m_button, _("Disk usage"));
+ gtk_container_add (GTK_CONTAINER (m_button), gtk_image_new_from_pixbuf (NULL));
+
+ m_view = DiskList_new (NULL, false);
+ ygtk_menu_button_set_popup_align (YGTK_MENU_BUTTON (m_button), m_view, 0.0, 1.0);
+
+ m_diskPixbuf = YGUtils::loadPixbuf (std::string (DATADIR) + "/harddisk.png");
+ m_diskFullPixbuf = YGUtils::loadPixbuf (std::string (DATADIR) + "/harddisk-full.png");
+
+ Ypp::get()->getDisk()->addListener (this);
+ updateDisk();
+}
+
+DiskView::~DiskView()
+{
+ g_object_unref (m_diskPixbuf);
+ g_object_unref (m_diskFullPixbuf);
+}
+
+void DiskView::updateDisk()
+{
+ #define MIN_PERCENT_WARN 90
+ #define MIN_FREE_MB_WARN (500*1024)
+ bool warn = false;
+ Ypp::Disk *disk = Ypp::get()->getDisk();
+ for (int i = 0; disk->getPartition (i); i++) {
+ const Ypp::Disk::Partition *part = disk->getPartition (i);
+
+ int usage_percent = (part->used * 100) / (part->total + 1);
+ int delta_percent = (part->delta * 100) / (part->total + 1);
+
+ bool full = usage_percent > MIN_PERCENT_WARN &&
+ (part->total - part->used) < MIN_FREE_MB_WARN;
+ if (full) warn = true;
+ std::string description (part->used_str + _(" of ") + part->total_str);
+ std::string delta_str;
+ if (part->delta) {
+ delta_str = (part->delta > 0 ? "(+" : "(");
+ delta_str += part->delta_str + ")";
+ }
+ DiskList_setup (m_view, i, part->path, usage_percent, delta_percent,
+ description, delta_str, full);
+ }
+ GdkPixbuf *pixbuf = m_diskPixbuf;
+ if (warn) {
+ pixbuf = m_diskFullPixbuf;
+ popupWarning();
+ }
+ gtk_image_set_from_pixbuf (GTK_IMAGE (GTK_BIN (m_button)->child), pixbuf);
+}
+
+void DiskView::popupWarning()
+{
+ if (m_hasWarn) return;
+ m_hasWarn = true;
+ if (!GTK_WIDGET_REALIZED (getWidget())) return;
+
+ GtkWidget *dialog, *view;
+ dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK, "%s", _("Disk Almost Full !"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
+ _("One of the partitions is reaching its limit of capacity. You may "
+ "have to remove packages if you wish to install some."));
+
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_view));
+ view = DiskList_new (model, true);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view);
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (gtk_widget_destroy), this);
+ gtk_widget_show (dialog);
+}
+
Added: trunk/gtk/src/pkg/ygtkdiskview.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkdiskview.h?rev=5…
==============================================================================
--- trunk/gtk/src/pkg/ygtkdiskview.h (added)
+++ trunk/gtk/src/pkg/ygtkdiskview.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,32 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Show partitions.
+*/
+
+#ifndef YGTK_DISK_VIEW_H
+#define YGTK_DISK_VIEW_H
+
+#include "yzyppwrapper.h"
+#include <gtk/gtk.h>
+
+class DiskView : public Ypp::Disk::Listener
+{
+GdkPixbuf *m_diskPixbuf, *m_diskFullPixbuf;
+bool m_hasWarn;
+GtkWidget *m_button, *m_view;
+
+public:
+ GtkWidget *getWidget();
+
+ DiskView ();
+ ~DiskView();
+
+private:
+ virtual void updateDisk();
+ void popupWarning();
+};
+
+#endif /*YGTK_DISK_VIEW_H*/
+
Added: trunk/gtk/src/pkg/ygtknotebook.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtknotebook.c?rev=5…
==============================================================================
--- trunk/gtk/src/pkg/ygtknotebook.c (added)
+++ trunk/gtk/src/pkg/ygtknotebook.c Thu Nov 26 18:16:21 2009
@@ -0,0 +1,138 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkNotebook widget */
+// check the header file for information about this widget
+
+#include <config.h>
+#include "ygtknotebook.h"
+#include <gtk/gtk.h>
+
+extern void ygutils_setWidgetFont (GtkWidget *widget, PangoStyle style,
+ PangoWeight weight, double scale);
+
+G_DEFINE_TYPE (YGtkNotebook, ygtk_notebook, GTK_TYPE_NOTEBOOK)
+
+static void ygtk_notebook_init (YGtkNotebook *view)
+{
+}
+
+static void ygtk_notebook_destroy (GtkObject *object)
+{
+ YGtkNotebook *notebook = YGTK_NOTEBOOK (object);
+ ygtk_notebook_set_corner_widget (notebook, NULL);
+ GTK_OBJECT_CLASS (ygtk_notebook_parent_class)->destroy (object);
+}
+
+static void ygtk_notebook_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ YGtkNotebook *notebook = YGTK_NOTEBOOK (widget);
+ if (notebook->corner_widget) {
+ GtkRequisition child_req; // many widgets require size_request asked
+ gtk_widget_size_request (notebook->corner_widget, &child_req);
+ }
+ GTK_WIDGET_CLASS (ygtk_notebook_parent_class)->size_request (widget, requisition);
+}
+
+static void ygtk_notebook_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ GTK_WIDGET_CLASS (ygtk_notebook_parent_class)->size_allocate (widget, allocation);
+ gboolean reverse = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+ YGtkNotebook *ynotebook = YGTK_NOTEBOOK (widget);
+ if (ynotebook->corner_widget) {
+ GtkRequisition child_req;
+ gtk_widget_get_child_requisition (ynotebook->corner_widget, &child_req);
+
+ GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+ int tabs_width = 0;
+ int npages = gtk_notebook_get_n_pages (notebook);
+ GtkWidget *last_label = gtk_notebook_get_nth_page (notebook, npages-1);
+ if (last_label)
+ last_label = gtk_notebook_get_tab_label (notebook, last_label);
+ if (last_label) {
+ if (reverse)
+ tabs_width = (allocation->width + allocation->x) - last_label->allocation.x + 8;
+ else
+ tabs_width = (last_label->allocation.width + last_label->allocation.x) - allocation->x + 8;
+ }
+
+ GtkAllocation child_alloc;
+ child_alloc.width = MAX (0, MIN (allocation->width - tabs_width, child_req.width));
+ child_alloc.height = child_req.height;
+ if (reverse)
+ child_alloc.x = allocation->x;
+ else
+ child_alloc.x = allocation->x + (allocation->width - child_alloc.width);
+ child_alloc.y = allocation->y +
+ MAX (0, (last_label->allocation.y-allocation->y) + last_label->allocation.height + 3 - child_req.height);
+
+ gtk_widget_size_allocate (ynotebook->corner_widget, &child_alloc);
+ }
+}
+
+static void ygtk_notebook_forall (GtkContainer *container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ g_return_if_fail (callback != NULL);
+ if (include_internals) {
+ YGtkNotebook *notebook = YGTK_NOTEBOOK (container);
+ if (notebook->corner_widget)
+ (* callback) (notebook->corner_widget, callback_data);
+ }
+ GTK_CONTAINER_CLASS (ygtk_notebook_parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void ygtk_notebook_map (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (ygtk_notebook_parent_class)->map (widget);
+ YGtkNotebook *notebook = YGTK_NOTEBOOK (widget);
+ if (notebook->corner_widget) {
+ GtkWidget *corner = notebook->corner_widget;
+ if (corner && GTK_WIDGET_VISIBLE (corner) && !GTK_WIDGET_MAPPED (corner))
+ gtk_widget_map (corner);
+ }
+}
+
+static void ygtk_notebook_switch_page (
+ GtkNotebook *notebook, GtkNotebookPage *_page, guint page_nb)
+{ // don't let user select insensitive tab
+ GtkWidget *page = gtk_notebook_get_nth_page (notebook, page_nb);
+ GtkWidget *label = gtk_notebook_get_tab_label (notebook, page);
+ if (label && !GTK_WIDGET_IS_SENSITIVE (label))
+ ; // insensitive; don't call parent
+ else
+ GTK_NOTEBOOK_CLASS (ygtk_notebook_parent_class)->switch_page (
+ notebook, _page, page_nb);
+}
+
+void ygtk_notebook_set_corner_widget (YGtkNotebook *ynotebook, GtkWidget *child)
+{
+ if (ynotebook->corner_widget)
+ gtk_widget_unparent (ynotebook->corner_widget);
+ if (child)
+ gtk_widget_set_parent (child, GTK_WIDGET (ynotebook));
+ ynotebook->corner_widget = child;
+}
+
+GtkWidget *ygtk_notebook_new (void)
+{ return g_object_new (YGTK_TYPE_NOTEBOOK, NULL); }
+
+static void ygtk_notebook_class_init (YGtkNotebookClass *klass)
+{
+ GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+ gtkobject_class->destroy = ygtk_notebook_destroy;
+
+ GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->size_request = ygtk_notebook_size_request;
+ gtkwidget_class->size_allocate = ygtk_notebook_size_allocate;
+ gtkwidget_class->map = ygtk_notebook_map;
+
+ GtkContainerClass *gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
+ gtkcontainer_class->forall = ygtk_notebook_forall;
+
+ GtkNotebookClass *gtknotebook_class = GTK_NOTEBOOK_CLASS (klass);
+ gtknotebook_class->switch_page = ygtk_notebook_switch_page;
+}
+
Added: trunk/gtk/src/pkg/ygtknotebook.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtknotebook.h?rev=5…
==============================================================================
--- trunk/gtk/src/pkg/ygtknotebook.h (added)
+++ trunk/gtk/src/pkg/ygtknotebook.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,46 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Makes GtkNotebook's top-corner available for a widget.
+ Also makes pages, whose tab labels are insentitive, unaccesible.
+*/
+
+#ifndef YGTK_NOTEBOOK_H
+#define YGTK_NOTEBOOK_H
+
+#include <gtk/gtknotebook.h>
+G_BEGIN_DECLS
+
+#define YGTK_TYPE_NOTEBOOK (ygtk_notebook_get_type ())
+#define YGTK_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), YGTK_TYPE_NOTEBOOK, YGtkNotebook))
+#define YGTK_NOTEBOOK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), YGTK_TYPE_NOTEBOOK, YGtkNotebookClass))
+#define YGTK_IS_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YGTK_TYPE_NOTEBOOK))
+#define YGTK_IS_NOTEBOOK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), YGTK_TYPE_NOTEBOOK))
+#define YGTK_NOTEBOOK_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), YGTK_TYPE_NOTEBOOK, YGtkNotebookClass))
+
+typedef struct _YGtkNotebook
+{
+ GtkNotebook parent;
+ // private:
+ GtkWidget *corner_widget;
+} YGtkNotebook;
+
+typedef struct _YGtkNotebookClass
+{
+ GtkNotebookClass parent_class;
+} YGtkNotebookClass;
+
+GtkWidget* ygtk_notebook_new (void);
+GType ygtk_notebook_get_type (void) G_GNUC_CONST;
+
+void ygtk_notebook_set_corner_widget (YGtkNotebook *notebook, GtkWidget *child);
+
+G_END_DECLS
+#endif /*YGTK_NOTEBOOK_H*/
+
Added: trunk/gtk/src/pkg/ygtkpackageview.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkpackageview.cc?r…
==============================================================================
--- trunk/gtk/src/pkg/ygtkpackageview.cc (added)
+++ trunk/gtk/src/pkg/ygtkpackageview.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,1372 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkZyppView, Zypp GtkTreeView implementation */
+// check the header file for information about this widget
+
+/*
+ Textdomain "yast2-gtk"
+ */
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "ygtkpackageview.h"
+#include "ygtktreeview.h"
+#include "ygtktreemodel.h"
+#include "ygtkcellrendererbutton.h"
+#include "YGi18n.h"
+#include "YGUtils.h"
+#include <gtk/gtk.h>
+#include <string.h>
+
+//** Icons resources
+
+struct PackageIcons {
+ GdkPixbuf *installed, *installed_upgradable, *installed_locked,
+ *installed_upgradable_locked, *available, *available_locked,
+ *to_install, *to_install_upgrade, *to_remove, *to_auto_install,
+ *to_auto_remove;
+
+ static PackageIcons *get()
+ { // let the system reclaim the mem after sw_single finishes
+ static PackageIcons *icons = NULL;
+ if (!icons)
+ icons = new PackageIcons();
+ return icons;
+ }
+
+ PackageIcons() {
+ installed = loadPixbuf ("pkg-installed.png");
+ installed_upgradable = loadPixbuf ("pkg-installed-upgradable.png");
+ installed_locked = loadPixbuf ("pkg-installed-locked.png");
+ installed_upgradable_locked = loadPixbuf ("pkg-installed-upgradable-locked.png");
+ available = loadPixbuf ("pkg-available.png");
+ available_locked = loadPixbuf ("pkg-available-locked.png");
+ to_install = loadPixbuf ("pkg-install.png");
+ to_install_upgrade = loadPixbuf ("pkg-upgrade.png");
+ to_remove = loadPixbuf ("pkg-remove.png");
+ to_auto_install = loadPixbuf ("pkg-install-auto.png");
+ to_auto_remove = loadPixbuf ("pkg-remove-auto.png");
+ }
+ ~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_install_upgrade));
+ g_object_unref (G_OBJECT (to_auto_install));
+ g_object_unref (G_OBJECT (to_auto_remove));
+ }
+
+ static GdkPixbuf *loadPixbuf (const char *icon)
+ { return YGUtils::loadPixbuf (std::string (DATADIR) + "/" + icon); }
+
+ GdkPixbuf *getPixbuf (Ypp::Package *package)
+ {
+ bool locked = package->isLocked();
+ bool auto_ = package->isAuto();
+ if (package->toInstall()) {
+ if (auto_)
+ return to_auto_install;
+ else {
+ if (package->isInstalled())
+ return to_install_upgrade;
+ return to_install;
+ }
+ }
+ else if (package->toRemove()) {
+ if (auto_)
+ return to_auto_remove;
+ else
+ return to_remove;
+ }
+ else if (package->hasUpgrade()) {
+ if (locked)
+ return installed_upgradable_locked;
+ else
+ return installed_upgradable;
+ }
+ else if (package->isInstalled()) {
+ if (locked)
+ return installed_locked;
+ return installed;
+ }
+ if (locked)
+ return available_locked;
+ return available;
+ }
+};
+
+//** Model
+
+enum Property {
+ // pixbuf
+ ICON_PROP,
+ // text
+ NAME_PROP, SUMMARY_PROP, NAME_SUMMARY_PROP, REPOSITORY_PROP, SUPPORT_PROP,
+ SIZE_PROP, INSTALLED_VERSION_PROP, AVAILABLE_VERSION_PROP,
+ // checks
+ TO_INSTALL_PROP, TO_UPGRADE_PROP, TO_REMOVE_PROP, TO_MODIFY_PROP,
+ // internal
+ STYLE_PROP, WEIGHT_PROP, SENSITIVE_PROP, CHECK_VISIBLE_PROP,
+ FOREGROUND_PROP, BACKGROUND_PROP, XPAD_PROP,
+ INSTALL_LABEL_PROP, REMOVE_LABEL_PROP, INSTALL_STOCK_PROP, REMOVE_STOCK_PROP,
+ // misc
+ PTR_PROP, TOTAL_PROPS
+};
+
+static GType _columnType (int col)
+{
+ switch (col) {
+ case ICON_PROP:
+ return GDK_TYPE_PIXBUF;
+ case NAME_PROP:
+ case SUMMARY_PROP:
+ case NAME_SUMMARY_PROP:
+ case REPOSITORY_PROP:
+ case SUPPORT_PROP:
+ case SIZE_PROP:
+ case INSTALLED_VERSION_PROP:
+ case AVAILABLE_VERSION_PROP:
+ case FOREGROUND_PROP:
+ case BACKGROUND_PROP:
+ case INSTALL_LABEL_PROP:
+ case REMOVE_LABEL_PROP:
+ case INSTALL_STOCK_PROP:
+ case REMOVE_STOCK_PROP:
+ return G_TYPE_STRING;
+ case TO_INSTALL_PROP:
+ case TO_UPGRADE_PROP:
+ case TO_REMOVE_PROP:
+ case TO_MODIFY_PROP:
+ case SENSITIVE_PROP:
+ case CHECK_VISIBLE_PROP:
+ return G_TYPE_BOOLEAN;
+ case STYLE_PROP:
+ case WEIGHT_PROP:
+ case XPAD_PROP:
+ return G_TYPE_INT;
+ case PTR_PROP:
+ return G_TYPE_POINTER;
+ }
+ return 0;
+}
+
+static void _getValueDefault (int col, GValue *value)
+{
+ switch (col) {
+ case ICON_PROP:
+ g_value_set_object (value, NULL);
+ break;
+ case NAME_PROP:
+ case SUMMARY_PROP:
+ case NAME_SUMMARY_PROP:
+ case REPOSITORY_PROP:
+ case SUPPORT_PROP:
+ case SIZE_PROP:
+ case INSTALLED_VERSION_PROP:
+ case AVAILABLE_VERSION_PROP:
+ case INSTALL_LABEL_PROP:
+ case REMOVE_LABEL_PROP:
+ case INSTALL_STOCK_PROP:
+ case REMOVE_STOCK_PROP:
+ g_value_set_string (value, g_strdup (""));
+ break;
+ case FOREGROUND_PROP:
+ case BACKGROUND_PROP:
+ g_value_set_string (value, NULL);
+ break;
+ case TO_INSTALL_PROP:
+ case TO_UPGRADE_PROP:
+ case TO_REMOVE_PROP:
+ case TO_MODIFY_PROP:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case STYLE_PROP:
+ g_value_set_int (value, PANGO_STYLE_NORMAL);
+ break;
+ case WEIGHT_PROP:
+ g_value_set_int (value, PANGO_WEIGHT_NORMAL);
+ break;
+ case XPAD_PROP:
+ g_value_set_int (value, 0);
+ break;
+ case SENSITIVE_PROP:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case CHECK_VISIBLE_PROP:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case PTR_PROP:
+ g_value_set_pointer (value, NULL);
+ break;
+ }
+}
+
+struct YGtkZyppModel : public YGtkTreeModel, Ypp::PkgList::Listener
+{
+ YGtkZyppModel()
+ {}
+
+ void append (const std::string &header, Ypp::PkgList list, const std::string &applyAllLabel)
+ {
+ block.segments.push_back (Block::Segment (&block, header, list, applyAllLabel));
+ list.addListener (this);
+ }
+
+protected:
+ struct Block {
+ struct Segment {
+ Segment (Block *block, const std::string &header, Ypp::PkgList list, const std::string &applyAllLabel)
+ : block (block), header (header), applyAll (applyAllLabel), list (list)
+ {}
+
+ int size()
+ {
+ int size = list.size();
+ if (size == 0) return 0;
+ return size + (header.empty() ? 0 : 1) + (applyAll.empty() ? 0 : 1);
+ }
+
+ void signalChanged (int index, YGtkTreeModel::Listener *listener)
+ {
+ int row = getRow() + index + (header.empty() ? 0 : 1);
+ listener->rowChanged (row);
+ }
+
+ void signalInserted (int index, YGtkTreeModel::Listener *listener)
+ {
+ int row = getRow() + index + (header.empty() ? 0 : 1);
+ if (list.size() == 1) {
+ if (!header.empty())
+ listener->rowInserted (row-1);
+ if (!applyAll.empty())
+ listener->rowInserted (row+1);
+ }
+ listener->rowInserted (row);
+ }
+
+ void signalDelete (int index, YGtkTreeModel::Listener *listener)
+ {
+ int row = getRow() + index + (header.empty() ? 0 : 1);
+ if (list.size() == 1) {
+ if (!header.empty())
+ listener->rowDeleted (row-1);
+ if (!applyAll.empty())
+ listener->rowDeleted (row+1);
+ }
+ listener->rowDeleted (row);
+ }
+
+ int getRow()
+ {
+ int row = 0;
+ for (std::list <Segment>::iterator it = block->segments.begin();
+ it != block->segments.end(); it++) {
+ if (&(*it) == this)
+ break;
+ row += it->size();
+ }
+ return row;
+ }
+
+ Block *block;
+ std::string header, applyAll;
+ Ypp::PkgList list;
+ };
+
+ std::list <Segment> segments;
+
+ Segment *get (const Ypp::PkgList *list)
+ {
+ for (std::list <Segment>::iterator it = segments.begin(); it != segments.end(); it++)
+ if (it->list == *list)
+ return &(*it);
+ return NULL;
+ }
+
+ bool get (int row, Segment **segment, int *index)
+ {
+ int size = 0;
+ for (std::list <Segment>::iterator it = segments.begin(); it != segments.end(); it++) {
+ int _size = it->size();
+ if (size+_size > row) {
+ *segment = &(*it);
+ *index = row - size - (it->header.empty() ? 0 : 1);
+ if (!it->applyAll.empty() && *index == _size-1)
+ *index = -2;
+ return true;
+ }
+ size += _size;
+ }
+ return false;
+ }
+
+ int sumSize()
+ {
+ int size = 0;
+ for (std::list <Segment>::iterator it = segments.begin(); it != segments.end(); it++)
+ size += it->size();
+ return size;
+ }
+ };
+
+ Block block;
+
+ virtual int rowsNb()
+ { return block.sumSize(); }
+
+ virtual int columnsNb() const
+ { return TOTAL_PROPS; }
+
+ virtual bool showEmptyEntry() const
+ { return true; }
+
+ virtual GType columnType (int col) const
+ { return _columnType (col); }
+
+ virtual void getValue (int row, int col, GValue *value)
+ {
+ if (row == -1) {
+ switch (col) {
+ case NAME_PROP:
+ g_value_set_string (value, g_strdup (_("(No entries.)")));
+ break;
+ case STYLE_PROP:
+ g_value_set_int (value, PANGO_STYLE_ITALIC);
+ break;
+ case CHECK_VISIBLE_PROP:
+ g_value_set_boolean (value, FALSE);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+
+ Block::Segment *segment = 0;
+ int index = 0;
+ block.get (row, &segment, &index);
+
+ if (index == -1) { // header
+ switch (col) {
+ case NAME_PROP:
+ g_value_set_string (value, g_strdup (segment->header.c_str()));
+ break;
+ case NAME_SUMMARY_PROP: {
+ std::string header (segment->header);
+ header = "<big>" + header + "</big>";
+ g_value_set_string (value, g_strdup (header.c_str()));
+ break;
+ }
+ case WEIGHT_PROP:
+ g_value_set_int (value, PANGO_WEIGHT_BOLD);
+ break;
+ case CHECK_VISIBLE_PROP:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case FOREGROUND_PROP:
+ g_value_set_string (value, g_strdup ("darkgray"));
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+ if (index == -2) { // apply all label
+ switch (col) {
+ case NAME_PROP:
+ case NAME_SUMMARY_PROP:
+ g_value_set_string (value, g_strdup (segment->applyAll.c_str()));
+ break;
+ case BACKGROUND_PROP: {
+#if 0
+ case FOREGROUND_PROP:
+ GtkStyle *style = gtk_widget_get_default_style();
+ GdkColor *color = &style->bg [GTK_STATE_SELECTED];
+ if (col == FOREGROUND_PROP)
+ color = &style->fg [GTK_STATE_NORMAL];
+ gchar *str = gdk_color_to_string (color); // old: "lightblue"
+ g_value_set_string (value, str);
+#endif
+ g_value_set_string (value, g_strdup ("lightblue"));
+ break;
+ }
+ case FOREGROUND_PROP:
+ g_value_set_string (value, g_strdup ("black"));
+ break;
+ case TO_INSTALL_PROP:
+ case TO_UPGRADE_PROP:
+ case TO_REMOVE_PROP:
+ case TO_MODIFY_PROP: {
+ bool modified = segment->list.modified();
+ g_value_set_boolean (value, modified);
+ break;
+ }
+ case INSTALL_LABEL_PROP:
+ case REMOVE_LABEL_PROP:
+ g_value_set_string (value, g_strdup (_("All")));
+ break;
+ case INSTALL_STOCK_PROP:
+ case REMOVE_STOCK_PROP:
+ g_value_set_string (value, g_strdup (GTK_STOCK_SELECT_ALL));
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+
+ Ypp::Package *package = segment->list.get (index);
+ switch (col) {
+ case ICON_PROP: {
+ GdkPixbuf *pixbuf = 0;
+ if (package->type() == Ypp::Package::PATTERN_TYPE) {
+ std::string filename (package->icon());
+ GtkIconTheme *icons = gtk_icon_theme_get_default();
+ pixbuf = gtk_icon_theme_load_icon (icons,
+ filename.c_str(), 32, GtkIconLookupFlags (0), NULL);
+ if (!package->isInstalled()) {
+ GdkPixbuf *_pixbuf = pixbuf;
+ pixbuf = YGUtils::setOpacity (_pixbuf, 50, true);
+ g_object_unref (_pixbuf);
+ }
+ }
+ if (!pixbuf)
+ pixbuf = PackageIcons::get()->getPixbuf (package);
+ g_value_set_object (value, (GObject *) pixbuf);
+ break;
+ }
+ case NAME_PROP: {
+ std::string str (package->name());
+ g_value_set_string (value, g_strdup (str.c_str()));
+ break;
+ }
+ case SUMMARY_PROP: {
+ std::string str (package->summary());
+ g_value_set_string (value, g_strdup (str.c_str()));
+ break;
+ }
+ case NAME_SUMMARY_PROP: {
+ 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 REPOSITORY_PROP: {
+ const Ypp::Package::Version *version = 0;
+ if (package->toInstall (&version)) ;
+ if (!version)
+ version = package->getInstalledVersion();
+ std::string repo;
+ if (version && version->repo)
+ repo = version->repo->name;
+ g_value_set_string (value, g_strdup (repo.c_str()));
+ break;
+ }
+ case SUPPORT_PROP:
+ g_value_set_string (value, g_strdup (package->support().c_str()));
+ break;
+ case SIZE_PROP:
+ g_value_set_string (value, g_strdup (package->size().c_str()));
+ break;
+ case INSTALLED_VERSION_PROP: {
+ const Ypp::Package::Version *version = package->getInstalledVersion();
+ if (version)
+ g_value_set_string (value, g_strdup (version->number.c_str()));
+ break;
+ }
+ case AVAILABLE_VERSION_PROP: {
+ const Ypp::Package::Version *version = package->getAvailableVersion (0);
+ if (version)
+ g_value_set_string (value, g_strdup (version->number.c_str()));
+ break;
+ }
+ case TO_INSTALL_PROP:
+ g_value_set_boolean (value, package->toInstall());
+ break;
+ case TO_UPGRADE_PROP: {
+ const Ypp::Package::Version *version = 0;
+ if (package->toInstall (&version))
+ g_value_set_boolean (value, version->cmp > 0);
+ break;
+ }
+ case TO_REMOVE_PROP:
+ g_value_set_boolean (value, package->toRemove());
+ break;
+ case TO_MODIFY_PROP:
+ g_value_set_boolean (value, package->toModify());
+ break;
+ case SENSITIVE_PROP: {
+ bool sensitive = !package->isLocked();
+ g_value_set_boolean (value, sensitive);
+ break;
+ }
+/*
+ case STYLE_PROP: {
+ PangoStyle style = PANGO_STYLE_NORMAL;
+ if (package->isAuto())
+ style = PANGO_STYLE_ITALIC;
+ g_value_set_int (value, style);
+ break;
+ }
+*/
+ case WEIGHT_PROP: {
+ bool highlight = segment->list.highlight (package);
+ int weight = highlight ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
+ g_value_set_int (value, weight);
+ break;
+ }
+ case XPAD_PROP: {
+ int xpad = package->isAuto() ? 15 : 0;
+ g_value_set_int (value, xpad);
+ break;
+ }
+ case INSTALL_LABEL_PROP: {
+ const char *label = _("Add");
+/* if (package->toModify())
+ label = _("Undo");
+ else if (package->hasUpgrade())
+ label = _("Upgrade");*/
+ if (package->hasUpgrade())
+ label = _("Upgrade");
+ g_value_set_string (value, g_strdup (label));
+ break;
+ }
+ case REMOVE_LABEL_PROP: {
+ const char *label = _("Remove");
+/* if (package->toModify())
+ label = _("Undo");*/
+ g_value_set_string (value, g_strdup (label));
+ break;
+ }
+ case INSTALL_STOCK_PROP: {
+ const char *stock = GTK_STOCK_ADD;
+/* if (package->toModify())
+ stock = GTK_STOCK_UNDO;*/
+ g_value_set_string (value, g_strdup (stock));
+ break;
+ }
+ case REMOVE_STOCK_PROP: {
+ const char *stock = GTK_STOCK_REMOVE;
+/* if (package->toModify())
+ stock = GTK_STOCK_UNDO;*/
+ g_value_set_string (value, g_strdup (stock));
+ break;
+ }
+ case PTR_PROP:
+ g_value_set_pointer (value, (void *) package);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ }
+
+ virtual void entryChanged (const Ypp::PkgList list, int index, Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalChanged (index, listener);
+ }
+
+ virtual void entryInserted (const Ypp::PkgList list, int index, Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalInserted (index, listener);
+ }
+
+ virtual void entryDeleted (const Ypp::PkgList list, int index, Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalDelete (index, listener);
+ }
+};
+
+static GtkTreeModel *ygtk_zypp_model_new()
+{ return ygtk_tree_model_new (new YGtkZyppModel()); }
+
+static void ygtk_zypp_model_append (GtkTreeModel *model,
+ const std::string &header, Ypp::PkgList list, const std::string &applyAllLabel)
+{
+ YGtkZyppModel *zmodel = (YGtkZyppModel *) ygtk_tree_model_get_model (model);
+ zmodel->append (header, list, applyAllLabel);
+}
+
+// model to show "loading..." on query
+struct EmptyModel : public YGtkTreeModel
+{
+ virtual bool showEmptyEntry() const { return false; }
+ virtual int rowsNb() { return 1; }
+ virtual int columnsNb() const { return TOTAL_PROPS; }
+ virtual GType columnType (int col) const { return _columnType (col); }
+
+ virtual void getValue (int row, int col, GValue *value)
+ {
+ switch (col) {
+ case NAME_PROP:
+ g_value_set_string (value, g_strdup (_("Query...")));
+ break;
+ case STYLE_PROP:
+ g_value_set_int (value, PANGO_STYLE_ITALIC);
+ break;
+ case CHECK_VISIBLE_PROP:
+ g_value_set_boolean (value, FALSE);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ }
+
+ virtual void setListener (YGtkTreeModel::Listener *listener) {}
+};
+
+//** View
+
+struct Column {
+ const char *header;
+ std::string prop;
+ bool visibleDefault, allowHide, sortable;
+};
+static const Column columns[] = {
+ { NULL, "to-install", true, false, false },
+ { "Name", "name", true, false, true },
+ { "Version", "available-version", true, true, false },
+ { "Repository", "repository", false, true, false },
+ { "Support", "support", false, true, false },
+ { "Size", "size", false, true, true },
+};
+static int columns_size = sizeof (columns) / sizeof (Column);
+
+static Property translateProperty (const std::string &prop)
+{
+ if (prop == "name")
+// return NAME_PROP;
+ return NAME_SUMMARY_PROP;
+ if (prop == "available-version")
+ return AVAILABLE_VERSION_PROP;
+ if (prop == "repository")
+ return REPOSITORY_PROP;
+ if (prop == "support")
+ return SUPPORT_PROP;
+ if (prop == "size")
+ return SIZE_PROP;
+ if (prop == "to-install")
+ return TO_INSTALL_PROP;
+ return (Property) 0;
+}
+
+struct YGtkPackageView::Impl
+{
+ Impl (GtkWidget *scroll, bool descriptiveTooltip)
+ : m_listener (NULL), m_popup_hack (NULL), m_descriptiveTooltip (descriptiveTooltip),
+ m_model (NULL), m_modelId (0), m_activate_action (NONE_ACTION)
+ {
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ GtkTreeView *view = GTK_TREE_VIEW (m_view = ygtk_tree_view_new());
+ gtk_tree_view_set_search_column (view, NAME_PROP);
+ gtk_tree_view_set_fixed_height_mode (view, TRUE);
+ gtk_tree_view_set_headers_visible (view, FALSE);
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (packages_selected_cb), this);
+ gtk_tree_selection_set_select_function (selection, can_select_row_cb,
+ this, NULL);
+
+ g_signal_connect (G_OBJECT (m_view), "row-activated",
+ G_CALLBACK (package_activated_cb), this);
+ g_signal_connect (G_OBJECT (m_view), "right-click",
+ G_CALLBACK (popup_menu_cb), this);
+ gtk_widget_set_has_tooltip (m_view, TRUE);
+ g_signal_connect (G_OBJECT (m_view), "query-tooltip",
+ G_CALLBACK (query_tooltip_cb), this);
+
+ gtk_container_add (GTK_CONTAINER (scroll), m_view);
+ gtk_widget_show_all (scroll);
+ clear();
+
+ for (int i = 0; i < columns_size; i++) {
+ const Column *column = &columns[i];
+ if (column->prop.compare (0, 3, "to-") == 0)
+ appendButtonColumn (column->header, column->prop);
+ else
+ appendTextColumn (column->header, column->prop,
+ column->visibleDefault, column->sortable);
+ }
+ }
+
+ ~Impl()
+ {
+ if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ }
+
+ // data
+ YGtkPackageView::Listener *m_listener;
+ GtkWidget *m_view, *m_popup_hack;
+ bool m_descriptiveTooltip;
+ GtkTreeModel *m_model;
+ Ypp::PkgList m_list;
+ guint m_modelId;
+ Action m_activate_action;
+
+ // methods
+ void setList (Ypp::PkgList list, const char *applyAllLabel)
+ {
+ m_list = list;
+ setListImpl (list, applyAllLabel);
+ }
+
+ void setListImpl (Ypp::PkgList list, const char *applyAllLabel)
+ {
+ std::string _applyAllLabel = applyAllLabel ? applyAllLabel : "";
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ m_model = ygtk_zypp_model_new();
+ ygtk_zypp_model_append (m_model, std::string (""), list, _applyAllLabel);
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ gtk_tree_view_set_model (view, m_model);
+ if (GTK_WIDGET_REALIZED (view))
+ gtk_tree_view_scroll_to_point (view, -1, 0);
+ }
+
+ void packList (const char *header, Ypp::PkgList list, const char *applyAllLabel)
+ {
+ std::string _header = header ? header : "";
+ std::string _applyAllLabel = applyAllLabel ? applyAllLabel : "";
+ if (!m_model)
+ m_model = ygtk_zypp_model_new();
+ ygtk_zypp_model_append (m_model, _header, list, _applyAllLabel);
+ if (!m_modelId)
+ m_modelId = g_idle_add_full (G_PRIORITY_LOW, set_model_cb, this, NULL);
+ }
+
+ void clear()
+ {
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ m_model = 0;
+ static GtkTreeModel *empty = 0;
+ if (!empty)
+ empty = ygtk_tree_model_new (new EmptyModel());
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), empty);
+ }
+
+ GList *getSelectedPaths (GtkTreeModel **model)
+ { return gtk_tree_selection_get_selected_rows (getTreeSelection(), model); }
+
+ void selectAll()
+ { gtk_tree_selection_select_all (getTreeSelection()); }
+
+ void unselectAll()
+ { gtk_tree_selection_unselect_all (getTreeSelection()); }
+
+ int countSelected()
+ { return gtk_tree_selection_count_selected_rows (getTreeSelection()); }
+
+ Ypp::PkgList getSelected()
+ {
+ GtkTreeModel *model;
+ GList *paths = getSelectedPaths (&model);
+ Ypp::PkgList 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, PTR_PROP, &package, -1);
+ gtk_tree_path_free (path);
+ if (package)
+ packages.append (package);
+ }
+ g_list_free (paths);
+ return packages;
+ }
+
+ GtkTreeViewColumn *getColumn (const std::string &property)
+ {
+ for (int i = 0; i < columns_size; i++)
+ if (columns[i].prop == property)
+ return gtk_tree_view_get_column (GTK_TREE_VIEW (m_view), i);
+ return NULL;
+ }
+
+ std::string getColumnProp (GtkTreeViewColumn *column)
+ {
+ gchar *prop = (gchar *) g_object_get_data (G_OBJECT (column), "property");
+ return prop;
+ }
+
+ void setVisible (const std::string &property, bool visible)
+ { gtk_tree_view_column_set_visible (getColumn (property), visible); }
+
+ bool isVisible (const std::string &property)
+ { return gtk_tree_view_column_get_visible (getColumn (property)); }
+
+ void appendIconColumn (const char *header, int col)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ if (header)
+ gtk_tree_view_set_headers_visible (view, TRUE);
+ GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
+ int height = MAX (34, YGUtils::getCharsHeight (m_view, 2));
+ gtk_cell_renderer_set_fixed_size (renderer, -1, height);
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (
+ header, renderer, "pixbuf", col,
+ "cell-background", BACKGROUND_PROP, NULL);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (column, 38);
+ gtk_tree_view_append_column (view, column);
+ }
+
+ static Action columnAction (int col)
+ {
+ switch (col) {
+ case TO_INSTALL_PROP:
+ case TO_UPGRADE_PROP:
+ default:
+ return INSTALL_ACTION;
+ case TO_REMOVE_PROP:
+ return REMOVE_ACTION;
+ case TO_MODIFY_PROP:
+ return UNDO_ACTION;
+ }
+ }
+
+ void appendCheckColumn (const std::string &prop)
+ {
+ int modelCol = translateProperty (prop);
+
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer, "active", modelCol, "visible", CHECK_VISIBLE_PROP,
+ "sensitive", SENSITIVE_PROP,
+ "cell-background", BACKGROUND_PROP, NULL);
+ g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (renderer_toggled_cb), this);
+
+ // it seems like GtkCellRendererToggle has no width at start, so fixed doesn't work
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (column, 25);
+ gtk_tree_view_append_column (view, column);
+
+ Action action = columnAction (modelCol);
+ g_object_set_data (G_OBJECT (renderer), "action", GINT_TO_POINTER (action));
+ if (m_activate_action == NONE_ACTION)
+ m_activate_action = action;
+ g_object_set_data (G_OBJECT (column), "status-tooltip", GINT_TO_POINTER (1));
+ }
+
+ void appendButtonColumn (const char *header, const std::string &prop)
+ {
+ int modelCol = translateProperty (prop);
+ int labelCol, stockCol;
+ switch (modelCol) {
+ case TO_INSTALL_PROP: case TO_UPGRADE_PROP: default:
+ labelCol = INSTALL_LABEL_PROP;
+ stockCol = INSTALL_STOCK_PROP;
+ break;
+ case TO_REMOVE_PROP:
+ labelCol = REMOVE_LABEL_PROP;
+ stockCol = REMOVE_STOCK_PROP;
+ break;
+ }
+
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkCellRenderer *renderer = ygtk_cell_renderer_button_new();
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (
+ header, renderer, "active", modelCol,
+ "visible", CHECK_VISIBLE_PROP,
+ "sensitive", SENSITIVE_PROP,
+ "cell-background", BACKGROUND_PROP,
+ "text", labelCol, "stock-id", stockCol, NULL);
+ g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (renderer_toggled_cb), this);
+
+ PangoRectangle rect;
+ int width = 0;
+ const char *text[] = { _("Add"), _("Remove") };
+ for (int i = 0; i < 2; i++) {
+ PangoLayout *layout = gtk_widget_create_pango_layout (m_view, text[i]);
+ pango_layout_get_pixel_extents (layout, NULL, &rect);
+ width = MAX (width, rect.width);
+ g_object_unref (G_OBJECT (layout));
+ }
+ width += 36;
+
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (column, width);
+ gtk_tree_view_append_column (view, column);
+
+ Action action = columnAction (modelCol);
+ g_object_set_data (G_OBJECT (renderer), "action", GINT_TO_POINTER (action));
+ if (m_activate_action == NONE_ACTION)
+ m_activate_action = action;
+ g_object_set_data (G_OBJECT (column), "status-tooltip", GINT_TO_POINTER (1));
+ }
+
+ void appendTextColumn (const char *header, const std::string &prop, bool visible, bool sortable, bool identAuto = false)
+ {
+ int col = translateProperty (prop);
+ int size = 100;
+ if (col == NAME_PROP || col == NAME_SUMMARY_PROP)
+ size = -1;
+
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ if (header)
+ gtk_tree_view_set_headers_visible (view, TRUE);
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_END;
+ if (size >= 0 && col != NAME_SUMMARY_PROP)
+ ellipsize = PANGO_ELLIPSIZE_MIDDLE;
+ g_object_set (G_OBJECT (renderer), "ellipsize", ellipsize, NULL);
+/* gboolean reverse = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
+ if (reverse) { // work-around: Pango ignored alignment flag on RTL
+ gtk_widget_set_direction (m_view, GTK_TEXT_DIR_LTR);
+ g_object_set (renderer, "alignment", PANGO_ALIGN_RIGHT, NULL);
+ }*/
+ const char *colType = col == NAME_SUMMARY_PROP ? "markup" : "text";
+ GtkTreeViewColumn *column;
+ column = gtk_tree_view_column_new_with_attributes (
+ header, renderer, colType, col,
+ "sensitive", SENSITIVE_PROP,
+ "style", STYLE_PROP,
+ "weight", WEIGHT_PROP,
+ "foreground", FOREGROUND_PROP,
+ "cell-background", BACKGROUND_PROP,
+ NULL);
+ g_object_set_data_full (G_OBJECT (column), "property", g_strdup (prop.c_str()), g_free);
+ if (identAuto)
+ gtk_tree_view_column_add_attribute (column, renderer, "xpad", XPAD_PROP);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ if (size >= 0)
+ gtk_tree_view_column_set_fixed_width (column, size);
+ else
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_visible (column, visible);
+ gtk_tree_view_column_set_clickable (column, sortable);
+ if (sortable)
+ g_signal_connect (G_OBJECT (column), "clicked",
+ G_CALLBACK (column_clicked_cb), this);
+ if (col == NAME_PROP || col == NAME_SUMMARY_PROP) {
+ gtk_tree_view_column_set_sort_indicator (column, TRUE);
+ gtk_tree_view_column_set_sort_order (column, GTK_SORT_ASCENDING);
+ }
+// gtk_tree_view_insert_column (view, column, reverse ? 0 : -1);
+ gtk_tree_view_append_column (view, column);
+ }
+
+ void appendEmptyColumn (int size)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkTreeViewColumn *column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (column, size);
+ gtk_tree_view_append_column (view, column);
+ }
+
+ void removeColumn (const char *header)
+ { gtk_tree_view_remove_column (GTK_TREE_VIEW (m_view), getColumn (header)); }
+
+ bool hasColumn (const char *header)
+ { return getColumn (header); }
+
+ void setRulesHint (bool hint)
+ { gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (m_view), TRUE); }
+
+ GtkTreeSelection *getTreeSelection()
+ { return gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view)); }
+
+ void signalSelected()
+ { if (m_listener) m_listener->packagesSelected (getSelected()); }
+
+ void signalPopup (int button, int event_time)
+ {
+ // GtkMenu emits "deactivate" before Items notifications, so there isn't
+ // a better way to de-allocate the popup
+ if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
+ GtkWidget *menu = m_popup_hack = gtk_menu_new();
+
+ struct inner {
+ static void appendItem (GtkWidget *menu, const char *label,
+ const char *tooltip, const char *icon, bool sensitive,
+ void (& callback) (GtkMenuItem *item, Impl *pThis), Impl *pThis)
+ {
+ GtkWidget *item;
+ if (icon) {
+ if (label) {
+ item = gtk_image_menu_item_new_with_mnemonic (label);
+ GtkWidget *image;
+ if (*icon == 'g')
+ image = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU);
+ else {
+ std::string filename = std::string (DATADIR) + "/" + icon;
+ image = gtk_image_new_from_file (filename.c_str());
+ }
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ }
+ else
+ item = gtk_image_menu_item_new_from_stock (icon, NULL);
+ }
+ else
+ item = gtk_menu_item_new_with_mnemonic (label);
+ if (tooltip)
+ gtk_widget_set_tooltip_markup (item, tooltip);
+ if (!sensitive)
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (callback), pThis);
+ }
+ static void install_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().install(); }
+ static void remove_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().remove(); }
+ static void undo_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().undo(); }
+ static void lock_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().lock (true); }
+ static void unlock_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().lock (false); }
+ static void select_all_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->selectAll(); }
+ static void show_column_cb (GtkCheckMenuItem *item, Impl *pThis)
+ {
+ GList *siblings = gtk_container_get_children (GTK_CONTAINER (
+ gtk_widget_get_parent (GTK_WIDGET (item)))), *i;
+ for (i = siblings; i; i = i->next)
+ if (i->data == item)
+ break;
+ int index = g_list_position (siblings, i) + 1;
+ g_list_free (siblings);
+ bool visible = gtk_check_menu_item_get_active (item);
+ GtkTreeViewColumn *column = gtk_tree_view_get_column (
+ GTK_TREE_VIEW (pThis->m_view), index);
+ gtk_tree_view_column_set_visible (column, visible);
+ }
+ };
+
+ Ypp::PkgList packages = getSelected();
+ bool empty = true, canLock = packages.canLock(), unlocked = packages.unlocked();
+ bool locked = !unlocked && canLock;
+ if (packages.notInstalled())
+ inner::appendItem (menu, _("_Install"), 0, GTK_STOCK_SAVE,
+ !locked, inner::install_cb, this), empty = false;
+ if (packages.upgradable())
+ inner::appendItem (menu, _("_Upgrade"), 0, GTK_STOCK_GOTO_TOP,
+ !locked, inner::install_cb, this), empty = false;
+ if (packages.installed() && packages.canRemove())
+ inner::appendItem (menu, _("_Remove"), 0, GTK_STOCK_DELETE,
+ !locked, inner::remove_cb, this), empty = false;
+ if (packages.modified())
+ inner::appendItem (menu, _("_Undo"), 0, GTK_STOCK_UNDO,
+ true, inner::undo_cb, this), empty = false;
+ if (canLock) {
+ static const char *lock_tooltip =
+ "<b>Package lock:</b> prevents the package status from being modified by "
+ "the solver (that is, it won't honour dependencies or collections ties.)";
+ if (packages.locked())
+ inner::appendItem (menu, _("_Unlock"), _(lock_tooltip), "pkg-unlocked.png",
+ true, inner::unlock_cb, this), empty = false;
+ if (unlocked)
+ inner::appendItem (menu, _("_Lock"), _(lock_tooltip), "pkg-locked.png",
+ true, inner::lock_cb, this), empty = false;
+ }
+ if (!empty)
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
+
+ GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Show Column"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ GtkWidget *submenu = gtk_menu_new();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
+ for (int i = 0; i < columns_size; i++) {
+ const Column *column = &columns[i];
+ if (column->header) {
+ GtkWidget *item = gtk_check_menu_item_new_with_label (column->header);
+ gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), isVisible (column->prop));
+ if (column->allowHide)
+ g_signal_connect (G_OBJECT (item), "toggled",
+ G_CALLBACK (inner::show_column_cb), this);
+ else
+ gtk_widget_set_sensitive (item, FALSE);
+ }
+ }
+
+ gtk_menu_attach_to_widget (GTK_MENU (menu), m_view, NULL);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time);
+ gtk_widget_show_all (menu);
+ }
+
+ // callbacks
+ static gboolean set_model_cb (gpointer data)
+ {
+ Impl *pThis = (Impl *) data;
+ GtkTreeView *view = GTK_TREE_VIEW (pThis->m_view);
+ if (gtk_tree_view_get_model (view) == pThis->m_model)
+ gtk_tree_view_set_model (view, NULL);
+ gtk_tree_view_set_model (view, pThis->m_model);
+ pThis->m_modelId = 0;
+ return FALSE;
+ }
+
+ static void packages_selected_cb (GtkTreeSelection *selection, Impl *pThis)
+ { if (GTK_WIDGET_REALIZED (pThis->m_view)) pThis->signalSelected(); }
+
+ static void popup_menu_cb (YGtkTreeView *view, gboolean outreach, Impl *pThis)
+ { if (!outreach) pThis->signalPopup(3, gtk_get_current_event_time()); }
+
+ static gboolean can_select_row_cb (GtkTreeSelection *selection, GtkTreeModel *model,
+ GtkTreePath *path, gboolean path_currently_selected, gpointer data)
+ {
+ void *package;
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, PTR_PROP, &package, -1);
+ return package != NULL;
+ }
+
+ static void apply (Ypp::Package *package, Action action, bool enable)
+ {
+ if (enable)
+ switch (action) {
+ case INSTALL_ACTION: package->install (0); break;
+ case REMOVE_ACTION: package->remove(); break;
+ case UNDO_ACTION: package->undo(); break;
+ case NONE_ACTION: break;
+ }
+ else
+ package->undo();
+ }
+
+ static gboolean apply_iter_cb (GtkTreeModel *model,
+ GtkTreePath *path, GtkTreeIter *iter, gpointer action)
+ {
+ Ypp::Package *package;
+ gboolean enable;
+ enable = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model), "enable"));
+ gtk_tree_model_get (model, iter, PTR_PROP, &package, -1);
+ if (package)
+ apply (package, (Action) GPOINTER_TO_INT (action), enable);
+ return FALSE;
+ }
+
+ static void renderer_toggled_cb (GtkCellRenderer *renderer, gchar *path_str,
+ Impl *pThis)
+ {
+ Ypp::Package *package = 0;
+ GtkTreeView *view = GTK_TREE_VIEW (pThis->m_view);
+ GtkTreeModel *model = gtk_tree_view_get_model (view);
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter_from_string (model, &iter, path_str);
+ gtk_tree_model_get (model, &iter, PTR_PROP, &package, -1);
+
+ gboolean active;
+ if (GTK_IS_CELL_RENDERER_TOGGLE (renderer))
+ active = gtk_cell_renderer_toggle_get_active (GTK_CELL_RENDERER_TOGGLE (renderer));
+ else
+ active = ygtk_cell_renderer_button_get_active (YGTK_CELL_RENDERER_BUTTON (renderer));
+
+ Action action = (Action) GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "action"));
+ if (package)
+ apply (package, action, !active);
+ else {
+ if (!gtk_tree_model_iter_next (model, &iter)) { // on apply-all
+ g_object_set_data (G_OBJECT (model), "enable", GINT_TO_POINTER (!active));
+ Ypp::get()->startTransactions();
+ gtk_tree_model_foreach (model, apply_iter_cb, GINT_TO_POINTER (action));
+ Ypp::get()->finishTransactions();
+ }
+ }
+ }
+
+ static void package_activated_cb (GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *column, Impl *pThis)
+ {
+ Ypp::PkgList packages = pThis->getSelected();
+ switch (pThis->m_activate_action) {
+ case INSTALL_ACTION: packages.install(); break;
+ case REMOVE_ACTION: packages.remove(); break;
+ case UNDO_ACTION: packages.undo(); break;
+ case NONE_ACTION: break;
+ }
+ }
+
+ static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y,
+ gboolean keyboard_mode, GtkTooltip *tooltip, Impl *pThis)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (widget);
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ if (gtk_tree_view_get_tooltip_context (view,
+ &x, &y, keyboard_mode, &model, &path, &iter)) {
+ gtk_tree_view_set_tooltip_row (view, tooltip, path);
+ gtk_tree_path_free (path);
+
+ Ypp::Package *package = 0;
+ gtk_tree_model_get (model, &iter, PTR_PROP, &package, -1);
+ if (!package) return FALSE;
+
+ std::string text;
+ text.reserve (64);
+ if (!pThis->m_descriptiveTooltip) {
+ GtkTreeViewColumn *column;
+ int bx, by;
+ gtk_tree_view_convert_widget_to_bin_window_coords (
+ view, x, y, &bx, &by);
+ gtk_tree_view_get_path_at_pos (
+ view, x, y, NULL, &column, NULL, NULL);
+ if (g_object_get_data (G_OBJECT (column), "status-tooltip")) {
+ if (package->toInstall()) {
+ if (package->isInstalled())
+ text = _("To re-install a different version");
+ else
+ text = _("To install");
+ }
+ else if (package->toRemove())
+ text = _("To remove");
+ else if (package->isInstalled()) {
+ text = _("Installed");
+ if (package->hasUpgrade())
+ text += _(" (upgrade available)");
+ }
+ else
+ text = _("Not installed");
+ if (package->isAuto())
+ text += _("\n<i>status changed by the dependency solver</i>");
+ }
+ else {
+ if (package->isLocked())
+ text = _("locked: right-click to unlock");
+ else if (package->isAuto())
+ text = _("auto: automatically selected due to dependencies");
+ }
+ }
+ else {
+ text = std::string ("<b>") + package->name() + "</b>\n";
+ text += package->description (GTK_MARKUP);
+ }
+ if (text.empty())
+ return FALSE;
+ gtk_tooltip_set_markup (tooltip, text.c_str());
+
+ if (pThis->m_descriptiveTooltip) {
+ GdkPixbuf *pixbuf = 0;
+ std::string filename (package->icon());
+ if (!filename.empty())
+ pixbuf = YGUtils::loadPixbuf (filename.c_str());
+ if (!pixbuf)
+ gtk_tree_model_get (model, &iter, ICON_PROP, &pixbuf, -1);
+ if (pixbuf) {
+ gtk_tooltip_set_icon (tooltip, pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ static void column_clicked_cb (GtkTreeViewColumn *column, Impl *pThis)
+ {
+fprintf (stderr, "column clicked\n");
+ GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (pThis->m_view));
+ for (GList *i = columns; i; i = i->next) {
+ GtkTreeViewColumn *col = (GtkTreeViewColumn *) i->data;
+ if (col != column)
+ gtk_tree_view_column_set_sort_indicator (col, FALSE);
+ }
+
+ GtkSortType sort;
+ if (gtk_tree_view_column_get_sort_indicator (column)) {
+ GtkSortType sort = gtk_tree_view_column_get_sort_order (column);
+ if (sort == GTK_SORT_ASCENDING)
+ sort = GTK_SORT_DESCENDING;
+ else
+ sort = GTK_SORT_ASCENDING;
+ }
+ else
+ sort = GTK_SORT_ASCENDING;
+ gtk_tree_view_column_set_sort_indicator (column, TRUE);
+ gtk_tree_view_column_set_sort_order (column, sort);
+fprintf (stderr, "column indicator: %d\n", gtk_tree_view_column_get_sort_indicator (column));
+ std::string prop = pThis->getColumnProp (column);
+ Ypp::PkgList l (pThis->m_list);
+ if (prop != "name")
+ l = Ypp::PkgSort (pThis->m_list, prop.c_str(), sort == GTK_SORT_ASCENDING);
+ pThis->setListImpl (l, NULL);
+ }
+};
+
+G_DEFINE_TYPE (YGtkPackageView, ygtk_package_view, GTK_TYPE_SCROLLED_WINDOW)
+
+static void ygtk_package_view_init (YGtkPackageView *view)
+{}
+
+YGtkPackageView *ygtk_package_view_new (gboolean descriptiveTooltip)
+{
+ YGtkPackageView *view = (YGtkPackageView *) g_object_new (YGTK_TYPE_PACKAGE_VIEW, NULL);
+ view->impl = new YGtkPackageView::Impl (GTK_WIDGET (view), descriptiveTooltip);
+ return view;
+}
+
+static void ygtk_package_view_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (ygtk_package_view_parent_class)->finalize (object);
+ YGtkPackageView *view = YGTK_PACKAGE_VIEW (object);
+ delete view->impl;
+ view->impl = NULL;
+}
+
+static void ygtk_package_view_class_init (YGtkPackageViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ygtk_package_view_finalize;
+}
+
+void YGtkPackageView::setList (Ypp::PkgList list, const char *applyAllLabel)
+{ impl->setList (list, applyAllLabel); }
+
+void YGtkPackageView::packList (const char *header, Ypp::PkgList list, const char *applyAllLabel)
+{ impl->packList (header, list, applyAllLabel); }
+
+void YGtkPackageView::clear()
+{ impl->clear(); }
+
+void YGtkPackageView::setVisible (const std::string &property, bool visible)
+{ impl->setVisible (property, visible); }
+
+bool YGtkPackageView::isVisible (const std::string &property)
+{ return impl->isVisible (property); }
+
+void YGtkPackageView::setRulesHint (bool hint)
+{ impl->setRulesHint (hint); }
+
+void YGtkPackageView::setActivateAction (Action action)
+{ impl->m_activate_action = action; }
+
+void YGtkPackageView::setListener (Listener *listener)
+{ impl->m_listener = listener; }
+
+Ypp::PkgList YGtkPackageView::getSelected()
+{ return impl->getSelected(); }
+
Added: trunk/gtk/src/pkg/ygtkpackageview.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtkpackageview.h?re…
==============================================================================
--- trunk/gtk/src/pkg/ygtkpackageview.h (added)
+++ trunk/gtk/src/pkg/ygtkpackageview.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,60 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* A view for Ypp's query results.
+*/
+
+#ifndef YGTK_PACKAGE_VIEW_H
+#define YGTK_PACKAGE_VIEW_H
+
+#include "yzyppwrapper.h"
+#include <gtk/gtkscrolledwindow.h>
+
+#define YGTK_TYPE_PACKAGE_VIEW (ygtk_package_view_get_type ())
+#define YGTK_PACKAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_PACKAGE_VIEW, YGtkPackageView))
+#define YGTK_PACKAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_PACKAGE_VIEW, YGtkPackageViewClass))
+#define YGTK_IS_PACKAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ YGTK_TYPE_PACKAGE_VIEW))
+#define YGTK_IS_PACKAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ YGTK_TYPE_PACKAGE_VIEW))
+#define YGTK_PACKAGE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_PACKAGE_VIEW, YGtkPackageViewClass))
+
+struct YGtkPackageView
+{ // use ygtk_package_view_new() to instance the object
+ GtkScrolledWindow parent;
+
+ void setList (Ypp::PkgList list, const char *applyAllLabel);
+ void packList (const char *header, Ypp::PkgList list, const char *applyAllLabel);
+ void clear();
+
+ void setVisible (const std::string &property, bool visible);
+ bool isVisible (const std::string &property);
+
+ void setRulesHint (bool hint);
+ enum Action { NONE_ACTION, INSTALL_ACTION, REMOVE_ACTION, UNDO_ACTION };
+ void setActivateAction (Action action);
+
+ struct Listener {
+ virtual void packagesSelected (Ypp::PkgList packages) = 0;
+ };
+ void setListener (Listener *listener);
+ Ypp::PkgList getSelected();
+
+ struct Impl;
+ Impl *impl;
+};
+
+struct YGtkPackageViewClass
+{
+ GtkScrolledWindowClass parent_class;
+};
+
+YGtkPackageView* ygtk_package_view_new (gboolean descriptiveTooltip);
+GType ygtk_package_view_get_type (void) G_GNUC_CONST;
+
+#endif /*YGTK_PACKAGE_VIEW_H*/
+
Added: trunk/gtk/src/pkg/ygtktooltip.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtktooltip.c?rev=59…
==============================================================================
--- trunk/gtk/src/pkg/ygtktooltip.c (added)
+++ trunk/gtk/src/pkg/ygtktooltip.c Thu Nov 26 18:16:21 2009
@@ -0,0 +1,265 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkTooltip widget */
+// check the header file for information about this widget
+
+#include <config.h>
+#include "ygtktooltip.h"
+#include <gtk/gtk.h>
+
+#define TOOLTIP_TIMEOUT 10000
+#define POINTER_LENGTH 10
+
+// header
+
+#define YGTK_TYPE_TOOLTIP (ygtk_tooltip_get_type ())
+#define YGTK_TOOLTIP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_TOOLTIP, YGtkTooltip))
+#define YGTK_TOOLTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_TOOLTIP, YGtkTooltipClass))
+#define YGTK_IS_TOOLTIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ YGTK_TYPE_TOOLTIP))
+#define YGTK_IS_TOOLTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ YGTK_TYPE_TOOLTIP))
+#define YGTK_TOOLTIP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_TOOLTIP, YGtkTooltipClass))
+
+typedef struct YGtkTooltip
+{
+ GtkWindow parent;
+ // private:
+ YGtkPointerType pointer;
+ guint timeout_id;
+} YGtkTooltip;
+
+typedef struct YGtkTooltipClass
+{
+ GtkWindowClass parent_class;
+} YGtkTooltipClass;
+
+GtkWidget *ygtk_tooltip_new (void);
+GType ygtk_tooltip_get_type (void) G_GNUC_CONST;
+
+// implementation
+
+G_DEFINE_TYPE (YGtkTooltip, ygtk_tooltip, GTK_TYPE_WINDOW)
+
+static void ygtk_tooltip_init (YGtkTooltip *tooltip)
+{
+ GtkWidget *widget = GTK_WIDGET (tooltip);
+ GtkWindow *window = GTK_WINDOW (tooltip);
+ // we may need to do this if _new() not used
+ //g_object_set (G_OBJECT (tooltip), "type", GTK_WINDOW_POPUP, NULL);
+ gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_TOOLTIP);
+ gtk_widget_set_app_paintable (widget, TRUE);
+ gtk_window_set_resizable (window, FALSE);
+ gtk_widget_set_name (widget, "gtk-tooltip");
+}
+
+static void ygtk_tooltip_finalize (GObject *object)
+{
+ YGtkTooltip *tooltip = YGTK_TOOLTIP (object);
+ if (tooltip->timeout_id) {
+ g_source_remove (tooltip->timeout_id);
+ tooltip->timeout_id = 0;
+ }
+ G_OBJECT_CLASS (ygtk_tooltip_parent_class)->finalize (object);
+}
+
+static void get_border (YGtkTooltip *tooltip, gint *left_border, gint *right_border,
+ gint *up_border, gint *down_border)
+{
+ GtkWidget *widget = GTK_WIDGET (tooltip);
+ *left_border = *right_border = widget->style->xthickness;
+ *up_border = *down_border = widget->style->ythickness;
+ int len = POINTER_LENGTH + 2;
+ switch (tooltip->pointer) {
+ case YGTK_POINTER_NONE: break;
+ case YGTK_POINTER_UP_LEFT:
+ *left_border += len;
+ break;
+ case YGTK_POINTER_UP_RIGHT:
+ *right_border += len;
+ break;
+ case YGTK_POINTER_DOWN_LEFT:
+ case YGTK_POINTER_DOWN_RIGHT:
+ *down_border += len;
+ break;
+ }
+}
+
+static void ygtk_tooltip_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ GTK_WIDGET_CLASS (ygtk_tooltip_parent_class)->size_request (widget, requisition);
+ gint left_border, right_border, up_border, down_border;
+ get_border (YGTK_TOOLTIP (widget), &left_border, &right_border,
+ &up_border, &down_border);
+ requisition->width += left_border + right_border;
+ requisition->height += up_border + down_border;
+}
+
+static void ygtk_tooltip_size_allocate (GtkWidget *widget, GtkAllocation *alloc)
+{
+ GTK_WIDGET_CLASS (ygtk_tooltip_parent_class)->size_allocate (widget, alloc);
+ gint left_border, right_border, up_border, down_border;
+ get_border (YGTK_TOOLTIP (widget), &left_border, &right_border,
+ &up_border, &down_border);
+ GtkAllocation child_alloc = {
+ alloc->x + left_border, alloc->y + up_border,
+ alloc->width - (left_border+right_border),
+ alloc->height - (up_border+down_border)
+ };
+ gtk_widget_size_allocate (GTK_BIN (widget)->child, &child_alloc);
+}
+
+static gboolean ygtk_tooltip_expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+ gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT, NULL, widget, "tooltip", 0, 0, widget->allocation.width,
+ widget->allocation.height);
+ YGtkPointerType pointer = YGTK_TOOLTIP (widget)->pointer;
+ if (pointer) {
+ gint x = 0, y = 0, len_x = 0, len_y = 0;
+ switch (pointer) {
+ case YGTK_POINTER_NONE: break;
+ case YGTK_POINTER_UP_LEFT:
+ case YGTK_POINTER_DOWN_LEFT:
+ x = 2;
+ len_x = POINTER_LENGTH;
+ break;
+ case YGTK_POINTER_UP_RIGHT:
+ case YGTK_POINTER_DOWN_RIGHT:
+ x = widget->allocation.width - 2;
+ len_x = -POINTER_LENGTH;
+ break;
+ }
+ switch (pointer) {
+ case YGTK_POINTER_NONE: break;
+ case YGTK_POINTER_UP_LEFT:
+ case YGTK_POINTER_UP_RIGHT:
+ y = 2;
+ len_y = POINTER_LENGTH;
+ break;
+ case YGTK_POINTER_DOWN_LEFT:
+ case YGTK_POINTER_DOWN_RIGHT:
+ y = widget->allocation.height - 2;
+ len_y = -POINTER_LENGTH;
+ break;
+ }
+
+ GdkPoint points[3] = {
+ { x, y }, { x + len_x, y }, { x, y + len_y } };
+ gdk_draw_polygon (widget->window, *widget->style->dark_gc, TRUE, points, 3);
+ }
+ GTK_WIDGET_CLASS (ygtk_tooltip_parent_class)->expose_event (widget, event);
+ return FALSE;
+}
+
+static gboolean tooltip_timeout_cb (void *pdata)
+{
+ YGtkTooltip *tooltip = (YGtkTooltip *) pdata;
+ tooltip->timeout_id = 0;
+ gtk_widget_destroy (GTK_WIDGET (tooltip));
+ return FALSE;
+}
+
+static YGtkTooltip *ygtk_tooltip_create (const gchar *text, const gchar *stock)
+{
+ GtkWidget *tooltip, *box, *label, *image = 0;
+ tooltip = ygtk_tooltip_new();
+ label = gtk_label_new (text);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_widget_set_size_request (label, 200, -1);
+ box = gtk_hbox_new (FALSE, 6);
+ if (stock) {
+ image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (box), image, FALSE, TRUE, 0);
+ }
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+ gtk_widget_show_all (box);
+ gtk_container_add (GTK_CONTAINER (tooltip), box);
+ return YGTK_TOOLTIP (tooltip);
+}
+
+static YGtkTooltip *singleton = 0;
+
+static void ygtk_tooltip_show (YGtkTooltip *tooltip, gint x, gint y)
+{
+ gtk_window_move (GTK_WINDOW (tooltip), x, y);
+ gtk_widget_show (GTK_WIDGET (tooltip));
+ if (singleton)
+ gtk_widget_destroy (GTK_WIDGET (singleton));
+ singleton = tooltip;
+ tooltip->timeout_id = g_timeout_add (TOOLTIP_TIMEOUT, tooltip_timeout_cb, tooltip);
+}
+
+void ygtk_tooltip_show_at (gint x, gint y, YGtkPointerType pointer,
+ const gchar *label, const gchar *stock)
+{
+ YGtkTooltip *tooltip = ygtk_tooltip_create (label, stock);
+ tooltip->pointer = pointer;
+ ygtk_tooltip_show (tooltip, x, y);
+}
+
+#define XMARGIN 8
+#define YMARGIN 2
+
+void ygtk_tooltip_show_at_widget (GtkWidget *widget, YGtkPointerType pointer,
+ const gchar *label, const gchar *stock)
+{
+ YGtkTooltip *tooltip = ygtk_tooltip_create (label, stock);
+ tooltip->pointer = pointer;
+ gint x, y;
+ gdk_window_get_origin (widget->window, &x, &y);
+ if (GTK_WIDGET_NO_WINDOW (widget)) {
+ x += widget->allocation.x;
+ y += widget->allocation.y;
+ }
+ GtkRequisition tooltip_req;
+ gtk_widget_size_request (GTK_WIDGET (tooltip), &tooltip_req);
+ switch (pointer) {
+ case YGTK_POINTER_NONE: break;
+ case YGTK_POINTER_UP_RIGHT:
+ case YGTK_POINTER_DOWN_RIGHT:
+ x -= (tooltip_req.width - widget->allocation.width) + XMARGIN;
+ break;
+ case YGTK_POINTER_UP_LEFT:
+ case YGTK_POINTER_DOWN_LEFT:
+ x += XMARGIN;
+ break;
+ }
+ switch (pointer) {
+ case YGTK_POINTER_NONE: break;
+ case YGTK_POINTER_UP_RIGHT:
+ case YGTK_POINTER_UP_LEFT:
+ y += widget->allocation.height + YMARGIN;
+ break;
+ case YGTK_POINTER_DOWN_RIGHT:
+ case YGTK_POINTER_DOWN_LEFT:
+ y -= tooltip_req.height + YMARGIN;
+ break;
+ }
+ ygtk_tooltip_show (tooltip, x, y);
+}
+
+GtkWidget *ygtk_tooltip_new (void)
+{
+ return g_object_new (YGTK_TYPE_TOOLTIP, "type", GTK_WINDOW_POPUP, NULL);
+}
+
+static void ygtk_tooltip_class_init (YGtkTooltipClass *klass)
+{
+ ygtk_tooltip_parent_class = g_type_class_peek_parent (klass);
+
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = ygtk_tooltip_finalize;
+
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
+ widget_class->size_request = ygtk_tooltip_size_request;
+ widget_class->size_allocate = ygtk_tooltip_size_allocate;
+ widget_class->expose_event = ygtk_tooltip_expose_event;
+}
+
Added: trunk/gtk/src/pkg/ygtktooltip.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtktooltip.h?rev=59…
==============================================================================
--- trunk/gtk/src/pkg/ygtktooltip.h (added)
+++ trunk/gtk/src/pkg/ygtktooltip.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,27 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkTooltip, unlike GtkTooltip, can be used independently of a widget.
+ Also displays an arrow since it's meant to descript some element.
+*/
+
+#ifndef YGTK_TOOLTIP_H
+#define YGTK_TOOLTIP_H
+
+#include <gtk/gtkwidget.h>
+G_BEGIN_DECLS
+
+typedef enum { YGTK_POINTER_NONE, YGTK_POINTER_UP_LEFT, YGTK_POINTER_UP_RIGHT,
+ YGTK_POINTER_DOWN_LEFT, YGTK_POINTER_DOWN_RIGHT } YGtkPointerType;
+
+// will display the tooltip and destroy it after a few seconds
+// note: no need to free the thing yourself
+void ygtk_tooltip_show_at (gint x, gint y, YGtkPointerType pointer,
+ const gchar *label, const gchar *stock_id);
+void ygtk_tooltip_show_at_widget (GtkWidget *widget, YGtkPointerType pointer,
+ const gchar *label, const gchar *stock_id);
+
+G_END_DECLS
+#endif /*YGTK_TOOLTIP_H*/
+
Added: trunk/gtk/src/pkg/ygtktreemodel.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtktreemodel.cc?rev…
==============================================================================
--- trunk/gtk/src/pkg/ygtktreemodel.cc (added)
+++ trunk/gtk/src/pkg/ygtktreemodel.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,221 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkTreeModel, C++ wrapper for gtk+ */
+// check the header file for information about this wrapper
+
+#include <gtk/gtk.h>
+#include "ygtktreemodel.h"
+
+#define YGTK_TYPE_WRAP_MODEL (ygtk_wrap_model_get_type ())
+#define YGTK_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_WRAP_MODEL, YGtkWrapModel))
+#define YGTK_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_WRAP_MODEL, YGtkWrapModelClass))
+#define YGTK_IS_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YGTK_TYPE_WRAP_MODEL))
+#define YGTK_IS_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YGTK_TYPE_WRAP_MODEL))
+#define YGTK_WRAP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_WRAP_MODEL, YGtkWrapModelClass))
+
+struct YGtkWrapModel
+{
+ GObject parent;
+ YGtkTreeModel *model;
+ struct Notify;
+ Notify *notify;
+};
+
+struct YGtkWrapModelClass
+{
+ GObjectClass parent_class;
+};
+
+// bridge as we don't want to mix c++ class polymorphism and gobject
+static void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row);
+static void ygtk_wrap_model_entry_inserted (YGtkWrapModel *model, int row);
+static void ygtk_wrap_model_entry_deleted (YGtkWrapModel *model, int row);
+
+struct YGtkWrapModel::Notify : public YGtkTreeModel::Listener {
+YGtkWrapModel *model;
+ Notify (YGtkWrapModel *model) : model (model) {}
+ virtual void rowChanged (int row)
+ { ygtk_wrap_model_entry_changed (model, row); }
+ virtual void rowInserted (int row)
+ { ygtk_wrap_model_entry_inserted (model, row); }
+ virtual void rowDeleted (int row)
+ { ygtk_wrap_model_entry_deleted (model, row); }
+};
+
+static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (YGtkWrapModel, ygtk_wrap_model, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, ygtk_wrap_model_tree_model_init))
+
+static void ygtk_wrap_model_init (YGtkWrapModel *zmodel)
+{}
+
+static void ygtk_wrap_model_finalize (GObject *object)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (object);
+ delete ymodel->model;
+ ymodel->model = NULL;
+ delete ymodel->notify;
+ ymodel->notify = NULL;
+ G_OBJECT_CLASS (ygtk_wrap_model_parent_class)->finalize (object);
+}
+
+static GtkTreeModelFlags ygtk_wrap_model_get_flags (GtkTreeModel *model)
+{ return (GtkTreeModelFlags) (GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY); }
+
+static gboolean ygtk_wrap_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter,
+ GtkTreePath *path)
+{ // from Path to Iter
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ gint index = gtk_tree_path_get_indices (path)[0];
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
+ return TRUE;
+ return index < rowsNb;
+}
+
+static GtkTreePath *ygtk_wrap_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
+{ // from Iter to Path
+ int index = GPOINTER_TO_INT (iter->user_data);
+ GtkTreePath *path = gtk_tree_path_new();
+ gtk_tree_path_append_index (path, index);
+ return path;
+}
+
+static gboolean ygtk_wrap_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ int index = GPOINTER_TO_INT (iter->user_data) + 1;
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ return index < rowsNb;
+}
+
+static gboolean ygtk_wrap_model_iter_parent (GtkTreeModel *, GtkTreeIter *, GtkTreeIter *)
+{ return FALSE; }
+
+static gboolean ygtk_wrap_model_iter_has_child (GtkTreeModel *, GtkTreeIter *)
+{ return FALSE; }
+
+static gint ygtk_wrap_model_iter_n_children (GtkTreeModel *model, GtkTreeIter *iter)
+{ return 0; }
+
+static gboolean ygtk_wrap_model_iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
+ GtkTreeIter *parent, gint index)
+{
+ if (parent) return FALSE;
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
+ return TRUE;
+ return index < rowsNb;
+}
+
+static gboolean ygtk_wrap_model_iter_children (
+ GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent)
+{ return ygtk_wrap_model_iter_nth_child (model, iter, parent, 0); }
+
+void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row)
+{
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_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_wrap_model_entry_inserted (YGtkWrapModel *ymodel, int row)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
+
+ if (row == 0 && ymodel->model->rowsNb() == 1 && ymodel->model->showEmptyEntry())
+ gtk_tree_model_row_changed (model, path, &iter);
+ else
+ gtk_tree_model_row_inserted (model, path, &iter);
+ gtk_tree_path_free (path);
+}
+
+void ygtk_wrap_model_entry_deleted (YGtkWrapModel *ymodel, int row)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
+
+ if (row == 0 && ymodel->model->rowsNb() == 1 && ymodel->model->showEmptyEntry())
+ gtk_tree_model_row_changed (model, path, &iter);
+ else
+ gtk_tree_model_row_deleted (model, path);
+ gtk_tree_path_free (path);
+}
+
+static gint ygtk_wrap_model_get_n_columns (GtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model->columnsNb();
+}
+
+static GType ygtk_wrap_model_get_column_type (GtkTreeModel *model, gint column)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model->columnType (column);
+}
+
+static void ygtk_wrap_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
+ gint column, GValue *value)
+{
+ int row = GPOINTER_TO_INT (iter->user_data);
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ g_value_init (value, ymodel->model->columnType (column));
+ if (row == 0 && ymodel->model->rowsNb() == 0)
+ row = -1;
+ ymodel->model->getValue (row, column, value);
+}
+
+GtkTreeModel *ygtk_tree_model_new (YGtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = (YGtkWrapModel *) g_object_new (YGTK_TYPE_WRAP_MODEL, NULL);
+ ymodel->model = model;
+ ymodel->notify = new YGtkWrapModel::Notify (ymodel);
+ model->listener = ymodel->notify;
+ return GTK_TREE_MODEL (ymodel);
+}
+
+YGtkTreeModel *ygtk_tree_model_get_model (GtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model;
+}
+
+static void ygtk_wrap_model_class_init (YGtkWrapModelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ygtk_wrap_model_finalize;
+}
+
+static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_flags = ygtk_wrap_model_get_flags;
+ iface->get_n_columns = ygtk_wrap_model_get_n_columns;
+ iface->get_column_type = ygtk_wrap_model_get_column_type;
+ iface->get_iter = ygtk_wrap_model_get_iter;
+ iface->get_path = ygtk_wrap_model_get_path;
+ iface->get_value = ygtk_wrap_model_get_value;
+ iface->iter_next = ygtk_wrap_model_iter_next;
+ iface->iter_children = ygtk_wrap_model_iter_children;
+ iface->iter_has_child = ygtk_wrap_model_iter_has_child;
+ iface->iter_n_children = ygtk_wrap_model_iter_n_children;
+ iface->iter_nth_child = ygtk_wrap_model_iter_nth_child;
+ iface->iter_parent = ygtk_wrap_model_iter_parent;
+}
+
Added: trunk/gtk/src/pkg/ygtktreemodel.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/ygtktreemodel.h?rev=…
==============================================================================
--- trunk/gtk/src/pkg/ygtktreemodel.h (added)
+++ trunk/gtk/src/pkg/ygtktreemodel.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,38 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Wraps GtkTreeModel as a C++ model.
+*/
+
+#ifndef YGTK_TREE_MODEL_H
+#define YGTK_TREE_MODEL_H
+
+#include <gtk/gtktreemodel.h>
+
+struct YGtkTreeModel
+{
+ virtual void getValue (int row, int col, GValue *value) = 0;
+ virtual int rowsNb() = 0;
+ virtual int columnsNb() const = 0;
+ virtual GType columnType (int col) const = 0;
+ // if 'showEmptyEntry' will call getValue(row=-1) for the empty entry
+ virtual bool showEmptyEntry() const = 0;
+
+ // implement setListener() to signal model changes, if dynamic
+ struct Listener {
+ virtual void rowChanged (int row) = 0;
+ virtual void rowInserted (int row) = 0;
+ virtual void rowDeleted (int row) = 0;
+ };
+ Listener *listener;
+
+ virtual ~YGtkTreeModel() {}
+};
+
+GtkTreeModel *ygtk_tree_model_new (YGtkTreeModel *model);
+
+YGtkTreeModel *ygtk_tree_model_get_model (GtkTreeModel *model);
+
+#endif /*YGTK_TREE_MODEL_H*/
+
Added: trunk/gtk/src/pkg/yzypptags.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/yzypptags.cc?rev=598…
==============================================================================
--- trunk/gtk/src/pkg/yzypptags.cc (added)
+++ trunk/gtk/src/pkg/yzypptags.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,121 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/*
+ Textdomain "yast2-gtk"
+ */
+
+/* Tags PackageKit translator */
+// check the header file for information about this translator
+
+#include "YGi18n.h"
+#define YUILogComponent "gtk-pkg"
+#include <YUILog.h>
+#include "yzypptags.h"
+#include <string>
+
+/**
+ * translations taken from packagekit
+ **/
+const char *
+zypp_tag_group_enum_to_localised_text (YPkgGroupEnum group)
+{
+ switch (group) {
+ case PK_GROUP_ENUM_EDUCATION: return _( "Education" );
+ case PK_GROUP_ENUM_GAMES: return _( "Games" );
+ case PK_GROUP_ENUM_GRAPHICS: return _( "Graphics" );
+ case PK_GROUP_ENUM_OFFICE: return _( "Office" );
+ case PK_GROUP_ENUM_PROGRAMMING: return _( "Programming" );
+ case PK_GROUP_ENUM_MULTIMEDIA: return _( "Multimedia" );
+ case PK_GROUP_ENUM_SYSTEM: return _( "System" );
+ case PK_GROUP_ENUM_DESKTOP_GNOME: return _( "GNOME Desktop" );
+ case PK_GROUP_ENUM_DESKTOP_KDE: return _( "KDE Desktop" );
+ case PK_GROUP_ENUM_DESKTOP_XFCE: return _( "XFCE Desktop" );
+ case PK_GROUP_ENUM_DESKTOP_OTHER: return _( "Other Desktops" );
+ case PK_GROUP_ENUM_PUBLISHING: return _( "Publishing" );
+ case PK_GROUP_ENUM_ADMIN_TOOLS: return _( "Admin Tools" );
+ case PK_GROUP_ENUM_LOCALIZATION: return _( "Localization" );
+ case PK_GROUP_ENUM_SECURITY: return _( "Security" );
+ case PK_GROUP_ENUM_COMMUNICATION: return _( "Communication" );
+ case PK_GROUP_ENUM_NETWORK: return _( "Network" );
+ case PK_GROUP_ENUM_DOCUMENTATION: return _( "Documentation" );
+ case PK_GROUP_ENUM_UTILITIES: return _( "Utilities" );
+ case PK_GROUP_ENUM_UNKNOWN: return _( "Unknown Group" );
+ case PK_GROUP_ENUM_SIZE: break;
+ }
+ return "";
+}
+
+const char *
+zypp_tag_enum_to_icon (YPkgGroupEnum group)
+{
+ // NOTE: some icons are customized (bug 404818)
+ switch (group)
+ {
+ case PK_GROUP_ENUM_EDUCATION: return( "package_edutainment" );
+ case PK_GROUP_ENUM_GAMES: return( "package_games" );
+ case PK_GROUP_ENUM_GRAPHICS: return( "package_graphics" );
+ case PK_GROUP_ENUM_OFFICE: return( "applications-office" );
+ case PK_GROUP_ENUM_PROGRAMMING: return( "package_development" );
+ case PK_GROUP_ENUM_MULTIMEDIA: return( "package_multimedia" );
+ case PK_GROUP_ENUM_SYSTEM: return( "applications-system" );
+ case PK_GROUP_ENUM_DESKTOP_GNOME: return( "pattern-gnome" );
+ case PK_GROUP_ENUM_DESKTOP_KDE: return( "pattern-kde" );
+ case PK_GROUP_ENUM_DESKTOP_XFCE: return( "pattern-xfce" );
+ case PK_GROUP_ENUM_DESKTOP_OTHER: return( "user-desktop" );
+ case PK_GROUP_ENUM_PUBLISHING: return( "package_main" );
+ case PK_GROUP_ENUM_ADMIN_TOOLS: return( "yast-sysconfig" );
+ case PK_GROUP_ENUM_LOCALIZATION: return( "yast-language" );
+ case PK_GROUP_ENUM_SECURITY: return( "yast-security" );
+ case PK_GROUP_ENUM_COMMUNICATION: return( "yast-modem" );
+ case PK_GROUP_ENUM_NETWORK: return( "package_network" );
+ case PK_GROUP_ENUM_DOCUMENTATION: return( "package_documentation" );
+ case PK_GROUP_ENUM_UTILITIES: return( "package_utilities" );
+ case PK_GROUP_ENUM_UNKNOWN: return( "package_main" );
+ case PK_GROUP_ENUM_SIZE: break;
+ }
+ return "";
+}
+
+YPkgGroupEnum
+zypp_tag_convert (const std::string &groupu)
+{
+ std::string group (groupu); // lower-case
+ for (unsigned int i = 0; i < group.length(); i++)
+ if (group[i] >= 'A' && group[i] <= 'Z')
+ group[i] = group[i] - 'A' + 'a';
+
+ // yast2-qt: (modified to speed up)
+ if (group.compare (0, 22, "productivity/archiving") == 0) return PK_GROUP_ENUM_ADMIN_TOOLS;
+ if (group.compare (0, 23, "productivity/clustering") == 0) return PK_GROUP_ENUM_ADMIN_TOOLS;
+ if (group.compare (0, 22, "productivity/databases") == 0) return PK_GROUP_ENUM_ADMIN_TOOLS;
+ if (group.compare (0, 17, "system/monitoring") == 0) return PK_GROUP_ENUM_ADMIN_TOOLS;
+ if (group.compare (0, 17, "system/management") == 0) return PK_GROUP_ENUM_ADMIN_TOOLS;
+ if (group.compare (0, 23, "productivity/publishing") == 0) return PK_GROUP_ENUM_PUBLISHING;
+ if (group.compare (0, 22, "productivity/telephony") == 0) return PK_GROUP_ENUM_COMMUNICATION;
+ if (group.compare (0, 19, "amusements/teaching") == 0) return PK_GROUP_ENUM_EDUCATION;
+ if (group.compare (0, 17, "publishing/office") == 0) return PK_GROUP_ENUM_OFFICE;
+ if (group.compare (0, 17, "productivity/text") == 0) return PK_GROUP_ENUM_OFFICE;
+ if (group.compare (0, 20, "productivity/editors") == 0) return PK_GROUP_ENUM_OFFICE;
+ if (group.compare (0, 21, "productivity/graphics") == 0) return PK_GROUP_ENUM_GRAPHICS;
+ if (group.compare (0, 10, "amusements") == 0) return PK_GROUP_ENUM_GAMES;
+ if (group.compare (0, 19, "system/localization") == 0) return PK_GROUP_ENUM_LOCALIZATION;
+ if (group.compare (0, 11, "development") == 0) return PK_GROUP_ENUM_PROGRAMMING;
+ if (group.compare (0, 20, "productivity/network") == 0) return PK_GROUP_ENUM_NETWORK;
+ if (group.compare (0, 21, "productivity/security") == 0) return PK_GROUP_ENUM_SECURITY;
+ if (group.compare (0, 16, "system/gui/gnome") == 0) return PK_GROUP_ENUM_DESKTOP_GNOME;
+ if (group.compare (0, 14, "system/gui/kde") == 0) return PK_GROUP_ENUM_DESKTOP_KDE;
+ if (group.compare (0, 15, "system/gui/xfce") == 0) return PK_GROUP_ENUM_DESKTOP_XFCE;
+ if (group.compare (0, 10, "system/gui") == 0) return PK_GROUP_ENUM_DESKTOP_OTHER;
+ if (group.compare (0, 8, "hardware") == 0) return PK_GROUP_ENUM_SYSTEM;
+ if (group.compare (0, 6, "system") == 0) return PK_GROUP_ENUM_SYSTEM;
+ if (group.find ("scientific") != string::npos) return PK_GROUP_ENUM_EDUCATION;
+ if (group.find ("multimedia") != string::npos) return PK_GROUP_ENUM_MULTIMEDIA;
+
+ // our own:
+ if (group.compare (0, 13, "documentation") == 0) return PK_GROUP_ENUM_DOCUMENTATION;
+ if (group.compare (0, 12, "productivity") == 0) return PK_GROUP_ENUM_UTILITIES;
+ return PK_GROUP_ENUM_UNKNOWN;
+}
+
Added: trunk/gtk/src/pkg/yzypptags.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/yzypptags.h?rev=5980…
==============================================================================
--- trunk/gtk/src/pkg/yzypptags.h (added)
+++ trunk/gtk/src/pkg/yzypptags.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,39 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Converts RPM to PackageKit-like terminology.
+ Code from yast-qt-pkg.
+*/
+
+typedef enum {
+ /* PackageKit values */
+ PK_GROUP_ENUM_OFFICE,
+ PK_GROUP_ENUM_PUBLISHING,
+ PK_GROUP_ENUM_GRAPHICS,
+ PK_GROUP_ENUM_MULTIMEDIA,
+ PK_GROUP_ENUM_EDUCATION,
+ PK_GROUP_ENUM_GAMES,
+ PK_GROUP_ENUM_DESKTOP_GNOME,
+ PK_GROUP_ENUM_DESKTOP_KDE,
+ PK_GROUP_ENUM_DESKTOP_XFCE,
+ PK_GROUP_ENUM_DESKTOP_OTHER,
+ PK_GROUP_ENUM_COMMUNICATION,
+ PK_GROUP_ENUM_NETWORK,
+ PK_GROUP_ENUM_PROGRAMMING,
+ PK_GROUP_ENUM_DOCUMENTATION,
+ PK_GROUP_ENUM_ADMIN_TOOLS,
+ PK_GROUP_ENUM_SECURITY,
+ PK_GROUP_ENUM_LOCALIZATION,
+ PK_GROUP_ENUM_SYSTEM,
+ PK_GROUP_ENUM_UTILITIES,
+ PK_GROUP_ENUM_UNKNOWN,
+ PK_GROUP_ENUM_SIZE,
+} YPkgGroupEnum;
+
+
+YPkgGroupEnum zypp_tag_convert (const std::string &rpm_group);
+
+const char *zypp_tag_group_enum_to_localised_text (YPkgGroupEnum group);
+const char *zypp_tag_enum_to_icon (YPkgGroupEnum group);
+
Added: trunk/gtk/src/pkg/yzyppwrapper.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/yzyppwrapper.cc?rev=…
==============================================================================
--- trunk/gtk/src/pkg/yzyppwrapper.cc (added)
+++ trunk/gtk/src/pkg/yzyppwrapper.cc Thu Nov 26 18:16:21 2009
@@ -0,0 +1,2810 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/*
+ Textdomain "yast2-gtk"
+ */
+
+/* Ypp, zypp wrapper */
+// check the header file for information about this wrapper
+
+#include "YGi18n.h"
+#include "yzyppwrapper.h"
+#include "yzypptags.h"
+#include <string.h>
+#include <string>
+#include <algorithm>
+#include <vector>
+#include <sstream>
+#define YUILogComponent "gtk-pkg"
+#include <YUILog.h>
+#include "config.h"
+
+#include <zypp/ZYppFactory.h>
+#include <zypp/ResObject.h>
+#include <zypp/ResPoolProxy.h>
+#include <zypp/ui/Selectable.h>
+#include <zypp/Patch.h>
+#include <zypp/Package.h>
+#include <zypp/Pattern.h>
+#include <zypp/Product.h>
+#include <zypp/Repository.h>
+#include <zypp/RepoManager.h>
+#include <zypp/sat/LocaleSupport.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;
+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); }
+
+//** 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;
+ const char *trans_domain;
+ GNode *root;
+
+ StringTree (Compare compare, char delim, const char *trans_domain)
+ : compare (compare), delim (delim), trans_domain (trans_domain)
+ {
+ // 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()
+ {
+ if (root->children)
+ return (Ypp::Node *) root->children->data;
+ return NULL;
+ }
+
+ Ypp::Node *add (const std::string &tree_str, const std::string &order)
+ { // NOTE: returns NULL for empty strings
+ const gchar delimiter[2] = { delim, '\0' };
+ gchar **nodes_str = g_strsplit (tree_str.c_str(), delimiter, -1);
+
+ GNode *parent = root, *sibling = 0;
+ Ypp::Node *ret = 0;
+ gchar **i;
+ for (i = nodes_str; *i; i++) {
+ if (!**i)
+ continue;
+ const char *str = *i;
+ if (trans_domain)
+ str = dgettext (trans_domain, str);
+ bool found = false;
+ if (!order.empty())
+ // when ordered, make sure it already doesn't exist with another order
+ for (sibling = parent->children; sibling; sibling = sibling->next) {
+ Ypp::Node *node = (Ypp::Node *) sibling->data;
+ int cmp = (*compare) (str, node->name.c_str());
+ if (cmp == 0) {
+ found = true;
+ ret = node;
+ break;
+ }
+ }
+ if (!found) {
+ const char *s1 = order.empty() ? str : order.c_str();
+ for (sibling = parent->children; sibling; sibling = sibling->next) {
+ Ypp::Node *node = (Ypp::Node *) sibling->data;
+ const char *s2 = order.empty() ? node->name.c_str() : node->order.c_str();
+ int cmp = (*compare) (s1, s2);
+ if (cmp == 0) {
+ found = true;
+ ret = node;
+ break;
+ }
+ else if (cmp < 0)
+ break;
+ }
+ }
+ if (!found)
+ break;
+ parent = sibling;
+ }
+
+ for (; *i; i++) {
+ Ypp::Node *node = new Ypp::Node();
+ GNode *n = g_node_new ((void *) node);
+ const char *str = *i;
+ if (trans_domain)
+ str = dgettext (trans_domain, str);
+ node->name = str;
+ node->order = order;
+ node->icon = NULL;
+ node->impl = (void *) n;
+ g_node_insert_before (parent, sibling, n);
+ parent = n;
+ sibling = NULL;
+ ret = node;
+ }
+ g_strfreev (nodes_str);
+ 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);
+ const Repository *getRepository (const std::string &zyppId);
+ zypp::RepoInfo getRepoInfo (const Repository *repo);
+ Disk *getDisk();
+
+ // for Packages
+ bool acceptLicense (Ypp::Package *package, const std::string &license);
+ void notifyMessage (Ypp::Package *package, const std::string &message);
+ void packageModified (Ypp::Package *package);
+
+ // for the Primitive Pools
+ PkgList *getPackages (Package::Type type);
+
+ Ypp::Node *mapCategory2Enum (YPkgGroupEnum group);
+
+private:
+ bool resolveProblems();
+ Node *addCategory (Ypp::Package::Type type, const std::string &str, const std::string &order);
+ void polishCategories (Ypp::Package::Type type);
+
+ void startTransactions();
+ void finishTransactions();
+
+ friend class Ypp;
+ PkgList *packages [Package::TOTAL_TYPES]; // primitive pools
+ StringTree *categories [Package::TOTAL_TYPES], *categories2;
+ Ypp::Node *mapCategories2 [PK_GROUP_ENUM_SIZE];
+ std::vector <Repository *> repos;
+ const Repository *favoriteRepo;
+ int favoriteRepoPriority;
+ Disk *disk;
+ Interface *interface;
+ GSList *pkg_listeners;
+ bool inTransaction;
+ GSList *transactions;
+};
+
+//** Package
+
+struct Ypp::Package::Impl
+{
+ /* Ypp::Package serves as a proxy to this class which is derived into
+ PackageSel for packages, patterns and patches, and PackageLang for locales. */
+
+Type type;
+Package *m_parent;
+std::string m_name, m_summary;
+
+ Impl (Type type) : type (type) {}
+
+ virtual std::string name() = 0;
+ virtual std::string summary() = 0;
+ virtual Node *category() { return NULL; }
+ virtual Node *category2() { return NULL; }
+ virtual bool containsPackage (const Ypp::Package *package) = 0;
+ virtual void containsStats (int *installed, int *total) = 0;
+
+ virtual std::string description (MarkupType markup) = 0;
+ virtual std::string filelist (MarkupType markup) { return ""; }
+ virtual std::string changelog() { return ""; }
+ virtual std::string authors (MarkupType markup) { return ""; }
+ virtual std::string support() { return ""; }
+ virtual std::string supportText (MarkupType markup) { return ""; }
+ virtual std::string size() { return ""; }
+ virtual std::string icon() = 0;
+ virtual bool isRecommended() const { return false; }
+ virtual bool isSuggested() const { return false; }
+ virtual int buildAge() const { return 0; }
+ virtual bool isSupported() const { return true; }
+ virtual int severity() const { return 0; }
+
+ virtual std::string provides (MarkupType markup) const { return ""; }
+ virtual std::string requires (MarkupType markup) const { return ""; }
+
+ virtual const Ypp::Package::Version *getInstalledVersion() { return false; }
+ virtual const Ypp::Package::Version *getAvailableVersion (int nb) { return false; }
+
+ virtual bool isInstalled() = 0;
+ virtual bool hasUpgrade() = 0;
+ virtual bool isLocked() = 0;
+
+ virtual bool toInstall (const Ypp::Package::Version **repo = 0) = 0;
+ virtual bool toRemove() = 0;
+ virtual bool toModify() = 0;
+ virtual bool isAuto() = 0;
+
+ virtual void install (const Ypp::Package::Version *repo) = 0;
+ virtual void remove() = 0;
+ virtual void undo() = 0;
+ virtual bool canLock() = 0;
+ virtual bool canRemove() = 0;
+ virtual void lock (bool lock) = 0;
+
+ // internal: did the resolver touch it
+ virtual bool isTouched() = 0;
+ virtual void setNotTouched() = 0;
+};
+
+Ypp::Package::Package (Impl *impl) : impl (impl) { impl->m_parent = this; }
+Ypp::Package::~Package() { delete impl; }
+
+Ypp::Package::Type Ypp::Package::type() const { return impl->type; }
+
+const std::string &Ypp::Package::name() const
+{
+ if (impl->m_name.empty())
+ impl->m_name = const_cast <Impl *> (impl)->name();
+ return impl->m_name;
+}
+
+const std::string &Ypp::Package::summary()
+{
+ if (impl->m_summary.empty())
+ impl->m_summary = const_cast <Impl *> (impl)->summary();
+ return impl->m_summary;
+}
+
+Ypp::Node *Ypp::Package::category() { return impl->category(); }
+Ypp::Node *Ypp::Package::category2() { return impl->category2(); }
+bool Ypp::Package::containsPackage (const Ypp::Package *package) const
+{ return const_cast <Impl *> (impl)->containsPackage (package); }
+void Ypp::Package::containsStats (int *installed, int *total) const
+{ const_cast <Impl *> (impl)->containsStats (installed, total); }
+
+std::string Ypp::Package::description (MarkupType markup) { return impl->description (markup); }
+std::string Ypp::Package::filelist (MarkupType markup) { return impl->filelist (markup); }
+std::string Ypp::Package::changelog() { return impl->changelog(); }
+std::string Ypp::Package::authors (MarkupType markup) { return impl->authors (markup); }
+std::string Ypp::Package::support() { return impl->support(); }
+std::string Ypp::Package::supportText (MarkupType markup) { return impl->supportText (markup); }
+std::string Ypp::Package::size() { return impl->size(); }
+std::string Ypp::Package::icon() { return impl->icon(); }
+bool Ypp::Package::isRecommended() const { return impl->isRecommended(); }
+bool Ypp::Package::isSuggested() const { return impl->isSuggested(); }
+int Ypp::Package::buildAge() const { return impl->buildAge(); }
+bool Ypp::Package::isSupported() const { return impl->isSupported(); }
+
+int Ypp::Package::severity() const { return impl->severity(); }
+
+std::string Ypp::Package::severityStr (int id)
+{
+ switch (id) {
+ case 0: return _("Security");
+ case 1: return _("Recommended");
+ case 2: return "YaST";
+ case 3: return _("Documentation");
+ case 4: return _("Optional");
+ case 5: default: break;
+ }
+ return _("Other");
+}
+
+
+std::string Ypp::Package::provides (MarkupType markup) const { return impl->provides (markup); }
+std::string Ypp::Package::requires (MarkupType markup) const { return impl->requires (markup); }
+
+std::string Ypp::Package::getPropertyStr (const std::string &prop, MarkupType markup)
+{
+ if (prop == "name")
+ return name();
+ if (prop == "summary")
+ return summary();
+ if (prop == "description")
+ return description (markup);
+ if (prop == "filelist")
+ return filelist (markup);
+ if (prop == "support")
+ return support();
+ if (prop == "size")
+ return size();
+ if (prop == "available-version") {
+ const Ypp::Package::Version *version = getAvailableVersion (0);
+ if (version)
+ return version->number;
+ return "";
+ }
+ if (prop == "repository") {
+ const Ypp::Package::Version *version = 0;
+ if (!toInstall (&version))
+ version = getInstalledVersion();
+ std::string repo;
+ if (version && version->repo)
+ return version->repo->name;
+ return "";
+ }
+ yuiError() << "No string property: " << prop << std::endl;
+ return "";
+}
+
+int Ypp::Package::getPropertyInt (const std::string &prop)
+{
+ if (prop == "severity")
+ return severity();
+ yuiError() << "No integer property: " << prop << std::endl;
+ return 0;
+}
+
+bool Ypp::Package::getPropertyBool (const std::string &prop)
+{
+ if (prop == "is-recommended")
+ return isRecommended();
+ if (prop == "is-suggested")
+ return isSuggested();
+ if (prop == "is-supported")
+ return isSupported();
+ if (prop == "to-install")
+ return toInstall();
+ yuiError() << "No boolean property: " << prop << std::endl;
+ return false;
+}
+
+const Ypp::Package::Version *Ypp::Package::getInstalledVersion()
+{ return impl->getInstalledVersion(); }
+const Ypp::Package::Version *Ypp::Package::getAvailableVersion (int nb)
+{ return impl->getAvailableVersion (nb); }
+const Ypp::Package::Version *Ypp::Package::fromRepository (const Repository *repo)
+{
+ for (int i = 0; getAvailableVersion (i); i++) {
+ const Version *version = getAvailableVersion (i);
+ if (version->repo == repo)
+ return version;
+ }
+ return NULL;
+}
+
+bool Ypp::Package::isInstalled() { return impl->isInstalled(); }
+bool Ypp::Package::hasUpgrade() { return impl->hasUpgrade(); }
+bool Ypp::Package::isLocked() { return impl->isLocked(); }
+
+bool Ypp::Package::toInstall (const Ypp::Package::Version **version)
+{ return impl->toInstall (version); }
+bool Ypp::Package::toRemove() { return impl->toRemove(); }
+bool Ypp::Package::toModify() { return impl->toModify(); }
+bool Ypp::Package::isAuto() { return impl->isAuto(); }
+
+void Ypp::Package::install (const Version *version)
+{
+ impl->install (version);
+ ypp->impl->packageModified (this);
+}
+
+void Ypp::Package::remove()
+{
+ impl->remove();
+ ypp->impl->packageModified (this);
+}
+
+void Ypp::Package::undo()
+{
+ impl->undo();
+ ypp->impl->packageModified (this);
+}
+
+bool Ypp::Package::canLock() { return impl->canLock(); }
+
+bool Ypp::Package::canRemove() { return impl->canRemove(); }
+
+void Ypp::Package::lock (bool lock)
+{
+ impl->lock (lock);
+ ypp->impl->packageModified (this);
+}
+
+struct PackageSel : public Ypp::Package::Impl
+{
+ZyppSelectable m_sel;
+Ypp::Node *m_category, *m_category2;
+GSList *m_availableVersions;
+Ypp::Package::Version *m_installedVersion;
+bool m_isInstalled, m_hasUpgrade;
+zypp::ui::Status m_curStatus; // so we know if resolver touched it
+// for Patterns
+GSList *m_containsPackages;
+int m_installedPkgs, m_totalPkgs;
+
+ PackageSel (Ypp::Package::Type type, ZyppSelectable sel, Ypp::Node *category, Ypp::Node *category2)
+ : Impl (type), m_sel (sel), m_category (category), m_category2 (category2),
+ m_availableVersions (NULL), m_installedVersion (NULL), m_containsPackages (NULL)
+ {
+ // for patterns, there is no reliable way to know if it's installed (because
+ // if it set to be installed that will alter candidate's satisfied status.)
+ if (type == Ypp::Package::PATTERN_TYPE || type == Ypp::Package::PATCH_TYPE)
+ m_isInstalled = sel->candidateObj().isSatisfied() &&
+ // from yast-qt, may be it is satisfied because is preselected:
+ !sel->candidateObj().status().isToBeInstalled();
+ else {
+ if (sel->installedEmpty())
+ m_isInstalled = false;
+ else
+ m_isInstalled = !sel->installedObj().isBroken();
+ }
+ // don't use getAvailableVersion(0) for hasUpgrade() has its inneficient.
+ // let's just cache candidate() at start, which should point to the newest version.
+ const ZyppObject candidate = sel->candidateObj();
+ const ZyppObject installed = sel->installedObj();
+ m_hasUpgrade = false;
+ if (!!candidate && !!installed)
+ m_hasUpgrade = zypp::Edition::compare (candidate->edition(), installed->edition()) > 0;
+
+ setNotTouched();
+ m_installedPkgs = m_totalPkgs = 0;
+ }
+
+ virtual ~PackageSel()
+ {
+ delete m_installedVersion;
+ for (GSList *i = m_availableVersions; i; i = i->next)
+ delete ((Ypp::Package::Version *) i->data);
+ g_slist_free (m_availableVersions);
+ g_slist_free (m_containsPackages);
+ }
+
+ virtual bool isTouched()
+ { return m_curStatus != m_sel->status(); }
+ virtual void setNotTouched()
+ { m_curStatus = m_sel->status(); }
+
+ GSList *getContainedPackages()
+ {
+ if (!m_containsPackages) {
+ switch (type) {
+ case Ypp::Package::PATTERN_TYPE: {
+ ZyppObject object = m_sel->theObj();
+ ZyppPattern pattern = tryCastToZyppPattern (object);
+ zypp::Pattern::Contents contents (pattern->contents());
+ for (zypp::Pattern::Contents::Selectable_iterator it =
+ contents.selectableBegin(); it != contents.selectableEnd(); it++) {
+ ZyppSelectablePtr sel = get_pointer (*it);
+ m_containsPackages = g_slist_append (m_containsPackages, sel);
+ if (!sel->installedEmpty())
+ m_installedPkgs++;
+ m_totalPkgs++;
+ }
+ break;
+ }
+ case Ypp::Package::PATCH_TYPE: {
+ ZyppObject object = m_sel->theObj();
+ ZyppPatch patch = tryCastToZyppPatch (object);
+ zypp::Patch::Contents contents (patch->contents());
+ for (zypp::Patch::Contents::Selectable_iterator it =
+ contents.selectableBegin(); it != contents.selectableEnd(); it++) {
+ ZyppSelectablePtr sel = get_pointer (*it);
+ m_containsPackages = g_slist_append (m_containsPackages, sel);
+ if (!sel->installedEmpty())
+ m_installedPkgs++;
+ m_totalPkgs++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return m_containsPackages;
+ }
+
+ virtual std::string name()
+ {
+ if (type == Ypp::Package::PATTERN_TYPE)
+ return m_sel->theObj()->summary();
+ return m_sel->name();
+ }
+
+ virtual std::string summary()
+ {
+ if (type == Ypp::Package::PATTERN_TYPE) {
+ int installed, total;
+ containsStats (&installed, &total);
+ std::ostringstream stream;
+ stream << _("Installed: ") << installed << _(" of ") << total;
+ return stream.str();
+ }
+ return m_sel->theObj()->summary();
+ }
+
+ virtual std::string description (MarkupType markup)
+ {
+ ZyppObject object = m_sel->theObj();
+ std::string text = object->description(), br = "<br>";
+ if (markup == GTK_MARKUP && type == Ypp::Package::PACKAGE_TYPE) {
+ YGUtils::escapeMarkup (text);
+ text += "\n";
+ const Ypp::Package::Version *version;
+ version = getInstalledVersion();
+ if (version)
+ text += std::string ("\n") + _("Installed:") + " " + version->number;
+ version = getAvailableVersion (0);
+ if (version) {
+ text += std::string ("\n") + _("Candidate:") + " " + version->number;
+ text += std::string (" (") + _("from") + " " + version->repo->name + ")";
+ }
+ return text;
+ }
+ if (markup == NO_MARKUP)
+ return text;
+
+ switch (type) {
+ case Ypp::Package::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))
+ ;
+ else {
+ // cut authors block
+ std::string::size_type i = text.find ("\nAuthors:", 0);
+ if (i == std::string::npos)
+ i = text.find ("\nAuthor:", 0);
+ if (i != std::string::npos)
+ text.erase (i);
+ // cut any lines at the end
+ while (text.length() > 0 && text [text.length()-1] == '\n')
+ text.erase (text.length()-1);
+
+ YGUtils::escapeMarkup (text);
+ YGUtils::replace (text, "\n\n", 2, "<br>"); // break every double line
+ text += br;
+ }
+
+ if (!isInstalled() && (isRecommended() || isSuggested())) {
+ text += "<font color=\"#715300\">";
+ if (isRecommended())
+ text += _("(As this package is an extension to an already installed package, it is <b>recommended</b> it be installed.)");
+ if (isSuggested())
+ text += _("(As this package complements some installed packages, it is <b>suggested</b> it be installed.)");
+ text += "</font>" + br;
+ }
+
+ // specific
+ ZyppPackage package = tryCastToZyppPkg (object);
+#if ZYPP_VERSION >= 5013001
+ text += br + "<b>" + _("Size:") + "</b> " + object->installSize().asString();
+#else
+ text += br + "<b>" + _("Size:") + "</b> " + object->installsize().asString();
+#endif
+ std::string url = package->url(), license = package->license();
+ if (!url.empty())
+ text += br + "<b>" + _("Website:") + "</b> <a href=\"" + url + "\">" + url + "</a>";
+ if (!license.empty())
+ text += br + "<b>" + _("License:") + "</b> " + license;
+#if 0
+ text += br + "<b>" + _("Category:") + "</b> " + package->group();
+#endif
+#if 0 // show "Installed at:" and "Last build:" info
+ bool hasCandidate = m_sel->hasCandidateObj();
+ if (isInstalled()) {
+ text += br + "<b>" + _("Installed at:") + "</b> " + m_sel->installedObj()->installtime().form("%x");
+ if (!hasUpgrade())
+ hasCandidate = false; // only for upgrades
+ if (hasCandidate)
+ text += " ";
+ }
+ else if (hasCandidate)
+ text += br;
+ if (hasCandidate)
+ text += std::string ("<b>") + _("Last build:") + "</b> " + m_sel->candidateObj()->buildtime().form("%x");
+#endif
+ break;
+ }
+ case Ypp::Package::PATCH_TYPE:
+ {
+ ZyppPatch patch = tryCastToZyppPatch (object);
+ if (patch->rebootSuggested()) {
+ text += br + br + "<b>" + _("Reboot required: ") + "</b>";
+ text += _("the system will have to be restarted in order for "
+ "this patch to take effect.");
+ }
+ if (patch->reloginSuggested()) {
+ text += br + br + "<b>" + _("Relogin required: ") + "</b>";
+ text += _("you must logout and login again for "
+ "this patch to take effect.");
+ }
+ if (patch->referencesBegin() != patch->referencesEnd()) {
+ text += br + br + "<b>Bugzilla:</b><ul>";
+ for (zypp::Patch::ReferenceIterator it = patch->referencesBegin();
+ it != patch->referencesEnd(); it++)
+ text += "<li><a href=\"" + it.href() + "\">" + it.title() + "</a></li>";
+ text += "</ul>";
+ }
+ break;
+ }
+ case Ypp::Package::PATTERN_TYPE:
+ {
+ int installed, total;
+ containsStats (&installed, &total);
+ std::ostringstream stream;
+ if (markup == HTML_MARKUP)
+ stream << "<br><br>";
+ stream << "\n\n" << _("Installed: ") << installed << _(" of ") << total;
+ text += stream.str();
+ break;
+ }
+ default:
+ break;
+ }
+ return text;
+ }
+
+ virtual std::string filelist (MarkupType markup)
+ {
+ std::string text;
+ ZyppObject object = m_sel->installedObj();
+ ZyppPackage package = tryCastToZyppPkg (object);
+ if (package) {
+ if (markup == HTML_MARKUP) {
+ StringTree tree (strcmp, '/', NULL);
+
+#if ZYPP_VERSION > 5024005
+ zypp::Package::FileList files = package->filelist();
+ for (zypp::Package::FileList::iterator it = files.begin();
+ it != files.end(); it++)
+ tree.add (*it, "");
+#else
+ std::list <std::string> files (package->filenames());
+ for (std::list <std::string>::iterator it = files.begin();
+ it != files.end(); it++)
+ tree.add (*it, "");
+#endif
+
+ struct inner {
+ static std::string getPath (GNode *node)
+ {
+ Ypp::Node *yNode = (Ypp::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)
+ {
+ Ypp::Node *yNode = (Ypp::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);
+ }
+ else {
+#if ZYPP_VERSION > 5024005
+ zypp::Package::FileList files = package->filelist();
+ for (zypp::Package::FileList::iterator it = files.begin();
+ it != files.end(); it++)
+ text += *it + " ";
+#else
+ std::list <std::string> files (package->filenames());
+ for (std::list <std::string>::iterator it = files.begin();
+ it != files.end(); it++)
+ text += *it + " ";
+#endif
+ }
+ }
+ return text;
+ }
+
+ virtual std::string changelog()
+ {
+ std::string text;
+ ZyppObject object = m_sel->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 date (it->date().form ("%d %B %Y")), author (it->author()),
+ changes (it->text());
+ YGUtils::escapeMarkup (author);
+ YGUtils::escapeMarkup (changes);
+ YGUtils::replace (changes, "\n", 1, "<br>");
+ if (author.compare (0, 2, "- ", 2) == 0) // zypp returns a lot of author strings as
+ author.erase (0, 2); // "- author". wtf?
+ text += date + " (" + author + "):<br><blockquote>" + changes + "</blockquote>";
+ }
+ }
+ return text;
+ }
+
+ virtual std::string authors (MarkupType markup)
+ {
+ std::string text;
+ ZyppObject object = m_sel->theObj();
+ ZyppPackage package = tryCastToZyppPkg (object);
+ if (package) {
+ std::string packager = package->packager(), vendor = package->vendor(), authors;
+ YGUtils::escapeMarkup (packager);
+ YGUtils::escapeMarkup (vendor);
+ 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);
+ if (markup != NO_MARKUP)
+ YGUtils::escapeMarkup (author);
+ if (!authors.empty()) {
+ if (markup == HTML_MARKUP)
+ authors += "<br>";
+ else
+ authors += "\n";
+ }
+ authors += author;
+ }
+ // look for Authors line in description
+ std::string description = package->description();
+ std::string::size_type i = description.find ("\nAuthors:\n-----", 0);
+ if (i != std::string::npos) {
+ i += sizeof ("\nAuthors:\n----");
+ i = description.find ("\n", i);
+ if (i != std::string::npos)
+ i++;
+ }
+ else {
+ i = description.find ("\nAuthor:", 0);
+ if (i == std::string::npos) {
+ i = description.find ("\nAuthors:", 0);
+ if (i != std::string::npos)
+ i++;
+ }
+ if (i != std::string::npos)
+ i += sizeof ("\nAuthor:");
+ }
+ if (i != std::string::npos) {
+ std::string str = description.substr (i);
+ if (markup != NO_MARKUP)
+ YGUtils::escapeMarkup (str);
+ if (markup == HTML_MARKUP)
+ YGUtils::replace (str, "\n", 1, "<br>");
+ authors += str;
+ }
+ if (markup == HTML_MARKUP) {
+ if (!authors.empty()) {
+ text = _("Developed by:") + ("<blockquote>" + authors) + "</blockquote>";
+ if (!packager.empty() || !vendor.empty()) {
+ text += _("Packaged by:");
+ text += "<blockquote>";
+ if (!packager.empty()) text += packager + " ";
+ if (!vendor.empty()) text += "(" + vendor + ")";
+ text += "</blockquote>";
+ }
+ }
+ }
+ else
+ return authors;
+ }
+ return text;
+ }
+
+ virtual std::string support()
+ {
+ ZyppObject object = m_sel->theObj();
+ ZyppPackage package = tryCastToZyppPkg (object);
+ if (package) {
+ zypp::VendorSupportOption opt = package->vendorSupport();
+ return zypp::asUserString (opt);
+ }
+ return "";
+ }
+
+ virtual std::string supportText (MarkupType markup)
+ {
+ ZyppObject object = m_sel->theObj();
+ ZyppPackage package = tryCastToZyppPkg (object);
+ if (package) {
+ zypp::VendorSupportOption opt = package->vendorSupport();
+ std::string str (zypp::asUserStringDescription (opt));
+ if (markup != HTML_MARKUP)
+ YGUtils::escapeMarkup (str);
+ return str;
+ }
+ return "";
+ }
+
+ virtual std::string size()
+ { return m_sel->theObj()->installSize().asString(); }
+
+ virtual std::string icon()
+ {
+ if (type == Ypp::Package::PATTERN_TYPE) {
+ ZyppObject object = m_sel->theObj();
+ ZyppPattern pattern = tryCastToZyppPattern (object);
+ std::string icon = pattern->icon().asString().c_str();
+ // from yast2-qt: HACK most patterns have wrong default icon
+ if ((icon == zypp::Pathname("yast-system").asString()) || icon.empty())
+ icon = "pattern-generic";
+ // mine: remove start "./"
+ else if (icon.compare (0, 2, "./", 2) == 0)
+ icon.erase (0, 2);
+ return icon;
+ }
+ return "";
+ }
+
+ virtual bool isRecommended() const
+ {
+ // like yast2-qt: different instances may be assigned different groups
+ if (m_sel->hasCandidateObj())
+ for (int i = 0; i < 2; i++) {
+ ZyppObject obj;
+ if (i == 0)
+ obj = m_sel->candidateObj();
+ else
+ obj = m_sel->installedObj();
+ if (obj && zypp::PoolItem (obj).status().isRecommended())
+ return true;
+ }
+ return false;
+ }
+
+ virtual bool isSuggested() const
+ {
+ if (m_sel->hasCandidateObj())
+ for (int i = 0; i < 2; i++) {
+ ZyppObject obj;
+ if (i == 0)
+ obj = m_sel->candidateObj();
+ else
+ obj = m_sel->installedObj();
+ if (obj && zypp::PoolItem (obj).status().isSuggested())
+ return true;
+ }
+ return false;
+ }
+
+ virtual int buildAge() const
+ {
+ if (m_sel->hasCandidateObj()) {
+ time_t build = static_cast <time_t> (m_sel->candidateObj()->buildtime());
+ time_t now = time (NULL);
+ return (now - build) / (60*60*24); // in days
+ }
+ return -1;
+ }
+
+ virtual bool isSupported() const
+ {
+#if ZYPP_VERSION >= 5013001
+ if (type != Ypp::Package::PACKAGE_TYPE)
+ return false;
+ ZyppObject object = m_sel->theObj();
+ ZyppPackage package = tryCastToZyppPkg (object);
+ return !package->maybeUnsupported();
+#else
+ return true;
+#endif
+ }
+
+ virtual int severity() const
+ {
+ ZyppObject object = m_sel->theObj();
+ ZyppPatch patch = tryCastToZyppPatch (object);
+ if (patch->category() == "security") return 0;
+ if (patch->category() == "recommended") return 1;
+ if (patch->category() == "yast") return 2;
+ if (patch->category() == "document") return 3;
+ if (patch->category() == "optional") return 4;
+ //if (patch->category() == "other")
+ return 5;
+ }
+
+ virtual std::string provides (MarkupType markup) const
+ {
+ std::string text;
+ ZyppObject object = m_sel->theObj();
+ const zypp::Capabilities &capSet = object->dep (zypp::Dep::PROVIDES);
+ for (zypp::Capabilities::const_iterator it = capSet.begin();
+ it != capSet.end(); it++) {
+ if (!text.empty())
+ text += "\n";
+ text += it->asString();
+ }
+ if (markup != HTML_MARKUP)
+ YGUtils::escapeMarkup (text);
+ return text;
+ }
+
+ virtual std::string requires (MarkupType markup) const
+ {
+ std::string text;
+ ZyppObject object = m_sel->theObj();
+ const zypp::Capabilities &capSet = object->dep (zypp::Dep::REQUIRES);
+ for (zypp::Capabilities::const_iterator it = capSet.begin();
+ it != capSet.end(); it++) {
+ if (!text.empty())
+ text += "\n";
+ text += it->asString();
+ }
+ if (markup != NO_MARKUP)
+ YGUtils::escapeMarkup (text);
+ return text;
+ }
+
+ virtual bool containsPackage (const Ypp::Package *package)
+ {
+ PackageSel *sel = (PackageSel *) package->impl;
+ return g_slist_find (getContainedPackages(), get_pointer (sel->m_sel)) != NULL;
+ }
+
+ virtual void containsStats (int *installed, int *total)
+ {
+ getContainedPackages(); // init
+ *installed = m_installedPkgs;
+ *total = m_totalPkgs;
+ }
+
+ virtual Ypp::Node *category()
+ { return m_category; }
+
+ virtual Ypp::Node *category2()
+ {
+ if (!m_category2) {
+ YPkgGroupEnum group = PK_GROUP_ENUM_UNKNOWN;
+ for (int i = 0; i < 2; i++) {
+ ZyppObject obj;
+ if (i == 0)
+ obj = m_sel->candidateObj();
+ else
+ obj = m_sel->installedObj();
+ ZyppPackage pkg = tryCastToZyppPkg (obj);
+ if (pkg) {
+ group = zypp_tag_convert (pkg->group());
+ if (group != PK_GROUP_ENUM_UNKNOWN)
+ break;
+ }
+ }
+ m_category2 = ypp->impl->mapCategory2Enum (group);
+ }
+ return m_category2;
+ }
+
+ virtual bool isInstalled()
+ {
+ return m_isInstalled;
+ }
+
+ virtual bool hasUpgrade()
+ {
+ return m_hasUpgrade;
+ }
+
+ virtual bool isLocked()
+ {
+ zypp::ui::Status status = m_sel->status();
+ return status == zypp::ui::S_Taboo || status == zypp::ui::S_Protected;
+ }
+
+ virtual bool toInstall (const Ypp::Package::Version **version)
+ {
+ if (version) {
+ ZyppObject candidate = m_sel->candidateObj();
+ for (int i = 0; getAvailableVersion (i); i++) {
+ const Ypp::Package::Version *v = getAvailableVersion (i);
+ ZyppObject obj = (ZyppObjectPtr) v->impl;
+ if (obj == candidate) {
+ *version = v;
+ break;
+ }
+ }
+ }
+ return m_sel->toInstall();
+ }
+
+ virtual bool toRemove()
+ { return m_sel->toDelete(); }
+
+ virtual bool toModify()
+ { return m_sel->toModify(); }
+
+ virtual bool isAuto()
+ {
+ zypp::ui::Status status = m_sel->status();
+ return status == zypp::ui::S_AutoInstall || status == zypp::ui::S_AutoUpdate ||
+ status == zypp::ui::S_AutoDel;
+ }
+
+ virtual void install (const Ypp::Package::Version *version)
+ {
+ if (isLocked())
+ return;
+ if (!m_sel->hasLicenceConfirmed())
+ {
+ ZyppObject obj = m_sel->candidateObj();
+ const std::string &license = obj->licenseToConfirm();
+ if (!license.empty())
+ if (!ypp->impl->acceptLicense (m_parent, license))
+ return;
+ m_sel->setLicenceConfirmed();
+
+ const std::string &msg = obj->insnotify();
+ if (!msg.empty())
+ ypp->impl->notifyMessage (m_parent, msg);
+ }
+
+ zypp::ui::Status status = m_sel->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;
+ }
+
+ m_sel->setStatus (status);
+ if (toInstall (NULL)) {
+ if (!version) {
+ version = getAvailableVersion (0);
+ const Ypp::Repository *repo = ypp->favoriteRepository();
+ if (repo && fromRepository (repo))
+ version = fromRepository (repo);
+ }
+ ZyppObject candidate = (ZyppObjectPtr) version->impl;
+ if (!m_sel->setCandidate (candidate)) {
+ yuiWarning () << "Error: Could not set package '" << name() << "' candidate to '" << version->number << "'\n";
+ return;
+ }
+ }
+ }
+
+ virtual void remove()
+ {
+ if (m_sel->hasCandidateObj()) {
+ const std::string &msg = m_sel->candidateObj()->delnotify();
+ if (!msg.empty())
+ ypp->impl->notifyMessage (m_parent, msg);
+ }
+
+ zypp::ui::Status status = m_sel->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;
+ }
+
+ m_sel->setStatus (status);
+ }
+
+ virtual void undo()
+ {
+ zypp::ui::Status status = m_sel->status();
+ switch (status) {
+ // not applicable
+ case zypp::ui::S_Protected:
+ case zypp::ui::S_Taboo:
+ case zypp::ui::S_NoInst:
+ case zypp::ui::S_KeepInstalled:
+ break;
+
+ // undo
+ case zypp::ui::S_Install:
+ status = zypp::ui::S_NoInst;
+ break;
+ case zypp::ui::S_Update:
+ case zypp::ui::S_Del:
+ status = zypp::ui::S_KeepInstalled;
+ break;
+
+ // for auto status, undo them by locking them
+ case zypp::ui::S_AutoInstall:
+ status = zypp::ui::S_Taboo;
+ break;
+ case zypp::ui::S_AutoUpdate:
+ case zypp::ui::S_AutoDel:
+ status = zypp::ui::S_Protected;
+ break;
+ }
+
+ m_sel->setStatus (status);
+ }
+
+ virtual bool canLock() { return type != Ypp::Package::PATTERN_TYPE; }
+ virtual bool canRemove() { return type == Ypp::Package::PACKAGE_TYPE; }
+
+ virtual void 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;
+
+ m_sel->setStatus (status);
+ }
+
+ static Ypp::Package::Version *constructVersion (
+ ZyppObject object, ZyppObject installedObj)
+ {
+ Ypp::Package::Version *version = new Ypp::Package::Version();
+ version->number = object->edition().asString();
+ version->arch = object->arch().asString();
+ version->repo = ypp->impl->getRepository (object->repoInfo().alias());
+ version->cmp = installedObj ? zypp::Edition::compare (object->edition(), installedObj->edition()) : 0;
+ version->impl = (void *) get_pointer (object);
+ return version;
+ }
+
+ virtual const Ypp::Package::Version *getInstalledVersion()
+ {
+ if (!m_installedVersion) {
+ ZyppObject installedObj = m_sel->installedObj();
+ if (type == Ypp::Package::PATCH_TYPE) {
+ if (m_sel->candidateObj() && m_sel->candidateObj().isSatisfied() &&
+ !m_sel->candidateObj().status().isToBeInstalled())
+ installedObj = m_sel->candidateObj();
+ }
+ if (installedObj)
+ m_installedVersion = constructVersion (installedObj, NULL);
+ }
+ return m_installedVersion;
+ }
+
+ virtual const Ypp::Package::Version *getAvailableVersion (int nb)
+ {
+ if (!m_availableVersions) {
+ ZyppObject installedObj = m_sel->installedObj();
+ if (type == Ypp::Package::PATCH_TYPE) {
+ if (m_sel->candidateObj() && m_sel->candidateObj().isSatisfied())
+ installedObj = m_sel->candidateObj();
+ }
+ const ZyppObject candidateObj = m_sel->candidateObj();
+ for (zypp::ui::Selectable::available_iterator it = m_sel->availableBegin();
+ it != m_sel->availableEnd(); it++) {
+ if (candidateObj && (*it)->edition() == candidateObj->edition() &&
+ (*it)->arch() == candidateObj->arch())
+ continue;
+ Ypp::Package::Version *version = constructVersion (*it, installedObj);
+ m_availableVersions = g_slist_append (m_availableVersions, version);
+ }
+ if (candidateObj) { // make sure this goes first
+ Ypp::Package::Version *version = constructVersion (candidateObj, installedObj);
+ m_availableVersions = g_slist_prepend (m_availableVersions, version);
+ }
+#if 0 // let zypp order prevail
+ struct inner {
+ static gint version_compare (gconstpointer pa, gconstpointer pb)
+ {
+ ZyppObjectPtr a = (ZyppObjectPtr) ((Ypp::Package::Version *) pa)->impl;
+ ZyppObjectPtr b = (ZyppObjectPtr) ((Ypp::Package::Version *) pb)->impl;
+ // swapped arguments, as we want them sorted from newer to older
+ return zypp::Edition::compare (b->edition(), a->edition());
+ }
+ };
+ m_availableVersions = g_slist_sort (m_availableVersions, inner::version_compare);
+#endif
+ }
+ return (Ypp::Package::Version *) g_slist_nth_data (m_availableVersions, nb);
+ }
+
+ virtual const Ypp::Package::Version *fromRepository (const Ypp::Repository *repo)
+ {
+ for (int i = 0; getAvailableVersion (i); i++)
+ if (getAvailableVersion (i)->repo == repo)
+ return getAvailableVersion (i);
+ return NULL;
+ }
+};
+
+struct PackageLang : public Ypp::Package::Impl
+{
+zypp::Locale m_locale;
+GSList *m_containsPackages;
+bool m_installed, m_setInstalled;
+int m_installedPkgs, m_totalPkgs;
+
+ PackageLang (Ypp::Package::Type type, const zypp::Locale &zyppLang)
+ : Impl (type), m_locale (zyppLang), m_containsPackages (NULL)
+ {
+ m_installed = m_setInstalled = isSetInstalled();
+ m_installedPkgs = m_totalPkgs = 0;
+ }
+
+ ~PackageLang()
+ {
+ g_slist_free (m_containsPackages);
+ }
+
+ virtual bool isTouched()
+ { return m_setInstalled == isSetInstalled(); }
+ virtual void setNotTouched()
+ { m_setInstalled = isSetInstalled(); }
+
+ virtual std::string name()
+ { return m_locale.name(); }
+
+ virtual std::string summary()
+ {
+ int installed, total;
+ containsStats (&installed, &total);
+ std::ostringstream stream;
+ stream << _("Installed: ") << installed << _(" of ") << total;
+ return stream.str();
+ }
+
+ virtual std::string description (MarkupType markup)
+ {
+ std::string text ("(" + m_locale.code() + ")");
+ int installed, total;
+ containsStats (&installed, &total);
+ std::ostringstream stream;
+ if (markup == HTML_MARKUP)
+ stream << "<br><br>";
+ stream << "\n\n" << _("Installed: ") << installed << _(" of ") << total;
+ text += stream.str();
+ return text;
+ }
+
+ GSList *getContainedPackages()
+ {
+ if (!m_containsPackages) {
+ zypp::sat::LocaleSupport myLocale (m_locale);
+ for_( it, myLocale.selectableBegin(), myLocale.selectableEnd() ) {
+ ZyppSelectablePtr sel = get_pointer (*it);
+ m_containsPackages = g_slist_append (m_containsPackages, sel);
+ if (!sel->installedEmpty())
+ m_installedPkgs++;
+ m_totalPkgs++;
+ }
+ }
+ return m_containsPackages;
+ }
+
+ virtual bool containsPackage (const Ypp::Package *package)
+ {
+ PackageSel *sel = (PackageSel *) package->impl;
+ return g_slist_find (getContainedPackages(), get_pointer (sel->m_sel)) != NULL;
+ }
+
+ virtual void containsStats (int *installed, int *total)
+ {
+ getContainedPackages(); // init
+ *installed = m_installedPkgs;
+ *total = m_totalPkgs;
+ }
+
+ virtual std::string icon()
+ {
+ #define ICON_PATH "/usr/share/locale/l10n/"
+ static int hasPath = -1;
+ if (hasPath == -1)
+ hasPath = g_file_test (ICON_PATH, G_FILE_TEST_IS_DIR) ? 1 : 0;
+ if (hasPath) {
+ std::string code (m_locale.code());
+ std::string::size_type i = code.find_last_of ('_');
+ if (i != std::string::npos) {
+ code.erase (0, i+1);
+ // down case country name
+ gchar *str = g_ascii_strdown (code.c_str(), -1);
+ code = str;
+ g_free (str);
+ }
+ std::string filename (ICON_PATH);
+ filename += code + "/flag.png";
+ if (g_file_test (filename.c_str(), G_FILE_TEST_IS_REGULAR))
+ return filename;
+ }
+ return "";
+ }
+
+ bool isSetInstalled()
+ { return zypp::getZYpp()->pool().isRequestedLocale (m_locale); }
+
+ virtual bool isInstalled()
+ { return m_installed; }
+ virtual bool hasUpgrade()
+ { return false; }
+ virtual bool isLocked()
+ { return false; }
+
+ virtual bool toInstall (const Ypp::Package::Version **repo)
+ { return !m_installed && isSetInstalled(); }
+ virtual bool toRemove()
+ { return m_installed && !isSetInstalled(); }
+ virtual bool toModify()
+ { return m_installed != isSetInstalled(); }
+ virtual bool isAuto()
+ { return false; }
+
+ virtual void install (const Ypp::Package::Version *repo)
+ {
+ if (!isSetInstalled())
+ zypp::getZYpp()->pool().addRequestedLocale (m_locale);
+ }
+
+ virtual void remove()
+ {
+ if (isSetInstalled())
+ zypp::getZYpp()->pool().eraseRequestedLocale (m_locale);
+ }
+
+ virtual void undo()
+ {
+ if (isSetInstalled())
+ remove();
+ else if (m_installed)
+ install (0);
+ }
+
+ virtual void lock (bool lock) {}
+
+ virtual bool canRemove() { return true; }
+ virtual bool canLock() { return false; }
+};
+
+// Packages Factory
+Ypp::PkgList *Ypp::Impl::getPackages (Ypp::Package::Type type)
+{
+ if (!packages[type]) {
+ interface->loading (0);
+
+ PkgList *list = new PkgList();
+ struct inner {
+ // slower -- don't use for packages -- only for languages
+ static bool utf8_order (Package *a, Package *b)
+ { return g_utf8_collate (a->name().c_str(), b->name().c_str()) < 0; }
+ static bool pattern_order (Package *a, Package *b)
+ {
+ ZyppPattern pattern1 = tryCastToZyppPattern (((PackageSel *) a->impl)->m_sel->theObj());
+ ZyppPattern pattern2 = tryCastToZyppPattern (((PackageSel *) b->impl)->m_sel->theObj());
+ return strcmp (pattern1->order().c_str(), pattern2->order().c_str()) < 0;
+ }
+ static int pk_group_order (const char *a, const char *b)
+ {
+ const char *unknown = zypp_tag_group_enum_to_localised_text (PK_GROUP_ENUM_UNKNOWN);
+ if (!strcmp (a, unknown)) {
+ if (!strcmp (b, unknown))
+ return 0;
+ return 1;
+ }
+ if (!strcmp (b, unknown)) {
+ if (!strcmp (a, unknown))
+ return 0;
+ return -1;
+ }
+ return strcmp (a, b);
+ }
+ };
+
+ if (type == Package::LANGUAGE_TYPE) {
+ zypp::LocaleSet locales = zypp::getZYpp()->pool().getAvailableLocales();
+ list->reserve (locales.size());
+ for (zypp::LocaleSet::const_iterator it = locales.begin();
+ it != locales.end(); it++) {
+ Package *package = new Package (new PackageLang (type, *it));
+ list->append (package);
+ }
+ }
+ else { // Pool Selectables
+ ZyppPool::const_iterator it, end;
+ int size = 0;
+ switch (type) {
+ case Package::PACKAGE_TYPE:
+ it = zyppPool().byKindBegin <zypp::Package>();
+ end = zyppPool().byKindEnd <zypp::Package>();
+ size = zyppPool().size(zypp::ResKind::package);
+
+ // for the categories
+ bindtextdomain ("rpm-groups", LOCALEDIR);
+ bind_textdomain_codeset ("rpm-groups", "utf8");
+ // layout all categories2 already and assign it to packages on request
+ categories2 = new StringTree (inner::pk_group_order, '/', NULL);
+ for (int i = 0; i < PK_GROUP_ENUM_SIZE; i++) {
+ YPkgGroupEnum group = (YPkgGroupEnum) i;
+ const char *name = zypp_tag_group_enum_to_localised_text (group);
+ const char *icon = zypp_tag_enum_to_icon (group);
+ Ypp::Node *node = categories2->add (name, "");
+ node->icon = icon;
+ mapCategories2 [i] = node;
+ }
+ break;
+ case Package::PATTERN_TYPE:
+ it = zyppPool().byKindBegin <zypp::Pattern>();
+ end = zyppPool().byKindEnd <zypp::Pattern>();
+ size = zyppPool().size(zypp::ResKind::pattern);
+ break;
+ case Package::PATCH_TYPE:
+ it = zyppPool().byKindBegin <zypp::Patch>();
+ end = zyppPool().byKindEnd <zypp::Patch>();
+ size = zyppPool().size(zypp::ResKind::patch);
+ break;
+ default:
+ break;
+ }
+ list->reserve (size);
+
+ for (; it != end; it++) {
+ Ypp::Node *category = 0, *category2 = 0;
+ ZyppSelectable sel = *it;
+ ZyppObject object = sel->theObj();
+
+ // don't show if installed broken and there is no available
+ if (!sel->candidateObj()) {
+ if (!sel->installedEmpty() && sel->installedObj().isBroken())
+ continue;
+ }
+
+ // add category and test visibility
+ switch (type) {
+ case Package::PACKAGE_TYPE:
+ {
+ ZyppPackage zpackage = tryCastToZyppPkg (object);
+ if (!zpackage)
+ continue;
+ category = addCategory (type, zpackage->group(), "");
+ break;
+ }
+ case Package::PATTERN_TYPE:
+ {
+ ZyppPattern pattern = tryCastToZyppPattern (object);
+ if (!pattern || !pattern->userVisible())
+ continue;
+ category = addCategory (type, pattern->category(), pattern->order());
+ break;
+ }
+ case Package::PATCH_TYPE:
+ {
+ ZyppPatch patch = tryCastToZyppPatch (object);
+ if (!patch)
+ continue;
+ if (sel->candidateObj()) {
+ if (!sel->candidateObj().isRelevant())
+ continue;
+ }
+
+ std::string str;
+#if 0 // Zypp patch->categoryEnum() seems broken: always returns the same value (opensuse 11.1)
+ switch (patch->categoryEnum()) {
+ case zypp::Patch::CAT_OTHER: str = _("Other"); break;
+ case zypp::Patch::CAT_YAST: str = "YaST"; break;
+ case zypp::Patch::CAT_SECURITY: str = _("Security"); break;
+ case zypp::Patch::CAT_RECOMMENDED: str = _("Recommended"); break;
+ case zypp::Patch::CAT_OPTIONAL: str = _("Optional"); break;
+ case zypp::Patch::CAT_DOCUMENT: str = _("Documentation"); break;
+ }
+#else
+ if (patch->category() == "security")
+ str = _("Security");
+ else if (patch->category() == "recommended")
+ str = _("Recommended");
+ else if (patch->category() == "yast")
+ str = "YaST";
+ else if (patch->category() == "document")
+ str = _("Documentation");
+ else if (patch->category() == "optional")
+ str = _("Optional");
+ else if (patch->category() == "other")
+ str = _("Other");
+#endif
+ category = addCategory (type, str, "");
+ break;
+ }
+ default:
+ break;
+ }
+
+ Package *package = new Package (new PackageSel (type, sel, category, category2));
+ list->append (package);
+
+ int i = list->size();
+ if ((i % 500) == 0)
+ interface->loading (i / (float) size);
+ }
+ }
+ // a sort merge. Don't use g_slist_insert_sorted() -- its linear
+ if (type == Ypp::Package::PATTERN_TYPE)
+ list->sort (inner::pattern_order);
+ else if (type == Ypp::Package::LANGUAGE_TYPE)
+
+ list->sort (inner::utf8_order);
+ else
+ list->sort();
+ packages[type] = list;
+ polishCategories (type);
+ interface->loading (1);
+ }
+ return packages[type];
+}
+
+Ypp::Node *Ypp::Impl::mapCategory2Enum (YPkgGroupEnum group)
+{ return mapCategories2 [group]; }
+
+//** PkgList
+
+struct Ypp::PkgList::Impl : public Ypp::PkgList::Listener
+{
+PkgList *parent;
+std::list <PkgList::Listener *> listeners;
+std::vector <Ypp::Package *> pool;
+guint inited : 2, _allInstalled : 2, _allNotInstalled : 2, _allUpgradable : 2,
+ _allModified : 2, _allLocked : 2, _allUnlocked : 2, _allCanLock : 2,
+ _allCanRemove : 2;
+int refcount;
+
+ Impl (const Ypp::PkgList *lparent) : Listener()
+ , parent (NULL), inited (false), refcount (1)
+ {
+ if (lparent) {
+ parent = new PkgList (*lparent);
+ parent->addListener (this);
+ }
+ }
+
+ ~Impl()
+ {
+ if (parent) {
+ parent->removeListener (this);
+ delete parent;
+ }
+ }
+
+ // implementations
+ int find (const Package *package) const
+ {
+ for (unsigned int i = 0; i < pool.size(); i++)
+ if (pool[i] == package)
+ return i;
+ return -1;
+ }
+
+ void remove (int i)
+ {
+ std::vector <Package *>::iterator it = pool.begin();
+ it += i;
+ pool.erase (it);
+ }
+
+ void addListener (Ypp::PkgList::Listener *listener)
+ {
+ listeners.push_back (listener);
+ }
+
+ void removeListener (Ypp::PkgList::Listener *listener)
+ { listeners.remove (listener); }
+
+ void buildProps() const
+ { if (!inited) const_cast <Impl *> (this)->_buildProps(); }
+
+ void _buildProps()
+ {
+ inited = true;
+ if (!pool.empty()) {
+ _allInstalled = _allNotInstalled = _allUpgradable = _allModified =
+ _allLocked = _allUnlocked = _allCanLock = _allCanRemove = true;
+ for (unsigned int i = 0; i < pool.size(); i++) {
+ Package *pkg = pool[i];
+ if (!pkg->isInstalled()) {
+ _allInstalled = false;
+ _allUpgradable = false;
+ }
+ else {
+ _allNotInstalled = false;
+ if (!pkg->hasUpgrade())
+ _allUpgradable = false;
+ }
+ if (pkg->toModify())
+ // if modified, can't be locked or unlocked
+ _allLocked = _allUnlocked = false;
+ else
+ _allModified = false;
+ if (pkg->isLocked())
+ _allUnlocked = false;
+ else
+ _allLocked = false;
+ if (!pkg->canLock())
+ _allCanLock = false;
+ if (!pkg->canRemove())
+ _allCanRemove = false;
+ }
+ }
+ else
+ _allInstalled = _allNotInstalled = _allUpgradable = _allModified =
+ _allLocked = _allUnlocked = _allCanLock = _allCanRemove = false;
+ }
+
+ void signalChanged (int index, Package *package)
+ {
+ inited = false;
+ PkgList list (this); refcount++;
+ for (std::list <PkgList::Listener *>::iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ (*it)->entryChanged (list, index, package);
+ }
+
+ void signalInserted (int index, Package *package)
+ {
+ inited = false;
+ PkgList list (this); refcount++;
+ for (std::list <PkgList::Listener *>::iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ (*it)->entryInserted (list, index, package);
+ }
+
+ void signalDeleted (int index, Package *package)
+ {
+ inited = false;
+ PkgList list (this); refcount++;
+ for (std::list <PkgList::Listener *>::iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ (*it)->entryDeleted (list, index, package);
+ }
+
+ // Ypp callback
+ void packageModified (Package *package)
+ {
+ bool live = liveList();
+ if (!live && listeners.empty())
+ return;
+
+ bool match = this->match (package);
+ int index = find (package);
+ if (live) {
+ if (index >= 0) { // is on the pool
+ if (match) // modified
+ signalChanged (index, package);
+ else { // removed
+ signalDeleted (index, package);
+ remove (index);
+ }
+ }
+ else { // not on pool
+ if (match) { // inserted
+ pool.push_back (package);
+ signalInserted (pool.size()-1, package);
+ }
+ }
+ }
+ else if (index >= 0)
+ signalChanged (index, package);
+ }
+
+ virtual void entryChanged (const PkgList list, int index, Package *package)
+ { packageModified (package); }
+ virtual void entryInserted (const PkgList list, int index, Package *package)
+ { packageModified (package); }
+ virtual void entryDeleted (const PkgList list, int index, Package *package)
+ { packageModified (package); }
+
+ // for sub-classes to implement live lists
+ virtual bool liveList() const { return false; }
+ virtual bool match (Package *pkg) const { return true; }
+ virtual bool highlight (Package *pkg) const { return false; }
+};
+
+Ypp::PkgList::PkgList()
+: impl (new PkgList::Impl (NULL))
+{}
+
+Ypp::PkgList::PkgList (Ypp::PkgList::Impl *impl) // sub-class
+: impl (impl)
+{}
+
+Ypp::PkgList::PkgList (const Ypp::PkgList &other)
+: impl (other.impl)
+{ impl->refcount++; }
+
+Ypp::PkgList & Ypp::PkgList::operator = (const Ypp::PkgList &other)
+{
+ if (--impl->refcount <= 0) delete impl;
+ impl = other.impl;
+ impl->refcount++;
+ return *this;
+}
+
+Ypp::PkgList::~PkgList()
+{ if (--impl->refcount <= 0) delete impl; }
+
+Ypp::Package *Ypp::PkgList::get (int i) const
+{ return i >= (signed) impl->pool.size() ? NULL : impl->pool.at (i); }
+
+bool Ypp::PkgList::highlight (Ypp::Package *pkg) const
+{ return impl->highlight (pkg); }
+
+int Ypp::PkgList::size() const
+{ return impl->pool.size(); }
+
+void Ypp::PkgList::reserve (int size)
+{ impl->pool.reserve (size); }
+
+void Ypp::PkgList::append (Ypp::Package *package)
+{ impl->pool.push_back (package); }
+
+static bool pkgorder (Ypp::Package *a, Ypp::Package *b)
+{ return strcasecmp (a->name().c_str(), b->name().c_str()) < 0; }
+
+void Ypp::PkgList::sort (bool (* compare) (Package *, Package *))
+{ std::sort (impl->pool.begin(), impl->pool.end(), compare ? compare : pkgorder); }
+
+void Ypp::PkgList::remove (int i)
+{ impl->remove (i); }
+
+void Ypp::PkgList::copy (const Ypp::PkgList list)
+{
+ bool showProgress = false;
+ GTimeVal then;
+ g_get_current_time (&then);
+
+ for (int i = 0; i < list.size(); i++) {
+ Package *pkg = list.get (i);
+ if (impl->match (pkg))
+ append (pkg);
+
+ if (showProgress) {
+ if ((i % 500) == 0)
+ ypp->impl->interface->loading (i / (float) list.size());
+ }
+ else if (i == 499) { // show progress if it takes more than 1 sec to drive 'N' loops
+ GTimeVal now;
+ g_get_current_time (&now);
+ if (now.tv_usec - then.tv_usec >= 35*1000 || now.tv_sec - then.tv_sec >= 1) {
+ showProgress = true;
+ ypp->impl->interface->loading (0);
+ }
+ }
+ }
+ if (showProgress)
+ ypp->impl->interface->loading (1);
+}
+
+bool Ypp::PkgList::contains (const Ypp::Package *package) const
+{ return find (package) != -1; }
+
+int Ypp::PkgList::find (const Ypp::Package *package) const
+{ return impl->find (package); }
+
+Ypp::Package *Ypp::PkgList::find (const std::string &name) const
+{
+ for (int i = 0; i < size(); i++)
+ if (name == get (i)->name())
+ return get (i);
+ return NULL;
+}
+
+bool Ypp::PkgList::operator == (const Ypp::PkgList &other) const
+{ return this->impl == other.impl; }
+
+bool Ypp::PkgList::installed() const
+{ impl->buildProps(); return impl->_allInstalled; }
+
+bool Ypp::PkgList::notInstalled() const
+{ impl->buildProps(); return impl->_allNotInstalled; }
+
+bool Ypp::PkgList::upgradable() const
+{ impl->buildProps(); return impl->_allUpgradable; }
+
+bool Ypp::PkgList::modified() const
+{ impl->buildProps(); return impl->_allModified; }
+
+bool Ypp::PkgList::locked() const
+{ impl->buildProps(); return impl->_allLocked; }
+
+bool Ypp::PkgList::unlocked() const
+{ impl->buildProps(); return impl->_allUnlocked; }
+
+bool Ypp::PkgList::canLock() const
+{ impl->buildProps(); return impl->_allCanLock; }
+
+bool Ypp::PkgList::canRemove() const
+{ impl->buildProps(); return impl->_allCanRemove; }
+
+void Ypp::PkgList::install()
+{
+ Ypp::get()->startTransactions();
+ for (int i = 0; get (i); i++)
+ get (i)->install (0);
+ Ypp::get()->finishTransactions();
+}
+
+void Ypp::PkgList::remove()
+{
+ Ypp::get()->startTransactions();
+ for (int i = 0; get (i); i++)
+ get (i)->remove();
+ Ypp::get()->finishTransactions();
+}
+
+void Ypp::PkgList::lock (bool toLock)
+{
+ Ypp::get()->startTransactions();
+ for (int i = 0; get (i); i++)
+ get (i)->lock (toLock);
+ Ypp::get()->finishTransactions();
+}
+
+void Ypp::PkgList::undo()
+{
+ Ypp::get()->startTransactions();
+ for (int i = 0; get (i); i++)
+ get (i)->undo();
+ Ypp::get()->finishTransactions();
+}
+
+void Ypp::PkgList::addListener (Ypp::PkgList::Listener *listener) const
+{ const_cast <Impl *> (impl)->addListener (listener); }
+
+void Ypp::PkgList::removeListener (Ypp::PkgList::Listener *listener) const
+{ const_cast <Impl *> (impl)->removeListener (listener); }
+
+//** PkgQuery
+
+struct Ypp::PkgQuery::Query::Impl
+{
+ template <typename T>
+ struct Key
+ {
+ Key() : defined (false) {}
+ void set (T v)
+ {
+ defined = true;
+ value = v;
+ }
+ bool is (const T &v) const
+ {
+ if (!defined) return true;
+ return value == v;
+ }
+ bool defined;
+ T value;
+ };
+
+ template <typename T>
+ struct Keys
+ {
+ Keys() : defined (false) {}
+ void add (T v)
+ {
+ defined = true;
+ values.push_back (v);
+ }
+ bool is (const T &v) const
+ {
+ if (!defined) return true;
+ typename std::list <T>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++)
+ if (*it == v)
+ return true;
+ return false;
+ }
+ bool defined;
+ std::list <T> values;
+ };
+
+ Keys <std::string> names;
+ unsigned int use_name : 1, use_summary : 1, use_description : 1, use_filelist : 1,
+ use_authors : 1, whole_word : 1, whole_string : 1;
+ Keys <Node *> categories, categories2;
+ Keys <const Package *> collections;
+ Keys <const Repository *> repositories;
+ Key <bool> isInstalled, hasUpgrade, toModify, toInstall, toRemove;
+ Key <bool> isRecommended, isSuggested;
+ Key <int> buildAge;
+ Key <bool> isSupported;
+ Key <int> severity;
+ bool clear;
+ Ypp::Package *highlight;
+
+ Impl() : clear (false), highlight (NULL)
+ {}
+
+ bool match (Package *package) const
+ {
+ struct inner {
+ static bool strstr (const char *str1, const char *str2,
+ bool case_sensitive, bool whole_word, bool whole_string)
+ {
+ const char *i;
+ if (whole_string) {
+ if (case_sensitive)
+ return strcmp (str1, str2) == 0;
+ return strcasecmp (str1, str2) == 0;
+ }
+ if (case_sensitive)
+ i = ::strstr (str1, str2);
+ else
+ i = ::strcasestr (str1, str2);
+ if (whole_word && i) { // check boundries
+ if (i != str1 && isalpha (i[-1]))
+ return false;
+ int len = strlen (str2);
+ if (i [len] && isalpha (i [len]))
+ return false;
+ return true;
+ }
+ return i;
+ }
+ };
+
+ if (clear)
+ return false;
+ bool match = true;
+ if (match && (isInstalled.defined || hasUpgrade.defined)) {
+ // only one of the specified status must match
+ bool status_match = false;
+ if (isInstalled.defined)
+ status_match = isInstalled.is (package->isInstalled());
+ if (!status_match && hasUpgrade.defined)
+ status_match = hasUpgrade.is (package->hasUpgrade());
+ match = status_match;
+ }
+ if (match && toModify.defined)
+ match = toModify.is (package->toModify());
+ if (match && toInstall.defined)
+ match = toInstall.is (package->toInstall());
+ if (match && toRemove.defined)
+ match = toRemove.is (package->toRemove());
+ if (match && isRecommended.defined)
+ match = isRecommended.is (package->isRecommended());
+ if (match && isSuggested.defined)
+ match = isSuggested.is (package->isSuggested());
+ if (match && buildAge.defined) {
+ int age = package->buildAge();
+ if (age < 0 || age > buildAge.value)
+ match = false;
+ }
+ if (match && isSupported.defined)
+ match = isSupported.is (package->isSupported());
+ if (match && severity.defined)
+ match = severity.is (package->severity());
+ if (match && names.defined) {
+ const std::list <std::string> &values = names.values;
+ std::list <std::string>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++) {
+ const char *key = it->c_str();
+ bool str_match = false;
+ if (use_name)
+ str_match = inner::strstr (package->name().c_str(), key,
+ false, whole_word, whole_string);
+ if (!str_match && use_summary)
+ str_match = inner::strstr (package->summary().c_str(), key,
+ false, whole_word, whole_string);
+ if (!str_match && use_description)
+ str_match = inner::strstr (package->description (NO_MARKUP).c_str(), key,
+ false, whole_word, whole_string);
+ if (!str_match && use_filelist)
+ str_match = inner::strstr (package->filelist (NO_MARKUP).c_str(), key,
+ false, whole_word, whole_string);
+ if (!str_match && use_authors)
+ str_match = inner::strstr (package->authors (NO_MARKUP).c_str(), key,
+ false, whole_word, whole_string);
+ if (!str_match) {
+ match = false;
+ break;
+ }
+ }
+ if (match && !highlight && use_name) {
+ if (values.size() == 1 && !strcasecmp (values.front().c_str(), package->name().c_str()))
+ const_cast <Impl *> (this)->highlight = package;
+ }
+ }
+ if (match && categories.defined) {
+ Ypp::Node *pkg_category = package->category();
+ const std::list <Ypp::Node *> &values = categories.values;
+ std::list <Ypp::Node *>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++) {
+ GNode *node = (GNode *) (*it)->impl;
+ if (g_node_find (node, G_PRE_ORDER, G_TRAVERSE_ALL, pkg_category))
+ break;
+ }
+ match = it != values.end();
+ }
+ if (match && categories2.defined) {
+ Ypp::Node *pkg_category = package->category2();
+ const std::list <Ypp::Node *> &values = categories2.values;
+ std::list <Ypp::Node *>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++) {
+ GNode *node = (GNode *) (*it)->impl;
+ if (g_node_find (node, G_PRE_ORDER, G_TRAVERSE_ALL, pkg_category))
+ break;
+ }
+ match = it != values.end();
+ }
+ if (match && repositories.defined) {
+ const std::list <const Repository *> &values = repositories.values;
+ std::list <const Repository *>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++) {
+ bool match = false;
+ for (int i = 0; package->getAvailableVersion (i); i++) {
+ const Ypp::Package::Version *version = package->getAvailableVersion (i);
+ if (version->repo == *it) {
+ // filter if available isn't upgrade
+ if (package->isInstalled() && hasUpgrade.defined && hasUpgrade.value) {
+ if (version->cmp > 0)
+ match = true;
+ }
+ else
+ match = true;
+ break;
+ }
+ }
+ if (match)
+ break;
+ }
+ match = it != values.end();
+ }
+ if (match && collections.defined) {
+ const std::list <const Ypp::Package *> &values = collections.values;
+ std::list <const Ypp::Package *>::const_iterator it;
+ for (it = values.begin(); it != values.end(); it++)
+ if (package->fromCollection (*it))
+ break;
+ match = it != values.end();
+ }
+ return match;
+ }
+};
+
+Ypp::PkgQuery::Query::Query()
+{ impl = new Impl(); }
+Ypp::PkgQuery::Query::~Query()
+{ delete impl; }
+
+void Ypp::PkgQuery::Query::addNames (std::string value, char separator, bool use_name,
+ bool use_summary, bool use_description, bool use_filelist, bool use_authors,
+ bool whole_word, bool whole_string)
+{
+ if (separator) {
+ const gchar delimiter[2] = { separator, '\0' };
+ gchar **names = g_strsplit (value.c_str(), delimiter, -1);
+ for (gchar **i = names; *i; i++)
+ impl->names.add (*i);
+ g_strfreev (names);
+ }
+ else
+ impl->names.add (value);
+ impl->use_name = use_name;
+ impl->use_summary = use_summary;
+ impl->use_description = use_description;
+ impl->use_filelist = use_filelist;
+ impl->use_authors = use_authors;
+ impl->whole_word = whole_word;
+ impl->whole_string = whole_string;
+}
+void Ypp::PkgQuery::Query::addCategory (Ypp::Node *value)
+{ impl->categories.add (value); }
+void Ypp::PkgQuery::Query::addCategory2 (Ypp::Node *value)
+{ impl->categories2.add (value); }
+void Ypp::PkgQuery::Query::addCollection (const Ypp::Package *value)
+{ impl->collections.add (value); }
+void Ypp::PkgQuery::Query::addRepository (const Repository *value)
+{ impl->repositories.add (value); }
+void Ypp::PkgQuery::Query::setIsInstalled (bool value)
+{ impl->isInstalled.set (value); }
+void Ypp::PkgQuery::Query::setHasUpgrade (bool value)
+{ impl->hasUpgrade.set (value); }
+void Ypp::PkgQuery::Query::setToModify (bool value)
+{ impl->toModify.set (value); }
+void Ypp::PkgQuery::Query::setToInstall (bool value)
+{ impl->toInstall.set (value); }
+void Ypp::PkgQuery::Query::setToRemove (bool value)
+{ impl->toRemove.set (value); }
+void Ypp::PkgQuery::Query::setIsRecommended (bool value)
+{ impl->isRecommended.set (value); }
+void Ypp::PkgQuery::Query::setIsSuggested (bool value)
+{ impl->isSuggested.set (value); }
+void Ypp::PkgQuery::Query::setBuildAge (int value)
+{ impl->buildAge.set (value); }
+void Ypp::PkgQuery::Query::setIsSupported (bool value)
+{ impl->isSupported.set (value); }
+void Ypp::PkgQuery::Query::setSeverity (int value)
+{ impl->severity.set (value); }
+void Ypp::PkgQuery::Query::setClear()
+{ impl->clear = true; }
+
+struct Ypp::PkgQuery::Impl : public Ypp::PkgList::Impl
+{
+Query *query;
+
+ Impl (const PkgList parent, Query *query)
+ : PkgList::Impl (&parent), query (query)
+ {}
+
+ ~Impl()
+ { delete query; }
+
+ virtual bool liveList() const
+ { return true; }
+
+ virtual bool match (Package *pkg) const
+ { return query ? query->impl->match (pkg) : true; }
+
+ virtual bool highlight (Package *pkg) const
+ {
+ if (query && query->impl->highlight == pkg)
+ return true;
+ return parent->highlight (pkg); // this might be a sub-query
+ }
+};
+
+Ypp::PkgQuery::PkgQuery (const Ypp::PkgList list, Ypp::PkgQuery::Query *query)
+: PkgList ((impl = new PkgQuery::Impl (list, query)))
+{ copy (list); }
+
+Ypp::PkgQuery::PkgQuery (Ypp::Package::Type type, Ypp::PkgQuery::Query *query)
+: PkgList ((impl = new PkgQuery::Impl (Ypp::get()->getPackages (type), query)))
+{ copy (Ypp::get()->getPackages (type)); }
+
+//** PkgSort
+
+static std::string _prop; // hack
+static bool _ascend;
+
+static bool prop_order (Ypp::Package *a, Ypp::Package *b)
+{
+ int r = strcasecmp (a->getPropertyStr (_prop).c_str(), b->getPropertyStr (_prop).c_str());
+ return _ascend ? r < 0 : r >= 0;
+}
+
+Ypp::PkgSort::PkgSort (PkgList list, const std::string &prop, bool ascend)
+: PkgList()
+{ copy (list); _prop = prop; _ascend = ascend; sort (prop_order); }
+
+//** Misc
+
+struct Ypp::Disk::Impl
+{
+std::list <Ypp::Disk::Listener *> listeners;
+std::vector <Disk::Partition *> partitions;
+
+ Impl()
+ : partitions (NULL)
+ {
+ if (zypp::getZYpp()->diskUsage().empty())
+ zypp::getZYpp()->setPartitions (
+ zypp::DiskUsageCounter::detectMountPoints());
+ }
+
+ ~Impl()
+ {
+ clearPartitions();
+ }
+
+ void packageModified()
+ {
+ clearPartitions();
+ for (std::list <Ypp::Disk::Listener *>::iterator it = listeners.begin();
+ it != listeners.end(); it++)
+ (*it)->updateDisk();
+ }
+
+ void clearPartitions()
+ {
+ for (unsigned int i = 0; i < partitions.size(); i++)
+ delete partitions[i];
+ partitions.clear();
+ }
+
+ const Partition *getPartition (int nb)
+ {
+ if (partitions.empty()) {
+ typedef zypp::DiskUsageCounter::MountPoint ZyppDu;
+ typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet;
+ typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator;
+
+ ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
+ partitions.reserve (diskUsage.size());
+ for (ZyppDuSetIterator it = diskUsage.begin(); it != diskUsage.end(); it++) {
+ const ZyppDu &point = *it;
+ if (!point.readonly) {
+ // partition fields: dir, used_size, total_size (size on Kb)
+ Ypp::Disk::Partition *partition = new Partition();
+ partition->path = point.dir;
+ partition->used = point.pkg_size;
+ partition->delta = point.pkg_size - point.used_size;
+ partition->total = point.total_size;
+ partition->used_str =
+ zypp::ByteCount (partition->used, zypp::ByteCount::K).asString();
+ partition->free_str =
+ zypp::ByteCount (partition->total - partition->used,
+ zypp::ByteCount::K).asString();
+ partition->delta_str =
+ zypp::ByteCount (partition->delta, zypp::ByteCount::K).asString();
+ partition->total_str =
+ zypp::ByteCount (partition->total, zypp::ByteCount::K).asString();
+ partitions.push_back (partition);
+ }
+ }
+ }
+ if (nb >= (signed) partitions.size())
+ return NULL;
+ return partitions[nb];
+ }
+};
+
+Ypp::Disk::Disk()
+{ impl = new Impl(); }
+Ypp::Disk::~Disk()
+{ delete impl; }
+
+void Ypp::Disk::addListener (Ypp::Disk::Listener *listener)
+{ impl->listeners.push_back (listener); }
+
+const Ypp::Disk::Partition *Ypp::Disk::getPartition (int nb)
+{ return impl->getPartition (nb); }
+
+Ypp::Node *Ypp::getFirstCategory (Ypp::Package::Type type)
+{
+ impl->getPackages (type);
+ if (impl->categories[type] != 0)
+ return impl->categories[type]->getFirst();
+ return NULL;
+}
+
+Ypp::Node *Ypp::getFirstCategory2 (Ypp::Package::Type type)
+{
+ impl->getPackages (type);
+ return impl->categories2->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;
+}
+
+Ypp::Node *Ypp::Impl::addCategory (Ypp::Package::Type type, const std::string &category_str, const std::string &order)
+{
+ 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 strcasecmp (a, b);
+// return g_utf8_collate (a, b); // slow?
+ }
+ };
+
+ if (!categories[type]) {
+ const char *trans_domain = 0;
+ if (type == Package::PACKAGE_TYPE)
+ trans_domain = "rpm-groups";
+ categories[type] = new StringTree (inner::cmp, '/', trans_domain);
+ }
+
+ std::string category = category_str;
+ if (category_str.empty())
+ category = _("Other");
+ return categories[type]->add (category, order);
+}
+
+void Ypp::Impl::polishCategories (Ypp::Package::Type type)
+{
+ // some treatment on categories
+ // Packages must be on leaves. If not, create a "Other" leaf, and put it there.
+ if (type == Package::PACKAGE_TYPE) {
+ PkgList *list = ypp->impl->getPackages (type);
+ for (int i = 0; list->get (i); i++) {
+ Package *pkg = list->get (i);
+ PackageSel *sel = (PackageSel *) pkg->impl;
+ 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"))
+ sel->m_category = (Ypp::Node *) last->data;
+ else {
+ // must create a "Other" node
+ Ypp::Node *yN = new Ypp::Node();
+ GNode *n = g_node_new ((void *) yN);
+ yN->name = _("Other");
+ yN->icon = NULL;
+ yN->impl = (void *) n;
+ g_node_insert_before (node, NULL, n);
+ sel->m_category = yN;
+ }
+ }
+ }
+ }
+}
+
+//** Ypp top methods & internal connections
+
+Ypp::Impl::Impl()
+: favoriteRepo (NULL), disk (NULL), interface (NULL),
+ pkg_listeners (NULL), inTransaction (false), transactions (NULL)
+{
+ for (int i = 0; i < Package::TOTAL_TYPES; i++) {
+ packages[i] = NULL;
+ categories[i] = NULL;
+ }
+ categories2 = NULL;
+}
+
+Ypp::Impl::~Impl()
+{
+ struct inner {
+ static void free_repo (void *data, void *_data)
+ { delete ((Repository *) data); }
+ };
+
+ for (int t = 0; t < Package::TOTAL_TYPES; t++) {
+ if (packages [t])
+ for (int p = 0; p < packages[t]->size(); p++)
+ delete packages[t]->get (p);
+ delete packages [t];
+ delete categories[t];
+ }
+ delete categories2;
+ for (unsigned int i = 0; i < repos.size(); i++)
+ delete repos[i];
+
+ // don't delete pools as they don't actually belong to Ypp, just listeners
+ g_slist_free (pkg_listeners);
+ delete disk;
+}
+
+const Ypp::Repository *Ypp::Impl::getRepository (int nb)
+{
+ if (repos.empty()) {
+ struct inner {
+ static void addRepo (Ypp::Impl *impl, const zypp::RepoInfo &info)
+ {
+ Repository *repo = new Repository();
+ repo->name = info.name();
+ if (!info.baseUrlsEmpty())
+ repo->url = info.baseUrlsBegin()->asString();
+ repo->alias = info.alias();
+ repo->enabled = info.enabled();
+ impl->repos.push_back (repo);
+ }
+ };
+
+ int size;
+ zypp::RepoManager manager;
+ std::list <zypp::RepoInfo> known_repos = manager.knownRepositories();
+ size = known_repos.size();
+ size += zyppPool().knownRepositoriesSize();
+ repos.reserve (size);
+
+ for (zypp::ResPoolProxy::repository_iterator it = zyppPool().knownRepositoriesBegin();
+ it != zyppPool().knownRepositoriesEnd(); it++) {
+ const zypp::Repository &zrepo = *it;
+ if (zrepo.isSystemRepo())
+ continue;
+ inner::addRepo (this, zrepo.info());
+ }
+ // zyppPool::knownRepositories is more accurate, but it doesn't feature disabled
+ // repositories. Add them with the following API.
+ for (std::list <zypp::RepoInfo>::const_iterator it = known_repos.begin();
+ it != known_repos.end(); it++) {
+ const zypp::RepoInfo info = *it;
+ if (info.enabled())
+ continue;
+ inner::addRepo (this, info);
+ }
+ }
+ if (nb >= (signed) repos.size())
+ return NULL;
+ return repos[nb];
+}
+
+const Ypp::Repository *Ypp::Impl::getRepository (const std::string &alias)
+{
+ for (int i = 0; getRepository (i); i++)
+ if (getRepository (i)->alias == alias)
+ return getRepository (i);
+ return NULL; /*error*/
+}
+
+zypp::RepoInfo Ypp::Impl::getRepoInfo (const Repository *repo)
+{
+ 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 (repo->alias == it->alias())
+ return *it;
+ // error
+ zypp::RepoInfo i;
+ return i;
+}
+
+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)
+ return interface->acceptLicense (package, license);
+ return true;
+}
+
+void Ypp::Impl::notifyMessage (Ypp::Package *package, const std::string &message)
+{
+ if (interface)
+ interface->notifyMessage (package, message);
+}
+
+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);
+
+ if (resolved) {
+ 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;
+ }
+
+ zResolver->applySolutions (choices);
+ }
+ else
+ break;
+ }
+
+ if (!resolved)
+ zResolver->undo();
+ return resolved;
+}
+
+void Ypp::Impl::packageModified (Ypp::Package *package)
+{
+ if (!g_slist_find (transactions, package)) /* could be a result of undo */
+ transactions = g_slist_append (transactions, package);
+ if (!inTransaction)
+ finishTransactions();
+}
+
+void Ypp::Impl::startTransactions()
+{
+ inTransaction = true;
+}
+
+void Ypp::Impl::finishTransactions()
+{
+ inTransaction = true;
+ bool cancel = (resolveProblems() == false);
+ // check if any package was modified from a restricted repo
+ if (!cancel && ypp->favoriteRepository()) {
+ const Repository *repo = ypp->favoriteRepository();
+ PkgList confirmPkgs;
+ const PkgList *list = packages [Ypp::Package::PACKAGE_TYPE];
+ for (int i = 0; list->get (i); i++) {
+ Ypp::Package *pkg = list->get (i);
+ if (pkg->impl->isTouched()) {
+ const Ypp::Package::Version *version = 0;
+ if (pkg->toInstall (&version)) {
+ if (version->repo != repo)
+ confirmPkgs.append (pkg);
+ }
+ }
+ }
+ if (confirmPkgs.size() != 0)
+ cancel = (interface->allowRestrictedRepo (confirmPkgs) == false);
+ }
+
+ interface->loading (0);
+ if (cancel) {
+ // user canceled resolver -- undo all
+ for (GSList *i = transactions; i; i = i->next)
+ ((Ypp::Package *) i->data)->undo();
+ }
+ else {
+ // resolver won't tell us what changed -- tell pools about Auto packages
+ // notify pools by the following order: 1st user selected, then autos (dependencies)
+ for (int order = 0; order < 2; order++)
+ for (int type = 0; type < Ypp::Package::TOTAL_TYPES; type++) {
+ const PkgList *list = packages [type];
+ if (list)
+ for (int i = 0; i < list->size(); i++) {
+ Ypp::Package *pkg = list->get (i);
+ if (pkg->impl->isTouched()) {
+ bool isAuto = pkg->isAuto();
+ if ((order == 0 && !isAuto) || (order == 1 && isAuto)) {
+ list->impl->signalChanged (i, pkg);
+ pkg->impl->setNotTouched();
+ }
+ }
+#if 0
+ if ((i % 500) == 0) {
+ float total = 2*Ypp::Package::TOTAL_TYPES*list->size();
+ float progress = (i*order*type) / total;
+ interface->loading (progress);
+ }
+#endif
+ }
+ }
+ }
+ g_slist_free (transactions);
+ transactions = NULL;
+ inTransaction = false;
+ if (disk)
+ disk->impl->packageModified();
+ interface->loading (1);
+}
+
+Ypp::Ypp()
+{
+ impl = new Impl();
+ zyppPool().saveState <zypp::Package>();
+ zyppPool().saveState <zypp::Pattern>();
+ zyppPool().saveState <zypp::Patch >();
+}
+
+Ypp::~Ypp()
+{
+ setFavoriteRepository (NULL);
+ delete impl;
+}
+
+const Ypp::Repository *Ypp::getRepository (int nb)
+{ return impl->getRepository (nb); }
+
+void Ypp::setFavoriteRepository (const Ypp::Repository *repo)
+{
+ if (impl->favoriteRepo) {
+ zypp::RepoInfo info = impl->getRepoInfo (impl->favoriteRepo);
+ info.setPriority (impl->favoriteRepoPriority);
+ }
+
+ impl->favoriteRepo = repo;
+
+ if (repo) {
+ zypp::RepoInfo info = impl->getRepoInfo (repo);
+ impl->favoriteRepoPriority = info.priority();
+ info.setPriority (1);
+ }
+}
+
+const Ypp::Repository *Ypp::favoriteRepository()
+{ return impl->favoriteRepo; }
+
+Ypp::Disk *Ypp::getDisk()
+{ return impl->getDisk(); }
+
+void Ypp::setInterface (Ypp::Interface *interface)
+{
+ impl->interface = interface;
+ // run the solver at start to check for problems
+ impl->resolveProblems();
+}
+
+const Ypp::PkgList Ypp::getPackages (Ypp::Package::Type type)
+{ return *impl->getPackages (type); }
+
+bool Ypp::isModified()
+{
+ return zyppPool().diffState<zypp::Package>() ||
+ zyppPool().diffState<zypp::Pattern>() ||
+ zyppPool().diffState<zypp::Patch >();
+}
+
+void Ypp::startTransactions()
+{ impl->startTransactions(); }
+
+void Ypp::finishTransactions()
+{ impl->finishTransactions(); }
+
+#include <fstream>
+#include <zypp/SysContent.h>
+
+bool Ypp::importList (const char *filename)
+{
+ bool ret = true;
+ startTransactions();
+ try {
+ std::ifstream importFile (filename);
+ zypp::syscontent::Reader reader (importFile);
+
+ for (zypp::syscontent::Reader::const_iterator it = reader.begin();
+ it != reader.end(); it++) {
+ std::string kind = it->kind(), name = it->name();
+
+ Package::Type type = Ypp::Package::PACKAGE_TYPE;
+ if (kind == "pattern") // else "package"
+ type = Ypp::Package::PATTERN_TYPE;
+
+ Ypp::Package *pkg = getPackages (type).find (name);
+ if (pkg && !pkg->isInstalled())
+ pkg->install (0);
+ }
+ }
+ catch (const zypp::Exception &exception) {
+ ret = false;
+ }
+ finishTransactions();
+ return ret;
+}
+
+bool Ypp::exportList (const char *filename)
+{
+ bool ret = true;
+ zypp::syscontent::Writer writer;
+ const zypp::ResPool &pool = zypp::getZYpp()->pool();
+
+ // from yast-qt:
+ for_each (pool.begin(), pool.end(),
+ boost::bind (&zypp::syscontent::Writer::addIf, boost::ref (writer), _1));
+
+ try {
+ std::ofstream exportFile (filename);
+ exportFile.exceptions (std::ios_base::badbit | std::ios_base::failbit);
+ exportFile << writer;
+
+ yuiMilestone() << "Package list exported to " << filename << endl;
+ }
+ catch (std::exception &exception) {
+ ret = false;
+ }
+ return ret;
+}
+
+bool Ypp::createSolverTestcase (const char *dirname)
+{
+ bool success;
+ yuiMilestone() << "Generating solver test case START" << endl;
+ success = zypp::getZYpp()->resolver()->createSolverTestcase (dirname);
+ yuiMilestone() << "Generating solver test case END" << endl;
+ return success;
+}
+
Added: trunk/gtk/src/pkg/yzyppwrapper.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/pkg/yzyppwrapper.h?rev=5…
==============================================================================
--- trunk/gtk/src/pkg/yzyppwrapper.h (added)
+++ trunk/gtk/src/pkg/yzyppwrapper.h Thu Nov 26 18:16:21 2009
@@ -0,0 +1,294 @@
+/********************************************************************
+ * 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 PkgQuery with
+ it. Package has a set of manipulation methods, the results of which are
+ then reported to PkgList listeners, which you can choose to act on your
+ interface, if you want them reflected on the viewer.
+ Iterate PkgList using integers (it's actually a vector).
+
+ 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.
+*/
+
+#ifndef ZYPP_WRAPPER_H
+#define ZYPP_WRAPPER_H
+
+#include <string>
+#include <list>
+
+enum MarkupType {
+ HTML_MARKUP, GTK_MARKUP, NO_MARKUP
+};
+
+struct Ypp
+{
+ struct Repository;
+
+ // Utilities
+ struct Node {
+ std::string name, order;
+ const char *icon;
+ Node *next();
+ Node *child();
+ void *impl;
+ };
+
+ // Entries
+ struct Package {
+ enum Type {
+ PACKAGE_TYPE, PATTERN_TYPE, LANGUAGE_TYPE, PATCH_TYPE, TOTAL_TYPES
+ };
+
+ Type type() const;
+ const std::string &name() const;
+ const std::string &summary();
+ Node *category();
+ Node *category2();
+ bool containsPackage (const Ypp::Package *package) const;
+ bool fromCollection (const Ypp::Package *collection) const
+ { return collection->containsPackage (this); }
+ void containsStats (int *installed, int *total) const;
+
+ std::string description (MarkupType markup);
+ std::string filelist (MarkupType markup);
+ std::string changelog();
+ std::string authors (MarkupType markup);
+ std::string support();
+ std::string supportText (MarkupType markup);
+ std::string size();
+ std::string icon();
+ bool isRecommended() const;
+ bool isSuggested() const;
+ int buildAge() const; // if < 0 , unsupported or error
+ bool isSupported() const;
+ int severity() const;
+ static std::string severityStr (int id);
+
+ std::string provides (MarkupType markup) const;
+ std::string requires (MarkupType markup) const;
+
+ std::string getPropertyStr (const std::string &prop, MarkupType markup = NO_MARKUP);
+ int getPropertyInt (const std::string &prop);
+ bool getPropertyBool (const std::string &prop);
+
+ struct Version {
+ std::string number, arch;
+ const Repository *repo;
+ int cmp /* relatively to installed -- ignore if not installed */;
+ void *impl;
+ };
+ const Version *getInstalledVersion();
+ // available versions order is not specified
+ // however the most recent version is ensured to be placed as nb==0
+ const Version *getAvailableVersion (int nb);
+ // convenience -- null if not from repo:
+ const Version *fromRepository (const Repository *repo);
+
+ bool isInstalled();
+ bool hasUpgrade();
+ bool isLocked();
+
+ bool toInstall (const Version **version = 0);
+ bool toRemove();
+ bool toModify();
+ bool isAuto(); /* installing/removing cause of dependency */
+
+ void install (const Version *version); // if installed, will re-install
+ // null for most recent version
+ void remove();
+ void undo();
+ void lock (bool lock);
+
+ bool canRemove();
+ bool canLock();
+
+ struct Impl;
+ Impl *impl;
+ Package (Impl *impl);
+ ~Package();
+ };
+
+ // when installing/removing/... a few packages at a time, you should use this pair,
+ // so that the problem resolver gets only kicked after they are all queued
+ void startTransactions();
+ void finishTransactions();
+
+ // Listing
+ // this class and all proper subclassed are refcounted
+ struct PkgList { // NOTE: this is actually implemented as a vector
+ Package *get (int index) const;
+ bool highlight (Ypp::Package *pkg) const; // applicable to some subclasses only
+ int size() const;
+
+ void reserve (int size);
+ void append (Package *package);
+ void sort (bool (* order) (Package *, Package *) = 0);
+ void remove (int index);
+ void copy (const PkgList list); // will only copy entry for which match() == true
+
+ bool contains (const Package *package) const;
+ int find (const Package *package) const; // -1 if not found
+ Package *find (const std::string &name) const;
+
+ // NOTE: checks if both lists point to the same memory space, not equal contents
+ bool operator == (const PkgList &other) const;
+
+ // common properties
+ // NOTE: there is a hit first time one of these methods is used
+ bool installed() const;
+ bool notInstalled() const;
+ bool upgradable() const;
+ bool modified() const;
+ bool locked() const;
+ bool unlocked() const;
+ bool canRemove() const;
+ bool canLock() const;
+
+ // actions
+ // NOTE: can take time (depending on size); show busy cursor
+ void install(); // or upgrade
+ void remove();
+ void lock (bool toLock);
+ void undo();
+
+ // a Listener can be plugged for when an entry gets modified
+ // -- Inserted and Deleted are only available for particular subclasses
+ struct Listener {
+ virtual void entryChanged (const PkgList list, int index, Package *package) = 0;
+ virtual void entryInserted (const PkgList list, int index, Package *package) = 0;
+ virtual void entryDeleted (const PkgList list, int index, Package *package) = 0;
+ };
+ void addListener (Listener *listener) const;
+ void removeListener (Listener *listener) const;
+ // FIXME: listeners only works for getPackages() lists and PkgQuery ones.
+
+ struct Impl;
+ Impl *impl;
+ PkgList();
+ PkgList (Impl *); // sub-class (to share refcount)
+ PkgList (const PkgList &other);
+ PkgList & operator = (const PkgList &other);
+ virtual ~PkgList();
+ };
+
+ // listing of packages as filtered
+ struct PkgQuery : public PkgList {
+ struct Query {
+ Query();
+ void addNames (std::string name, char separator = 0, bool use_name = true,
+ bool use_summary = true, bool use_description = false,
+ bool use_filelist = false, bool use_authors = false,
+ bool whole_word = false, bool whole_string = false);
+ void addCategory (Ypp::Node *category);
+ void addCategory2 (Ypp::Node *category);
+ void addCollection (const Ypp::Package *package);
+ void addRepository (const Ypp::Repository *repository);
+ void setIsInstalled (bool installed);
+ void setHasUpgrade (bool upgradable);
+ void setToModify (bool modify);
+ void setToInstall (bool install);
+ void setToRemove (bool remove);
+ void setIsRecommended (bool recommended);
+ void setIsSuggested (bool suggested);
+ void setBuildAge (int days);
+ void setIsSupported (bool supported);
+ void setSeverity (int severity);
+ void setClear();
+
+ ~Query();
+ struct Impl;
+ Impl *impl;
+ };
+
+ PkgQuery (const PkgList list, Query *query);
+ PkgQuery (Package::Type type, Query *query); // shortcut
+
+ struct Impl;
+ Impl *impl;
+ };
+
+ struct PkgSort : public PkgList {
+ PkgSort (PkgList list, const std::string &prop, bool ascending);
+ };
+
+ // list primitives
+ const PkgList getPackages (Package::Type type);
+
+ // 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;
+ virtual void notifyMessage (Package *package, const std::string &message) = 0;
+ // resolveProblems = false to cancel the action that had that effect
+ virtual bool resolveProblems (const std::list <Problem *> &problems) = 0;
+ virtual bool allowRestrictedRepo (const PkgList list) = 0;
+ virtual void loading (float progress) = 0;
+ };
+ void setInterface (Interface *interface);
+
+ // Repositories
+ struct Repository {
+ std::string name, url, alias /*internal use*/;
+ bool enabled;
+ };
+ const Repository *getRepository (int nb);
+ void setFavoriteRepository (const Repository *repo); /* 0 to disable restrictions */
+ const Repository *favoriteRepository();
+
+ // Misc
+ Node *getFirstCategory (Package::Type type);
+ Node *getFirstCategory2 (Package::Type type);
+
+ struct Disk {
+ struct Partition {
+ std::string path, used_str, delta_str, free_str, total_str;
+ long long used, delta, total;
+ };
+ const Partition *getPartition (int nb);
+
+ struct Listener {
+ virtual void updateDisk() = 0;
+ };
+ void addListener (Listener *listener);
+
+ Disk();
+ ~Disk();
+ struct Impl;
+ Impl *impl;
+ };
+ Disk *getDisk();
+
+ bool isModified(); // any change made?
+
+ bool importList (const char *filename);
+ bool exportList (const char *filename);
+ bool createSolverTestcase (const char *dirname);
+
+ Ypp();
+ ~Ypp();
+ struct Impl;
+ Impl *impl;
+};
+
+#endif /*ZYPP_WRAPPER_H*/
+
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/660f918b95fb16b6bf617ac05c9637e3.jpg?s=120&d=mm&r=g)
[yast-commit] r59805 - in /trunk/gtk/src: ygtktooltip.c ygtktooltip.h
by rpmcruz@svn.opensuse.org 26 Nov '09
by rpmcruz@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: rpmcruz
Date: Thu Nov 26 18:15:15 2009
New Revision: 59805
URL: http://svn.opensuse.org/viewcvs/yast?rev=59805&view=rev
Log:
* Reverted to development state.
Removed:
trunk/gtk/src/ygtktooltip.c
trunk/gtk/src/ygtktooltip.h
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
Author: rpmcruz
Date: Thu Nov 26 18:14:14 2009
New Revision: 59804
URL: http://svn.opensuse.org/viewcvs/yast?rev=59804&view=rev
Log:
* Reverted to development state.
Added:
trunk/gtk/src/CMakeLists.txt
Removed:
trunk/gtk/src/YGPackageSelector.cc
trunk/gtk/src/ygtkhandlebox.c
trunk/gtk/src/ygtkhandlebox.h
trunk/gtk/src/ygtknotebook.c
trunk/gtk/src/ygtknotebook.h
trunk/gtk/src/ygtktogglebutton.c
trunk/gtk/src/ygtktogglebutton.h
trunk/gtk/src/ygtktreemodel.cc
trunk/gtk/src/ygtktreemodel.h
trunk/gtk/src/ygtkzyppview.cc
trunk/gtk/src/ygtkzyppview.h
trunk/gtk/src/ygtkzyppwrapper.cc
trunk/gtk/src/ygtkzyppwrapper.h
trunk/gtk/src/yzypptags.cc
trunk/gtk/src/yzypptags.h
trunk/gtk/src/yzyppwrapper.cc
trunk/gtk/src/yzyppwrapper.h
Modified:
trunk/gtk/src/YGComboBox.cc
trunk/gtk/src/YGDialog.cc
trunk/gtk/src/YGDumbTab.cc
trunk/gtk/src/YGFrame.cc
trunk/gtk/src/YGImage.cc
trunk/gtk/src/YGInputField.cc
trunk/gtk/src/YGIntField.cc
trunk/gtk/src/YGLabel.cc
trunk/gtk/src/YGLayout.cc
trunk/gtk/src/YGMenuButton.cc
trunk/gtk/src/YGProgressBar.cc
trunk/gtk/src/YGPushButton.cc
trunk/gtk/src/YGRadioButton.cc
trunk/gtk/src/YGSelectionModel.cc
trunk/gtk/src/YGTable.cc
trunk/gtk/src/YGText.cc
trunk/gtk/src/YGUI.cc
trunk/gtk/src/YGUI.h
trunk/gtk/src/YGUtils.cc
trunk/gtk/src/YGWidget.cc
trunk/gtk/src/YGWizard.cc
trunk/gtk/src/YGi18n.h
trunk/gtk/src/test.cc
trunk/gtk/src/ygtkbargraph.c
trunk/gtk/src/ygtkbargraph.h
trunk/gtk/src/ygtkcellrenderertextpixbuf.c
trunk/gtk/src/ygtkcellrenderertextpixbuf.h
trunk/gtk/src/ygtkfindentry.c
trunk/gtk/src/ygtkfindentry.h
trunk/gtk/src/ygtkhtmlwrap.c
trunk/gtk/src/ygtkhtmlwrap.h
trunk/gtk/src/ygtkratiobox.c
trunk/gtk/src/ygtkrichtext.c
trunk/gtk/src/ygtkrichtext.h
trunk/gtk/src/ygtkscrolledwindow.h
trunk/gtk/src/ygtksteps.c
trunk/gtk/src/ygtksteps.h
trunk/gtk/src/ygtktextview.c
trunk/gtk/src/ygtktreeview.c
trunk/gtk/src/ygtkwizard.c
trunk/gtk/src/ygtkwizard.h
Added: trunk/gtk/src/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/CMakeLists.txt?rev=59804…
==============================================================================
--- trunk/gtk/src/CMakeLists.txt (added)
+++ trunk/gtk/src/CMakeLists.txt Thu Nov 26 18:14:14 2009
@@ -0,0 +1,96 @@
+## Makefile.am
+
+set (gtk_yast_plugin_SRCS
+ YGBarGraph.cc
+ YGComboBox.cc
+ YGDialog.cc
+ YGDumbTab.cc
+ YGFrame.cc
+ YGInputField.cc
+ YGIntField.cc
+ YGImage.cc
+ YGMenuButton.cc
+ YGLabel.cc
+ YGLayout.cc
+ YGPackageSelectorPluginStub.cc
+ YGPushButton.cc
+ YGProgressBar.cc
+ YGRadioButton.cc
+ YGSelectionModel.cc
+ YGTable.cc
+ YGText.cc
+ YGUtils.cc
+ YGUI.cc
+ YGWidget.cc
+ YGWizard.cc
+ ygdkmngloader.c
+ ygtkcellrenderertextpixbuf.c
+ ygtkbargraph.c
+ ygtkfieldentry.c
+ ygtkhtmlwrap.c
+ ygtkmenubutton.c
+ ygtklinklabel.c
+ ygtkfindentry.c
+ ygtkfixed.c
+ ygtkimage.c
+ ygtkratiobox.c
+ ygtkrichtext.c
+ ygtksteps.c
+ ygtktextview.c
+ ygtktimezonepicker.c
+ ygtktreeview.c
+ ygtkwizard.c
+ )
+
+# if you tell cmake to install the icons/ directory
+# it will make room for the .svn dir as well...
+set (gtk_yast_plugin_DATA
+ icons/harddisk.png
+ icons/harddisk-full.png
+ icons/pkg-available.png
+ icons/pkg-available-locked.png
+ icons/pkg-installed.png
+ icons/pkg-install.png
+ icons/pkg-install-auto.png
+ icons/pkg-installed-locked.png
+ icons/pkg-installed-upgradable.png
+ icons/pkg-installed-upgradable-locked.png
+ icons/pkg-remove.png
+ icons/pkg-remove-auto.png
+ icons/pkg-locked.png
+ icons/pkg-unlocked.png
+ icons/pkg-upgrade.png
+ )
+
+## includes:
+
+include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+include_directories (${GTK2_INCLUDE_DIRS})
+include_directories (${LIBYUI_INCLUDE_DIR})
+
+## target:
+
+add_library (py2gtk SHARED ${gtk_yast_plugin_SRCS})
+
+## libraries:
+
+target_link_libraries (py2gtk ${GTK2_LIBRARIES})
+target_link_libraries (py2gtk ${LIBYUI_LIBRARY})
+set_target_properties (py2gtk PROPERTIES SOVERSION 2)
+set_target_properties (py2gtk PROPERTIES LINK_FLAGS "--no-undefined")
+
+## install:
+
+install (TARGETS py2gtk LIBRARY DESTINATION ${UI_PLUGIN_DIR})
+install (FILES ${gtk_yast_plugin_DATA} DESTINATION ${DATADIR})
+
+add_subdirectory (pkg)
+
+## test:
+
+link_directories (${CMAKE_BINARY_DIR}/src)
+add_executable (test test.cc)
+target_link_libraries (test libpy2gtk.so)
+target_link_libraries (test ${GTK2_LIBRARIES})
+target_link_libraries (test ${LIBYUI_LIBRARY})
+
Modified: trunk/gtk/src/YGComboBox.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGComboBox.cc?rev=59804&…
==============================================================================
--- trunk/gtk/src/YGComboBox.cc (original)
+++ trunk/gtk/src/YGComboBox.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include <YGUI.h>
#include "YGUtils.h"
#include "YComboBox.h"
Modified: trunk/gtk/src/YGDialog.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGDialog.cc?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/YGDialog.cc (original)
+++ trunk/gtk/src/YGDialog.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include "YGUI.h"
#include "YGDialog.h"
#include "YGUtils.h"
@@ -22,8 +23,8 @@
be a YGDialog and is swap-able.
*/
-#define DEFAULT_WIDTH 650
-#define DEFAULT_HEIGHT 600
+#define DEFAULT_WIDTH 700
+#define DEFAULT_HEIGHT 650
class YGWindow;
static YGWindow *main_window = 0;
@@ -36,6 +37,7 @@
// (ie. dump yast tree)
YWidget *m_child;
GdkCursor *m_busyCursor;
+ bool m_isBusy;
public:
YGWindowCloseFn m_canClose;
@@ -51,6 +53,7 @@
m_child = NULL;
m_canClose = NULL;
m_busyCursor = NULL;
+ m_isBusy = false;
{
std::stack<YDialog *> &stack = YDialog::_dialogStack;
@@ -90,7 +93,13 @@
}
if (_main_window) {
- gtk_window_set_default_size (window, DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;
+ if (YGUI::ui()->defaultWidth())
+ width = YGUI::ui()->defaultWidth();
+ if (YGUI::ui()->defaultHeight())
+ height = YGUI::ui()->defaultHeight();
+
+ gtk_window_set_default_size (window, width, height);
if (YGUI::ui()->setFullscreen())
gtk_window_fullscreen (window);
else if (YUI::app()->displayWidth() <= 800 || YUI::app()->displayHeight() <= 600)
@@ -115,7 +124,6 @@
~YGWindow()
{
- IMPL
setChild (NULL);
if (m_busyCursor)
gdk_cursor_unref (m_busyCursor);
@@ -128,23 +136,26 @@
void normalCursor()
{
- gdk_window_set_cursor (m_widget->window, NULL);
+ if (m_isBusy)
+ gdk_window_set_cursor (m_widget->window, NULL);
+ m_isBusy = false;
}
void busyCursor()
{
- GdkDisplay *display = gtk_widget_get_display (m_widget);
if (!m_busyCursor) {
+ GdkDisplay *display = gtk_widget_get_display (m_widget);
m_busyCursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_cursor_ref (m_busyCursor);
}
- gdk_window_set_cursor (m_widget->window, m_busyCursor);
+ if (!m_isBusy)
+ gdk_window_set_cursor (m_widget->window, m_busyCursor);
+ m_isBusy = true;
}
void setChild (YWidget *new_child)
{
- IMPL
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget));
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget));
if (child)
gtk_container_remove (GTK_CONTAINER (m_widget), child);
if (new_child) {
@@ -183,7 +194,6 @@
static gboolean 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->close();
@@ -193,7 +203,6 @@
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) {
@@ -438,7 +447,7 @@
cairo_t *cr = gdk_cairo_create (widget->window);
cairo_rectangle (cr, x, y, w, h);
- cairo_set_source_rgb (cr, (0xff/255.0), (0x88)/255.0, 0);
+ cairo_set_source_rgb (cr, 0xff/255.0, 0x88/255.0, 0);
cairo_fill (cr);
cairo_destroy (cr);
return FALSE;
@@ -563,10 +572,7 @@
}
YDialog *YGWidgetFactory::createDialog (YDialogType dialogType, YDialogColorMode colorMode)
-{
- IMPL
- return new YGDialog (dialogType, colorMode);
-}
+{ return new YGDialog (dialogType, colorMode); }
YEvent *YGDialog::waitForEventInternal (int timeout_millisec)
{ return YGUI::ui()->waitInput (timeout_millisec, true); }
Modified: trunk/gtk/src/YGDumbTab.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGDumbTab.cc?rev=59804&r…
==============================================================================
--- trunk/gtk/src/YGDumbTab.cc (original)
+++ trunk/gtk/src/YGDumbTab.cc Thu Nov 26 18:14:14 2009
@@ -2,8 +2,9 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGWidget.h"
#include "YGUtils.h"
#include "YDumbTab.h"
@@ -20,10 +21,9 @@
: YDumbTab (NULL),
YGWidget (this, parent, GTK_TYPE_NOTEBOOK, NULL)
{
- IMPL
m_containee = gtk_event_box_new();
- gtk_widget_show (m_containee);
g_object_ref_sink (G_OBJECT (m_containee));
+ gtk_widget_show (m_containee);
m_last_tab = 0;
// GTK+ keeps the notebook size set to the biggset page. We can't
@@ -34,9 +34,8 @@
connect (getWidget(), "switch-page", G_CALLBACK (changed_tab_cb), this);
}
- ~YGDumbTab()
+ virtual ~YGDumbTab()
{
- IMPL
gtk_widget_destroy (m_containee);
g_object_unref (G_OBJECT (m_containee));
}
@@ -84,11 +83,11 @@
virtual void deleteAllItems()
{
- YDumbTab::deleteAllItems();
GList *children = gtk_container_get_children (GTK_CONTAINER (getWidget()));
for (GList *i = children; i; i = i->next)
gtk_container_remove (GTK_CONTAINER (getWidget()), (GtkWidget *) i->data);
g_list_free (children);
+ YDumbTab::deleteAllItems();
}
// to re-use the same widget in all tabs (m_fixed), we will remove and
@@ -100,15 +99,12 @@
GtkNotebook *notebook = GTK_NOTEBOOK (getWidget());
int nb = gtk_notebook_get_current_page (notebook);
- GtkWidget *tab = gtk_notebook_get_nth_page (notebook, nb);
-
- gtk_container_add (GTK_CONTAINER (tab), m_containee);
- m_last_tab = tab;
+ m_last_tab = gtk_notebook_get_nth_page (notebook, nb);
+ gtk_container_add (GTK_CONTAINER (m_last_tab), m_containee);
}
virtual YItem *selectedItem()
{
- IMPL
GtkNotebook *notebook = GTK_NOTEBOOK (getWidget());
int nb = gtk_notebook_get_current_page (notebook);
if (nb < 0) return NULL;
@@ -126,6 +122,7 @@
gtk_notebook_set_current_page (GTK_NOTEBOOK (getWidget()), page);
syncTabPage();
}
+ YDumbTab::selectItem (item, selected);
}
virtual void shortcutChanged()
@@ -150,6 +147,7 @@
GtkWidget *child = gtk_notebook_get_nth_page (notebook, tab_nb);
YItem *item = (YItem *) g_object_get_data (G_OBJECT (child), "yitem");
+ pThis->YDumbTab::selectItem (item);
YGUI::ui()->sendEvent (new YMenuEvent (item));
pThis->syncTabPage();
}
@@ -158,8 +156,5 @@
};
YDumbTab *YGOptionalWidgetFactory::createDumbTab (YWidget *parent)
-{
- IMPL
- return new YGDumbTab (parent);
-}
+{ return new YGDumbTab (parent); }
Modified: trunk/gtk/src/YGFrame.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGFrame.cc?rev=59804&r1=…
==============================================================================
--- trunk/gtk/src/YGFrame.cc (original)
+++ trunk/gtk/src/YGFrame.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include "YGUI.h"
#include "YGWidget.h"
#include "YGUtils.h"
@@ -20,9 +21,8 @@
public:
YGBaseFrame (YWidget *ywidget, YWidget *parent)
: YGWidget (ywidget, parent,
- GTK_TYPE_FRAME, "shadow-type", GTK_SHADOW_NONE, NULL)
+ 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, CHILD_INDENTATION, 0);
@@ -87,10 +87,8 @@
}
// YFrame
-
virtual void setLabel (const string &_str)
{
- IMPL
GtkWidget *label = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
string str (YGUtils::mapKBAccel (_str));
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), str.c_str());
@@ -100,17 +98,13 @@
YGWIDGET_IMPL_CONTAINER (YFrame)
// YGWidget
-
virtual string getDebugLabel() const
{ return label(); }
};
YFrame *YGWidgetFactory::createFrame (YWidget *parent, const string &label)
-{
- IMPL
- return new YGFrame (parent, label);
-}
+{ return new YGFrame (parent, label); }
#include "YCheckBoxFrame.h"
@@ -121,7 +115,6 @@
: YCheckBoxFrame (NULL, label, checked),
YGBaseFrame (this, parent)
{
- IMPL
GtkWidget *button = gtk_check_button_new_with_mnemonic("");
YGUtils::setWidgetFont (gtk_bin_get_child (GTK_BIN (button)), PANGO_STYLE_NORMAL,
PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
@@ -134,7 +127,6 @@
}
// YCheckBoxFrame
-
virtual void setLabel (const string &_str)
{
GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
@@ -159,7 +151,6 @@
}
// YGWidget
-
virtual void doSetEnabled (bool enabled)
{
GtkWidget *frame = getWidget();
@@ -185,10 +176,7 @@
}
};
-YCheckBoxFrame *YGWidgetFactory::createCheckBoxFrame (YWidget *parent, const string &label,
- bool checked)
-{
- IMPL
- return new YGCheckBoxFrame (parent, label, checked);
-}
+YCheckBoxFrame *YGWidgetFactory::createCheckBoxFrame (
+ YWidget *parent, const string &label, bool checked)
+{ return new YGCheckBoxFrame (parent, label, checked); }
Modified: trunk/gtk/src/YGImage.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGImage.cc?rev=59804&r1=…
==============================================================================
--- trunk/gtk/src/YGImage.cc (original)
+++ trunk/gtk/src/YGImage.cc Thu Nov 26 18:14:14 2009
@@ -2,15 +2,16 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
+#define YUILogComponent "gtk"
+#include "config.h"
#include "ygdkmngloader.h"
-#include <config.h>
#include "YGUI.h"
#include "YGWidget.h"
#include "YImage.h"
#include "ygtkimage.h"
#include <string.h>
-static bool endsWith (const std::string &str1, const char *str2)
+static inline bool endsWith (const std::string &str1, const char *str2)
{
size_t len = strlen (str2);
if (str1.size() < len) return false;
@@ -24,7 +25,6 @@
: YImage (NULL, filename, animated),
YGWidget (this, parent, YGTK_TYPE_IMAGE, NULL)
{
- IMPL
YGtkImage *image = YGTK_IMAGE (getWidget());
const char *stock = NULL;
if (endsWith (filename, "/msg_question.png"))
@@ -55,7 +55,5 @@
};
YImage *YGWidgetFactory::createImage (YWidget *parent, const string &filename, bool animated)
-{
- return new YGImage (parent, filename, animated);
-}
+{ return new YGImage (parent, filename, animated); }
Modified: trunk/gtk/src/YGInputField.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGInputField.cc?rev=5980…
==============================================================================
--- trunk/gtk/src/YGInputField.cc (original)
+++ trunk/gtk/src/YGInputField.cc Thu Nov 26 18:14:14 2009
@@ -2,8 +2,9 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGWidget.h"
#include "YGUtils.h"
#include "ygtkfieldentry.h"
@@ -95,7 +96,6 @@
YGLabeledWidget (this, parent, label, YD_HORIZ,
YGTK_TYPE_FIELD_ENTRY, NULL)
{
- IMPL
YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
ygtk_field_entry_add_field (field, ':');
ygtk_field_entry_add_field (field, ':');
@@ -120,7 +120,6 @@
virtual string value()
{
- IMPL
const gchar *hours, *mins;
YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget());
hours = ygtk_field_entry_get_field_text (entry, 0);
@@ -141,10 +140,7 @@
};
YTimeField *YGOptionalWidgetFactory::createTimeField (YWidget *parent, const string &label)
-{
- IMPL
- return new YGTimeField (parent, label);
-}
+{ return new YGTimeField (parent, label); }
#include "YDateField.h"
#include "ygtkmenubutton.h"
@@ -158,7 +154,6 @@
: YDateField (NULL, label),
YGLabeledWidget (this, parent, label, YD_HORIZ, YGTK_TYPE_FIELD_ENTRY, NULL)
{
- IMPL
ygtk_field_entry_add_field (getField(), '-');
ygtk_field_entry_add_field (getField(), '-');
ygtk_field_entry_add_field (getField(), '-');
@@ -204,7 +199,6 @@
virtual string value()
{
- IMPL
const gchar *year, *month, *day;
year = ygtk_field_entry_get_field_text (getField(), 0);
month = ygtk_field_entry_get_field_text (getField(), 1);
@@ -280,10 +274,7 @@
};
YDateField *YGOptionalWidgetFactory::createDateField (YWidget *parent, const string &label)
-{
- IMPL
- return new YGDateField (parent, label);
-}
+{ return new YGDateField (parent, label); }
#include "YTimezoneSelector.h"
#include "ygtktimezonepicker.h"
@@ -296,7 +287,6 @@
: YTimezoneSelector (NULL, pixmap, timezones),
YGWidget (this, parent, YGTK_TYPE_TIME_ZONE_PICKER, NULL)
{
- IMPL
setStretchable (YD_HORIZ, true);
setStretchable (YD_VERT, true);
ygtk_time_zone_picker_set_map (YGTK_TIME_ZONE_PICKER (getWidget()),
@@ -345,7 +335,5 @@
YTimezoneSelector *YGOptionalWidgetFactory::createTimezoneSelector (YWidget *parent,
const std::string &pixmap, const std::map <std::string, std::string> &timezones)
-{
- return new YGTimezoneSelector (parent, pixmap, timezones);
-}
+{ return new YGTimezoneSelector (parent, pixmap, timezones); }
Modified: trunk/gtk/src/YGIntField.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGIntField.cc?rev=59804&…
==============================================================================
--- trunk/gtk/src/YGIntField.cc (original)
+++ trunk/gtk/src/YGIntField.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,7 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
#include "YGUI.h"
#include "YGUtils.h"
#include "YGWidget.h"
@@ -114,9 +114,7 @@
YIntField *YGWidgetFactory::createIntField (YWidget *parent, const string &label,
int minValue, int maxValue, int initialValue)
-{
- return new YGIntField (parent, label, minValue, maxValue, initialValue);
-}
+{ return new YGIntField (parent, label, minValue, maxValue, initialValue); }
#include "YSlider.h"
@@ -138,8 +136,5 @@
YSlider *YGOptionalWidgetFactory::createSlider (YWidget *parent, const string &label,
int minValue, int maxValue, int initialValue)
-{
- IMPL
- return new YGSlider (parent, label, minValue, maxValue, initialValue);
-}
+{ return new YGSlider (parent, label, minValue, maxValue, initialValue); }
Modified: trunk/gtk/src/YGLabel.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGLabel.cc?rev=59804&r1=…
==============================================================================
--- trunk/gtk/src/YGLabel.cc (original)
+++ trunk/gtk/src/YGLabel.cc Thu Nov 26 18:14:14 2009
@@ -2,35 +2,33 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "YGUI.h"
#include "YGUtils.h"
#include "YGWidget.h"
-
#include "YLabel.h"
class YGLabel : public YLabel, public YGWidget
{
public:
- YGLabel (YWidget *parent, const string &text, bool heading, bool outputField)
- : YLabel (NULL, text, heading, outputField),
- YGWidget (this, parent, GTK_TYPE_LABEL, NULL)
+ YGLabel (YWidget *parent, const std::string &text, bool heading, bool outputField)
+ : YLabel (NULL, text, heading, outputField),
+ YGWidget (this, parent, GTK_TYPE_LABEL, NULL)
{
- IMPL
gtk_misc_set_alignment (GTK_MISC (getWidget()), 0.0, 0.5);
if (outputField) {
gtk_label_set_selectable (GTK_LABEL (getWidget()), TRUE);
gtk_label_set_single_line_mode (GTK_LABEL (getWidget()), TRUE);
YGUtils::setWidgetFont (getWidget(), PANGO_STYLE_ITALIC, PANGO_WEIGHT_NORMAL,
- PANGO_SCALE_MEDIUM);
+ PANGO_SCALE_MEDIUM);
}
if (heading)
YGUtils::setWidgetFont (getWidget(), PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD,
- PANGO_SCALE_LARGE);
+ PANGO_SCALE_LARGE);
setLabel (text);
}
- virtual void setText (const string &label)
+ virtual void setText (const std::string &label)
{
YLabel::setText (label);
gtk_label_set_label (GTK_LABEL (getWidget()), label.c_str());
@@ -51,9 +49,7 @@
YGWIDGET_IMPL_USE_BOLD (YLabel)
};
-YLabel *YGWidgetFactory::createLabel (YWidget *parent, const string &text, bool heading,
- bool outputField)
-{
- return new YGLabel (parent, text, heading, outputField);
-}
+YLabel *YGWidgetFactory::createLabel (YWidget *parent,
+ const std::string &text, bool heading, bool outputField)
+{ return new YGLabel (parent, text, heading, outputField); }
Modified: trunk/gtk/src/YGLayout.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGLayout.cc?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/YGLayout.cc (original)
+++ trunk/gtk/src/YGLayout.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include "YGWidget.h"
#include "YGUtils.h"
@@ -86,10 +87,7 @@
};
YLayoutBox *YGWidgetFactory::createLayoutBox (YWidget *parent, YUIDimension dimension)
-{
- IMPL
- return new YGLayoutBox (parent, dimension);
-}
+{ return new YGLayoutBox (parent, dimension); }
#if YAST2_VERSION >= 2017006
#include <YButtonBox.h>
@@ -121,10 +119,7 @@
};
YButtonBox *YGWidgetFactory::createButtonBox (YWidget *parent)
-{
- IMPL
- return new YGButtonBox (parent);
-}
+{ return new YGButtonBox (parent); }
#endif
@@ -154,11 +149,11 @@
YGLAYOUT_PREFERRED_SIZE_IMPL (YAlignment)
YGLAYOUT_SET_SIZE_IMPL (YAlignment)
- virtual void setBackgroundPixmap (string filename)
+ virtual void setBackgroundPixmap (const std::string &_filename)
{
+ YAlignment::setBackgroundPixmap (_filename);
// YAlignment will prepend a path to the image
- YAlignment::setBackgroundPixmap (filename);
- filename = YAlignment::backgroundPixmap();
+ std::string filename (YAlignment::backgroundPixmap());
if (m_background_pixbuf)
g_object_unref (G_OBJECT (m_background_pixbuf));
@@ -202,10 +197,7 @@
YAlignment *YGWidgetFactory::createAlignment (YWidget *parent, YAlignmentType halign,
YAlignmentType valign)
-{
- IMPL
- return new YGAlignment (parent, halign, valign);
-}
+{ return new YGAlignment (parent, halign, valign); }
#include <YEmpty.h>
@@ -224,10 +216,7 @@
};
YEmpty *YGWidgetFactory::createEmpty (YWidget *parent)
-{
- IMPL
- return new YGEmpty (parent);
-}
+{ return new YGEmpty (parent); }
#include <YSpacing.h>
@@ -272,9 +261,7 @@
};
YReplacePoint *YGWidgetFactory::createReplacePoint (YWidget *parent)
-{
- return new YGReplacePoint (parent);
-}
+{ return new YGReplacePoint (parent); }
#include <YSquash.h>
@@ -294,8 +281,5 @@
};
YSquash *YGWidgetFactory::createSquash (YWidget *parent, bool hsquash, bool vsquash)
-{
- IMPL
- return new YGSquash (parent, hsquash, vsquash);
-}
+{ return new YGSquash (parent, hsquash, vsquash); }
Modified: trunk/gtk/src/YGMenuButton.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGMenuButton.cc?rev=5980…
==============================================================================
--- trunk/gtk/src/YGMenuButton.cc (original)
+++ trunk/gtk/src/YGMenuButton.cc Thu Nov 26 18:14:14 2009
@@ -2,13 +2,53 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGUtils.h"
#include "YGWidget.h"
#include "YMenuButton.h"
#include "ygtkmenubutton.h"
+static void selected_item_cb (GtkMenuItem *menuitem, YItem *item)
+{
+ YGUI::ui()->sendEvent (new YMenuEvent (item));
+}
+
+static void doCreateMenu (GtkWidget *parent, YItemIterator begin, YItemIterator end)
+{
+ for (YItemIterator it = begin; it != end; it++) {
+ GtkWidget *entry, *image = 0;
+ string str = YGUtils::mapKBAccel ((*it)->label());
+
+ if ((*it)->hasIconName()) {
+ GdkPixbuf *pixbuf = YGUtils::loadPixbuf ((*it)->iconName());
+ if (pixbuf) {
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+
+ if (image) {
+ entry = gtk_image_menu_item_new_with_mnemonic (str.c_str());
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (entry), image);
+ }
+ else
+ entry = gtk_menu_item_new_with_mnemonic (str.c_str());
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (parent), entry);
+
+ if ((*it)->hasChildren()) {
+ GtkWidget *submenu = gtk_menu_new();
+ doCreateMenu (submenu, (*it)->childrenBegin(), (*it)->childrenEnd());
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry), submenu);
+ }
+ else
+ g_signal_connect (G_OBJECT (entry), "activate",
+ G_CALLBACK (selected_item_cb), *it);
+ }
+}
+
class YGMenuButton : public YMenuButton, public YGWidget
{
public:
@@ -16,7 +56,6 @@
: YMenuButton (NULL, label),
YGWidget (this, parent, YGTK_TYPE_MENU_BUTTON, NULL)
{
- IMPL
string str = YGUtils::mapKBAccel (label.c_str());
ygtk_menu_button_set_label (YGTK_MENU_BUTTON (getWidget()), str.c_str());
}
@@ -24,56 +63,52 @@
// YMenuButton
virtual void rebuildMenuTree()
{
- GtkWidget *menu = doCreateMenu (itemsBegin(), itemsEnd());
+ GtkWidget *menu = gtk_menu_new();
+ doCreateMenu (menu, itemsBegin(), itemsEnd());
gtk_widget_show_all (menu);
ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (getWidget()), menu);
}
- static GtkWidget* doCreateMenu (YItemIterator begin, YItemIterator end)
- {
- GtkWidget *menu = gtk_menu_new();
- for (YItemIterator it = begin; it != end; it++) {
- GtkWidget *entry, *image = 0;
- string str = YGUtils::mapKBAccel ((*it)->label());
-
- if ((*it)->hasIconName()) {
- GdkPixbuf *pixbuf = YGUtils::loadPixbuf ((*it)->iconName());
- if (pixbuf) {
- image = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
-
- if (image) {
- entry = gtk_image_menu_item_new_with_mnemonic (str.c_str());
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (entry), image);
- }
- else
- entry = gtk_menu_item_new_with_mnemonic (str.c_str());
+ YGWIDGET_IMPL_COMMON (YMenuButton)
+};
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
+YMenuButton *YGWidgetFactory::createMenuButton (YWidget *parent, const string &label)
+{ return new YGMenuButton (parent, label); }
- if ((*it)->hasChildren())
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry),
- doCreateMenu ((*it)->childrenBegin(), (*it)->childrenEnd()));
- else
- g_signal_connect (G_OBJECT (entry), "activate",
- G_CALLBACK (selected_item_cb), *it);
- }
+#if YAST2_VERSION > 2018003
+#include <YContextMenu.h>
- return menu;
+class YGContextMenu : public YContextMenu, public YGWidget
+{
+public:
+ YGContextMenu()
+ : YContextMenu(),
+ YGWidget (this, NULL, GTK_TYPE_MENU, NULL)
+ {
+ connect (getWidget(), "cancel", G_CALLBACK (cancel_cb), this);
}
- static void selected_item_cb (GtkMenuItem *menuitem, YItem *item)
+ // YContextMenu
+ virtual void rebuildMenuTree()
{
- YGUI::ui()->sendEvent (new YMenuEvent (item));
+ GtkWidget *menu = getWidget();
+ doCreateMenu (menu, itemsBegin(), itemsEnd());
+ gtk_widget_show_all (menu);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
}
- YGWIDGET_IMPL_COMMON (YMenuButton)
+ // callbacks
+ static void cancel_cb (GtkMenuShell *menu, YGContextMenu *pThis)
+ { YGUI::ui()->sendEvent (new YCancelEvent()); }
+
+ YGWIDGET_IMPL_COMMON (YContextMenu)
};
-YMenuButton *YGWidgetFactory::createMenuButton (YWidget *parent, const string &label)
+bool YGApplication::openContextMenu (const YItemCollection &itemCollection)
{
- return new YGMenuButton (parent, label);
+ YGContextMenu *menu = new YGContextMenu();
+ menu->addItems (itemCollection);
+ return true;
}
+#endif
Modified: trunk/gtk/src/YGProgressBar.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGProgressBar.cc?rev=598…
==============================================================================
--- trunk/gtk/src/YGProgressBar.cc (original)
+++ trunk/gtk/src/YGProgressBar.cc Thu Nov 26 18:14:14 2009
@@ -6,8 +6,9 @@
Textdomain "yast2-gtk"
*/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGWidget.h"
#include "YGi18n.h"
@@ -51,7 +52,6 @@
// YProgressBar
virtual void setValue (int value)
{
- IMPL
YProgressBar::setValue (value);
GtkProgressBar *bar = GTK_PROGRESS_BAR (getWidget());
float fraction = CLAMP ((float) value / maxValue(), 0, 1);
@@ -121,10 +121,7 @@
YDownloadProgress *YGOptionalWidgetFactory::createDownloadProgress (YWidget *parent,
const string &label, const string &filename, YFileSize_t expectedFileSize)
-{
- IMPL
- return new YGDownloadProgress (parent, label, filename, expectedFileSize);
-}
+{ return new YGDownloadProgress (parent, label, filename, expectedFileSize); }
#include "ygtkratiobox.h"
#include "YMultiProgressMeter.h"
@@ -187,9 +184,7 @@
YMultiProgressMeter *YGOptionalWidgetFactory::createMultiProgressMeter (YWidget *parent,
YUIDimension dim, const vector <float> &maxValues)
-{
- return new YGMultiProgressMeter (parent, dim, maxValues);
-}
+{ return new YGMultiProgressMeter (parent, dim, maxValues); }
#include "YBusyIndicator.h"
@@ -258,8 +253,5 @@
};
YBusyIndicator *YGWidgetFactory::createBusyIndicator (YWidget *parent, const string &label, int timeout)
-{
- IMPL
- return new YGBusyIndicator (parent, label, timeout);
-}
+{ return new YGBusyIndicator (parent, label, timeout); }
Modified: trunk/gtk/src/YGPushButton.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGPushButton.cc?rev=5980…
==============================================================================
--- trunk/gtk/src/YGPushButton.cc (original)
+++ trunk/gtk/src/YGPushButton.cc Thu Nov 26 18:14:14 2009
@@ -2,8 +2,9 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include <YPushButton.h>
#include "YGUtils.h"
#include "YGWidget.h"
@@ -19,12 +20,10 @@
: YPushButton (NULL, label),
YGWidget (this, parent, GTK_TYPE_BUTTON, "can-default", TRUE, NULL)
{
- IMPL
m_customIcon = m_labelIcon = false;
gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE);
setLabel (label);
connect (getWidget(), "clicked", G_CALLBACK (clicked_cb), this);
- g_signal_connect (G_OBJECT (getWidget()), "expose-event", G_CALLBACK (treat_icon_cb), this);
}
void setStockIcon (const std::string &label)
@@ -41,7 +40,7 @@
case 7: stock = GTK_STOCK_PREFERENCES; break; // Expert
case 8: stock = GTK_STOCK_GO_BACK; break;
case 9: stock = GTK_STOCK_CANCEL; break;
-// case 10: stock = GTK_STOCK_GO_FORWARD; break;
+ case 10: stock = GTK_STOCK_OK; break; // Next/Finish/OK
default: break;
}
#if YAST2_VERSION >= 2017006
@@ -60,7 +59,6 @@
// YPushButton
virtual void setLabel (const string &label)
{
- IMPL
YPushButton::setLabel (label);
string str = YGUtils::mapKBAccel (label);
gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str());
@@ -92,7 +90,6 @@
virtual void setIcon (const string &icon)
{
- IMPL
GtkButton *button = GTK_BUTTON (getWidget());
if (icon.empty()) {
m_customIcon = false;
@@ -149,7 +146,7 @@
}
return true;
}
-#if 1
+#if 0
static gboolean treat_icon_cb (GtkWidget *widget, GdkEventExpose *event,
YGPushButton *pThis)
{
@@ -201,7 +198,5 @@
};
YPushButton *YGWidgetFactory::createPushButton (YWidget *parent, const string &label)
-{
- return new YGPushButton (parent, label);
-}
+{ return new YGPushButton (parent, label); }
Modified: trunk/gtk/src/YGRadioButton.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGRadioButton.cc?rev=598…
==============================================================================
--- trunk/gtk/src/YGRadioButton.cc (original)
+++ trunk/gtk/src/YGRadioButton.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include "YGUI.h"
#include "YGUtils.h"
#include "YGWidget.h"
@@ -51,7 +52,6 @@
: YRadioButton (NULL, label),
YGWidget (this, parent, getCheckRadioButtonType(), NULL)
{
- IMPL
if (!is_horizontal_box (parent))
setStretchable (YD_HORIZ, true);
setLabel (label);
@@ -66,21 +66,16 @@
{
// 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.c_str());
gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str());
YRadioButton::setLabel (text);
}
virtual bool value()
- {
- IMPL
- return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (getWidget()));
- }
+ { return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (getWidget())); }
virtual void setValue (bool checked)
{
- IMPL
BlockEvents block (this);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), checked);
if (checked) {
@@ -105,7 +100,6 @@
YRadioButton *YGWidgetFactory::createRadioButton (YWidget *parent, const string &label,
bool isChecked)
{
- IMPL
YRadioButton *button = new YGRadioButton (parent, label, isChecked);
// libyui instructs us to do it here due to vfuncs craziness
@@ -145,7 +139,6 @@
: YCheckBox (NULL, label),
YGWidget (this, parent, GTK_TYPE_CHECK_BUTTON, NULL)
{
- IMPL
if (!is_horizontal_box (parent))
setStretchable (YD_HORIZ, true);
setLabel (label);
@@ -158,7 +151,6 @@
// YCheckButton
virtual void setLabel (const string &text)
{
- IMPL
string str = YGUtils::mapKBAccel(text);
gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str());
YCheckBox::setLabel (text);
@@ -166,7 +158,6 @@
virtual YCheckBoxState value()
{
- IMPL
GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget());
if (gtk_toggle_button_get_inconsistent (button))
@@ -176,7 +167,6 @@
virtual void setValue (YCheckBoxState value)
{
- IMPL
BlockEvents block (this);
GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget());
switch (value) {
@@ -208,8 +198,5 @@
YCheckBox *YGWidgetFactory::createCheckBox (YWidget *parent, const string &label,
bool isChecked)
-{
- IMPL
- return new YGCheckBox (parent, label, isChecked);
-}
+{ return new YGCheckBox (parent, label, isChecked); }
Modified: trunk/gtk/src/YGSelectionModel.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGSelectionModel.cc?rev=…
==============================================================================
--- trunk/gtk/src/YGSelectionModel.cc (original)
+++ trunk/gtk/src/YGSelectionModel.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include <gtk/gtk.h>
#include <YTreeItem.h>
#include "YGSelectionModel.h"
Modified: trunk/gtk/src/YGTable.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGTable.cc?rev=59804&r1=…
==============================================================================
--- trunk/gtk/src/YGTable.cc (original)
+++ trunk/gtk/src/YGTable.cc Thu Nov 26 18:14:14 2009
@@ -2,22 +2,22 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGUtils.h"
#include "YGWidget.h"
#include "YSelectionWidget.h"
#include "YGSelectionModel.h"
#include "ygtkcellrenderertextpixbuf.h"
-#include "ygtkscrolledwindow.h"
-#include <time.h>
+#include "ygtktreeview.h"
/* A generic widget for table related widgets. */
class YGTableView : public YGScrolledWidget, public YGSelectionModel
{
protected:
int m_colsNb;
- time_t m_blockTime; // GtkTreeSelection signals act weird
+ guint m_blockTimeout;
public:
YGTableView (YWidget *ywidget, YWidget *parent, const string &label,
@@ -26,8 +26,6 @@
YGTK_TYPE_TREE_VIEW, NULL)
, YGSelectionModel ((YSelectionWidget *) ywidget, ordinaryModel, isTree)
{
- IMPL
- m_blockTime = time (NULL);
if (ordinaryModel) {
appendIconTextColumn ("", YAlignUnchanged, YGSelectionModel::ICON_COLUMN,
YGSelectionModel::LABEL_COLUMN);
@@ -41,6 +39,14 @@
gtk_tree_selection_set_mode (getSelection(), GTK_SELECTION_BROWSE);
// let the derivates do the event hooks. They have subtile differences.
+
+ m_blockTimeout = 0; // GtkTreeSelection idiotically fires when showing widget
+ g_signal_connect (getWidget(), "map", G_CALLBACK (block_init_cb), this);
+ }
+
+ virtual ~YGTableView()
+ {
+ if (m_blockTimeout) g_source_remove (m_blockTimeout);
}
inline GtkTreeView *getView()
@@ -50,7 +56,6 @@
void appendIconTextColumn (string header, YAlignmentType align, int icon_col, int text_col)
{
- IMPL
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
@@ -108,12 +113,24 @@
virtual bool immediateEvent() { return true; }
- // YGSelectionModel
+ static gboolean block_selected_timeout_cb (gpointer data)
+ {
+ YGTableView *pThis = (YGTableView *) data;
+ pThis->m_blockTimeout = 0;
+ return FALSE;
+ }
+ void blockSelected()
+ { // GtkTreeSelection only fires when idle; so set a timeout
+ if (m_blockTimeout) g_source_remove (m_blockTimeout);
+ m_blockTimeout = g_timeout_add_full (G_PRIORITY_LOW, 250, block_selected_timeout_cb, this, NULL);
+ }
+
+ // YGSelectionModel
virtual void doSelectItem (GtkTreeIter *iter)
{
if (!gtk_tree_selection_iter_is_selected (getSelection(), iter)) {
- m_blockTime = time (NULL);
+ blockSelected();
GtkTreePath *path = gtk_tree_model_get_path (getModel(), iter);
gtk_tree_view_expand_to_path (getView(), path);
@@ -128,7 +145,7 @@
virtual void doUnselectAll()
{
if (gtk_tree_selection_count_selected_rows (getSelection())) {
- m_blockTime = time (NULL);
+ blockSelected();
gtk_tree_selection_unselect_all (getSelection());
}
}
@@ -156,10 +173,13 @@
return 80;
}
+ // GTK callbacks
+ static void block_init_cb (GtkWidget *widget, YGTableView *pThis)
+ { pThis->blockSelected(); }
+
// 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;
@@ -174,7 +194,7 @@
static void selection_changed_cb (GtkTreeSelection *selection, YGTableView *pThis)
{
- if (time (NULL) - pThis->m_blockTime <= 2)
+ if (pThis->m_blockTimeout)
return;
if (!pThis->toggleMode()) {
GtkTreeSelection *selection = pThis->getSelection();
@@ -199,12 +219,18 @@
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);
}
+
+#if YAST2_VERSION > 2018003
+ static void right_click_cb (YGtkTreeView *view, gboolean outreach, YGTableView *pThis)
+ {
+ pThis->emitEvent (YEvent::ContextMenuActivated);
+ }
+#endif
};
#include "YTable.h"
@@ -223,7 +249,6 @@
#endif
, YGTableView (this, parent, string(), false, false)
{
- IMPL
gtk_tree_view_set_headers_visible (getView(), TRUE);
gtk_tree_view_set_rules_hint (getView(), columns() > 1);
#if YAST2_VERSION >= 2017005
@@ -250,7 +275,7 @@
connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this);
connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this);
- connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this);
+ connect (getWidget(), "right-click", G_CALLBACK (hack_right_click_cb), this);
connect (getWidget(), "key-press-event", G_CALLBACK (key_press_event_cb), this);
}
@@ -284,7 +309,6 @@
void setSortable (bool sortable)
{
- IMPL
if (!sortable && !GTK_WIDGET_REALIZED (getWidget()))
return;
int n = 0;
@@ -342,8 +366,12 @@
YGUI::ui()->sendEvent (event);
}
- static void right_click_cb (YGtkTreeView *view, gboolean outreach, YGTable *pThis)
+ static void hack_right_click_cb (YGtkTreeView *view, gboolean outreach, YGTable *pThis)
{
+#if YAST2_VERSION > 2018003
+ if (pThis->notifyContextMenu())
+ return YGTableView::right_click_cb (view, outreach, pThis);
+#endif
if (!YGDialog::currentDialog()->getFunctionWidget (5) ||
// undetermined case -- more than one table exists
YGDialog::currentDialog()->getClassWidgets ("YTable").size() > 1) {
@@ -416,6 +444,9 @@
{
connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this);
connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this);
+#endif
}
virtual bool isShrinkable() { return shrinkable(); }
@@ -425,10 +456,7 @@
};
YSelectionBox *YGWidgetFactory::createSelectionBox (YWidget *parent, const string &label)
-{
- IMPL
- return new YGSelectionBox (parent, label);
-}
+{ return new YGSelectionBox (parent, label); }
#include "YMultiSelectionBox.h"
@@ -446,11 +474,15 @@
createModel (types);
appendCheckColumn ("", 0);
appendIconTextColumn ("", YAlignUnchanged, 1, 2);
+ gtk_tree_view_set_search_column (getView(), 2);
setModel();
connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this);
// Let the user toggle, using space/enter or double click (not an event).
connect (getWidget(), "row-activated", G_CALLBACK (multi_activated_cb), this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this);
+#endif
}
// YMultiSelectionBox
@@ -483,7 +515,6 @@
{ pThis->toggle (path, 0); }
// YGSelectionModel
-
virtual void doSelectItem (GtkTreeIter *iter)
{
setCellToggle (iter, 0, true);
@@ -500,18 +531,13 @@
}
// YGWidget
-
virtual bool isShrinkable() { return shrinkable(); }
YGWIDGET_IMPL_COMMON (YMultiSelectionBox)
YGSELECTION_WIDGET_IMPL (YMultiSelectionBox)
};
-YMultiSelectionBox *YGWidgetFactory::createMultiSelectionBox (YWidget *parent,
- const string &label)
-{
- IMPL
- return new YGMultiSelectionBox (parent, label);
-}
+YMultiSelectionBox *YGWidgetFactory::createMultiSelectionBox (YWidget *parent, const string &label)
+{ return new YGMultiSelectionBox (parent, label); }
#include "YTree.h"
#include "YTreeItem.h"
@@ -527,6 +553,9 @@
connect (getWidget(), "row-expanded", G_CALLBACK (row_expanded_cb), this);
connect (getWidget(), "cursor-changed", G_CALLBACK (row_selected_cb), this);
connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this);
+#endif
}
// YTree
@@ -596,7 +625,7 @@
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
pThis->expand (&iter);
- YGTableView::selection_changed_cb (selection, pThis);
+ YGTable::selection_changed_cb (selection, pThis);
}
virtual unsigned int getMinSize (YUIDimension dim)
Modified: trunk/gtk/src/YGText.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGText.cc?rev=59804&r1=5…
==============================================================================
--- trunk/gtk/src/YGText.cc (original)
+++ trunk/gtk/src/YGText.cc Thu Nov 26 18:14:14 2009
@@ -2,8 +2,9 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include <string>
#include "YGUtils.h"
#include "YGWidget.h"
@@ -19,7 +20,6 @@
YGTK_TYPE_TEXT_VIEW, "wrap-mode", GTK_WRAP_WORD_CHAR,
"editable", editable, NULL)
{
- IMPL
setPolicy (GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
maxChars = -1;
connect (getBuffer(), "changed", G_CALLBACK (text_changed_cb), this);
@@ -29,14 +29,10 @@
{ return gtk_text_view_get_buffer (GTK_TEXT_VIEW (getWidget())); }
int getCharsNb()
- {
- IMPL
- return gtk_text_buffer_get_char_count (getBuffer());
- }
+ { return gtk_text_buffer_get_char_count (getBuffer()); }
void setCharsNb (int max_chars)
{
- IMPL
maxChars = max_chars;
if (maxChars != -1 && getCharsNb() > maxChars)
truncateText (maxChars);
@@ -53,19 +49,17 @@
void setText (const string &text)
{
- IMPL
BlockEvents block (this);
gtk_text_buffer_set_text (getBuffer(), text.c_str(), -1);
}
- string getText()
+ std::string 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);
- string str (text);
+ std::string str (text);
g_free (text);
return str;
}
@@ -120,11 +114,6 @@
return 30;
}
- virtual void doSetEnabled (bool enabled)
- {
- gtk_text_view_set_editable(GTK_TEXT_VIEW (getWidget()), enabled);
- }
-
YGLABEL_WIDGET_IMPL (YMultiLineEdit)
};
@@ -144,7 +133,6 @@
{}
// YLogView
-
virtual void displayLogText (const string &text)
{
setText (text);
@@ -152,7 +140,6 @@
}
// YGWidget
-
virtual unsigned int getMinSize (YUIDimension dim)
{
if (dim == YD_VERT) {
@@ -181,9 +168,8 @@
: YRichText (NULL, text, plainText)
, YGScrolledWidget (this, parent, ygtk_html_wrap_get_type(), NULL)
{
- IMPL
ygtk_html_wrap_init (getWidget());
- ygtk_html_wrap_connect_link_clicked (getWidget(), G_CALLBACK (link_clicked_cb), this);
+ ygtk_html_wrap_connect_link_clicked (getWidget(), link_clicked_cb, this);
setText (text, plainText);
}
@@ -236,13 +222,10 @@
}
// callbacks
- static void link_clicked_cb (GtkWidget *widget, const char *url, YGRichText *pThis)
- {
- YGUI::ui()->sendEvent (new YMenuEvent (url));
- }
+ static void link_clicked_cb (GtkWidget *widget, const char *url, gpointer data)
+ { YGUI::ui()->sendEvent (new YMenuEvent (url)); }
// YGWidget
-
virtual unsigned int getMinSize (YUIDimension dim)
{ return shrinkable() ? 10 : 100; }
Modified: trunk/gtk/src/YGUI.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUI.cc?rev=59804&r1=598…
==============================================================================
--- trunk/gtk/src/YGUI.cc (original)
+++ trunk/gtk/src/YGUI.cc Thu Nov 26 18:14:14 2009
@@ -6,7 +6,6 @@
Textdomain "yast2-gtk"
*/
-#include <config.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -34,15 +33,28 @@
#define DEFAULT_MACRO_FILE_NAME "macro.ycp"
#define BUSY_CURSOR_TIMEOUT 250
+YUI *createUI( bool withThreads )
+{
+ static YGUI *ui = 0;
+ if (!ui)
+ ui = new YGUI (withThreads);
+ return ui;
+}
+
YGUI::YGUI (bool with_threads)
: YUI (with_threads), m_done_init (false), busy_timeout (0)
{
- IMPL
m_have_wm = true;
m_no_border = m_fullscreen = false;
+ m_default_width = (m_default_height = 0);
YGUI::setTextdomain( TEXTDOMAIN );
+ // If we're running without threads, initialize Gtk stuff
+ // This enables standalone libyui use Gtk interface
+ if (!with_threads)
+ checkInit();
+
// without this none of the (default) threading action works ...
topmostConstructorHasFinished();
}
@@ -84,7 +96,12 @@
// intern the domain - that can be allocated (or belong to a transient
// plugin's address space).
const char *component = domain ? g_intern_string (domain) : "yast2-gtk";
- YUILog::instance()->log (ylevel, component, "yast2-gtk", 0, "") << message;
+ YUILog::instance()->log (ylevel, component, "yast2-gtk", 0, "") << message << std::endl;
+#if 0 // uncomment to put a stop to gdb
+ static int bugStop = 0;
+ if (bugStop-- <= 0)
+ abort();
+#endif
}
void YGUI::checkInit()
@@ -97,12 +114,11 @@
YCommandLine cmdLine;
int argc = cmdLine.argc();
char **argv = cmdLine.argv();
-
for (int i = 1; i < argc; i++) {
const char *argp = argv[i];
- if (!argp) continue;
if (argp[0] != '-') {
- //printf ("Warning: Unknown argument '%s'\n", argp);
+ if (!strcmp (argp, "sw_single") || !strcmp (argp, "online_update"))
+ YGUI::pkgSelectorSize (&m_default_width, &m_default_height);
continue;
}
argp++;
@@ -116,22 +132,18 @@
m_no_border = true;
else if (!strcmp (argp, "help")) {
printf (
- "Command line options for the YaST2 Gtk UI:\n"
- "\n"
+ "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"
+// "--geometry 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);
-*/
+ else if (pkgSelectorParse (argp)) ;
}
gtk_init (&argc, &argv);
@@ -152,7 +164,6 @@
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
@@ -175,7 +186,6 @@
static gboolean user_input_timeout_cb (YGUI *pThis)
{
- IMPL
if (!pThis->pendingEvent())
pThis->sendEvent (new YTimeoutEvent());
return FALSE;
@@ -184,7 +194,6 @@
// utility that implements both userInput() and pollInput()
YEvent *YGUI::waitInput (unsigned long timeout_ms, bool block)
{
- IMPL
checkInit();
if (!YDialog::currentDialog (false))
return NULL;
@@ -212,8 +221,11 @@
if (timeout)
g_source_remove (timeout);
- if (block) // if YCP keeps working for more than X time, set busy cursor
+ if (block) { // if YCP keeps working for more than X time, set busy cursor
+ if (busy_timeout)
+ g_source_remove (busy_timeout);
busy_timeout = g_timeout_add (BUSY_CURSOR_TIMEOUT, busy_timeout_cb, this);
+ }
return event;
}
@@ -325,14 +337,16 @@
//** YGApplication
+#define ICONDIR THEMEDIR "/icons/22x22/apps/"
+
YGApplication::YGApplication()
{
- setIconBasePath (ICON_DIR);
+ setIconBasePath (ICONDIR);
}
-void YGApplication::makeScreenShot (string filename)
+void YGApplication::makeScreenShot (const std::string &_filename)
{
- IMPL
+ std::string filename (_filename);
bool interactive = filename.empty();
GtkWidget *widget = GTK_WIDGET (YGDialog::currentWindow());
@@ -435,7 +449,6 @@
std::string askForFileOrDirectory (GtkFileChooserAction action,
const std::string &path, const std::string &filter, const std::string &title)
{
- IMPL
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new (title.c_str(),
YGDialog::currentWindow(), action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -499,45 +512,35 @@
std::string YGApplication::askForExistingDirectory (
const std::string &path, const std::string &title)
-{
- IMPL
- return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path,
- "", title);
-}
+{ return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path, "", title); }
std::string YGApplication::askForExistingFile (
const std::string &path, const std::string &filter, const std::string &title)
-{
- IMPL
- return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_OPEN, path, filter, title);
-}
+{ return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_OPEN, path, filter, title); }
std::string YGApplication::askForSaveFileName (
const std::string &path, const std::string &filter, const std::string &title)
-{
- IMPL
- return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SAVE, path, filter, title);
-}
+{ return askForFileOrDirectory (GTK_FILE_CHOOSER_ACTION_SAVE, path, filter, title); }
std::string YGApplication::glyph (const std::string &sym)
{
bool reverse = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
if (sym == YUIGlyph_ArrowLeft)
- return reverse ? "\u2192" : "\u2190";
+ return reverse ? "\u25b6" : "\u25c0";
if (sym == YUIGlyph_ArrowRight)
- return reverse ? "\u2190" : "\u2192";
+ return reverse ? "\u25c0" : "\u25b6";
if (sym == YUIGlyph_ArrowUp)
- return "\u2191";
+ return "\u25b2";
if (sym == YUIGlyph_ArrowDown)
- return "\u2193";
+ return "\u25bc";
if (sym == YUIGlyph_CheckMark)
return "\u2714";
if (sym == YUIGlyph_BulletArrowRight)
return reverse ? "\u21e6" : "\u279c";
if (sym == YUIGlyph_BulletCircle)
- return "\u274d";
+ return "\u26ab";
if (sym == YUIGlyph_BulletSquare)
- return "\u274f";
+ return "\u25fe";
return "";
}
@@ -792,7 +795,6 @@
{ gtk_widget_destroy (GTK_WIDGET (dialog)); }
};
- 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);
Modified: trunk/gtk/src/YGUI.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUI.h?rev=59804&r1=5980…
==============================================================================
--- trunk/gtk/src/YGUI.h (original)
+++ trunk/gtk/src/YGUI.h Thu Nov 26 18:14:14 2009
@@ -5,26 +5,16 @@
#ifndef YGUI_H
#define YGUI_H
-#include <gtk/gtk.h>
-#include <YSimpleEventHandler.h>
-#include <map>
-
+#include "config.h"
+#include <YUI.h>
#define YUILogComponent "gtk"
#include <YUILog.h>
-
-#define ICON_DIR THEMEDIR "/icons/22x22/apps/"
+#include <YSimpleEventHandler.h>
+#include <map>
+#include <gtk/gtk.h>
/* 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_RET(a) { IMPL; return (a); }
-
-#include <YUI.h>
+#define RET(a) { return (a); }
class YGUI: public YUI
{
@@ -40,7 +30,7 @@
virtual YApplication *createApplication();
public:
- static void setTextdomain( const char * domain );
+ static void setTextdomain (const char *domain);
virtual void idleLoop (int fd_ycp);
// called by YDialog::waitInput() / pollEvent()...
@@ -74,12 +64,18 @@
// window-related arguments
bool m_have_wm, m_no_border, m_fullscreen;
+ int m_default_width, m_default_height;
+
+ bool pkgSelectorParse (const char *arg);
+ void pkgSelectorSize (int *width, int *height);
public:
// Helpers for internal use [ visibility hidden ]
bool setFullscreen() const { return m_fullscreen; }
bool hasWM() const { return m_have_wm; }
bool unsetBorder() const { return m_no_border; }
+ int defaultWidth() const { return m_default_width; }
+ int defaultHeight() const { return m_default_height; }
};
// debug helpers.
@@ -117,8 +113,7 @@
virtual YMultiSelectionBox *createMultiSelectionBox (YWidget *parent, const string &label);
virtual YPackageSelector *createPackageSelector (YWidget * parent, long ModeFlags);
- virtual YWidget *createPkgSpecial (YWidget * parent, const string & subwidgetName)
- IMPL_RET (NULL) // for ncurses
+ virtual YWidget *createPkgSpecial (YWidget * parent, const string & subwidgetName) RET (NULL) // for ncurses
virtual YLayoutBox *createLayoutBox (YWidget *parent, YUIDimension dimension);
#if YAST2_VERSION >= 2017006
@@ -142,52 +137,52 @@
class YGOptionalWidgetFactory : public YOptionalWidgetFactory
{
public:
- virtual bool hasWizard() IMPL_RET (true)
+ virtual bool hasWizard() RET (true)
virtual YWizard *createWizard (YWidget *parent, const string &backButtonLabel,
const string &abortButtonLabel, const string &nextButtonLabel,
YWizardMode wizardMode);
- virtual bool hasDumbTab() IMPL_RET (true)
+ virtual bool hasDumbTab() RET (true)
virtual YDumbTab *createDumbTab (YWidget *parent);
- virtual bool hasSlider() IMPL_RET (true)
+ virtual bool hasSlider() RET (true)
virtual YSlider *createSlider (YWidget *parent, const string &label, int minVal,
int maxVal, int initialVal);
- virtual bool hasDateField() IMPL_RET (true)
+ virtual bool hasDateField() RET (true)
virtual YDateField *createDateField (YWidget *parent, const string &label);
- virtual bool hasTimeField() IMPL_RET (true)
+ virtual bool hasTimeField() RET (true)
virtual YTimeField *createTimeField (YWidget *parent, const string &label);
- virtual bool hasTimezoneSelector() IMPL_RET (true)
+ virtual bool hasTimezoneSelector() RET (true)
virtual YTimezoneSelector *createTimezoneSelector (YWidget *parent,
const string &pixmap, const map <string, string> &timezones);
- virtual bool hasBarGraph() IMPL_RET (true)
+ virtual bool hasBarGraph() RET (true)
virtual YBarGraph *createBarGraph (YWidget *parent);
- virtual bool hasMultiProgressMeter() IMPL_RET (true)
+ virtual bool hasMultiProgressMeter() RET (true)
virtual YMultiProgressMeter *createMultiProgressMeter (YWidget *parent,
YUIDimension dim, const vector<float> &maxValues);
- virtual bool hasPartitionSplitter() IMPL_RET (true)
+ virtual bool hasPartitionSplitter() RET (true)
virtual YPartitionSplitter *createPartitionSplitter (YWidget *parent,
int usedSize, int totalFreeSize, int newPartSize, int minNewPartSize,
int minFreeSize, const string &usedLabel, const string &freeLabel,
const string &newPartLabel, const string &freeFieldLabel,
const string &newPartFieldLabel);
- virtual bool hasDownloadProgress() IMPL_RET (true)
+ virtual bool hasDownloadProgress() RET (true)
virtual YDownloadProgress *createDownloadProgress (YWidget *parent,
const string &label, const string & filename, YFileSize_t expectedFileSize);
- virtual bool hasSimplePatchSelector() IMPL_RET (false)
- virtual YWidget *createSimplePatchSelector (YWidget *parent, long modeFlags)
- IMPL_RET (NULL)
- virtual bool hasPatternSelector() IMPL_RET (false)
- virtual YWidget *createPatternSelector (YWidget *parent, long modeFlags)
- IMPL_RET (NULL)
+ virtual bool hasContextMenu() RET (true)
+
+ virtual bool hasSimplePatchSelector() RET (false)
+ virtual YWidget *createSimplePatchSelector (YWidget *parent, long modeFlags) RET (NULL)
+ virtual bool hasPatternSelector() RET (false)
+ virtual YWidget *createPatternSelector (YWidget *parent, long modeFlags) RET (NULL)
};
#include <YApplication.h>
@@ -209,7 +204,7 @@
virtual void busyCursor() { YGUI::ui()->busyCursor(); }
virtual void normalCursor() { YGUI::ui()->normalCursor(); }
- virtual void makeScreenShot (string filename);
+ virtual void makeScreenShot (const std::string &filename);
virtual void beep();
virtual int deviceUnits (YUIDimension dim, float layout_units);
@@ -222,17 +217,21 @@
virtual int defaultWidth(); // internally, use _defaultWidth / Height()
virtual int defaultHeight();
- virtual bool isTextMode() IMPL_RET (false)
- virtual bool leftHandedMouse() IMPL_RET (false)
- virtual bool hasImageSupport() IMPL_RET (true)
- virtual bool hasLocalImageSupport() IMPL_RET (true)
- virtual bool hasAnimationSupport() IMPL_RET (true)
- virtual bool hasIconSupport() IMPL_RET (true)
- virtual bool hasFullUtf8Support() IMPL_RET (true)
+ virtual bool isTextMode() RET (false)
+ virtual bool leftHandedMouse() RET (false)
+ virtual bool hasImageSupport() RET (true)
+ virtual bool hasLocalImageSupport() RET (true)
+ virtual bool hasAnimationSupport() RET (true)
+ virtual bool hasIconSupport() RET (true)
+ virtual bool hasFullUtf8Support() RET (true)
#ifdef USE_WEBKIT
- virtual bool richTextSupportsTable() IMPL_RET (true)
+ virtual bool richTextSupportsTable() RET (true)
#else
- virtual bool richTextSupportsTable() IMPL_RET (false)
+ virtual bool richTextSupportsTable() RET (false)
+#endif
+
+#if YAST2_VERSION > 2018003
+ virtual bool openContextMenu (const YItemCollection &itemCollection);
#endif
private:
@@ -241,5 +240,7 @@
std::string screenShotNameTemplate;
};
+#undef RET
+
#endif /*YGUI_H*/
Modified: trunk/gtk/src/YGUtils.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUtils.cc?rev=59804&r1=…
==============================================================================
--- trunk/gtk/src/YGUtils.cc (original)
+++ trunk/gtk/src/YGUtils.cc Thu Nov 26 18:14:14 2009
@@ -1,11 +1,16 @@
/********************************************************************
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
+/*
+ Textdomain "yast2-gtk"
+ */
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include <string.h>
-#include "YGUI.h"
#include "YGUtils.h"
+#include "YGUI.h"
+#include "YGi18n.h"
static inline void skipSpace (const char *instr, int *i)
{ while (g_ascii_isspace (instr[*i])) (*i)++; }
@@ -395,15 +400,15 @@
gtk_adjustment_set_value (vadj, vadj->upper - vadj->page_size);
return FALSE;
}
+
void YGUtils::scrollWidget (GtkAdjustment *vadj, bool top)
{
- // for some widgets, we need to change adjustment before moving down...
- gtk_adjustment_set_value (vadj, vadj->lower);
- if (!top) {
+ if (top)
+ gtk_adjustment_set_value (vadj, vadj->lower);
+ else
// since we usually want to call this together with a text change, we
// must wait till that gets in effect
- g_timeout_add_full (G_PRIORITY_LOW, 25, scroll_down_cb, vadj, NULL);
- }
+ g_idle_add_full (G_PRIORITY_LOW, scroll_down_cb, vadj, NULL);
}
void ygutils_scrollAdj (GtkAdjustment *vadj, gboolean top)
@@ -568,6 +573,9 @@
{
static bool firstTime = true; static std::map <std::string, std::string> stockMap;
if (firstTime) {
+ firstTime = false;
+
+ // match GTK stock labels to yast ones
GSList *list = gtk_stock_list_ids();
for (GSList *i = list; i; i = i->next) {
gchar *id = (gchar *) i->data;
@@ -585,7 +593,20 @@
g_free (id);
}
g_slist_free (list);
- firstTime = false;
+
+ stockMap [_("Apply")] = GTK_STOCK_APPLY;
+ stockMap [_("Accept")] = GTK_STOCK_APPLY;
+ stockMap [_("OK")] = GTK_STOCK_OK;
+ stockMap [_("Cancel")] = GTK_STOCK_CANCEL;
+ stockMap [_("Yes")] = GTK_STOCK_YES;
+ stockMap [_("No")] = GTK_STOCK_NO;
+ stockMap [_("Add")] = GTK_STOCK_ADD;
+ stockMap [_("Edit")] = GTK_STOCK_EDIT;
+ stockMap [_("Delete")] = GTK_STOCK_DELETE;
+ stockMap [_("Up")] = GTK_STOCK_GO_UP;
+ stockMap [_("Down")] = GTK_STOCK_GO_DOWN;
+ stockMap [_("Enable")] = GTK_STOCK_YES;
+ stockMap [_("Disable")] = GTK_STOCK_NO;
}
std::string id = cutUnderline (label);
@@ -605,8 +626,8 @@
if (gtk_style_lookup_icon_set (button->style, icon)) {
// we want to use GtkImage stock mode so it honors sensitive
GtkWidget *image = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_show (image);
+ gtk_button_set_image (GTK_BUTTON (button), image);
}
}
else {
Modified: trunk/gtk/src/YGWidget.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWidget.cc?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/YGWidget.cc (original)
+++ trunk/gtk/src/YGWidget.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include <stdarg.h>
#include "YGWidget.h"
#include "YGUtils.h"
@@ -67,7 +68,7 @@
{
m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args));
- if (type == GTK_TYPE_WINDOW)
+ if (type == GTK_TYPE_WINDOW || type == GTK_TYPE_MENU)
m_adj_size = m_widget;
else {
m_adj_size = ygtk_adj_size_new();
@@ -91,7 +92,6 @@
YGWidget::~YGWidget()
{
- IMPL
delete m_signals;
m_signals = 0;
if (YGUI::ui()->eventPendingFor (m_ywidget))
@@ -193,6 +193,10 @@
}
};
+#if YAST2_VERSION > 2018003
+ if (reason == YEvent::ContextMenuActivated && !m_ywidget->notifyContextMenu())
+ ; // cancel
+#endif
if (flags & IGNORE_NOTIFY_EVENT || m_ywidget->notify()) {
YWidgetEvent *event = new YWidgetEvent (m_ywidget, reason);
if (flags & DELAY_EVENT)
@@ -216,10 +220,7 @@
{ if (m_signals) m_signals->unblock(); }
void YGWidget::setBorder (unsigned int border)
-{
- IMPL
- gtk_container_set_border_width (GTK_CONTAINER (m_adj_size), border);
-}
+{ gtk_container_set_border_width (GTK_CONTAINER (m_adj_size), border); }
/* YGLabeledWidget follows */
Modified: trunk/gtk/src/YGWizard.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWizard.cc?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/YGWizard.cc (original)
+++ trunk/gtk/src/YGWizard.cc Thu Nov 26 18:14:14 2009
@@ -2,8 +2,9 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
-#include <YGUI.h>
+#define YUILogComponent "gtk"
+#include "config.h"
+#include "YGUI.h"
#include "YGWidget.h"
#include "YGUtils.h"
#include "ygtkwizard.h"
@@ -84,7 +85,6 @@
: YWizard (NULL, backButtonLabel, abortButtonLabel, nextButtonLabel, wizardMode)
, YGWidget (this, parent, YGTK_TYPE_WIZARD, NULL)
{
- IMPL
setBorder (0);
YGtkWizard *wizard = getWizard();
@@ -118,6 +118,7 @@
m_abort_button = new YGWButton (this, wizard->abort_button, abortButtonLabel);
m_next_button = new YGWButton (this, wizard->next_button, nextButtonLabel);
m_notes_button = new YGWButton (this, wizard->release_notes_button, string());
+ ygtk_wizard_set_default_button (wizard, wizard->next_button);
//** All event are sent through this signal together with an id
g_signal_connect (G_OBJECT (getWidget()), "action-triggered",
@@ -278,7 +279,6 @@
static void action_triggered_cb (YGtkWizard *wizard, gpointer id,
gint id_type, YGWizard *pThis)
{
- IMPL
if ((GType) id_type == G_TYPE_STRING)
YGUI::ui()->sendEvent (new YMenuEvent ((char *) id));
else
Modified: trunk/gtk/src/YGi18n.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGi18n.h?rev=59804&r1=59…
==============================================================================
--- trunk/gtk/src/YGi18n.h (original)
+++ trunk/gtk/src/YGi18n.h Thu Nov 26 18:14:14 2009
@@ -1,43 +1,20 @@
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE GmbH |
-\----------------------------------------------------------------------/
-
- File: YGi18n.h
-
- Author: Jiri Srain <jsrain(a)suse.cz>
-
-/-*/
-
-// -*- c++ -*-
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
#ifndef YGi18n_h
#define YGi18n_h
#include <libintl.h>
-
#define TEXTDOMAIN "yast2-gtk"
-// tag for translation but don't translate; no N_ in y2makepot ...
-#define __(a) (a)
-
-static inline const char * _( const char * msgid )
-{
- return ( !msgid || !*msgid ) ? "" : dgettext( TEXTDOMAIN, msgid );
-}
+static inline const char *_(const char *msgid)
+{ return dgettext (TEXTDOMAIN, msgid); }
#ifndef YGI18N_C
-static inline const char * _( const char * msgid1, const char * msgid2, unsigned long int n )
-{
- return dngettext( TEXTDOMAIN, msgid1, msgid2, n );
-}
+static inline const char * _(const char * msgid1, const char *msgid2, unsigned long int n)
+{ return dngettext(TEXTDOMAIN, msgid1, msgid2, n); }
#endif
-#endif // YGi18n_h
+#endif /*YGi18n_h*/
+
Modified: trunk/gtk/src/test.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/test.cc?rev=59804&r1=598…
==============================================================================
--- trunk/gtk/src/test.cc (original)
+++ trunk/gtk/src/test.cc Thu Nov 26 18:14:14 2009
@@ -2,7 +2,8 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-#include <config.h>
+#define YUILogComponent "gtk"
+#include "config.h"
#include <stdio.h>
#include <string.h>
#include <YUI.h>
Modified: trunk/gtk/src/ygtkbargraph.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkbargraph.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkbargraph.c (original)
+++ trunk/gtk/src/ygtkbargraph.c Thu Nov 26 18:14:14 2009
@@ -6,15 +6,18 @@
// check the header file for information about this widget
#include <config.h>
+#include "ygtkratiobox.h"
#include "ygtkbargraph.h"
#include <gtk/gtk.h>
-G_DEFINE_TYPE (YGtkBarGraph, ygtk_bar_graph, YGTK_TYPE_RATIO_HBOX)
+G_DEFINE_TYPE (YGtkBarGraph, ygtk_bar_graph, GTK_TYPE_FRAME)
static void ygtk_bar_graph_init (YGtkBarGraph *bar)
{
-// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (bar), TRUE);
- gtk_container_set_border_width (GTK_CONTAINER (bar), 12);
+ GtkWidget *box = ygtk_ratio_hbox_new (0);
+ gtk_widget_show (box);
+ gtk_container_add (GTK_CONTAINER (bar), box);
+ ygtk_bar_graph_set_style (bar, TRUE);
}
static void ygtk_bar_graph_size_request (GtkWidget *widget, GtkRequisition *requisition)
@@ -30,7 +33,7 @@
void ygtk_bar_graph_create_entries (YGtkBarGraph *bar, guint entries)
{
- YGtkRatioBox *box = YGTK_RATIO_BOX (bar);
+ YGtkRatioBox *box = YGTK_RATIO_BOX (GTK_BIN (bar)->child);
// Remove the ones in excess
guint i;
@@ -56,8 +59,8 @@
static GtkWidget *ygtk_bar_graph_get_label (YGtkBarGraph *bar, int index, GtkWidget **b)
{
- GtkWidget *box = ((YGtkRatioBoxChild *) g_list_nth_data (
- YGTK_RATIO_BOX (bar)->children, index))->widget;
+ YGtkRatioBox *hbox = YGTK_RATIO_BOX (GTK_BIN (bar)->child);
+ GtkWidget *box = ((YGtkRatioBoxChild *) g_list_nth_data (hbox->children, index))->widget;
if (b) *b = box;
return gtk_bin_get_child (GTK_BIN (box));
}
@@ -92,7 +95,8 @@
// Set proportion
gtk_widget_set_size_request (box, 0, -1);
- ygtk_ratio_box_set_child_packing (YGTK_RATIO_BOX (bar), box, MAX (value, 1));
+ YGtkRatioBox *hbox = YGTK_RATIO_BOX (GTK_BIN (bar)->child);
+ ygtk_ratio_box_set_child_packing (hbox, box, MAX (value, 1));
// Set background color
// The Tango palette
@@ -135,6 +139,8 @@
void ygtk_bar_graph_set_style (YGtkBarGraph *bar, gboolean flat)
{
bar->flat = flat;
+ GtkShadowType shadow = flat ? GTK_SHADOW_OUT : GTK_SHADOW_NONE;
+ gtk_frame_set_shadow_type (GTK_FRAME (bar), shadow);
}
void ygtk_bar_graph_customize_bg (YGtkBarGraph *bar, int index, GdkColor *color)
Modified: trunk/gtk/src/ygtkbargraph.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkbargraph.h?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkbargraph.h (original)
+++ trunk/gtk/src/ygtkbargraph.h Thu Nov 26 18:14:14 2009
@@ -9,7 +9,7 @@
#ifndef YGTK_BAR_GRAPH_H
#define YGTK_BAR_GRAPH_H
-#include "ygtkratiobox.h"
+#include <gtk/gtkframe.h>
G_BEGIN_DECLS
#define YGTK_TYPE_BAR_GRAPH (ygtk_bar_graph_get_type ())
@@ -29,14 +29,14 @@
struct _YGtkBarGraph
{
- YGtkRatioHBox parent;
+ GtkFrame parent;
// members:
guint flat : 2;
};
struct _YGtkBarGraphClass
{
- YGtkRatioHBoxClass parent_class;
+ GtkFrameClass parent_class;
};
GtkWidget *ygtk_bar_graph_new (void);
Modified: trunk/gtk/src/ygtkcellrenderertextpixbuf.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkcellrenderertextpixb…
==============================================================================
--- trunk/gtk/src/ygtkcellrenderertextpixbuf.c (original)
+++ trunk/gtk/src/ygtkcellrenderertextpixbuf.c Thu Nov 26 18:14:14 2009
@@ -8,11 +8,15 @@
#include <config.h>
#include "ygtkcellrenderertextpixbuf.h"
+extern GdkPixbuf *ygutils_setOpacity (const GdkPixbuf *src, int opacity, gboolean alpha);
+
#define PIXBUF_TEXT_SPACING 4
enum {
PROP_0,
- PROP_PIXBUF
+ PROP_PIXBUF,
+ PROP_STOCK_ID,
+ PROP_STOCK_SIZE,
};
G_DEFINE_TYPE (YGtkCellRendererTextPixbuf, ygtk_cell_renderer_text_pixbuf, GTK_TYPE_CELL_RENDERER_TEXT)
@@ -21,19 +25,28 @@
{
GtkCellRenderer *cell = GTK_CELL_RENDERER (tpcell);
cell->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
- cell->xalign = 0.0;
+ cell->xpad = cell->ypad = 0;
+ cell->xalign = 0;
cell->yalign = 0.5;
- cell->xpad = 0;
- cell->ypad = 0;
+ tpcell->stock_size = GTK_ICON_SIZE_MENU;
+}
+
+static void unset_image_properties (YGtkCellRendererTextPixbuf *cell)
+{
+ if (cell->stock_id) {
+ g_free (cell->stock_id);
+ cell->stock_id = NULL;
+ }
+ if (cell->pixbuf) {
+ g_object_unref (cell->pixbuf);
+ cell->pixbuf = NULL;
+ }
}
static void ygtk_cell_renderer_text_pixbuf_finalize (GObject *object)
{
YGtkCellRendererTextPixbuf *tpcell = YGTK_CELL_RENDERER_TEXT_PIXBUF (object);
- if (tpcell->pixbuf) {
- g_object_unref (G_OBJECT (tpcell->pixbuf));
- tpcell->pixbuf = NULL;
- }
+ unset_image_properties (tpcell);
G_OBJECT_CLASS (ygtk_cell_renderer_text_pixbuf_parent_class)->finalize (object);
}
@@ -46,6 +59,12 @@
case PROP_PIXBUF:
g_value_set_object (value, G_OBJECT (tpcell->pixbuf));
break;
+ case PROP_STOCK_ID:
+ g_value_set_string (value, tpcell->stock_id);
+ break;
+ case PROP_STOCK_SIZE:
+ g_value_set_uint (value, tpcell->stock_size);
+ break;
}
}
else
@@ -60,10 +79,16 @@
YGtkCellRendererTextPixbuf *tpcell = YGTK_CELL_RENDERER_TEXT_PIXBUF (object);
switch (param_id) {
case PROP_PIXBUF:
- if (tpcell->pixbuf)
- g_object_unref (G_OBJECT (tpcell->pixbuf));
+ unset_image_properties (tpcell);
tpcell->pixbuf = (GdkPixbuf *) g_value_dup_object (value);
break;
+ case PROP_STOCK_ID:
+ unset_image_properties (tpcell);
+ tpcell->stock_id = g_value_dup_string (value);
+ break;
+ case PROP_STOCK_SIZE:
+ tpcell->stock_size = g_value_get_uint (value);
+ break;
}
}
else
@@ -79,42 +104,82 @@
return NULL;
}
-#define XPAD 1
-#define YPAD 0
+static void ensure_pixbuf (YGtkCellRendererTextPixbuf *cell, GtkWidget *widget)
+{
+ if (cell->stock_id && !cell->pixbuf)
+ cell->pixbuf = gtk_widget_render_icon (widget, cell->stock_id, cell->stock_size, NULL);
+}
-static void ygtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
- GtkWidget *widget, GdkRectangle *cell_area, gint *xoffset, gint *yoffset,
- gint *width, gint *height)
+static void ygtk_cell_renderer_text_pixbuf_get_size_full (GtkCellRenderer *cell,
+ GtkWidget *widget, GdkRectangle *cell_area, gint *_xoffset, gint *_yoffset,
+ gint *_width, gint *_height, gint *_pixbuf_xoffset, gint *_pixbuf_yoffset,
+ gint *_pixbuf_width, gint *_pixbuf_height, gint *_text_xoffset, gint *_text_yoffset)
{
- GtkCellRendererText *tcell = GTK_CELL_RENDERER_TEXT (cell);
YGtkCellRendererTextPixbuf *tpcell = YGTK_CELL_RENDERER_TEXT_PIXBUF (cell);
+ ensure_pixbuf (tpcell, widget);
- // will be calculated at expose, as both pixbuf and text have their offsets...
- if (xoffset) *xoffset = 0;
- if (yoffset) *yoffset = 0;
- if (!width || !height)
- return;
- *width = 0;
- *height = 0;
-
+ int pixbuf_width = 0, pixbuf_height = 0;
if (tpcell->pixbuf) {
- *width += gdk_pixbuf_get_width (tpcell->pixbuf);
- *height = MAX (*height, gdk_pixbuf_get_height (tpcell->pixbuf));
+ pixbuf_width = gdk_pixbuf_get_width (tpcell->pixbuf);
+ pixbuf_height = gdk_pixbuf_get_height (tpcell->pixbuf);
}
- if (tcell->text) {
- if (tpcell->pixbuf)
- *width += PIXBUF_TEXT_SPACING;
-
- PangoLayout *layout = create_layout (tpcell, widget);
- int lw, lh;
- pango_layout_get_pixel_size (layout, &lw, &lh);
- *width += lw;
- *height = MAX (*height, lh);
- g_object_unref (G_OBJECT (layout));
+ PangoLayout *layout = create_layout (tpcell, widget);
+ int text_width = 0, text_height = 0;
+ if (layout) {
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, NULL, &rect);
+ text_width = rect.x + rect.width;
+ text_height = rect.y + rect.height;
}
- *width += (cell->xpad+XPAD)*2;
- *height += (cell->ypad+YPAD)*2;
+
+ int width, height;
+ width = pixbuf_width + text_width;
+ if (pixbuf_width && text_width)
+ width += PIXBUF_TEXT_SPACING;
+ height = MAX (pixbuf_height, text_height);
+
+ if (cell_area) {
+ gboolean reverse = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
+ gfloat xalign = cell->xalign, yalign = cell->yalign;
+ if (reverse)
+ xalign = 1.0 - xalign;
+
+ int cell_width = cell_area->width - cell->xpad*2,
+ cell_height = cell_area->height - cell->ypad*2;
+ int xoffset = (xalign * (cell_width - width)) + cell->xpad;
+ int yoffset = (yalign * (cell_height - height)) + cell->ypad;
+ if (_xoffset) *_xoffset = xoffset;
+ if (_yoffset) *_yoffset = yoffset;
+
+ int text_x = xoffset, text_y;
+ if (pixbuf_width && !reverse)
+ text_x += (pixbuf_width + PIXBUF_TEXT_SPACING);
+ text_y = (yalign * (cell_height - text_height)) + cell->ypad;
+
+ int pixbuf_x = xoffset, pixbuf_y;
+ if (text_width && reverse)
+ pixbuf_x += (text_width + PIXBUF_TEXT_SPACING);
+ pixbuf_y = (yalign * (cell_height - pixbuf_height)) + cell->ypad;
+
+ if (_pixbuf_xoffset) *_pixbuf_xoffset = pixbuf_x;
+ if (_pixbuf_yoffset) *_pixbuf_yoffset = pixbuf_y;
+ if (_pixbuf_width) *_pixbuf_width = pixbuf_width;
+ if (_pixbuf_height) *_pixbuf_height = pixbuf_height;
+ if (_text_xoffset) *_text_xoffset = text_x;
+ if (_text_yoffset) *_text_yoffset = text_y;
+ }
+
+ if (_width) *_width = width + (cell->xpad * 2);
+ if (_height) *_height = height + (cell->ypad * 2);
+}
+
+static void ygtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget, GdkRectangle *cell_area, gint *xoffset, gint *yoffset,
+ gint *width, gint *height)
+{
+ ygtk_cell_renderer_text_pixbuf_get_size_full (cell, widget, cell_area,
+ xoffset, yoffset, width, height, NULL, NULL, NULL, NULL, NULL, NULL);
}
static void ygtk_cell_renderer_text_pixbuf_render (GtkCellRenderer *cell,
@@ -142,55 +207,28 @@
state = GTK_STATE_NORMAL;
}
- // positioning
-
- gboolean reverse = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
- gfloat xalign = cell->xalign, yalign = cell->yalign;
- if (reverse)
- xalign = 1.0 - xalign;
-
- GdkPixbuf *pixbuf = tpcell->pixbuf;
- int pixbuf_width = 0, pixbuf_height = 0;
- if (pixbuf) {
- pixbuf_width = gdk_pixbuf_get_width (pixbuf);
- pixbuf_height = gdk_pixbuf_get_height (pixbuf);
- }
-
- PangoLayout *layout = create_layout (tpcell, widget);
- int text_width = 0, text_height = 0;
- if (layout) {
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, NULL, &rect);
- text_width = rect.width;
- text_height = rect.height;
- }
-
- int spacing = (text_width && pixbuf_width) ? PIXBUF_TEXT_SPACING : 0;
- int offset_x = xalign * (cell_area->width - (text_width + pixbuf_width + spacing));
-
- int text_x = offset_x, text_y;
- if (pixbuf_width && !reverse)
- text_x += (pixbuf_width + spacing);
- text_y = yalign * (cell_area->height - text_height);
-
- int pixbuf_x = offset_x, pixbuf_y;
- if (text_width && reverse)
- pixbuf_x += (text_width + spacing);
- pixbuf_y = yalign * (cell_area->height - pixbuf_height);
+ int text_xoffset, text_yoffset, pixbuf_xoffset, pixbuf_yoffset, pixbuf_width,
+ pixbuf_height;
+ ygtk_cell_renderer_text_pixbuf_get_size_full (cell, widget, cell_area,
+ NULL, NULL, NULL, NULL, &pixbuf_xoffset, &pixbuf_yoffset, &pixbuf_width,
+ &pixbuf_height, &text_xoffset, &text_yoffset);
// paint
- int x = cell_area->x + cell->xpad+XPAD, y = cell_area->y + cell->ypad+YPAD;
- if (pixbuf) {
+ ensure_pixbuf (tpcell, widget);
+ if (tpcell->pixbuf) {
+ int x = cell_area->x + pixbuf_xoffset, y = cell_area->y + pixbuf_yoffset;
cairo_t *cr = gdk_cairo_create (window);
- gdk_cairo_set_source_pixbuf (cr, pixbuf, pixbuf_x+x, pixbuf_y+y);
- cairo_rectangle (cr, pixbuf_x+x, pixbuf_y+y, pixbuf_width, pixbuf_height);
+ gdk_cairo_set_source_pixbuf (cr, tpcell->pixbuf, x, y);
+ cairo_rectangle (cr, x, y, pixbuf_width, pixbuf_height);
cairo_fill (cr);
cairo_destroy (cr);
}
+ PangoLayout *layout = create_layout (tpcell, widget);
if (layout) {
+ int x = cell_area->x + text_xoffset, y = cell_area->y + text_yoffset;
GtkStyle *style = gtk_widget_get_style (widget);
gtk_paint_layout (style, window, state, TRUE, expose_area, widget,
- "cellrenderertext", text_x+x, text_y+y, layout);
+ "cellrenderertext", x, y, layout);
g_object_unref (G_OBJECT (layout));
}
}
@@ -211,8 +249,14 @@
cell_class->get_size = ygtk_cell_renderer_text_pixbuf_get_size;
cell_class->render = ygtk_cell_renderer_text_pixbuf_render;
+ GParamFlags readwrite_flag =
+ G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB;
g_object_class_install_property (object_class, PROP_PIXBUF,
- g_param_spec_object ("pixbuf", "Image", "Side image", GDK_TYPE_PIXBUF,
- G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+ g_param_spec_object ("pixbuf", "Image", "Side image", GDK_TYPE_PIXBUF, readwrite_flag));
+ g_object_class_install_property (object_class, PROP_STOCK_ID,
+ g_param_spec_string ("stock-id", "Stock ID", "Stock icon to render", NULL, readwrite_flag));
+ g_object_class_install_property (object_class, PROP_STOCK_SIZE,
+ g_param_spec_uint ("stock-size", "Size", "GtkIconSize of the rendered icon",
+ 0, G_MAXUINT, GTK_ICON_SIZE_MENU, readwrite_flag));
}
Modified: trunk/gtk/src/ygtkcellrenderertextpixbuf.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkcellrenderertextpixb…
==============================================================================
--- trunk/gtk/src/ygtkcellrenderertextpixbuf.h (original)
+++ trunk/gtk/src/ygtkcellrenderertextpixbuf.h Thu Nov 26 18:14:14 2009
@@ -33,6 +33,8 @@
// private:
GdkPixbuf *pixbuf;
+ gchar *stock_id;
+ GtkIconSize stock_size;
} YGtkCellRendererTextPixbuf;
typedef struct _YGtkCellRendererTextPixbufClass
Modified: trunk/gtk/src/ygtkfindentry.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkfindentry.c?rev=5980…
==============================================================================
--- trunk/gtk/src/ygtkfindentry.c (original)
+++ trunk/gtk/src/ygtkfindentry.c Thu Nov 26 18:14:14 2009
@@ -301,7 +301,7 @@
if (entry->find_icon) {
left_border = gdk_pixbuf_get_width (entry->find_icon) + 2;
if (entry->context_menu)
- left_border += ARROW_SIZE - 1;
+ left_border += ARROW_SIZE;
}
if (entry->clear_icon)
right_border = gdk_pixbuf_get_width (entry->clear_icon) + 2;
@@ -346,6 +346,19 @@
gdk_window_hide (eentry->right_window); // show when text is inserted
}
+static void ygtk_find_entry_unrealize (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->unrealize (widget);
+
+ YGtkFindEntry *fentry = YGTK_FIND_ENTRY (widget);
+ generate_icon (NULL, NULL, &fentry->find_icon, &fentry->find_hover_icon);
+ generate_icon (NULL, NULL, &fentry->clear_icon, &fentry->clear_hover_icon);
+
+ YGtkExtEntry *eentry = YGTK_EXT_ENTRY (widget);
+ ygtk_ext_entry_set_border_window_size (eentry, YGTK_EXT_ENTRY_LEFT_WIN, 0);
+ ygtk_ext_entry_set_border_window_size (eentry, YGTK_EXT_ENTRY_RIGHT_WIN, 0);
+}
+
static void ygtk_find_entry_map (GtkWidget *widget)
{
GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->map (widget);
@@ -365,17 +378,22 @@
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) {
+ if (event->window == eentry->left_window || event->window == eentry->right_window) {
gboolean hover = hover_window == event->window;
+ int win_width, win_height;
+ gdk_drawable_get_size (event->window, &win_width, &win_height);
+
+/* if (fentry->context_menu && event->window == eentry->left_window)
+ gtk_paint_box (widget->style, event->window, GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT, &event->area, widget, "combobox",
+ 0, 0, win_width, win_height);*/
+
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);
+ int pix_height = gdk_pixbuf_get_height (pixbuf), y;
y = (win_height - pix_height) / 2;
gdk_draw_pixbuf (event->window, widget->style->fg_gc[0], pixbuf,
@@ -383,10 +401,8 @@
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);
+ GTK_SHADOW_NONE, &event->area, widget, NULL, GTK_ARROW_DOWN, FALSE,
+ win_width - ARROW_SIZE-1, (win_height - ARROW_SIZE)/2, ARROW_SIZE, ARROW_SIZE);
}
else
GTK_WIDGET_CLASS (ygtk_find_entry_parent_class)->expose_event (widget, event);
@@ -630,6 +646,7 @@
{
GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->realize = ygtk_find_entry_realize;
+ gtkwidget_class->unrealize = ygtk_find_entry_unrealize;
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;
Modified: trunk/gtk/src/ygtkfindentry.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkfindentry.h?rev=5980…
==============================================================================
--- trunk/gtk/src/ygtkfindentry.h (original)
+++ trunk/gtk/src/ygtkfindentry.h Thu Nov 26 18:14:14 2009
@@ -14,6 +14,8 @@
YGtkFindEntry is a convinience widget that has a find icon, with an
optional menu, at the left, and an erase icon at the right. It can
interact with an option image menu, and does auto-completion.
+
+ TODO: deprecate in favor of using GtkEntry 2.16 new APIs.
*/
#ifndef YGTK_FIND_ENTRY_H
Modified: trunk/gtk/src/ygtkhtmlwrap.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkhtmlwrap.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkhtmlwrap.c (original)
+++ trunk/gtk/src/ygtkhtmlwrap.c Thu Nov 26 18:14:14 2009
@@ -182,7 +182,7 @@
}
static WebKitNavigationResponse ygtk_webkit_navigation_requested_cb (
- WebKitWebView *view, WebKitWebFrame *frame, WebKitNetworkRequest *request, void (*callback) (GtkWidget *widget, const gchar *uri, gpointer d))
+ WebKitWebView *view, WebKitWebFrame *frame, WebKitNetworkRequest *request, LinkClickedCb callback)
{
const gchar *uri = webkit_network_request_get_uri (request);
// look for set_text to see why we need to cut the uri in some cases
@@ -194,7 +194,7 @@
return WEBKIT_NAVIGATION_RESPONSE_IGNORE;
}
-void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data)
+void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, LinkClickedCb callback, gpointer data)
{
g_object_set_data (G_OBJECT (widget), "pointer", data);
g_signal_connect (G_OBJECT (widget), "navigation-requested",
@@ -279,9 +279,9 @@
return gtk_html_engine_search_next (GTK_HTML (widget));
}
-void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data)
+void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, LinkClickedCb callback, gpointer data)
{
- g_signal_connect (G_OBJECT (widget), "link-clicked", callback, data);
+ g_signal_connect (G_OBJECT (widget), "link-clicked", G_CALLBACK (callback), data);
}
void ygtk_html_wrap_set_background (GtkWidget *widget, GdkPixbuf *pixbuf, const gchar *filename)
@@ -304,7 +304,11 @@
void ygtk_html_wrap_set_text (GtkWidget *widget, const gchar* text, gboolean plain_mode)
{
- ygtk_rich_text_set_text (YGTK_RICH_TEXT (widget), text, plain_mode);
+ YGtkRichText *rtext = YGTK_RICH_TEXT (widget);
+ if (plain_mode)
+ ygtk_rich_text_set_plain_text (rtext, text);
+ else
+ ygtk_rich_text_set_text (rtext, text);
}
void ygtk_html_wrap_scroll (GtkWidget *widget, gboolean top)
@@ -324,9 +328,9 @@
return ygtk_rich_text_forward_mark (YGTK_RICH_TEXT (widget), text);
}
-void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, GCallback callback, gpointer data)
+void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, LinkClickedCb callback, gpointer data)
{
- g_signal_connect (G_OBJECT (widget), "link-clicked", callback, data);
+ g_signal_connect (G_OBJECT (widget), "link-clicked", G_CALLBACK (callback), data);
}
void ygtk_html_wrap_set_background (GtkWidget *widget, GdkPixbuf *pixbuf, const gchar *filename)
Modified: trunk/gtk/src/ygtkhtmlwrap.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkhtmlwrap.h?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkhtmlwrap.h (original)
+++ trunk/gtk/src/ygtkhtmlwrap.h Thu Nov 26 18:14:14 2009
@@ -22,8 +22,8 @@
void ygtk_html_wrap_set_text (GtkWidget *widget, const gchar* text, gboolean plain_mode);
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);
+typedef void (*LinkClickedCb) (GtkWidget *htmlwrap, const gchar *url, gpointer data);
+void ygtk_html_wrap_connect_link_clicked (GtkWidget *widget, LinkClickedCb callback, gpointer data);
// not supported on plain text
gboolean ygtk_html_wrap_search (GtkWidget *widget, const gchar *text);
Modified: trunk/gtk/src/ygtkratiobox.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkratiobox.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkratiobox.c (original)
+++ trunk/gtk/src/ygtkratiobox.c Thu Nov 26 18:14:14 2009
@@ -121,6 +121,10 @@
requisition->width += spacing;
else
requisition->height += spacing;
+
+ int border = GTK_CONTAINER (box)->border_width;
+ requisition->width += border*2;
+ requisition->height += border*2;
}
static void ygtk_ratio_box_size_allocate (GtkWidget *widget,
@@ -144,11 +148,15 @@
gint spacing = children_nb ? box->spacing*(children_nb-1) : 0;
+ int border = GTK_CONTAINER (box)->border_width;
+ int x = allocation->x + border, y = allocation->y + border,
+ width = allocation->width - border*2, height = allocation->height - border*2;
+
gint length;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
- length = allocation->width - spacing;
+ length = width - spacing;
else
- length = allocation->height - spacing;
+ length = height - spacing;
gint child_pos = 0;
for (i = box->children; i; i = i->next) {
@@ -160,18 +168,20 @@
gtk_widget_get_child_requisition (child->widget, &child_req);
gint child_length = (child->ratio * length) / ratios_sum;
+ if (!i->next) // last takes rest (any residual length)
+ child_length = length - child_pos;
GtkAllocation child_alloc;
if (orientation == GTK_ORIENTATION_HORIZONTAL) {
- child_alloc.x = allocation->x + child_pos;
- child_alloc.y = allocation->y;
+ child_alloc.x = x + child_pos;
+ child_alloc.y = y;
child_alloc.width = child_length;
- child_alloc.height = allocation->height;
+ child_alloc.height = height;
}
else { // GTK_ORIENTATION_VERTICAL
- child_alloc.x = allocation->x;
- child_alloc.y = allocation->y + child_pos;
- child_alloc.width = allocation->width;
+ child_alloc.x = x;
+ child_alloc.y = y + child_pos;
+ child_alloc.width = width;
child_alloc.height = child_length;
}
Modified: trunk/gtk/src/ygtkrichtext.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkrichtext.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkrichtext.c (original)
+++ trunk/gtk/src/ygtkrichtext.c Thu Nov 26 18:14:14 2009
@@ -24,13 +24,10 @@
// 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)
+static const char *get_link_at_iter (GtkTextView *text_view, GtkTextIter *iter)
{
- 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;
+ 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");
@@ -42,23 +39,27 @@
g_slist_free (tags);
return link;
}
+static const char *get_link (GtkTextView *text_view, gint win_x, gint win_y)
+{
+ gint buffer_x, buffer_y;
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
+ GTK_TEXT_WINDOW_WIDGET, win_x, win_y, &buffer_x, &buffer_y);
+ GtkTextIter iter;
+ gtk_text_view_get_iter_at_location (text_view, &iter, buffer_x, buffer_y);
+ return get_link_at_iter (text_view, &iter);
+}
// 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;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ GdkEventButton *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.
@@ -66,10 +67,7 @@
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);
+ const char *link = get_link (GTK_TEXT_VIEW (text_view), event->x, event->y);
if (link) // report link
g_signal_emit (YGTK_RICH_TEXT (text_view), link_clicked_signal, 0, link);
return FALSE;
@@ -180,12 +178,9 @@
wy >= widget->allocation.height)
return;
}
- gint bx, by;
- gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
- wx, wy, &bx, &by);
static gboolean hovering_over_link = FALSE;
- gboolean hovering = get_link (view, bx, by) != NULL;
+ gboolean hovering = get_link (view, wx, wy) != NULL;
if (hovering != hovering_over_link) {
hovering_over_link = hovering;
@@ -382,8 +377,8 @@
// 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 if (!g_ascii_strcasecmp (element_name, "br")) ;
+ else if (!g_ascii_strcasecmp (element_name, "hr")) ;
else
{
@@ -553,18 +548,16 @@
} while (!gtk_text_iter_is_end (&iter));
}
-void ygtk_rich_text_set_text (YGtkRichText* rtext, const gchar* text, gboolean plain_mode)
+void ygtk_rich_text_set_plain_text (YGtkRichText* rtext, const gchar* text)
{
- GtkTextBuffer *buffer;
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext));
-
- if (plain_mode) {
- gtk_text_buffer_set_text (buffer, text, -1);
- return;
- }
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext));
+ gtk_text_buffer_set_text (buffer, text, -1);
+}
- // remove any possible existing text
- gtk_text_buffer_set_text (buffer, "", 0);
+void ygtk_rich_text_set_text (YGtkRichText* rtext, const gchar* text)
+{
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (rtext));
+ gtk_text_buffer_set_text (buffer, "", 0); // remove any existing text
GRTParseState state;
GRTParseState_init (&state, buffer);
@@ -691,7 +684,7 @@
g_object_ref (G_OBJECT (pixbuf));
}
-void ygtk_rich_text_class_init (YGtkRichTextClass *klass)
+static 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;
Modified: trunk/gtk/src/ygtkrichtext.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkrichtext.h?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtkrichtext.h (original)
+++ trunk/gtk/src/ygtkrichtext.h Thu Nov 26 18:14:14 2009
@@ -46,7 +46,8 @@
/* 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 plain_mode);
+void ygtk_rich_text_set_text (YGtkRichText* rtext, const gchar* text);
+void ygtk_rich_text_set_plain_text (YGtkRichText* rtext, const gchar* text);
// To be used together with an entry box to search for text
gboolean ygtk_rich_text_mark_text (YGtkRichText *rtext, const gchar *text);
Modified: trunk/gtk/src/ygtkscrolledwindow.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkscrolledwindow.h?rev…
==============================================================================
--- trunk/gtk/src/ygtkscrolledwindow.h (original)
+++ trunk/gtk/src/ygtkscrolledwindow.h Thu Nov 26 18:14:14 2009
@@ -49,45 +49,3 @@
G_END_DECLS
#endif /*YGTK_SCROLLED_WINDOW_H*/
-/* YGtkTreeView hacks support for a right-click signal.
-*/
-
-#ifndef YGTK_TREE_VIEW_H
-#define YGTK_TREE_VIEW_H
-
-#include <gtk/gtktreeview.h>
-G_BEGIN_DECLS
-
-#define YGTK_TYPE_TREE_VIEW (ygtk_tree_view_get_type ())
-#define YGTK_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindow))
-#define YGTK_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindowClass))
-#define YGTK_IS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- YGTK_TYPE_TREE_VIEW))
-#define YGTK_IS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- YGTK_TYPE_TREE_VIEW))
-#define YGTK_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindowClass))
-
-typedef struct _YGtkTreeView
-{
- GtkTreeView parent;
-} YGtkTreeView;
-
-typedef struct _YGtkTreeViewClass
-{
- GtkTreeViewClass parent_class;
-
- // signals:
- void (*right_click) (YGtkTreeView *view, gboolean outreach);
-} YGtkTreeViewClass;
-
-GtkWidget* ygtk_tree_view_new (void);
-GType ygtk_tree_view_get_type (void) G_GNUC_CONST;
-
-void ygtk_tree_view_popup_menu (YGtkTreeView *view, GtkWidget *menu);
-
-G_END_DECLS
-#endif /*YGTK_TREE_VIEW_H*/
-
Modified: trunk/gtk/src/ygtksteps.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtksteps.c?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/ygtksteps.c (original)
+++ trunk/gtk/src/ygtksteps.c Thu Nov 26 18:14:14 2009
@@ -26,15 +26,16 @@
gtk_box_set_spacing (GTK_BOX (steps), 8);
gtk_container_set_border_width (GTK_CONTAINER (steps), 4);
+ const gchar *check = "\u2714", *current = "\u25b6", *todo = "\u26ab";
+ if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
+ current = "\u25c0";
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);
-
- const gchar *check = "\u2714", *current = "<b>\u2192</b>";
- if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
- current = "<b>\u2190</b>";
- pango_layout_set_markup (steps->check_mark_layout, check, -1);
- pango_layout_set_markup (steps->current_mark_layout, current, -1);
+ steps->todo_mark_layout = pango_layout_new (context);
+ pango_layout_set_text (steps->check_mark_layout, check, -1);
+ pango_layout_set_text (steps->current_mark_layout, current, -1);
+ pango_layout_set_text (steps->todo_mark_layout, todo, -1);
steps->current_mark_timeout_id = steps->current_mark_frame = 0;
}
@@ -50,7 +51,9 @@
steps->check_mark_layout = NULL;
if (steps->current_mark_layout)
g_object_unref (steps->current_mark_layout);
- steps->current_mark_layout = NULL;
+ if (steps->todo_mark_layout)
+ g_object_unref (steps->todo_mark_layout);
+ steps->todo_mark_layout = NULL;
GTK_OBJECT_CLASS (ygtk_steps_parent_class)->destroy (object);
}
@@ -82,38 +85,44 @@
YGtkSteps *steps = YGTK_STEPS (widget);
gboolean reverse = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
- GtkStyle *style = gtk_widget_get_style (widget);
GList *children = gtk_container_get_children (GTK_CONTAINER (widget)), *i;
+
+ cairo_t *cr = gdk_cairo_create (event->window);
+ cairo_set_source_rgb (cr, 0, 0, 0);
int n = 0;
for (i = children; i; i = i->next, n++) {
- if (n <= steps->current_step) {
- GtkWidget *label = i->data;
- if (g_object_get_data (G_OBJECT (label), "is-header"))
- continue;
- PangoLayout *mark = (n == steps->current_step) ?
- steps->current_mark_layout : steps->check_mark_layout;
- int x = label->allocation.x, y = label->allocation.y;
- if (reverse) {
- PangoRectangle rect;
- pango_layout_get_pixel_extents (mark, NULL, &rect);
- x += label->allocation.width - rect.width - 4;
- }
+ GtkWidget *label = i->data;
+ if (g_object_get_data (G_OBJECT (label), "is-header"))
+ continue;
+ PangoLayout *layout;
+ if (n < steps->current_step)
+ layout = steps->check_mark_layout;
+ else if (n == steps->current_step)
+ layout = steps->current_mark_layout;
+ else //if (n > steps->current_step)
+ layout = steps->todo_mark_layout;
+ int x = label->allocation.x, y = label->allocation.y;
+ if (reverse) {
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, NULL, &rect);
+ x += label->allocation.width - rect.width - 4;
+ }
+ else
+ x += 4;
+ if (n == steps->current_step) {
+ int offset;
+ if (steps->current_mark_frame < CURRENT_MARK_FRAMES_NB/2)
+ offset = steps->current_mark_frame * CURRENT_MARK_ANIMATION_OFFSET;
else
- x += 4;
- if (n == steps->current_step) {
- int offset;
- if (steps->current_mark_frame < CURRENT_MARK_FRAMES_NB/2)
- offset = steps->current_mark_frame * CURRENT_MARK_ANIMATION_OFFSET;
- else
- offset = (CURRENT_MARK_FRAMES_NB - steps->current_mark_frame) *
- CURRENT_MARK_ANIMATION_OFFSET;
- x += offset * (reverse ? 1 : -1);
- }
-
- gtk_paint_layout (style, widget->window, GTK_STATE_NORMAL, TRUE,
- NULL, /*event->area,*/ widget, NULL, x, y, mark);
+ offset = (CURRENT_MARK_FRAMES_NB - steps->current_mark_frame) *
+ CURRENT_MARK_ANIMATION_OFFSET;
+ x += offset * (reverse ? 1 : -1);
}
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
}
+ cairo_destroy (cr);
g_list_free (children);
return FALSE;
}
@@ -126,6 +135,8 @@
gint ygtk_steps_append (YGtkSteps *steps, const gchar *text)
{
GtkWidget *label = gtk_label_new (text);
+ GdkColor black = { 0, 0, 0, 0 };
+ gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &black);
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
int mark_width = 10;
pango_layout_get_pixel_size (steps->check_mark_layout, &mark_width, NULL);
@@ -138,6 +149,8 @@
void ygtk_steps_append_heading (YGtkSteps *steps, const gchar *heading)
{
GtkWidget *label = gtk_label_new (heading);
+ GdkColor black = { 0, 0, 0, 0 };
+ gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &black);
g_object_set_data (G_OBJECT (label), "is-header", GINT_TO_POINTER (1));
gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
Modified: trunk/gtk/src/ygtksteps.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtksteps.h?rev=59804&r1…
==============================================================================
--- trunk/gtk/src/ygtksteps.h (original)
+++ trunk/gtk/src/ygtksteps.h Thu Nov 26 18:14:14 2009
@@ -39,7 +39,7 @@
// private:
gint current_step;
- PangoLayout *check_mark_layout, *current_mark_layout;
+ PangoLayout *check_mark_layout, *current_mark_layout, *todo_mark_layout;
// for current_mark little animation
guint current_mark_timeout_id, current_mark_frame;
Modified: trunk/gtk/src/ygtktextview.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtktextview.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtktextview.c (original)
+++ trunk/gtk/src/ygtktextview.c Thu Nov 26 18:14:14 2009
@@ -65,6 +65,40 @@
gtk_widget_show_all (GTK_WIDGET (menu));
}
+static inline gboolean is_space (gunichar ch)
+{ return g_unichar_isspace (ch) || ch == 0xfffc; }
+
+static gboolean ygtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
+{ // on right-click, select word under cursor if there is no selection
+ if (event->button == 3) {
+ GtkTextView *view = GTK_TEXT_VIEW (widget);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
+ if (!gtk_text_buffer_get_has_selection (buffer)) {
+ gint buffer_x, buffer_y;
+ gtk_text_view_window_to_buffer_coords (view,
+ GTK_TEXT_WINDOW_WIDGET, (gint) event->x, (gint) event->y, &buffer_x, &buffer_y);
+ GtkTextIter iter;
+ gtk_text_view_get_iter_at_location (view, &iter, buffer_x, buffer_y);
+
+ if (!is_space (gtk_text_iter_get_char (&iter))) {
+ GtkTextIter start, end = iter, temp = iter;
+ do {
+ start = temp;
+ if (!gtk_text_iter_backward_char (&temp))
+ break;
+ } while (!is_space (gtk_text_iter_get_char (&temp)));
+ do {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ } while (!is_space (gtk_text_iter_get_char (&end)));
+
+ gtk_text_buffer_select_range (buffer, &start, &end);
+ }
+ }
+ }
+ return GTK_WIDGET_CLASS (ygtk_text_view_parent_class)->button_press_event (widget, event);
+}
+
GtkWidget *ygtk_text_view_new (gboolean editable)
{ return g_object_new (YGTK_TYPE_TEXT_VIEW, "editable", editable, NULL); }
@@ -75,5 +109,6 @@
GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->realize = ygtk_text_view_realize;
+ gtkwidget_class->button_press_event = ygtk_text_view_button_press_event;
}
Modified: trunk/gtk/src/ygtktreeview.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtktreeview.c?rev=59804…
==============================================================================
--- trunk/gtk/src/ygtktreeview.c (original)
+++ trunk/gtk/src/ygtktreeview.c Thu Nov 26 18:14:14 2009
@@ -74,7 +74,7 @@
static void ygtk_tree_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc)
{
GTK_WIDGET_CLASS (ygtk_tree_view_parent_class)->size_allocate (widget, alloc);
-
+#if 0 // this doesn't work so well on gtk 2.18.1
GtkTreeView *view = GTK_TREE_VIEW (widget);
GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
GList *paths;
@@ -86,6 +86,7 @@
}
g_list_foreach (paths, (GFunc) gtk_tree_path_free, 0);
g_list_free (paths);
+#endif
}
Modified: trunk/gtk/src/ygtkwizard.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkwizard.c?rev=59804&r…
==============================================================================
--- trunk/gtk/src/ygtkwizard.c (original)
+++ trunk/gtk/src/ygtkwizard.c Thu Nov 26 18:14:14 2009
@@ -66,7 +66,7 @@
GTK_WIDGET (dialog), GTK_STOCK_HELP, GTK_ICON_SIZE_MENU, NULL);
gtk_window_set_icon (GTK_WINDOW (dialog), icon);
g_object_unref (G_OBJECT (icon));
- gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 350);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 450);
// help text
dialog->help_box = gtk_scrolled_window_new (NULL, NULL);
@@ -491,16 +491,12 @@
static GtkWidget *create_help_button()
{
- GtkWidget *button, *image = 0;
+ GtkWidget *button, *image;
button = gtk_toggle_button_new();
gtk_button_set_label (GTK_BUTTON (button), _("Help"));
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
- GdkPixbuf *pixbuf = gtk_widget_render_icon (button, GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON, NULL);
- if (pixbuf) {
- image = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- gtk_button_set_image (GTK_BUTTON (button), image);
- }
+ image = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
return button;
}
@@ -612,6 +608,7 @@
gtk_widget_set_size_request (wizard->m_buttons, 0, -1);
g_signal_connect_after (G_OBJECT (wizard->m_buttons), "size-allocate",
G_CALLBACK (buttons_size_allocate_cb), buttons_group);
+ wizard->m_default_button = NULL;
//** The menu and the navigation widgets will be created when requested.
// space for them
@@ -644,8 +641,10 @@
{
GTK_WIDGET_CLASS (ygtk_wizard_parent_class)->realize (widget);
YGtkWizard *wizard = YGTK_WIZARD (widget);
- gtk_widget_grab_default (wizard->next_button);
- gtk_widget_grab_focus (wizard->next_button);
+ if (wizard->m_default_button) {
+ gtk_widget_grab_default (wizard->m_default_button);
+ gtk_widget_grab_focus (wizard->m_default_button);
+ }
}
static void ygtk_wizard_map (GtkWidget *widget)
@@ -671,10 +670,8 @@
*hash = NULL;
}
-static void ygtk_wizard_destroy (GtkObject *object)
+static void ygtk_wizard_finalize (GObject *object)
{
- GTK_OBJECT_CLASS (ygtk_wizard_parent_class)->destroy (object);
-
YGtkWizard *wizard = YGTK_WIZARD (object);
wizard->help_button = NULL; // dialog unmap will try to access this
destroy_hash (&wizard->menu_ids, FALSE);
@@ -684,6 +681,7 @@
ygtk_help_text_destroy (wizard->m_help);
wizard->m_help = NULL;
}
+ G_OBJECT_CLASS (ygtk_wizard_parent_class)->finalize (object);
}
GtkWidget *ygtk_wizard_new (void)
@@ -702,10 +700,13 @@
g_signal_emit (wizard, action_triggered_signal, 0, id, G_TYPE_STRING);
}
-void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *widget)
+void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *child)
{
- wizard->m_child = widget;
- gtk_paned_pack2 (GTK_PANED (wizard->m_pane), widget, TRUE, TRUE);
+ if (wizard->m_child)
+ gtk_container_remove (GTK_CONTAINER (wizard->m_pane), wizard->m_child);
+ wizard->m_child = child;
+ if (child)
+ gtk_paned_pack2 (GTK_PANED (wizard->m_pane), child, TRUE, TRUE);
}
static gboolean ygtk_wizard_set_information_expose_cb (GtkWidget *widget, GdkEventExpose *event,
@@ -899,6 +900,9 @@
g_object_set_data (G_OBJECT (button), "ptr-id", id);
}
+void ygtk_wizard_set_default_button (YGtkWizard *wizard, GtkWidget *button)
+{ wizard->m_default_button = button; }
+
void ygtk_wizard_enable_button (YGtkWizard *wizard, GtkWidget *button, gboolean enable)
{
gtk_widget_set_sensitive (button, enable);
@@ -1075,8 +1079,8 @@
widget_class->realize = ygtk_wizard_realize;
widget_class->map = ygtk_wizard_map;
- GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
- gtkobject_class->destroy = ygtk_wizard_destroy;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ygtk_wizard_finalize;
action_triggered_signal = g_signal_new ("action-triggered",
G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), G_SIGNAL_RUN_LAST,
Modified: trunk/gtk/src/ygtkwizard.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkwizard.h?rev=59804&r…
==============================================================================
--- trunk/gtk/src/ygtkwizard.h (original)
+++ trunk/gtk/src/ygtkwizard.h Thu Nov 26 18:14:14 2009
@@ -105,7 +105,7 @@
/* Widgets we need to access. */
GtkWidget *tree_view, *steps, *menu,
*back_button, *abort_button, *next_button, *help_button,
- *release_notes_button;
+ *release_notes_button, *m_default_button;
/* The help text. */
YGtkHelpText *m_help;
@@ -150,6 +150,7 @@
const char *id);
void ygtk_wizard_set_button_ptr_id (YGtkWizard *wizard, GtkWidget *button,
gpointer id);
+void ygtk_wizard_set_default_button (YGtkWizard *wizard, GtkWidget *button); // before realize
void ygtk_wizard_set_extra_button (YGtkWizard *wizard, GtkWidget *widget);
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/660f918b95fb16b6bf617ac05c9637e3.jpg?s=120&d=mm&r=g)
[yast-commit] r59803 - /trunk/gtk/package/yast2-gtk-rpmlintrc
by rpmcruz@svn.opensuse.org 26 Nov '09
by rpmcruz@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: rpmcruz
Date: Thu Nov 26 18:10:57 2009
New Revision: 59803
URL: http://svn.opensuse.org/viewcvs/yast?rev=59803&view=rev
Log:
* Reverted to development state.
Removed:
trunk/gtk/package/yast2-gtk-rpmlintrc
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/660f918b95fb16b6bf617ac05c9637e3.jpg?s=120&d=mm&r=g)
[yast-commit] r59802 - in /trunk/gtk/modules: ./ FindGTK2.cmake
by rpmcruz@svn.opensuse.org 26 Nov '09
by rpmcruz@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: rpmcruz
Date: Thu Nov 26 18:10:24 2009
New Revision: 59802
URL: http://svn.opensuse.org/viewcvs/yast?rev=59802&view=rev
Log:
* Reverted to development state.
Added:
trunk/gtk/modules/
trunk/gtk/modules/FindGTK2.cmake
Added: trunk/gtk/modules/FindGTK2.cmake
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/modules/FindGTK2.cmake?rev=5…
==============================================================================
--- trunk/gtk/modules/FindGTK2.cmake (added)
+++ trunk/gtk/modules/FindGTK2.cmake Thu Nov 26 18:10:24 2009
@@ -0,0 +1,546 @@
+# - FindGTK2.cmake
+# This module can find the GTK2 widget libraries and several of its other
+# optional components like gtkmm, glade, and glademm.
+#
+# NOTE: If you intend to use version checking, CMake 2.6.2 or later is
+# required.
+#
+# Specify one or more of the following components
+# as you call this find module. See example below.
+#
+# gtk
+# gtkmm
+# glade
+# glademm
+#
+# The following variables will be defined for your use
+#
+# GTK2_FOUND - Were all of your specified components found?
+# GTK2_INCLUDE_DIRS - All include directories
+# GTK2_LIBRARIES - All libraries
+#
+# GTK2_VERSION - The version of GTK2 found (x.y.z)
+# GTK2_MAJOR_VERSION - The major version of GTK2
+# GTK2_MINOR_VERSION - The minor version of GTK2
+# GTK2_PATCH_VERSION - The patch version of GTK2
+#
+# Optional variables you can define prior to calling this module:
+#
+# GTK2_DEBUG - Enables verbose debugging of the module
+# GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced
+#
+#=================
+# Example Usage:
+#
+# Call find_package() once, here are some examples to pick from:
+#
+# Require GTK 2.6 or later
+# find_package(GTK2 2.6 REQUIRED gtk)
+#
+# Require GTK 2.10 or later and Glade
+# find_package(GTK2 2.10 REQUIRED gtk glade)
+#
+# Search for GTK/GTKMM 2.8 or later
+# find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
+#
+# if(GTK2_FOUND)
+# include_directories(${GTK2_INCLUDE_DIRS})
+# add_executable(mygui mygui.cc)
+# target_link_libraries(mygui ${GTK2_LIBRARIES})
+# endif()
+#
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2008-2009 Philip Lowman <philip(a)yhbt.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Version 0.7 (3/22/09)
+# * Checked into CMake CVS
+# * Added versioning support
+# * Module now defaults to searching for GTK if COMPONENTS not specified.
+# * Added HKCU prior to HKLM registry key and GTKMM specific environment
+# variable as per mailing list discussion.
+# * Added lib64 to include search path and a few other search paths where GTK
+# may be installed on Unix systems.
+# * Switched to lowercase CMake commands
+# * Prefaced internal variables with _GTK2 to prevent collision
+# * Changed internal macros to functions
+# * Enhanced documentation
+# Version 0.6 (1/8/08)
+# Added GTK2_SKIP_MARK_AS_ADVANCED option
+# Version 0.5 (12/19/08)
+# Second release to cmake mailing list
+
+#=============================================================
+# _GTK2_GET_VERSION
+# Internal function to parse the version number in gtkversion.h
+# _OUT_major = Major version number
+# _OUT_minor = Minor version number
+# _OUT_micro = Micro version number
+# _gtkversion_hdr = Header file to parse
+#=============================================================
+function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
+ file(READ ${_gtkversion_hdr} _contents)
+ if(_contents)
+ string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}")
+
+ if(NOT ${_OUT_major} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_minor} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_micro} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MICRO_VERSION!")
+ endif()
+
+ set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE)
+ set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE)
+ set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist")
+ endif()
+endfunction()
+
+#=============================================================
+# _GTK2_FIND_INCLUDE_DIR
+# Internal function to find the GTK include directories
+# _var = variable to set
+# _hdr = header file to look for
+#=============================================================
+function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )")
+ endif()
+
+ set(_relatives
+ # FIXME
+ glibmm-2.4
+ glib-2.0
+ atk-1.0
+ atkmm-1.6
+ cairo
+ cairomm-1.0
+ gdkmm-2.4
+ giomm-2.4
+ gtk-2.0
+ gtkmm-2.4
+ libglade-2.0
+ libglademm-2.4
+ pango-1.0
+ pangomm-1.4
+ sigc++-2.0
+ )
+
+ set(_suffixes)
+ foreach(_d ${_relatives})
+ list(APPEND _suffixes ${_d})
+ list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include
+ endforeach()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "include suffixes = ${_suffixes}")
+ endif()
+
+ find_path(${_var} ${_hdr}
+ PATHS
+ /usr/local/lib64
+ /usr/local/lib
+ /usr/lib64
+ /usr/lib
+ /opt/gnome/include
+ /opt/gnome/lib
+ /opt/openwin/include
+ /usr/openwin/lib
+ $ENV{GTKMM_BASEPATH}/include
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ PATH_SUFFIXES
+ ${_suffixes}
+ )
+
+ if(${_var})
+ set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ endif()
+
+endfunction(_GTK2_FIND_INCLUDE_DIR)
+
+#=============================================================
+# _GTK2_FIND_LIBRARY
+# Internal function to find libraries packaged with GTK2
+# _var = library variable to create
+#=============================================================
+function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )")
+ endif()
+
+ # Not GTK versions per se but the versions encoded into Windows
+ # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example)
+ # Also the MSVC libraries use _ for . (this is handled below)
+ set(_versions 2.20 2.18 2.16 2.14 2.12
+ 2.10 2.8 2.6 2.4 2.2 2.0
+ 1.20 1.18 1.16 1.14 1.12
+ 1.10 1.8 1.6 1.4 1.2 1.0)
+
+ set(_library)
+ set(_library_d)
+
+ set(_library ${_lib})
+
+ if(_expand_vc)
+ # Add vc80/vc90 midfixes
+ if(MSVC80)
+ set(_library ${_library}-vc80)
+ set(_library_d ${_library}-d)
+ elseif(MSVC90)
+ set(_library ${_library}-vc90)
+ set(_library_d ${_library}-d)
+ endif()
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "After midfix addition = ${_library} and ${_library_d}")
+ endif()
+
+ set(_lib_list)
+ set(_libd_list)
+ if(_append_version)
+ foreach(_ver ${_versions})
+ list(APPEND _lib_list "${_library}-${_ver}")
+ list(APPEND _libd_list "${_library_d}-${_ver}")
+ endforeach()
+ else()
+ set(_lib_list ${_library})
+ set(_libd_list ${_library_d})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "library list = ${_lib_list} and library debug list = ${_libd_list}")
+ endif()
+
+ # For some silly reason the MSVC libraries use _ instead of .
+ # in the version fields
+ if(_expand_vc AND MSVC)
+ set(_no_dots_lib_list)
+ set(_no_dots_libd_list)
+ foreach(_l ${_lib_list})
+ string(REPLACE "." "_" _no_dots_library ${_l})
+ list(APPEND _no_dots_lib_list ${_no_dots_library})
+ endforeach()
+ # And for debug
+ set(_no_dots_libsd_list)
+ foreach(_l ${_libd_list})
+ string(REPLACE "." "_" _no_dots_libraryd ${_l})
+ list(APPEND _no_dots_libd_list ${_no_dots_libraryd})
+ endforeach()
+
+ # Copy list back to original names
+ set(_lib_list ${_no_dots_lib_list})
+ set(_libd_list ${_no_dots_libd_list})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}, our proposed library list is ${_lib_list}")
+ endif()
+
+ find_library(${_var}
+ NAMES ${_lib_list}
+ PATHS
+ /opt/gnome/lib
+ /opt/gnome/lib64
+ /usr/openwin/lib
+ /usr/openwin/lib64
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(_expand_vc AND MSVC)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}")
+ endif()
+
+ find_library(${_var}_DEBUG
+ NAMES ${_libd_list}
+ PATHS
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(${_var} AND ${_var}_DEBUG)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var}_DEBUG)
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ endif()
+ else()
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ # Set debug to release
+ set(${_var}_DEBUG ${${_var}})
+ set(${_var}_DEBUG ${${_var}} PARENT_SCOPE)
+ endif()
+endfunction(_GTK2_FIND_LIBRARY)
+
+#=============================================================
+
+#
+# main()
+#
+
+set(GTK2_FOUND)
+set(GTK2_INCLUDE_DIRS)
+set(GTK2_LIBRARIES)
+
+if(NOT GTK2_FIND_COMPONENTS)
+ # Assume they only want GTK
+ set(GTK2_FIND_COMPONENTS gtk)
+endif()
+
+#
+# If specified, enforce version number
+#
+if(GTK2_FIND_VERSION)
+ cmake_minimum_required(VERSION 2.6.2)
+ set(GTK2_FAILED_VERSION_CHECK true)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "Searching for version ${GTK2_FIND_VERSION}")
+ endif()
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
+ if(GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION
+ ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+ if(GTK2_FIND_VERSION_EXACT)
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ else()
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR
+ GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ endif()
+ else()
+ # If we can't find the GTK include dir, we can't do version checking
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ message(FATAL_ERROR "Could not find GTK2 include directory")
+ endif()
+ return()
+ endif()
+
+ if(GTK2_FAILED_VERSION_CHECK)
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ if(GTK2_FIND_VERSION_EXACT)
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.")
+ else()
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required")
+ endif()
+ endif()
+
+ # If the version check fails, exit out of the module here
+ return()
+ endif()
+endif()
+
+#
+# Find all components
+#
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ if(_GTK2_component STREQUAL "gtk")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true)
+
+ #elseif(_GTK2_component STREQUAL "gdk_pixbuf")
+ #_GTK2_FIND_INCLUDE_DIR(GTK2_GDKPIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
+ #_GTK2_FIND_LIBRARY (GTK2_GDKPIXBUF_LIBRARY gdk_pixbuf false true)
+
+ elseif(_GTK2_component STREQUAL "gtkmm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
+ _GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true)
+
+ elseif(_GTK2_component STREQUAL "glade")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true)
+
+ elseif(_GTK2_component STREQUAL "glademm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true)
+
+ else()
+ message(FATAL_ERROR "Unknown GTK2 component ${_component}")
+ endif()
+endforeach()
+
+#
+# Solve for the GTK2 version if we haven't already
+#
+if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+endif()
+
+#
+# Try to enforce components
+#
+
+set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND
+
+include(FindPackageHandleStandardArgs)
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)
+
+ if(_GTK2_component STREQUAL "gtk")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
+ GTK2_GTK_LIBRARY
+ GTK2_GTK_INCLUDE_DIR
+
+ GTK2_GLIB_INCLUDE_DIR
+ GTK2_GLIBCONFIG_INCLUDE_DIR
+ GTK2_GLIB_LIBRARY
+
+ GTK2_GDK_INCLUDE_DIR
+ GTK2_GDKCONFIG_INCLUDE_DIR
+ GTK2_GDK_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "gtkmm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
+ GTK2_GTKMM_LIBRARY
+ GTK2_GTKMM_INCLUDE_DIR
+ GTK2_GTKMMCONFIG_INCLUDE_DIR
+
+ GTK2_GLIBMM_INCLUDE_DIR
+ GTK2_GLIBMMCONFIG_INCLUDE_DIR
+ GTK2_GLIBMM_LIBRARY
+
+ GTK2_GDKMM_INCLUDE_DIR
+ GTK2_GDKMMCONFIG_INCLUDE_DIR
+ GTK2_GDKMM_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "glade")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
+ GTK2_GLADE_LIBRARY
+ GTK2_GLADE_INCLUDE_DIR
+ )
+ elseif(_GTK2_component STREQUAL "glademm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found."
+ GTK2_GLADEMM_LIBRARY
+ GTK2_GLADEMM_INCLUDE_DIR
+ GTK2_GLADEMMCONFIG_INCLUDE_DIR
+ )
+ endif()
+
+ if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
+ set(_GTK2_did_we_find_everything false)
+ endif()
+endforeach()
+
+if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)
+ set(GTK2_FOUND true)
+else()
+ # Unset our variables.
+ set(GTK2_FOUND false)
+ set(GTK2_VERSION)
+ set(GTK2_VERSION_MAJOR)
+ set(GTK2_VERSION_MINOR)
+ set(GTK2_VERSION_PATCH)
+ set(GTK2_INCLUDE_DIRS)
+ set(GTK2_LIBRARIES)
+endif()
+
+if(GTK2_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS)
+endif()
+
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/d95f774280866d45941b1365718208ff.jpg?s=120&d=mm&r=g)
[yast-commit] r59801 - /branches/SuSE-Code-11-SP1-Branch/network/src/lan/help.ycp
by kmachalkova@svn.opensuse.org 26 Nov '09
by kmachalkova@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: kmachalkova
Date: Thu Nov 26 17:41:25 2009
New Revision: 59801
URL: http://svn.opensuse.org/viewcvs/yast?rev=59801&view=rev
Log:
Help++
Modified:
branches/SuSE-Code-11-SP1-Branch/network/src/lan/help.ycp
Modified: branches/SuSE-Code-11-SP1-Branch/network/src/lan/help.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/netwo…
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/network/src/lan/help.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/network/src/lan/help.ycp Thu Nov 26 17:41:25 2009
@@ -75,10 +75,16 @@
_("<p>For each route, enter destination network IP address, gateway address,
and netmask. To omit any of these values, use dash sign \"-\". Select
-the device through which the traffic to the defined network will be routed, as well.\"-\" is an alias for any interface.</p>
+the device through which the traffic to the defined network will be routed,
+as well.\"-\" is an alias for any interface.</p>
") +
/* Routing dialog help 2/2 */
-_("<p>Enable <b>IP Forwarding</b> if the system is a router. This will apply on both IPv4 and IPv6.</p>"),
+_("<p>Enable <b>IP Forwarding</b> (forwarding packets from external networks
+to the internal one) if this system is a router. Both IPv4 and IPv6 connectivity
+will be affected by this setting.
+<b>Important:</b> if the firewall is enabled, allowing IP forwarding alone is not enough.
+You should enable masquerade and/or set at least one redirect rule in firewall. You may
+use YaST firewall module for that.</p>"),
"dhcp_hostname":
_("<p>If you are using DHCP to get an IP address, check whether you get
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/d95f774280866d45941b1365718208ff.jpg?s=120&d=mm&r=g)
[yast-commit] r59800 - /branches/SuSE-Code-11-SP1-Branch/network/src/modules/Routing.ycp
by kmachalkova@svn.opensuse.org 26 Nov '09
by kmachalkova@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: kmachalkova
Date: Thu Nov 26 17:29:37 2009
New Revision: 59800
URL: http://svn.opensuse.org/viewcvs/yast?rev=59800&view=rev
Log:
With enabled firewall, use Get/SetSupportRoute
from SuSEFirewall (avoid overwriting ip_forwarding
by SuSEFirewall init scripts)
Modified:
branches/SuSE-Code-11-SP1-Branch/network/src/modules/Routing.ycp
Modified: branches/SuSE-Code-11-SP1-Branch/network/src/modules/Routing.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/netwo…
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/network/src/modules/Routing.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/network/src/modules/Routing.ycp Thu Nov 26 17:29:37 2009
@@ -18,6 +18,7 @@
import "NetHwDetection";
import "NetworkInterfaces";
import "Map";
+import "SuSEFirewall";
include "network/runtime.ycp";
include "network/routines.ycp";
@@ -91,6 +92,30 @@
Routes = route;
}
+void ReadIPForwarding() {
+ if ( SuSEFirewall::IsEnabled() ){
+ Forward = SuSEFirewall::GetSupportRoute();
+ }
+ else {
+ Forward = (SCR::Read(.sysconfig.sysctl.IP_FORWARD) == "yes");
+ }
+}
+
+void WriteIPForwarding() {
+ if ( SuSEFirewall::IsEnabled() ){
+ SuSEFirewall::SetSupportRoute( Forward );
+ }
+ else {
+ SCR::Write(.sysconfig.sysctl.IP_FORWARD, Forward ? "yes" : "no");
+ SCR::Write(.sysconfig.sysctl.IPV6_FORWARD, Forward ? "yes" : "no");
+ SCR::Write(.sysconfig.sysctl, nil);
+ }
+ SCR::Execute(.target.bash, sformat("echo %1 > /proc/sys/net/ipv4/ip_forward",
+ Forward ? 1 : 0));
+ SCR::Execute(.target.bash, sformat("echo %1 > /proc/sys/net/ipv6/conf/all/forwarding",
+ Forward ? 1 : 0));
+
+}
/**
* Read routing settings
@@ -105,9 +130,7 @@
else
Routes = [];
- /* enabled IP forwarding */
- if(SCR::Read(.sysconfig.sysctl.IP_FORWARD) == "yes")
- Forward = true;
+ ReadIPForwarding();
y2debug("Routes=%1", Routes);
y2debug("Forward=%1", Forward);
@@ -154,18 +177,7 @@
/*Progress stage 1/2*/
ProgressNextStage(_("Writing IP forwarding settings..."));
- if(Forward) {
- SCR::Write(.sysconfig.sysctl.IP_FORWARD, "yes");
- SCR::Write(.sysconfig.sysctl.IPV6_FORWARD, "yes");
- SCR::Execute(.target.bash, "echo 1 > /proc/sys/net/ipv4/ip_forward");
- SCR::Execute(.target.bash, "echo 1 > /proc/sys/net/ipv6/conf/all/forwarding");
- }
- else {
- SCR::Write(.sysconfig.sysctl.IP_FORWARD, "no");
- SCR::Write(.sysconfig.sysctl.IPV6_FORWARD, "no");
- SCR::Execute(.target.bash, "echo 0 > /proc/sys/net/ipv4/ip_forward");
- SCR::Execute(.target.bash, "echo 0 > /proc/sys/net/ipv6/conf/all/forwarding");
- }
+ WriteIPForwarding();
sleep(sl);
/* at first stop the running routes */
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/0cbed2c4f9cfdb209853a4743dd5705c.jpg?s=120&d=mm&r=g)
[yast-commit] r59799 - in /trunk/storage: package/yast2-storage.changes storage/src/include/custom_part_dialogs.ycp
by fehr@svn.opensuse.org 26 Nov '09
by fehr@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: fehr
Date: Thu Nov 26 17:04:49 2009
New Revision: 59799
URL: http://svn.opensuse.org/viewcvs/yast?rev=59799&view=rev
Log:
disable impossible mountby methods (#444328)
Modified:
trunk/storage/package/yast2-storage.changes
trunk/storage/storage/src/include/custom_part_dialogs.ycp
Modified: trunk/storage/package/yast2-storage.changes
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/package/yast2-storage.ch…
==============================================================================
--- trunk/storage/package/yast2-storage.changes (original)
+++ trunk/storage/package/yast2-storage.changes Thu Nov 26 17:04:49 2009
@@ -1,4 +1,9 @@
-------------------------------------------------------------------
+Thu Nov 26 17:07:16 CET 2009 - fehr(a)suse.de
+
+- disable impossible mountby methods (#444328)
+
+-------------------------------------------------------------------
Tue Nov 24 17:13:39 CET 2009 - fehr(a)suse.de
- do not format hfs boot partition on mac systems (#447782)
Modified: trunk/storage/storage/src/include/custom_part_dialogs.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/cust…
==============================================================================
--- trunk/storage/storage/src/include/custom_part_dialogs.ycp (original)
+++ trunk/storage/storage/src/include/custom_part_dialogs.ycp Thu Nov 26 17:04:49 2009
@@ -684,21 +684,27 @@
{
list no_mountby_type = [ `loop ];
list mountby_id_path_type = [ `primary, `logical ];
+ map enab = $[];
+ boolean tmp = !contains( no_mountby_type, new["type"]:`primary );
+ enab[`label] = tmp && FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
+ new["enc_type"]:`none==`none;
+ enab[`uuid] = tmp && (new["format"]:false || size(new["uuid"]:"")>0) &&
+ FileSystems::MountUuid( new["used_fs"]:`unknown );
+ tmp = contains(mountby_id_path_type, new["type"]:`none);
+ enab[`id] = tmp && size(new["udev_id"]:[])>0;
+ enab[`path] = tmp && size(new["udev_path"]:"")>0;
+ y2milestone( "FstabOptions enab %1", enab );
+ UI::ChangeWidget( `id(`label), `Enabled, enab[`label]:false );
+ UI::ChangeWidget( `id(`uuid), `Enabled, enab[`uuid]:false );
+ UI::ChangeWidget( `id(`id), `Enabled, enab[`id]:false );
+ UI::ChangeWidget( `id(`path), `Enabled, enab[`path]:false );
symbol defmb = !Mode::config() ? Storage::GetMountBy( new["device"]:"" )
: `device;
y2milestone( "FstabOptions defmb %1", defmb );
+ if( haskey( enab, defmb ) && !enab[defmb]:false )
+ defmb = `device;
UI::ChangeWidget( `id(`mt_group), `CurrentButton,
new["mountby"]:defmb );
- UI::ChangeWidget( `id(`label), `Enabled,
- FileSystems::MountLabel( new["used_fs"]:`unknown ) &&
- new["enc_type"]:`none==`none &&
- !contains( no_mountby_type, new["type"]:`primary ) );
- UI::ChangeWidget( `id(`uuid), `Enabled,
- (new["format"]:false || size(new["uuid"]:"")>0) &&
- FileSystems::MountUuid( new["used_fs"]:`unknown ) &&
- !contains( no_mountby_type, new["type"]:`primary ) );
- UI::ChangeWidget( `id(`id), `Enabled, contains(mountby_id_path_type, new["type"]:`none) );
- UI::ChangeWidget( `id(`path), `Enabled, contains(mountby_id_path_type, new["type"]:`none) );
}
if( UI::WidgetExists( `id(`vol_label) ))
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
Author: jsuchome
Date: Thu Nov 26 16:26:46 2009
New Revision: 59798
URL: http://svn.opensuse.org/viewcvs/yast?rev=59798&view=rev
Log:
Created tag stable-2_19_0 for irda
Added:
tags/stable-2_19_0/irda/
- copied from r59797, trunk/irda/
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/ccabc6c04379b11d036b089b67199614.jpg?s=120&d=mm&r=g)
[yast-commit] r59797 - in /trunk/irda: VERSION package/yast2-irda.changes src/ui.ycp testsuite/.cvsignore
by jsuchome@svn.opensuse.org 26 Nov '09
by jsuchome@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: jsuchome
Date: Thu Nov 26 16:26:34 2009
New Revision: 59797
URL: http://svn.opensuse.org/viewcvs/yast?rev=59797&view=rev
Log:
- check for `ok dialog return value (bnc#558525)
- 2.19.0
Modified:
trunk/irda/VERSION
trunk/irda/package/yast2-irda.changes
trunk/irda/src/ui.ycp
trunk/irda/testsuite/.cvsignore
Modified: trunk/irda/VERSION
URL: http://svn.opensuse.org/viewcvs/yast/trunk/irda/VERSION?rev=59797&r1=59796&…
==============================================================================
--- trunk/irda/VERSION (original)
+++ trunk/irda/VERSION Thu Nov 26 16:26:34 2009
@@ -1 +1 @@
-2.18.1
+2.19.0
Modified: trunk/irda/package/yast2-irda.changes
URL: http://svn.opensuse.org/viewcvs/yast/trunk/irda/package/yast2-irda.changes?…
==============================================================================
--- trunk/irda/package/yast2-irda.changes (original)
+++ trunk/irda/package/yast2-irda.changes Thu Nov 26 16:26:34 2009
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Thu Nov 26 16:20:52 CET 2009 - jsuchome(a)suse.cz
+
+- check for `ok dialog return value (bnc#558525)
+- 2.19.0
+
+-------------------------------------------------------------------
Fri Sep 4 12:25:48 CEST 2009 - ug(a)suse.de
- fixed typo in the desktop file which makes yast2-schema fail
Modified: trunk/irda/src/ui.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/irda/src/ui.ycp?rev=59797&r1=597…
==============================================================================
--- trunk/irda/src/ui.ycp (original)
+++ trunk/irda/src/ui.ycp Thu Nov 26 16:26:34 2009
@@ -313,7 +313,7 @@
} while (!contains ([`back, `abort, `cancel, `next, `ok], ret));
- if (ret == `next &&
+ if ((ret == `next || ret == `ok) &&
(start != Irda::start || port != Irda::port ||
baud_rate != Irda::max_baud_rate))
{
@@ -336,7 +336,7 @@
Irda::Read ();
symbol ret = IrDADialog ();
- if (ret == `next || ret == `finish)
+ if (ret == `next || ret == `finish || ret == `ok)
{
Irda::Write ();
}
Modified: trunk/irda/testsuite/.cvsignore
URL: http://svn.opensuse.org/viewcvs/yast/trunk/irda/testsuite/.cvsignore?rev=59…
==============================================================================
--- trunk/irda/testsuite/.cvsignore (original)
+++ trunk/irda/testsuite/.cvsignore Thu Nov 26 16:26:34 2009
@@ -9,4 +9,3 @@
config
run
*.test
-tests
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/d95f774280866d45941b1365718208ff.jpg?s=120&d=mm&r=g)
[yast-commit] r59796 - /branches/SuSE-Code-11-SP1-Branch/network/src/modules/Lan.ycp
by kmachalkova@svn.opensuse.org 26 Nov '09
by kmachalkova@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: kmachalkova
Date: Thu Nov 26 16:17:10 2009
New Revision: 59796
URL: http://svn.opensuse.org/viewcvs/yast?rev=59796&view=rev
Log:
Read firewall before routing (because of IP
forwarding setup)
Modified:
branches/SuSE-Code-11-SP1-Branch/network/src/modules/Lan.ycp
Modified: branches/SuSE-Code-11-SP1-Branch/network/src/modules/Lan.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/netwo…
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/network/src/modules/Lan.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/network/src/modules/Lan.ycp Thu Nov 26 16:17:10 2009
@@ -195,13 +195,13 @@
/* Progress stage 4/9 */
_("Read network configuration"),
/* Progress stage 5/9 */
- _("Read routing configuration"),
+ _("Read firewall settings"),
/* Progress stage 6/9 */
_("Read hostname and DNS configuration"),
/* Progress stage 7/9 */
_("Read installation information"),
/* Progress stage 8/9 */
- _("Read firewall settings"),
+ _("Read routing configuration"),
/* Progress stage 9/9 */
_("Detect current status"),
], [], "");
@@ -263,8 +263,10 @@
if(Abort()) return false;
/* Progress step 5/9 */
- ProgressNextStage(_("Reading routing configuration..."));
- Routing::Read();
+ ProgressNextStage(_("Reading firewall settings..."));
+ boolean orig = Progress::set (false);
+ SuSEFirewall4Network::Read ();
+ Progress::set (orig);
sleep(sl);
if(Abort()) return false;
@@ -282,10 +284,8 @@
if(Abort()) return false;
/* Progress step 8/9 */
- ProgressNextStage(_("Reading firewall settings..."));
- boolean orig = Progress::set (false);
- SuSEFirewall4Network::Read ();
- Progress::set (orig);
+ ProgressNextStage(_("Reading routing configuration..."));
+ Routing::Read();
sleep(sl);
if(Abort()) return false;
@@ -448,7 +448,7 @@
if (Mode::installation() && NetworkService::IsManaged()) y2internal("Export sysconfig settings into NetworkManager %1", SCR::Execute(.target.bash_output, "/usr/lib/NetworkManager/nm-opensuse-sysconfig-merge --connections"));
y2internal("virt_net_proposal %1", virt_net_proposal);
- if (Stage::cont() && virt_net_proposal && (Linuxrc::usessh() || Linuxrc::vnc() || Linuxrc::display_ip())) {
+ if (Stage::cont() && virt_net_proposal && (Linuxrc::usessh() || Linuxrc::vnc() || Linuxrc::display_ip())) {
UI::OpenDialog(`opt(`decorated), `HBox(
`HSpacing(1),
`HCenter(`HSquash(`VBox(
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
26 Nov '09
ref: refs/heads/master
commit 29afc1b199db7925cb108c00db8f8d2a29c981ec
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 16:01:40 2009 +0100
add test for bnc#555204
---
.../test/functional/status_controller_test.rb | 31 ++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
index 0667737..ec7be25 100644
--- a/plugins/status/test/functional/status_controller_test.rb
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -100,4 +100,35 @@ ATTR_DATA = {
assert_valid_markup
assert assigns(:logs)
end
+
+OUT_SYNC_ERROR = <<EOF
+<error>
+ <type>COLLECTD_SYNC_ERROR</type>
+ <description>blba bla</description>
+</error>
+EOF
+
+class ResponseMock
+ def body
+ return OUT_SYNC_ERROR
+ end
+
+ def code
+ return "503"
+ end
+end
+
+#status module must survive collectd out of sync
+ def test_collectd_out_of_sync
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.logs').returns(@logs_proxy)
+ sproxy = StatusProxy.new
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.status').returns(sproxy)
+ sproxy.stubs(:find).raises(ActiveResource::ServerError.new(ResponseMock.new,""))
+ get :index
+
+ assert_response :success
+ assert_valid_markup
+ assert assigns(:logs)
+ end
+
end
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> backgroud_patches_bnc550934 : add test for bnc#555204
by Josef Reidinger 26 Nov '09
by Josef Reidinger 26 Nov '09
26 Nov '09
ref: refs/heads/backgroud_patches_bnc550934
commit 29afc1b199db7925cb108c00db8f8d2a29c981ec
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 16:01:40 2009 +0100
add test for bnc#555204
---
.../test/functional/status_controller_test.rb | 31 ++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
index 0667737..ec7be25 100644
--- a/plugins/status/test/functional/status_controller_test.rb
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -100,4 +100,35 @@ ATTR_DATA = {
assert_valid_markup
assert assigns(:logs)
end
+
+OUT_SYNC_ERROR = <<EOF
+<error>
+ <type>COLLECTD_SYNC_ERROR</type>
+ <description>blba bla</description>
+</error>
+EOF
+
+class ResponseMock
+ def body
+ return OUT_SYNC_ERROR
+ end
+
+ def code
+ return "503"
+ end
+end
+
+#status module must survive collectd out of sync
+ def test_collectd_out_of_sync
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.logs').returns(@logs_proxy)
+ sproxy = StatusProxy.new
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.status').returns(sproxy)
+ sproxy.stubs(:find).raises(ActiveResource::ServerError.new(ResponseMock.new,""))
+ get :index
+
+ assert_response :success
+ assert_valid_markup
+ assert assigns(:logs)
+ end
+
end
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/ed60f082f214344d23d374769e5179ba.jpg?s=120&d=mm&r=g)
[yast-commit] Build failed in Hudson: webyast-client-head-i586 #659
by Hudson Integration Service 26 Nov '09
by Hudson Integration Service 26 Nov '09
26 Nov '09
See http://yast.suse.de:3334/job/webyast-client-head-i586/659/changes
Changes:
[Josef Reidinger] add testcase for language detection
[Martin Vidner] Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
[Josef Reidinger] add initial test suite for status
------------------------------------------
[...truncated 138 lines...]
-- create_table(:hosts)
-> 0.0038s
== CreateHosts: migrated (0.0040s) ===========================================
== InsertLocalhost: migrating ================================================
== InsertLocalhost: migrated (0.0860s) =======================================
== PrivatePortNumbers: migrating =============================================
== PrivatePortNumbers: migrated (0.0020s) ====================================
+ check_exit 0
+ '[' -z 0 ']'
+ MYEXIT=0
+ '[' 0 == 0 ']'
+ echo 'exit code: 0 ... good, lets continue'
exit code: 0 ... good, lets continue
+ return
+ popd
/src/web-client
+ '[' -d coverage ']'
+ mkdir coverage
+ rake test
(in /src/web-client)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/host_test.rb" "test/unit/basesystem_test.rb" "test/unit/helpers/controlpanel_helper_test.rb" "test/unit/account_test.rb" "test/unit/yast/service_resource_test.rb" "test/unit/client_exception_test.rb"
(in /src/web-client/webclient)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...............
Finished in 0.578053 seconds.
15 tests, 43 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/hosts_controller_test.rb" "test/functional/private_routing_test.rb" "test/functional/lang_controller_test.rb" "test/functional/controlpanel_controller_test.rb" "test/functional/sessions_controller_test.rb" "test/functional/basesystem_controller_test.rb" "test/functional/main_controller_test.rb"
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:33: warning: don't put space before argument parentheses
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:37: warning: don't put space before argument parentheses
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:25: warning: already initialized constant LANGUAGES
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.................DEPRECATION WARNING: Using assert_redirected_to with partial hash arguments is deprecated. Specify the full set arguments instead. (called from test_main_index_no_session at ./test/functional/main_controller_test.rb:12)
...Host(): nil
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:30:25", updated_at: "2009-11-26 14:30:25">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:30:25", updated_at: "2009-11-26 14:30:25">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:30:25", updated_at: "2009-11-26 14:30:25">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:30:25", updated_at: "2009-11-26 14:30:25">
.........Host(): nil
.Host(): nil
.
Finished in 1.189447 seconds.
35 tests, 66 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/integration/two_sessions_test.rb" "test/integration/manage_hosts_test.rb"
fakeweb not found, skipping two_session_test
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/custom_services)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/security)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/users)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/string_serialization_test.rb" "test/unit/array_serialization_test.rb"
(in /src/web-client/plugins/network)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.......
Finished in 0.003642 seconds.
7 tests, 7 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/network_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...
Finished in 0.279989 seconds.
3 tests, 9 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/samba_server)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/patch_updates)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/system)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/system_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
......
Finished in 2.00065 seconds.
6 tests, 20 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/administrator)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/administrator_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
Finished in 0.000219 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/registration)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/registration_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.....
Finished in 1.004495 seconds.
5 tests, 11 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/mail_settings)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/systemtime)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/systemtime_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..<html><body>You are being <a href="http://test.host/controlpanel/nextstep">redirected</a>.</body></html>
...
Finished in 0.736271 seconds.
5 tests, 26 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/language)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/language_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
Finished in 0.000234 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/services)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/services_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...
Finished in 0.253729 seconds.
3 tests, 6 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/eulas)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/eulas_controller_test.rb"
./test/functional/eulas_controller_test.rb:46: warning: don't put space before argument parentheses
./test/functional/eulas_controller_test.rb:47: warning: don't put space before argument parentheses
Taking ../../webclient for RAILS_PARENT
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..
Finished in 0.0735 seconds.
2 tests, 10 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/permissions)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/permission_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..
Finished in 0.602087 seconds.
2 tests, 4 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/status)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/status_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
F
Finished in 0.523573 seconds.
1) Failure:
test_index(StatusControllerTest)
[actionpack (2.3.4) lib/action_controller/test_case.rb:114:in `clean_backtrace'
/test/functional/status_controller_test.rb:51:in `test_index'
activesupport (2.3.4) lib/active_support/testing/setup_and_teardown.rb:62:in `__send__'
activesupport (2.3.4) lib/active_support/testing/setup_and_teardown.rb:62:in `run']:
Expected response to be a <:success>, but was <500>
<"">
1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
Errors running test:functionals!
rake aborted!
Error on execute task test on plugins/status
/src/web-client/Rakefile:20
(See full trace by running task with --trace)
++ error_exit 1
++ echo 'ERROR: detected exit code 1'
ERROR: detected exit code 1
++ footer_and_exit 1
++ '[' -z 1 ']'
++ MYEXIT=1
++ '[' 1 == 0 ']'
++ ascii_failed
++ cat
( )
( ) (
) _ )
( \_
_(_\ \)__
(____\___))
build failed
++ echo 'stopping dbus..'
stopping dbus..
++ /etc/init.d/dbus stop
Shutting down D-Bus daemon..done
++ exit 1
... unmounting sys
... unmounting proc
... unmounting pts
umount: /data/hudson/HUDSON-CHROOT/webyast-head-i586/dev/pts: not mounted
Can't unmount devpts /data/hudson/HUDSON-CHROOT/webyast-head-i586/dev/pts
[locks-and-latches] Releasing all the locks
[locks-and-latches] All the locks released
Publishing Javadoc
Archiving artifacts
Build wasn't successful, skipping saikuro coverage report
Publishing rails stats report...
[workspace] $ rake --silent stats
Failed to send e-mail to Martin Vidner because no e-mail address is known, and no default e-mail domain is configured
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
1
![](https://seccdn.libravatar.org/avatar/ed60f082f214344d23d374769e5179ba.jpg?s=120&d=mm&r=g)
[yast-commit] Build failed in Hudson: webyast-client-11.1-i586 #573
by Hudson Integration Service 26 Nov '09
by Hudson Integration Service 26 Nov '09
26 Nov '09
See http://yast.suse.de:3334/job/webyast-client-11.1-i586/573/changes
Changes:
[Josef Reidinger] add testcase for language detection
[Martin Vidner] Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
[Josef Reidinger] add initial test suite for status
------------------------------------------
[...truncated 136 lines...]
== CreateHosts: migrating ====================================================
-- create_table(:hosts)
-> 0.0041s
== CreateHosts: migrated (0.0044s) ===========================================
== InsertLocalhost: migrating ================================================
== InsertLocalhost: migrated (0.1196s) =======================================
== PrivatePortNumbers: migrating =============================================
== PrivatePortNumbers: migrated (0.0046s) ====================================
+ check_exit 0
+ '[' -z 0 ']'
+ MYEXIT=0
+ '[' 0 == 0 ']'
+ echo 'exit code: 0 ... good, lets continue'
exit code: 0 ... good, lets continue
+ return
+ popd
/src/web-client
+ '[' -d coverage ']'
+ mkdir coverage
+ rake test
(in /src/web-client)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/host_test.rb" "test/unit/basesystem_test.rb" "test/unit/helpers/controlpanel_helper_test.rb" "test/unit/account_test.rb" "test/unit/yast/service_resource_test.rb" "test/unit/client_exception_test.rb"
(in /src/web-client/webclient)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...............
Finished in 0.704751 seconds.
15 tests, 43 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/hosts_controller_test.rb" "test/functional/private_routing_test.rb" "test/functional/lang_controller_test.rb" "test/functional/controlpanel_controller_test.rb" "test/functional/sessions_controller_test.rb" "test/functional/basesystem_controller_test.rb" "test/functional/main_controller_test.rb"
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:33: warning: don't put space before argument parentheses
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:37: warning: don't put space before argument parentheses
/src/web-client/webclient/vendor/plugins/lang_helper/lib/lang_helper.rb:25: warning: already initialized constant LANGUAGES
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.................DEPRECATION WARNING: Using assert_redirected_to with partial hash arguments is deprecated. Specify the full set arguments instead. (called from test_main_index_no_session at ./test/functional/main_controller_test.rb:12)
...Host(): nil
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:31:35", updated_at: "2009-11-26 14:31:35">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:31:35", updated_at: "2009-11-26 14:31:35">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:31:35", updated_at: "2009-11-26 14:31:35">
.Host(1): #<Host id: 1, name: "Sample Host", url: "http://www.google.com:4711", description: "Just a sample, not for real use", created_at: "2009-11-26 14:31:35", updated_at: "2009-11-26 14:31:35">
.........Host(): nil
.Host(): nil
.
Finished in 1.762512 seconds.
35 tests, 66 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/integration/two_sessions_test.rb" "test/integration/manage_hosts_test.rb"
fakeweb not found, skipping two_session_test
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/custom_services)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/security)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/users)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/string_serialization_test.rb" "test/unit/array_serialization_test.rb"
(in /src/web-client/plugins/network)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.......
Finished in 0.003628 seconds.
7 tests, 7 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/network_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...
Finished in 0.297063 seconds.
3 tests, 9 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/samba_server)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/patch_updates)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/system)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/system_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
......
Finished in 1.748201 seconds.
6 tests, 20 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/administrator)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/administrator_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
Finished in 0.000216 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/registration)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/registration_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.....
Finished in 1.034082 seconds.
5 tests, 11 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/mail_settings)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/systemtime)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/systemtime_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..<html><body>You are being <a href="http://test.host/controlpanel/nextstep">redirected</a>.</body></html>
...
Finished in 0.725379 seconds.
5 tests, 26 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/language)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/language_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
Finished in 0.000215 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/services)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/services_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
...
Finished in 0.254199 seconds.
3 tests, 6 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/eulas)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/eulas_controller_test.rb"
./test/functional/eulas_controller_test.rb:46: warning: don't put space before argument parentheses
./test/functional/eulas_controller_test.rb:47: warning: don't put space before argument parentheses
Taking ../../webclient for RAILS_PARENT
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..
Finished in 0.07447 seconds.
2 tests, 10 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/permissions)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/permission_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..
Finished in 0.668884 seconds.
2 tests, 4 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
(in /src/web-client/plugins/status)
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/status_controller_test.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
F
Finished in 0.581292 seconds.
1) Failure:
test_index(StatusControllerTest)
[actionpack (2.3.4) lib/action_controller/test_case.rb:114:in `clean_backtrace'
/test/functional/status_controller_test.rb:51:in `test_index'
activesupport (2.3.4) lib/active_support/testing/setup_and_teardown.rb:62:in `__send__'
activesupport (2.3.4) lib/active_support/testing/setup_and_teardown.rb:62:in `run']:
Expected response to be a <:success>, but was <500>
<"">
1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
/usr/bin/ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb"
Errors running test:functionals!
rake aborted!
Error on execute task test on plugins/status
/src/web-client/Rakefile:20
(See full trace by running task with --trace)
++ error_exit 1
++ echo 'ERROR: detected exit code 1'
ERROR: detected exit code 1
++ footer_and_exit 1
++ '[' -z 1 ']'
++ MYEXIT=1
++ '[' 1 == 0 ']'
++ ascii_failed
++ cat
( )
( ) (
) _ )
( \_
_(_\ \)__
(____\___))
build failed
++ echo 'stopping dbus..'
stopping dbus..
++ /etc/init.d/dbus stop
Shutting down D-Bus daemon..done
++ exit 1
... unmounting sys
... unmounting proc
... unmounting pts
umount: /data/hudson/HUDSON-CHROOT/webyast-11.1-i586/dev/pts: not mounted
Can't unmount devpts /data/hudson/HUDSON-CHROOT/webyast-11.1-i586/dev/pts
[locks-and-latches] Releasing all the locks
[locks-and-latches] All the locks released
Archiving artifacts
Build wasn't successful, skipping saikuro coverage report
Publishing rails stats report...
[workspace] $ rake --silent stats
Failed to send e-mail to Martin Vidner because no e-mail address is known, and no default e-mail domain is configured
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
1
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> master : first working version of status tests
by Josef Reidinger 26 Nov '09
by Josef Reidinger 26 Nov '09
26 Nov '09
ref: refs/heads/master
commit 03f5e70674f23685a8a205614df598b0448b0953
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 15:44:28 2009 +0100
first working version of status tests
---
.../test/functional/status_controller_test.rb | 52 +++++++++++++++++++-
1 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
index 5de00c1..0667737 100644
--- a/plugins/status/test/functional/status_controller_test.rb
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -3,6 +3,21 @@ require 'test/unit'
require File.expand_path( File.join("test","validation_assert"), RailsParent.parent )
require 'mocha'
+#extra ugly hack for dynamic created type
+module YaST
+ module ServiceResource
+ module Proxies
+ module Status
+ module Metric
+ module Label
+ end
+ end
+ end
+ end
+ end
+end
+
+
class StatusControllerTest < ActionController::TestCase
class Log
@@ -21,18 +36,51 @@ DEFINED_LOGS = [
class StatusProxy
attr_accessor :result, :permissions, :timeout
- def find(arg=nil)
- return {}
+ def initialize
+ @permissions = { :read => true, :write => :true}
+ end
+ def find(arg=nil,arg2=nil)
+ return StatusMock.new
end
end
class LogsProxy
attr_accessor :result, :permissions, :timeout
+ def initialize
+ @permissions = { :read => true, :write => :true}
+ end
def find(arg)
return @result
end
end
+class MetricMock
+ attr_accessor :name, :metricgroup, :interval, :starttime
+ def initialize (n,m,i,s)
+ @name = n
+ @metricgroup = m
+ @interval = i
+ @starttime = s
+ end
+
+ def attributes
+ { "label" => ""}
+ end
+end
+
+ATTR_DATA = {
+ "metric" => [
+ MetricMock.new("test","tg",5,Time.now())
+ ],
+ "label" => "" #hach to avoid creating horrible mockup
+}
+
+ class StatusMock
+ def attributes
+ ATTR_DATA
+ end
+ end
+
def setup
StatusController.any_instance.stubs(:login_required)
@controller = StatusController.new
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> backgroud_patches_bnc550934 : first working version of status tests
by Josef Reidinger 26 Nov '09
by Josef Reidinger 26 Nov '09
26 Nov '09
ref: refs/heads/backgroud_patches_bnc550934
commit 03f5e70674f23685a8a205614df598b0448b0953
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 15:44:28 2009 +0100
first working version of status tests
---
.../test/functional/status_controller_test.rb | 52 +++++++++++++++++++-
1 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
index 5de00c1..0667737 100644
--- a/plugins/status/test/functional/status_controller_test.rb
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -3,6 +3,21 @@ require 'test/unit'
require File.expand_path( File.join("test","validation_assert"), RailsParent.parent )
require 'mocha'
+#extra ugly hack for dynamic created type
+module YaST
+ module ServiceResource
+ module Proxies
+ module Status
+ module Metric
+ module Label
+ end
+ end
+ end
+ end
+ end
+end
+
+
class StatusControllerTest < ActionController::TestCase
class Log
@@ -21,18 +36,51 @@ DEFINED_LOGS = [
class StatusProxy
attr_accessor :result, :permissions, :timeout
- def find(arg=nil)
- return {}
+ def initialize
+ @permissions = { :read => true, :write => :true}
+ end
+ def find(arg=nil,arg2=nil)
+ return StatusMock.new
end
end
class LogsProxy
attr_accessor :result, :permissions, :timeout
+ def initialize
+ @permissions = { :read => true, :write => :true}
+ end
def find(arg)
return @result
end
end
+class MetricMock
+ attr_accessor :name, :metricgroup, :interval, :starttime
+ def initialize (n,m,i,s)
+ @name = n
+ @metricgroup = m
+ @interval = i
+ @starttime = s
+ end
+
+ def attributes
+ { "label" => ""}
+ end
+end
+
+ATTR_DATA = {
+ "metric" => [
+ MetricMock.new("test","tg",5,Time.now())
+ ],
+ "label" => "" #hach to avoid creating horrible mockup
+}
+
+ class StatusMock
+ def attributes
+ ATTR_DATA
+ end
+ end
+
def setup
StatusController.any_instance.stubs(:login_required)
@controller = StatusController.new
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/d95f774280866d45941b1365718208ff.jpg?s=120&d=mm&r=g)
[yast-commit] r59795 - /tags/branch-Code-11-SP1-2_17_7/apparmor/
by kmachalkova@svn.opensuse.org 26 Nov '09
by kmachalkova@svn.opensuse.org 26 Nov '09
26 Nov '09
Author: kmachalkova
Date: Thu Nov 26 15:43:37 2009
New Revision: 59795
URL: http://svn.opensuse.org/viewcvs/yast?rev=59795&view=rev
Log:
Created tag branch-Code-11-SP1-2_17_7 for apparmor
Added:
tags/branch-Code-11-SP1-2_17_7/apparmor/ (props changed)
- copied from r59794, branches/SuSE-Code-11-SP1-Branch/apparmor/
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
26 Nov '09
ref: refs/heads/master
commit 69875c4a403c30977d70f6f4c5e8f2c99f3905a0
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 15:13:23 2009 +0100
add initial test suite for status
---
.../test/functional/status_controller_test.rb | 55 ++++++++++++++++++++
plugins/status/test/status_test.rb | 8 ---
plugins/status/test/test_helper.rb | 54 +++++++++++++++++++-
3 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
new file mode 100644
index 0000000..5de00c1
--- /dev/null
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
+require 'test/unit'
+require File.expand_path( File.join("test","validation_assert"), RailsParent.parent )
+require 'mocha'
+
+class StatusControllerTest < ActionController::TestCase
+
+class Log
+ attr_accessor :description,:id,:path
+ def initialize(d,i,p)
+ @description =d
+ @id = i
+ @path = p
+ end
+end
+
+DEFINED_LOGS = [
+ Log.new("test","test","/log/test"),
+ Log.new("test2","test2","/log/test2")
+]
+
+ class StatusProxy
+ attr_accessor :result, :permissions, :timeout
+ def find(arg=nil)
+ return {}
+ end
+ end
+
+ class LogsProxy
+ attr_accessor :result, :permissions, :timeout
+ def find(arg)
+ return @result
+ end
+ end
+
+ def setup
+ StatusController.any_instance.stubs(:login_required)
+ @controller = StatusController.new
+ @request = ActionController::TestRequest.new
+ # http://railsforum.com/viewtopic.php?id=1719
+ @request.session[:account_id] = 1 # defined in fixtures
+ @logs_proxy = LogsProxy.new
+ @logs_proxy.result = DEFINED_LOGS
+ end
+
+ def test_index
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.logs').returns(@logs_proxy)
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.status').returns(StatusProxy.new)
+ get :index
+
+ assert_response :success
+ assert_valid_markup
+ assert assigns(:logs)
+ end
+end
diff --git a/plugins/status/test/status_test.rb b/plugins/status/test/status_test.rb
deleted file mode 100644
index 8206f39..0000000
--- a/plugins/status/test/status_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'test_helper'
-
-class StatusTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
-end
diff --git a/plugins/status/test/test_helper.rb b/plugins/status/test/test_helper.rb
index 61e0acc..dd80852 100644
--- a/plugins/status/test/test_helper.rb
+++ b/plugins/status/test/test_helper.rb
@@ -1,2 +1,54 @@
+# find the rails parent
+require File.join(File.dirname(__FILE__), '..', 'config', 'rails_parent')
+
+ENV["RAILS_ENV"] = "test"
+require File.expand_path( File.join("config","environment"), RailsParent.parent )
+require 'test_help'
+
require 'active_support'
-require 'active_support/test_case'
\ No newline at end of file
+require 'active_support/test_case'
+
+class ActiveSupport::TestCase
+ # Transactional fixtures accelerate your tests by wrapping each test method
+ # in a transaction that's rolled back on completion. This ensures that the
+ # test database remains unchanged so your fixtures don't have to be reloaded
+ # between every test method. Fewer database queries means faster tests.
+ #
+ # Read Mike Clark's excellent walkthrough at
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
+ #
+ # Every Active Record database supports transactions except MyISAM tables
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
+ # is recommended.
+ #
+ # The only drawback to using transactional fixtures is when you actually
+ # need to test transactions. Since your test is bracketed by a transaction,
+ # any transactions started in your code will be automatically rolled back.
+ self.use_transactional_fixtures = true
+
+ # Instantiated fixtures are slow, but give you @david where otherwise you
+ # would need people(:david). If you don't want to migrate your existing
+ # test cases which use the @david style and don't mind the speed hit (each
+ # instantiated fixtures translates to a database query per test method),
+ # then set this back to true.
+ self.use_instantiated_fixtures = false
+
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
+ #
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
+ # -- they do not yet inherit this setting
+ fixtures :all
+
+ # Add more helper methods to be used by all tests here...
+
+ # See http://pennysmalls.com/2009/03/04/rails-23-breakage-and-fixage/
+ def clean_backtrace(&block)
+ yield
+ rescue ActiveSupport::TestCase::Assertion => error
+ framework_path = Regexp.new(File.expand_path("#{File.dirname(__FILE__)}/assertions"))
+ error.backtrace.reject! { |line| File.expand_path(line) =~ framework_path }
+ raise
+ end
+
+end
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> backgroud_patches_bnc550934 : add initial test suite for status
by Josef Reidinger 26 Nov '09
by Josef Reidinger 26 Nov '09
26 Nov '09
ref: refs/heads/backgroud_patches_bnc550934
commit 69875c4a403c30977d70f6f4c5e8f2c99f3905a0
Author: Josef Reidinger <jreidinger(a)suse.cz>
Date: Thu Nov 26 15:13:23 2009 +0100
add initial test suite for status
---
.../test/functional/status_controller_test.rb | 55 ++++++++++++++++++++
plugins/status/test/status_test.rb | 8 ---
plugins/status/test/test_helper.rb | 54 +++++++++++++++++++-
3 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/plugins/status/test/functional/status_controller_test.rb b/plugins/status/test/functional/status_controller_test.rb
new file mode 100644
index 0000000..5de00c1
--- /dev/null
+++ b/plugins/status/test/functional/status_controller_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
+require 'test/unit'
+require File.expand_path( File.join("test","validation_assert"), RailsParent.parent )
+require 'mocha'
+
+class StatusControllerTest < ActionController::TestCase
+
+class Log
+ attr_accessor :description,:id,:path
+ def initialize(d,i,p)
+ @description =d
+ @id = i
+ @path = p
+ end
+end
+
+DEFINED_LOGS = [
+ Log.new("test","test","/log/test"),
+ Log.new("test2","test2","/log/test2")
+]
+
+ class StatusProxy
+ attr_accessor :result, :permissions, :timeout
+ def find(arg=nil)
+ return {}
+ end
+ end
+
+ class LogsProxy
+ attr_accessor :result, :permissions, :timeout
+ def find(arg)
+ return @result
+ end
+ end
+
+ def setup
+ StatusController.any_instance.stubs(:login_required)
+ @controller = StatusController.new
+ @request = ActionController::TestRequest.new
+ # http://railsforum.com/viewtopic.php?id=1719
+ @request.session[:account_id] = 1 # defined in fixtures
+ @logs_proxy = LogsProxy.new
+ @logs_proxy.result = DEFINED_LOGS
+ end
+
+ def test_index
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.logs').returns(@logs_proxy)
+ YaST::ServiceResource.stubs(:proxy_for).with('org.opensuse.yast.system.status').returns(StatusProxy.new)
+ get :index
+
+ assert_response :success
+ assert_valid_markup
+ assert assigns(:logs)
+ end
+end
diff --git a/plugins/status/test/status_test.rb b/plugins/status/test/status_test.rb
deleted file mode 100644
index 8206f39..0000000
--- a/plugins/status/test/status_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'test_helper'
-
-class StatusTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
-end
diff --git a/plugins/status/test/test_helper.rb b/plugins/status/test/test_helper.rb
index 61e0acc..dd80852 100644
--- a/plugins/status/test/test_helper.rb
+++ b/plugins/status/test/test_helper.rb
@@ -1,2 +1,54 @@
+# find the rails parent
+require File.join(File.dirname(__FILE__), '..', 'config', 'rails_parent')
+
+ENV["RAILS_ENV"] = "test"
+require File.expand_path( File.join("config","environment"), RailsParent.parent )
+require 'test_help'
+
require 'active_support'
-require 'active_support/test_case'
\ No newline at end of file
+require 'active_support/test_case'
+
+class ActiveSupport::TestCase
+ # Transactional fixtures accelerate your tests by wrapping each test method
+ # in a transaction that's rolled back on completion. This ensures that the
+ # test database remains unchanged so your fixtures don't have to be reloaded
+ # between every test method. Fewer database queries means faster tests.
+ #
+ # Read Mike Clark's excellent walkthrough at
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
+ #
+ # Every Active Record database supports transactions except MyISAM tables
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
+ # is recommended.
+ #
+ # The only drawback to using transactional fixtures is when you actually
+ # need to test transactions. Since your test is bracketed by a transaction,
+ # any transactions started in your code will be automatically rolled back.
+ self.use_transactional_fixtures = true
+
+ # Instantiated fixtures are slow, but give you @david where otherwise you
+ # would need people(:david). If you don't want to migrate your existing
+ # test cases which use the @david style and don't mind the speed hit (each
+ # instantiated fixtures translates to a database query per test method),
+ # then set this back to true.
+ self.use_instantiated_fixtures = false
+
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
+ #
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
+ # -- they do not yet inherit this setting
+ fixtures :all
+
+ # Add more helper methods to be used by all tests here...
+
+ # See http://pennysmalls.com/2009/03/04/rails-23-breakage-and-fixage/
+ def clean_backtrace(&block)
+ yield
+ rescue ActiveSupport::TestCase::Assertion => error
+ framework_path = Regexp.new(File.expand_path("#{File.dirname(__FILE__)}/assertions"))
+ error.backtrace.reject! { |line| File.expand_path(line) =~ framework_path }
+ raise
+ end
+
+end
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/926abfa8eb8dab66c00070f582fc2b84.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> master : Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
by Martin Vidner 26 Nov '09
by Martin Vidner 26 Nov '09
26 Nov '09
ref: refs/heads/master
commit f17748ed6c4819fe03db808e4d8492cf42ce8b56
Author: Martin Vidner <mvidner(a)suse.cz>
Date: Thu Nov 26 15:18:46 2009 +0100
Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
---
webclient/package/yast2-webclient.changes | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/webclient/package/yast2-webclient.changes b/webclient/package/yast2-webclient.changes
index 40a57e7..5057b34 100644
--- a/webclient/package/yast2-webclient.changes
+++ b/webclient/package/yast2-webclient.changes
@@ -2,7 +2,7 @@
Thu Nov 26 14:43:11 CET 2009 - schubi(a)suse.de
- removed *.swp file, added .*.swp to .gitignore
-- fixed css issue Bug #555196
+- fixed css issue Bug #555875
- fixed css problem at status wrapper
- improve comment to avoid confusion
- remove fix "Waiting for yastws until he has really written his pid file (bnc#558307)"
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0
![](https://seccdn.libravatar.org/avatar/926abfa8eb8dab66c00070f582fc2b84.jpg?s=120&d=mm&r=g)
[yast-commit] <web-client> backgroud_patches_bnc550934 : Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
by Martin Vidner 26 Nov '09
by Martin Vidner 26 Nov '09
26 Nov '09
ref: refs/heads/backgroud_patches_bnc550934
commit f17748ed6c4819fe03db808e4d8492cf42ce8b56
Author: Martin Vidner <mvidner(a)suse.cz>
Date: Thu Nov 26 15:18:46 2009 +0100
Fixed the bug number for 68878fb5c1239437409cd21352141689b6e89577
---
webclient/package/yast2-webclient.changes | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/webclient/package/yast2-webclient.changes b/webclient/package/yast2-webclient.changes
index 40a57e7..5057b34 100644
--- a/webclient/package/yast2-webclient.changes
+++ b/webclient/package/yast2-webclient.changes
@@ -2,7 +2,7 @@
Thu Nov 26 14:43:11 CET 2009 - schubi(a)suse.de
- removed *.swp file, added .*.swp to .gitignore
-- fixed css issue Bug #555196
+- fixed css issue Bug #555875
- fixed css problem at status wrapper
- improve comment to avoid confusion
- remove fix "Waiting for yastws until he has really written his pid file (bnc#558307)"
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org
1
0