Print this page
*** NO COMMENTS ***
| Split |
Close |
| Expand all |
| Collapse all |
--- old/src/packagemanager.py
+++ new/src/packagemanager.py
1 1 #!/usr/bin/python2.4
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 # Use is subject to license terms.
24 24 #
25 25
26 26 # Progress:
27 27 # Startup Progress has two phases:
28 28 # - Start phase:
29 29 # The start phase should be fairly constant at around a few seconds and so is given 5%
30 30 # of the total progress bar.
31 31 # - Package entry loading phase:
32 32 # The package entry loading phase is given the remaining 95% of the bar for progress.
33 33
34 34 INITIAL_PROGRESS_TIME_INTERVAL = 0.5 # Time to update progress during start phase
35 35 INITIAL_PROGRESS_TIME_PERCENTAGE = 0.005 # Amount to update progress during start phase
36 36 INITIAL_PROGRESS_TOTAL_PERCENTAGE = 0.05 # Total progress for start phase
37 37 PACKAGE_PROGRESS_TOTAL_INCREMENTS = 95 # Total increments for loading phase
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
38 38 PACKAGE_PROGRESS_PERCENT_INCREMENT = 0.01 # Amount to update progress during loading phase
39 39 PACKAGE_PROGRESS_PERCENT_TOTAL = 1.0 # Total progress for loading phase
40 40 MAX_DESC_LEN = 60 # Max length of the description
41 41 MAX_INFO_CACHE_LIMIT = 100 # Max number of package descriptions to cache
42 42 NOTEBOOK_PACKAGE_LIST_PAGE = 0 # Main Package List page index
43 43 NOTEBOOK_START_PAGE = 1 # Main View Start page index
44 44 INFO_NOTEBOOK_LICENSE_PAGE = 3 # License Tab index
45 45 SHOW_INFO_DELAY = 600 # Delay before showing selected pacakge information
46 46 SHOW_LICENSE_DELAY = 600 # Delay before showing license information
47 47 SEARCH_STR_FORMAT = "<%s>"
48 -SEARCH_LIMIT = 100 # Maximum number of results shown for
49 - # api search
50 48 MIN_APP_WIDTH = 750 # Minimum application width
51 49 MIN_APP_HEIGHT = 500 # Minimum application height
52 50 INITIAL_APP_WIDTH_PREFERENCES = "/apps/packagemanager/preferences/initial_app_width"
53 51 INITIAL_APP_HEIGHT_PREFERENCES = "/apps/packagemanager/preferences/initial_app_height"
54 52 INITIAL_APP_HPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_hposition"
55 53 INITIAL_APP_VPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_vposition"
56 54 INITIAL_SHOW_FILTER_PREFERENCES = "/apps/packagemanager/preferences/initial_show_filter"
57 55 INITIAL_SECTION_PREFERENCES = "/apps/packagemanager/preferences/initial_section"
58 56 SHOW_STARTPAGE_PREFERENCES = "/apps/packagemanager/preferences/show_startpage"
59 57 API_SEARCH_ERROR_PREFERENCES = "/apps/packagemanager/preferences/api_search_error"
60 58 CATEGORIES_STATUS_COLUMN_INDEX = 0 # Index of Status Column in Categories TreeView
61 59
62 60 STATUS_COLUMN_INDEX = 2 # Index of Status Column in Application TreeView
63 61
64 62 PKG_CLIENT_NAME = "packagemanager"
65 63
66 64 # Location for themable icons
67 65 ICON_LOCATION = "usr/share/package-manager/icons"
68 66 # Load Start Page from lang dir if available
69 67 START_PAGE_CACHE_LANG_BASE = "var/pkg/gui_cache/startpagebase/%s/%s"
70 68 START_PAGE_LANG_BASE = "usr/share/package-manager/data/startpagebase/%s/%s"
71 69 START_PAGE_HOME = "startpage.html" # Default page
72 70
73 71 # StartPage Action support for url's on StartPage pages
74 72 PM_ACTION = 'pm-action' # Action field for StartPage url's
75 73
76 74 # Internal Example: <a href="pm?pm-action=internal&uri=top_picks.html">
77 75 ACTION_INTERNAL = 'internal' # Internal Action value: pm-action=internal
78 76 INTERNAL_URI = 'uri' # Internal field: uri to navigate to in StartPage
79 77 # without protocol scheme specified
80 78
81 79 # External Example: <a href="pm?pm-action=external&uri=www.opensolaris.com">
82 80 ACTION_EXTERNAL = 'external' # External Action value: pm-action=external
83 81 EXTERNAL_URI = 'uri' # External field: uri to navigate to in external
84 82 # default browser without protocol scheme specified
85 83 EXTERNAL_PROTOCOL = 'protocol' # External field: optional protocol scheme,
86 84 # defaults to http
87 85 DEFAULT_PROTOCOL = 'http'
88 86
89 87 import getopt
90 88 import pwd
91 89 import os
92 90 import sys
93 91 import time
94 92 import locale
95 93 import itertools
96 94 import urllib
97 95 import urlparse
98 96 import socket
99 97 import gettext
100 98 import signal
101 99 from threading import Thread
102 100 from threading import Lock
103 101 from urllib2 import HTTPError, URLError
104 102 from cPickle import UnpicklingError
105 103
106 104 try:
107 105 import gobject
108 106 import gnome
109 107 gobject.threads_init()
110 108 import gconf
111 109 import gtk
112 110 import gtk.glade
113 111 import pygtk
114 112 pygtk.require("2.0")
115 113 import gtkhtml2
116 114 import pango
117 115 from glib import GError
118 116 except ImportError:
119 117 sys.exit(1)
120 118 import pkg.misc as misc
121 119 import pkg.client.progress as progress
122 120 import pkg.client.api_errors as api_errors
123 121 import pkg.client.api as api
124 122 import pkg.client.publisher as publisher
125 123 import pkg.portable as portable
126 124 import pkg.fmri as fmri
127 125 import pkg.gui.repository as repository
128 126 import pkg.gui.beadmin as beadm
129 127 import pkg.gui.cache as cache
130 128 import pkg.gui.misc as gui_misc
131 129 import pkg.gui.imageinfo as imageinfo
132 130 import pkg.gui.installupdate as installupdate
133 131 import pkg.gui.enumerations as enumerations
134 132 import pkg.gui.parseqs as parseqs
135 133 import pkg.gui.webinstall as webinstall
136 134 from pkg.client import global_settings
137 135
138 136 # Put _() in the global namespace
139 137 import __builtin__
140 138 __builtin__._ = gettext.gettext
141 139
142 140 (
143 141 DISPLAY_LINK,
144 142 CLICK_LINK,
145 143 ) = range(2)
146 144
147 145 class PackageManager:
148 146 def __init__(self):
149 147 signal.signal(signal.SIGINT, self.__main_application_quit)
150 148 # We reset the HOME directory in case the user called us
151 149 # with gksu and had NFS mounted home directory in which
152 150 # case dbus called from gconf cannot write to the directory.
153 151 if os.getuid() == 0:
154 152 dir = self.__find_root_home_dir()
155 153 os.putenv('HOME', dir)
156 154 self.api_o = None
157 155 self.cache_o = None
158 156 self.img_timestamp = None
159 157 self.client = gconf.client_get_default()
160 158 try:
161 159 self.initial_show_filter = \
162 160 self.client.get_int(INITIAL_SHOW_FILTER_PREFERENCES)
163 161 self.initial_section = \
164 162 self.client.get_int(INITIAL_SECTION_PREFERENCES)
165 163 self.show_startpage = \
166 164 self.client.get_bool(SHOW_STARTPAGE_PREFERENCES)
167 165 self.gconf_not_show_repos = \
168 166 self.client.get_string(API_SEARCH_ERROR_PREFERENCES)
169 167 self.initial_app_width = \
170 168 self.client.get_int(INITIAL_APP_WIDTH_PREFERENCES)
171 169 self.initial_app_height = \
172 170 self.client.get_int(INITIAL_APP_HEIGHT_PREFERENCES)
173 171 self.initial_app_hpos = \
174 172 self.client.get_int(INITIAL_APP_HPOS_PREFERENCES)
175 173 self.initial_app_vpos = \
176 174 self.client.get_int(INITIAL_APP_VPOS_PREFERENCES)
177 175 except GError:
178 176 # Default values - the same as in the
179 177 # packagemanager-preferences.schemas
180 178 self.initial_show_filter = 0
181 179 self.initial_section = 3
182 180 self.show_startpage = True
183 181 self.gconf_not_show_repos = ""
184 182 self.initial_app_width = 800
185 183 self.initial_app_height = 600
186 184 self.initial_app_hpos = 200
187 185 self.initial_app_vpos = 320
188 186
189 187 if not self.gconf_not_show_repos:
190 188 self.gconf_not_show_repos = ""
191 189 self.set_show_filter = 0
192 190 self.set_section = 0
193 191 self.current_search_option = 0
194 192 self.in_search_mode = False
195 193
196 194 # Override default PKG_TIMEOUT_MAX and PKG_CLIENT_TIMEOUT
197 195 # if a value has been specified in the environment.
198 196 global_settings.PKG_TIMEOUT_MAX = int(os.environ.get(
199 197 "PKG_TIMEOUT_MAX", global_settings.PKG_TIMEOUT_MAX))
200 198
201 199 global_settings.PKG_CLIENT_TIMEOUT = int(os.environ.get(
202 200 "PKG_CLIENT_TIMEOUT", global_settings.PKG_CLIENT_TIMEOUT))
203 201
204 202 # This call only affects sockets created by Python. The
205 203 # transport framework must set the timeout value internally
206 204 #
207 205 # value is in seconds
208 206 socket.setdefaulttimeout(global_settings.PKG_TIMEOUT_MAX)
209 207
210 208 global_settings.client_name = PKG_CLIENT_NAME
211 209
212 210 try:
213 211 self.application_dir = os.environ["PACKAGE_MANAGER_ROOT"]
214 212 except KeyError:
215 213 self.application_dir = "/"
216 214 misc.setlocale(locale.LC_ALL, "")
217 215 for module in (gettext, gtk.glade):
218 216 module.bindtextdomain("pkg", os.path.join(
219 217 self.application_dir,
220 218 "usr/share/locale"))
221 219 module.textdomain("pkg")
222 220 # XXX Remove and use _() where self._ and self.parent._ are being used
223 221 self.main_window_title = _('Package Manager')
224 222 self.user_rights = portable.is_admin()
225 223 self.cancelled = False # For background processes
226 224 self.image_directory = None
227 225 self.description_thread_running = False # For background processes
228 226 gtk.rc_parse('~/.gtkrc-1.2-gnome2') # Load gtk theme
229 227 self.progress_stop_timer_thread = False
230 228 self.progress_fraction_time_count = 0
231 229 self.progress_canceled = False
232 230 self.catalog_loaded = False
233 231 self.image_dir_arg = None
234 232 self.update_all_proceed = False
235 233 self.ua_be_name = None
236 234 self.application_path = None
237 235 self.default_publisher = None
238 236 self.current_repos_with_search_errors = []
239 237 self.first_run = True
240 238 self.in_reload = False
241 239 self.selected_pkgstem = None
242 240 self.selected_model = None
243 241 self.selected_path = None
244 242 self.info_cache = {}
245 243 self.selected = 0
246 244 self.selected_pkgs = {}
247 245 self.to_install_update = {}
248 246 self.to_remove = {}
249 247 self.in_startpage_startup = self.show_startpage
250 248 self.lang = None
251 249 self.lang_root = None
252 250 self.visible_status_id = 0
253 251 self.categories_status_id = 0
254 252 self.icon_theme = gtk.IconTheme()
255 253 icon_location = os.path.join(self.application_dir, ICON_LOCATION)
256 254 self.icon_theme.append_search_path(icon_location)
257 255 self.search_options = [
258 256 ('ips-search',
259 257 gui_misc.get_icon(self.icon_theme, 'search', 20),
260 258 _("_Current Repository"),
261 259 _("Search Current Repository")),
262 260 ('ips-search-all',
|
↓ open down ↓ |
203 lines elided |
↑ open up ↑ |
263 261 gui_misc.get_icon(self.icon_theme, 'search_all', 20),
264 262 _("_All Repositories"),
265 263 _("Search All Repositories"))
266 264 ]
267 265 self.__register_iconsets(self.search_options)
268 266 self.visible_repository = None
269 267 self.visible_repository_uptodate = False
270 268 self.last_active_publisher = None
271 269 self.search_start = 0
272 270 self.search_time_sec = 0
271 + self.current_search_publisher = None
273 272 self.section_list = None
274 273 self.filter_list = self.__get_new_filter_liststore()
275 274 self.application_list = None
276 275 self.a11y_application_treeview = None
277 276 self.a11y_categories_treeview = None
278 277 self.application_treeview_range = None
279 278 self.application_treeview_initialized = False
280 279 self.categories_treeview_range = None
281 280 self.categories_treeview_initialized = False
282 281 self.category_list = None
283 282 self.repositories_list = None
284 283 self.pr = progress.NullProgressTracker()
285 284 self.pylintstub = None
286 285 self.release_notes_url = "http://www.opensolaris.org"
287 286 self.__image_activity_lock = Lock()
288 287
289 288 # Create Widgets and show gui
290 289 self.gladefile = os.path.join(self.application_dir,
291 290 "usr/share/package-manager/packagemanager.glade")
292 291 w_tree_main = gtk.glade.XML(self.gladefile, "mainwindow")
293 292 w_tree_progress = gtk.glade.XML(self.gladefile, "progressdialog")
294 293 w_tree_preferences = gtk.glade.XML(self.gladefile, "preferencesdialog")
295 294 w_tree_api_search_error = gtk.glade.XML(self.gladefile,
296 295 "api_search_error")
297 296 self.w_preferencesdialog = \
298 297 w_tree_preferences.get_widget("preferencesdialog")
299 298 self.w_startpage_checkbutton = \
300 299 w_tree_preferences.get_widget("startpage_checkbutton")
301 300 self.api_search_error_dialog = \
302 301 w_tree_api_search_error.get_widget("api_search_error")
303 302 self.api_search_error_textview = \
304 303 w_tree_api_search_error.get_widget("api_search_error_text")
305 304 self.api_search_checkbox = \
306 305 w_tree_api_search_error.get_widget("api_search_checkbox")
307 306 self.api_search_button = \
308 307 w_tree_api_search_error.get_widget("api_search_button")
309 308 infobuffer = self.api_search_error_textview.get_buffer()
310 309 infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
311 310
312 311 self.w_main_window = w_tree_main.get_widget("mainwindow")
313 312 self.w_main_hpaned = \
314 313 w_tree_main.get_widget("main_hpaned")
315 314 self.w_main_vpaned = \
316 315 w_tree_main.get_widget("main_vpaned")
317 316
318 317 self.w_application_treeview = \
319 318 w_tree_main.get_widget("applicationtreeview")
320 319 self.w_categories_treeview = w_tree_main.get_widget("categoriestreeview")
321 320 self.w_info_notebook = w_tree_main.get_widget("details_notebook")
322 321 self.w_generalinfo_textview = \
323 322 w_tree_main.get_widget("generalinfotextview")
324 323 self.w_generalinfo_textview.set_wrap_mode(gtk.WRAP_WORD)
325 324 self.w_installedfiles_textview = \
326 325 w_tree_main.get_widget("installedfilestextview")
327 326 self.w_license_textview = \
328 327 w_tree_main.get_widget("licensetextview")
329 328 self.w_dependencies_textview = \
330 329 w_tree_main.get_widget("dependenciestextview")
331 330 self.w_packagename_label = w_tree_main.get_widget("packagenamelabel")
332 331 self.w_shortdescription_label = \
333 332 w_tree_main.get_widget("shortdescriptionlabel")
334 333 w_package_hbox = \
335 334 w_tree_main.get_widget("package_hbox")
336 335 self.w_general_info_label = \
337 336 w_tree_main.get_widget("general_info_label")
338 337 self.w_startpage_frame = \
339 338 w_tree_main.get_widget("startpage_frame")
340 339 self.w_startpage_eventbox = \
341 340 w_tree_main.get_widget("startpage_eventbox")
342 341 self.w_startpage_eventbox.modify_bg(gtk.STATE_NORMAL,
343 342 gtk.gdk.color_parse("white"))
344 343
345 344 self.w_main_statusbar = w_tree_main.get_widget("statusbar")
346 345 self.w_infosearch_frame = w_tree_main.get_widget("infosearch_frame")
347 346 self.w_infosearch_button = w_tree_main.get_widget("infosearch_button")
348 347
349 348 self.w_main_view_notebook = \
350 349 w_tree_main.get_widget("main_view_notebook")
351 350 self.w_searchentry = w_tree_main.get_widget("searchentry")
352 351 self.w_installupdate_button = \
353 352 w_tree_main.get_widget("install_update_button")
354 353 self.w_remove_button = w_tree_main.get_widget("remove_button")
355 354 self.w_updateall_button = w_tree_main.get_widget("update_all_button")
356 355 self.w_reload_button = w_tree_main.get_widget("reloadbutton")
357 356 self.w_repository_combobox = w_tree_main.get_widget("repositorycombobox")
358 357 self.w_sections_combobox = w_tree_main.get_widget("sectionscombobox")
359 358 self.w_filter_combobox = w_tree_main.get_widget("filtercombobox")
360 359 self.w_packageicon_image = w_tree_main.get_widget("packageimage")
361 360 self.w_installupdate_menuitem = \
362 361 w_tree_main.get_widget("package_install_update")
363 362 self.w_remove_menuitem = w_tree_main.get_widget("package_remove")
364 363 self.w_updateall_menuitem = w_tree_main.get_widget("package_update_all")
365 364 self.w_cut_menuitem = w_tree_main.get_widget("edit_cut")
366 365 self.w_copy_menuitem = w_tree_main.get_widget("edit_copy")
367 366 self.w_paste_menuitem = w_tree_main.get_widget("edit_paste")
368 367 self.w_clear_menuitem = w_tree_main.get_widget("edit_clear")
369 368 self.w_selectall_menuitem = w_tree_main.get_widget("edit_select_all")
370 369 self.w_selectupdates_menuitem = \
371 370 w_tree_main.get_widget("edit_select_updates")
372 371 self.w_deselect_menuitem = w_tree_main.get_widget("edit_deselect")
373 372 self.w_main_clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)
374 373 self.w_progress_dialog = w_tree_progress.get_widget("progressdialog")
375 374 self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
376 375 self.w_progress_dialog.set_title(_("Update All"))
377 376 self.w_progressinfo_label = w_tree_progress.get_widget("progressinfo")
378 377 self.w_progressinfo_label.set_text(_(
379 378 "Checking SUNWipkg and SUNWipkg-gui versions\n\nPlease wait ..."))
380 379 self.w_progressbar = w_tree_progress.get_widget("progressbar")
381 380 self.w_progressbar.set_pulse_step(0.1)
382 381 self.w_progress_cancel = w_tree_progress.get_widget("progresscancel")
383 382 self.progress_canceled = False
384 383 self.w_clear_search_button = w_tree_main.get_widget("clear_search")
385 384 self.w_clear_search_button.set_sensitive(False)
386 385 clear_search_image = w_tree_main.get_widget("clear_image")
387 386 clear_search_image.set_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU)
388 387 self.saved_filter_combobox_active = self.initial_show_filter
389 388 self.search_image = w_tree_main.get_widget("search_image")
390 389 self.search_button = w_tree_main.get_widget("set_search")
391 390 self.a11y_search_button = self.search_button.get_accessible()
392 391 self.is_search_all = False
393 392 self.searchmenu = gtk.Menu()
394 393 self.search_image.set_from_pixbuf(self.search_options[0][1])
395 394 self.a11y_search_button.set_description(self.search_options[0][3])
396 395 for stock_id, pixbuf, label, description in self.search_options:
397 396 action = gtk.Action(stock_id, label, None, stock_id)
398 397 action.connect('activate',
399 398 self.__search_menu_item_activate)
400 399 menu_item = action.create_menu_item()
401 400 self.searchmenu.append(menu_item)
402 401 self.pylintstub = description
403 402 self.pylintstub = pixbuf
404 403 self.changing_search_option = False
405 404 self.saved_repository_combobox_active = -1
406 405 self.saved_sections_combobox_active = 0
407 406 self.saved_application_list = None
408 407 self.saved_application_list_filter = None
409 408 self.saved_application_list_sort = None
410 409 self.saved_category_list = None
411 410 self.saved_section_list = None
412 411 self.saved_selected_application_path = None
413 412 self.statusbar_message_id = 0
414 413 toolbar = w_tree_main.get_widget("toolbutton2")
415 414 toolbar.set_expand(True)
416 415 self.__init_repository_tree_view()
417 416 self.install_button_tooltip = gtk.Tooltips()
418 417 self.remove_button_tooltip = gtk.Tooltips()
419 418 self.__update_reload_button()
420 419 self.w_main_window.set_title(self.main_window_title)
421 420 self.w_searchentry.grab_focus()
422 421
423 422 # Update All Completed Dialog
424 423 w_xmltree_ua_completed = gtk.glade.XML(self.gladefile,
425 424 "ua_completed_dialog")
426 425 self.w_ua_completed_dialog = w_xmltree_ua_completed.get_widget(
427 426 "ua_completed_dialog")
428 427 self.w_ua_completed_dialog .connect("destroy",
429 428 self.__on_ua_completed_close)
430 429 self.w_ua_completed_release_label = w_xmltree_ua_completed.get_widget(
431 430 "ua_completed_release_label")
432 431 self.w_ua_completed_linkbutton = w_xmltree_ua_completed.get_widget(
433 432 "ua_completed_linkbutton")
434 433
435 434 # Setup Start Page
436 435 self.document = None
437 436 self.view = None
438 437 self.current_url = None
439 438 self.opener = None
440 439 self.__setup_startpage(self.show_startpage)
441 440
442 441 try:
443 442 dic_mainwindow = \
444 443 {
445 444 "on_mainwindow_delete_event": \
446 445 self.__on_mainwindow_delete_event,
447 446 "on_searchentry_changed":self.__on_searchentry_changed,
448 447 "on_searchentry_focus_in_event": \
449 448 self.__on_searchentry_focus_in,
450 449 "on_searchentry_focus_out_event": \
451 450 self.__on_searchentry_focus_out,
452 451 "on_searchentry_activate": \
453 452 self.__on_searchentry_activate,
454 453 "on_sectionscombobox_changed": \
455 454 self.__on_sectionscombobox_changed,
456 455 "on_filtercombobox_changed": \
457 456 self.__on_filtercombobox_changed,
458 457 "on_repositorycombobox_changed": \
459 458 self.__on_repositorycombobox_changed,
460 459 #menu signals
461 460 "on_file_quit_activate":self.__on_file_quit_activate,
462 461 "on_file_be_activate":self.__on_file_be_activate,
463 462 "on_package_install_update_activate": \
464 463 self.__on_install_update,
465 464 "on_settings_edit_repositories_activate": \
466 465 self.__on_edit_repositories_activate,
467 466 "on_package_remove_activate":self.__on_remove,
468 467 "on_help_about_activate":self.__on_help_about,
469 468 "on_help_help_activate":self.__on_help_help,
470 469 "on_edit_paste_activate":self.__on_edit_paste,
471 470 "on_edit_clear_activate":self.__on_clear_paste,
472 471 "on_edit_copy_activate":self.__on_copy,
473 472 "on_edit_cut_activate":self.__on_cut,
474 473 "on_edit_search_activate":self.__on_edit_search_clicked,
475 474 "on_set_search_clicked":self.__on_set_search_clicked,
476 475 "on_set_search_button_press_event":self.__on_set_search,
477 476 "on_clear_search_clicked":self.__on_clear_search,
478 477 "on_edit_select_all_activate":self.__on_select_all,
479 478 "on_edit_select_updates_activate": \
480 479 self.__on_select_updates,
481 480 "on_edit_deselect_activate":self.__on_deselect,
482 481 "on_edit_preferences_activate":self.__on_preferences,
483 482 # XXX disabled until new API
484 483 "on_package_update_all_activate":self.__on_update_all,
485 484 #toolbar signals
486 485 # XXX disabled until new API
487 486 "on_update_all_button_clicked":self.__on_update_all,
488 487 "on_reload_button_clicked":self.__on_reload,
489 488 "on_install_update_button_clicked": \
490 489 self.__on_install_update,
491 490 "on_remove_button_clicked":self.__on_remove,
492 491 "on_help_start_page_activate":self.__on_startpage,
493 492 "on_details_notebook_switch_page": \
494 493 self.__on_notebook_change,
495 494 "on_infosearch_button_clicked": \
496 495 self.__on_infosearch_button_clicked,
497 496 }
498 497 dic_progress = \
499 498 {
500 499 "on_cancel_progressdialog_clicked": \
501 500 self.__on_cancel_progressdialog_clicked,
502 501 }
503 502 dic_preferences = \
504 503 {
505 504 "on_startpage_checkbutton_toggled": \
506 505 self.__on_startpage_checkbutton_toggled,
507 506 "on_preferenceshelp_clicked": \
508 507 self.__on_preferenceshelp_clicked,
509 508 "on_preferencesclose_clicked": \
510 509 self.__on_preferencesclose_clicked,
511 510 }
512 511 dic_api_search_error = \
513 512 {
514 513 "on_api_search_checkbox_toggled": \
515 514 self.__on_api_search_checkbox_toggled,
516 515 "on_api_search_button_clicked": \
517 516 self.__on_api_search_button_clicked,
518 517 "on_api_search_error_delete_event": \
519 518 self.__on_api_search_error_delete_event,
520 519 }
521 520 dic_completed = \
522 521 {
523 522 "on_ua_complete_close_button_clicked": \
524 523 self.__on_ua_completed_close,
525 524 "on_ua_completed_linkbutton_clicked": \
526 525 self.__on_ua_completed_linkbutton_clicked,
527 526 }
528 527 w_xmltree_ua_completed.signal_autoconnect(dic_completed)
529 528
530 529
531 530 w_tree_main.signal_autoconnect(dic_mainwindow)
532 531 w_tree_progress.signal_autoconnect(dic_progress)
533 532 w_tree_preferences.signal_autoconnect(dic_preferences)
534 533 w_tree_api_search_error.signal_autoconnect(
535 534 dic_api_search_error)
536 535 except AttributeError, error:
537 536 print _(
538 537 "GUI will not respond to any event! %s."
539 538 "Check declare_signals()") \
540 539 % error
541 540
542 541 self.package_selection = None
543 542 self.category_list_filter = None
544 543 self.application_list_filter = None
545 544 self.application_list_sort = None
546 545 self.application_refilter_id = 0
547 546 self.application_refilter_idle_id = 0
548 547 self.last_show_info_id = 0
549 548 self.show_info_id = 0
550 549 self.last_show_licenses_id = 0
551 550 self.show_licenses_id = 0
552 551 self.showing_empty_details = False
553 552 self.in_setup = True
554 553 if self.initial_app_width >= MIN_APP_WIDTH and \
555 554 self.initial_app_height >= MIN_APP_HEIGHT:
556 555 self.w_main_window.resize(self.initial_app_width,
557 556 self.initial_app_height)
558 557 if self.initial_app_hpos > 0:
559 558 self.w_main_hpaned.set_position(self.initial_app_hpos)
560 559 if self.initial_app_vpos > 0:
561 560 self.w_main_vpaned.set_position(self.initial_app_vpos)
562 561 self.w_main_window.show_all()
563 562 gdk_win = self.w_main_window.get_window()
564 563 self.gdk_window = gtk.gdk.Window(gdk_win, gtk.gdk.screen_width(),
565 564 gtk.gdk.screen_height(), gtk.gdk.WINDOW_CHILD, 0, gtk.gdk.INPUT_ONLY)
566 565 gdk_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
567 566 self.gdk_window.set_cursor(gdk_cursor)
568 567 # Until package icons become available hide Package Icon Panel
569 568 w_package_hbox.hide()
570 569 if self.show_startpage:
571 570 self.w_main_view_notebook.set_current_page(NOTEBOOK_START_PAGE)
572 571 else:
573 572 self.w_main_view_notebook.set_current_page(
574 573 NOTEBOOK_PACKAGE_LIST_PAGE)
575 574 self.api_search_error_dialog.set_transient_for(self.w_main_window)
576 575 self.__setup_text_signals()
577 576
578 577 def __setup_text_signals(self):
579 578 self.w_generalinfo_textview.get_buffer().connect(
580 579 "notify::has-selection", self.__on_text_buffer_has_selection)
581 580 self.w_installedfiles_textview.get_buffer().connect(
582 581 "notify::has-selection", self.__on_text_buffer_has_selection)
583 582 self.w_dependencies_textview.get_buffer().connect(
584 583 "notify::has-selection", self.__on_text_buffer_has_selection)
585 584 self.w_license_textview.get_buffer().connect(
586 585 "notify::has-selection", self.__on_text_buffer_has_selection)
587 586 self.w_searchentry.connect(
588 587 "notify::cursor-position", self.__on_searchentry_selection)
589 588 self.w_searchentry.connect(
590 589 "notify::selection-bound", self.__on_searchentry_selection)
591 590 self.w_generalinfo_textview.connect(
592 591 "focus-in-event", self.__on_textview_focus_in)
593 592 self.w_installedfiles_textview.connect(
594 593 "focus-in-event", self.__on_textview_focus_in)
595 594 self.w_dependencies_textview.connect(
596 595 "focus-in-event", self.__on_textview_focus_in)
597 596 self.w_license_textview.connect(
598 597 "focus-in-event", self.__on_textview_focus_in)
599 598 self.w_generalinfo_textview.connect(
600 599 "focus-out-event", self.__on_textview_focus_out)
601 600 self.w_installedfiles_textview.connect(
602 601 "focus-out-event", self.__on_textview_focus_out)
603 602 self.w_dependencies_textview.connect(
604 603 "focus-out-event", self.__on_textview_focus_out)
605 604 self.w_license_textview.connect(
606 605 "focus-out-event", self.__on_textview_focus_out)
607 606
608 607 def __on_textview_focus_in(self, widget, event):
609 608 char_count = widget.get_buffer().get_char_count()
610 609 if char_count > 0:
611 610 self.w_selectall_menuitem.set_sensitive(True)
612 611 else:
613 612 self.w_selectall_menuitem.set_sensitive(False)
614 613 bounds = widget.get_buffer().get_selection_bounds()
615 614 if bounds:
616 615 offset1 = bounds[0].get_offset()
617 616 offset2 = bounds[1].get_offset()
618 617 if abs(offset2 - offset1) == char_count:
619 618 self.w_selectall_menuitem.set_sensitive(False)
620 619 self.w_deselect_menuitem.set_sensitive(True)
621 620 self.w_copy_menuitem.set_sensitive(True)
622 621 else:
623 622 self.w_deselect_menuitem.set_sensitive(False)
624 623
625 624 def __on_textview_focus_out(self, widget, event):
626 625 self.__enable_disable_select_all()
627 626 self.__enable_disable_deselect()
628 627 self.w_copy_menuitem.set_sensitive(False)
629 628
630 629 def __on_text_buffer_has_selection(self, object, pspec):
631 630 if object.get_selection_bounds():
632 631 self.w_copy_menuitem.set_sensitive(True)
633 632 self.w_deselect_menuitem.set_sensitive(True)
634 633 else:
635 634 self.w_copy_menuitem.set_sensitive(False)
636 635 self.w_deselect_menuitem.set_sensitive(False)
637 636
638 637 def __register_iconsets(self, icon_info):
639 638 factory = gtk.IconFactory()
640 639 for stock_id, pixbuf, name, description in icon_info:
641 640 iconset = gtk.IconSet(pixbuf)
642 641 factory.add(stock_id, iconset)
643 642 self.pylintstub = name
644 643 self.pylintstub = description
645 644 factory.add_default()
646 645
647 646 def __set_search_option(self, i):
648 647 # The value i is the index in the table search_options
649 648 # of the current choice.
650 649 # Index 0 corresponds to Current Repository.
651 650 # We assume that anything else is search all.
652 651 # This may need to be revisited if more search options are
653 652 # added.
654 653 if i == self.current_search_option:
655 654 return
656 655 self.current_search_option = i
657 656 self.changing_search_option = True
658 657 is_search_all = (i != 0)
659 658 self.__update_repository_combobox_for_search(is_search_all)
660 659 if is_search_all:
661 660 self.__setup_before_search_all_mode()
662 661 else:
663 662 self.__restore_setup_for_browse()
664 663 self.changing_search_option = False
665 664
666 665 def __update_repository_combobox_for_search(self, is_search_all):
667 666 if is_search_all:
|
↓ open down ↓ |
385 lines elided |
↑ open up ↑ |
668 667 self.saved_repository_combobox_active = \
669 668 self.w_repository_combobox.get_active()
670 669 self.__disconnect_repository_model()
671 670 if is_search_all:
672 671 self.repositories_list.prepend(
673 672 [-1, _("All Repositories Search Results"), ])
674 673 else:
675 674 self.repositories_list.remove(
676 675 self.repositories_list.get_iter_first())
677 676 self.w_repository_combobox.set_model(self.repositories_list)
678 - self.visible_repository = None
677 + #self.visible_repository = None
679 678
680 679
681 680 def __link_load_blank(self):
682 681 self.document.clear()
683 682 self.document.open_stream('text/html')
684 683 self.document.write_stream(_(
685 684 "<html><head></head><body></body></html>"))
686 685 self.document.close_stream()
687 686
688 687 def __search_menu_item_activate(self, widget):
689 688 name = widget.get_name()
690 689 i = 0
691 690 for stock_id, pixbuf, label, description in self.search_options:
692 691 if stock_id == name:
693 692 self.__set_search_option(i)
694 693 self.search_image.set_from_pixbuf(pixbuf)
695 694 self.a11y_search_button.set_description(description)
696 695 break
697 696 i += 1
698 697 self.pylintstub = label
699 698
700 699 def __setup_startpage(self, show_startpage):
701 700 self.opener = urllib.FancyURLopener()
702 701 self.document = gtkhtml2.Document()
703 702 self.document.connect('request_url', self.__request_url)
704 703 self.document.connect('link_clicked', self.__handle_link)
705 704 self.document.clear()
706 705
707 706 self.view = gtkhtml2.View()
708 707 self.view.set_document(self.document)
709 708 self.view.connect('request_object', self.__request_object)
710 709 self.view.connect('on_url', self.__on_url)
711 710
712 711 try:
713 712 self.lang, encode = locale.getlocale(locale.LC_CTYPE)
714 713 if debug:
715 714 print "Lang: %s: Encode: %s" % (self.lang, encode)
716 715 except locale.Error:
717 716 self.lang = "C"
718 717 if self.lang == None or self.lang == "":
719 718 self.lang = "C"
720 719 self.lang_root = self.lang.split('_')[0]
721 720 if show_startpage:
722 721 self.__load_startpage()
723 722 self.w_startpage_frame.add(self.view)
724 723
725 724 # Stub handler required by GtkHtml widget
726 725 def __request_object(self, *vargs):
727 726 pass
728 727
729 728 def __load_startpage(self):
730 729 if self.__load_startpage_locale(START_PAGE_CACHE_LANG_BASE):
731 730 return
732 731 if self.__load_startpage_locale(START_PAGE_LANG_BASE):
733 732 return
734 733 self.__handle_startpage_load_error(start_page_url)
735 734
736 735
737 736 def __load_startpage_locale(self, start_page_lang_base):
738 737 start_page_url = os.path.join(self.application_dir,
739 738 start_page_lang_base % (self.lang, START_PAGE_HOME))
740 739 if self.__load_uri(self.document, start_page_url):
741 740 return True
742 741
743 742 if self.lang_root != None and self.lang_root != self.lang:
744 743 start_page_url = os.path.join(self.application_dir,
745 744 start_page_lang_base % (self.lang_root, START_PAGE_HOME))
746 745 if self.__load_uri(self.document, start_page_url):
747 746 return True
748 747
749 748 start_page_url = os.path.join(self.application_dir,
750 749 start_page_lang_base % ("C", START_PAGE_HOME))
751 750 if self.__load_uri(self.document, start_page_url):
752 751 return True
753 752 return False
754 753
|
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
755 754 def __handle_startpage_load_error(self, start_page_url):
756 755 self.document.open_stream('text/html')
757 756 self.document.write_stream(_(
758 757 "<html><head></head><body><H2>Welcome to"
759 758 "PackageManager!</H2><br>"
760 759 "<font color='#0000FF'>Warning: Unable to "
761 760 "load Start Page:<br>%s</font></body></html>"
762 761 % (start_page_url)))
763 762 self.document.close_stream()
764 763
765 - def __parse_api_search_error(self, error):
764 + def __process_api_search_error(self, error):
766 765 self.current_repos_with_search_errors = []
767 - if "failed_servers" in error.__dict__ and len(error.failed_servers) > 0:
768 - #TBD we should not have to parse the error output
769 - rem_str = " doesn't speak a known version of search operation"
770 - timeout_str = "urlopen error timed out"
771 - repos = []
772 - for err in error.failed_servers:
773 - err_str = str(err[1])
774 - if rem_str in err_str:
775 - repo = err_str.replace(rem_str,"")
776 - self.current_repos_with_search_errors.append(repo)
777 - elif timeout_str in err_str:
778 - repo = err[0].repositories[0].origins[0].uri
779 - self.current_repos_with_search_errors.append(repo)
780 766
767 + for pub, err in error.failed_servers:
768 + self.current_repos_with_search_errors.append(
769 + (pub, _("failed to respond"), err))
770 + for pub in error.invalid_servers:
771 + self.current_repos_with_search_errors.append(
772 + (pub, _("invalid response"),
773 + _("A valid response was not returned.")))
774 + for pub, err in error.unsupported_servers:
775 + self.current_repos_with_search_errors.append(
776 + (pub, _("unsupported search"), err))
777 +
781 778 def __on_infosearch_button_clicked(self, widget):
782 779 self.__handle_api_search_error(True)
783 780
784 781 def __handle_api_search_error(self, show_all=False):
785 782 if len(self.current_repos_with_search_errors) == 0:
786 783 self.w_infosearch_frame.hide()
787 784 return
788 - else:
789 - self.w_infosearch_button.set_size_request(26, 22)
790 - self.w_infosearch_frame.show()
791 785
792 - repo_pubs = self.__get_repo_publishers()
793 786 repo_count = 0
794 - for url in self.current_repos_with_search_errors:
795 - if show_all or (url not in self.gconf_not_show_repos):
787 + for pub, err_type, err_str in self.current_repos_with_search_errors:
788 + if show_all or (pub not in self.gconf_not_show_repos):
796 789 repo_count += 1
797 790 if repo_count == 0:
791 + self.w_infosearch_frame.hide()
798 792 return
799 793
794 + self.w_infosearch_button.set_size_request(26, 22)
795 + self.w_infosearch_frame.show()
800 796 infobuffer = self.api_search_error_textview.get_buffer()
801 797 infobuffer.set_text("")
802 798 textiter = infobuffer.get_end_iter()
803 - for url in self.current_repos_with_search_errors:
804 - if show_all or (url not in self.gconf_not_show_repos):
799 + for pub, err_type, err_str in self.current_repos_with_search_errors:
800 +
801 + if show_all or (pub not in self.gconf_not_show_repos):
805 802 infobuffer.insert_with_tags_by_name(textiter,
806 - "%s" % repo_pubs[url], "bold")
807 - infobuffer.insert(textiter, " (%s)\n" % url)
803 + "%(pub)s (%(err_type)s)\n" % {"pub": pub,
804 + "err_type": err_type}, "bold")
805 + infobuffer.insert(textiter, "%s\n" % (err_str))
806 +
808 807 self.api_search_checkbox.set_active(False)
809 808 self.api_search_error_dialog.show()
810 809 self.api_search_button.grab_focus()
811 810
812 811 def __get_repo_publishers(self):
813 812 repo_pub_dict = {}
814 813 pubs = self.api_o.get_publishers()
815 814 for pub in pubs:
816 815 repo = pub.selected_repository
817 816 origin = repo.origins[0]
818 817 repo_pub_dict[origin.uri] = pub.prefix
819 818 return repo_pub_dict
820 819
821 820 def __on_url(self, view, link):
822 821 # Handle mouse over events on links and reset when not on link
823 822 if link == None or link == "":
824 823 self.update_statusbar()
825 824 else:
826 825 display_link = self.__handle_link(None, link, DISPLAY_LINK)
827 826 if display_link != None:
828 827 self.w_main_statusbar.push(0, display_link)
829 828 else:
830 829 self.update_statusbar()
831 830
832 831 @staticmethod
833 832 def __is_relative_to_server(url):
834 833 parts = urlparse.urlparse(url)
835 834 if parts[0] or parts[1]:
836 835 return 0
837 836 return 1
838 837
839 838 def __open_url(self, url):
840 839 uri = self.__resolve_uri(url)
841 840 return self.opener.open(uri)
842 841
843 842 def __resolve_uri(self, uri):
844 843 if self.__is_relative_to_server(uri) and self.current_url != uri:
845 844 return urlparse.urljoin(self.current_url, uri)
846 845 return uri
847 846
848 847 def __request_url(self, document, url, stream):
849 848 f = self.__open_url(url)
850 849 stream.set_cancel_func(self.__stream_cancel)
851 850 stream.write(f.read())
852 851
853 852 # Stub handler required by GtkHtml widget or widget will assert
854 853 def __stream_cancel(self, *vargs):
855 854 pass
856 855
857 856 def __load_uri(self, document, link):
858 857 self.w_main_statusbar.push(0, _("Loading... " + link))
859 858 try:
860 859 f = self.__open_url(link)
861 860 except (IOError, OSError), err:
862 861 if debug:
863 862 print "err: %s" % (err)
864 863 self.w_main_statusbar.push(0, _("Stopped"))
865 864 return False
866 865 self.current_url = self.__resolve_uri(link)
867 866
868 867 self.document.clear()
869 868 headers = f.info()
870 869 mime = headers.getheader('Content-type').split(';')[0]
871 870 if mime:
872 871 self.document.open_stream(mime)
873 872 else:
874 873 self.document.open_stream('text/plain')
875 874
876 875 self.document.write_stream(f.read())
877 876 self.document.close_stream()
878 877 self.w_main_statusbar.push(0, _("Done"))
879 878 return True
880 879
881 880 def __link_load_error(self, link):
882 881 self.document.clear()
883 882 self.document.open_stream('text/html')
884 883 self.document.write_stream(_(
885 884 "<html><head></head><body><font color='#000000'>\
886 885 <a href='stub'></a></font>\
887 886 <a href='pm?%s=internal&uri=%s'>\
888 887 <IMG SRC = 'startpage_star.png' \
889 888 style='border-style: none'></a> <br><br>\
890 889 <h2><font color='#0000FF'>Warning: Unable to \
891 890 load URL</font></h2><br>%s</body></html>"
892 891 % (PM_ACTION, START_PAGE_HOME, link)))
893 892 self.document.close_stream()
894 893
895 894 def __handle_link(self, document, link, handle_what = CLICK_LINK):
896 895 query_dict = self.__urlparse_qs(link)
897 896
898 897 action = None
899 898 if query_dict.has_key(PM_ACTION):
900 899 action = query_dict[PM_ACTION][0]
901 900 elif handle_what == DISPLAY_LINK:
902 901 return link
903 902 ext_uri = ""
904 903 protocol = None
905 904
906 905 # Internal Browse
907 906 if action == ACTION_INTERNAL:
908 907 if query_dict.has_key(INTERNAL_URI):
909 908 int_uri = query_dict[INTERNAL_URI][0]
910 909 if handle_what == DISPLAY_LINK:
911 910 return int_uri
912 911 else:
913 912 if handle_what == CLICK_LINK:
914 913 self.__link_load_error(_("No URI specified"))
915 914 return
916 915 if handle_what == CLICK_LINK and \
917 916 not self.__load_uri(document, int_uri):
918 917 self.__link_load_error(int_uri)
919 918 return
920 919 # External browse
921 920 elif action == ACTION_EXTERNAL:
922 921 if query_dict.has_key(EXTERNAL_URI):
923 922 ext_uri = query_dict[EXTERNAL_URI][0]
924 923 else:
925 924 if handle_what == CLICK_LINK:
926 925 self.__link_load_error(_("No URI specified"))
927 926 return
928 927 if query_dict.has_key(EXTERNAL_PROTOCOL):
929 928 protocol = query_dict[EXTERNAL_PROTOCOL][0]
930 929 else:
931 930 protocol = DEFAULT_PROTOCOL
932 931
933 932 if handle_what == DISPLAY_LINK:
934 933 return protocol + "://" + ext_uri
935 934 try:
936 935 gnome.url_show(protocol + "://" + ext_uri)
937 936 except gobject.GError:
938 937 self.__link_load_error(protocol + "://" + ext_uri)
939 938 elif handle_what == DISPLAY_LINK:
940 939 return None
941 940 elif action == None:
942 941 try:
943 942 gnome.url_show(link)
944 943 except gobject.GError:
945 944 self.__link_load_error(link)
946 945 # Handle empty and unsupported actions
947 946 elif action == "":
948 947 self.__link_load_error(_("Empty Action not supported"
949 948 % action))
950 949 return
951 950 elif action != None:
952 951 self.__link_load_error(_("Action not supported: %s"
953 952 % action))
954 953 return
955 954
956 955 @staticmethod
957 956 def __urlparse_qs(url, keep_blank_values=0, strict_parsing=0):
958 957 scheme, netloc, url, params, querystring, fragment = urlparse.urlparse(
959 958 url)
960 959 if debug:
961 960 print ("Query: scheme %s, netloc %s, url %s, params %s,"
962 961 "querystring %s, fragment %s"
963 962 % (scheme, netloc, url, params, querystring, fragment))
964 963 return parseqs.parse_qs(querystring)
965 964
966 965 @staticmethod
967 966 def __get_new_application_liststore():
968 967 return gtk.ListStore(
969 968 gobject.TYPE_BOOLEAN, # enumerations.MARK_COLUMN
970 969 gtk.gdk.Pixbuf, # enumerations.STATUS_ICON_COLUMN
971 970 gobject.TYPE_STRING, # enumerations.NAME_COLUMN
972 971 gobject.TYPE_STRING, # enumerations.DESCRIPTION_COLUMN
973 972 gobject.TYPE_INT, # enumerations.STATUS_COLUMN
974 973 gobject.TYPE_PYOBJECT, # enumerations.FMRI_COLUMN
975 974 gobject.TYPE_STRING, # enumerations.STEM_COLUMN
976 975 gobject.TYPE_STRING, # enumerations.DISPLAY_NAME_COLUMN
977 976 gobject.TYPE_BOOLEAN, # enumerations.IS_VISIBLE_COLUMN
978 977 gobject.TYPE_PYOBJECT, # enumerations.CATEGORY_LIST_COLUMN
979 978 gobject.TYPE_STRING # enumerations.REPOSITORY_COLUMN
980 979 )
981 980
982 981 @staticmethod
983 982 def __get_new_category_liststore():
984 983 return gtk.ListStore(
985 984 gobject.TYPE_INT, # enumerations.CATEGORY_ID
986 985 gobject.TYPE_STRING, # enumerations.CATEGORY_NAME
987 986 gobject.TYPE_STRING, # enumerations.CATEGORY_DESCRIPTION
988 987 gtk.gdk.Pixbuf, # enumerations.CATEGORY_ICON
989 988 gobject.TYPE_BOOLEAN, # enumerations.CATEGORY_ICON_VISIBLE
990 989 gobject.TYPE_BOOLEAN, # enumerations.CATEGORY_VISIBLE
991 990 gobject.TYPE_PYOBJECT, # enumerations.SECTION_LIST_OBJECT
992 991 )
993 992
994 993 @staticmethod
995 994 def __get_new_section_liststore():
996 995 return gtk.ListStore(
997 996 gobject.TYPE_INT, # enumerations.SECTION_ID
998 997 gobject.TYPE_STRING, # enumerations.SECTION_NAME
999 998 gobject.TYPE_STRING, # enumerations.SECTION_SUBCATEGORY
1000 999 gobject.TYPE_BOOLEAN, # enumerations.SECTION_ENABLED
1001 1000 )
1002 1001
1003 1002 @staticmethod
1004 1003 def __get_new_filter_liststore():
1005 1004 return gtk.ListStore(
1006 1005 gobject.TYPE_INT, # enumerations.FILTER_ID
1007 1006 gobject.TYPE_STRING, # enumerations.FILTER_NAME
|
↓ open down ↓ |
190 lines elided |
↑ open up ↑ |
1008 1007 )
1009 1008
1010 1009 @staticmethod
1011 1010 def __get_new_repositories_liststore():
1012 1011 return gtk.ListStore(
1013 1012 gobject.TYPE_INT, # enumerations.REPOSITORY_ID
1014 1013 gobject.TYPE_STRING, # enumerations.REPOSITORY_NAME
1015 1014 )
1016 1015
1017 1016 def __init_application_tree_view(self, application_list,
1018 - application_list_filter, application_list_sort):
1017 + application_list_filter, application_list_sort,
1018 + application_sort_column):
1019 1019 ##APPLICATION MAIN TREEVIEW
1020 1020 if application_list_filter == None:
1021 1021 application_list_filter = application_list.filter_new()
1022 1022 if application_list_sort == None:
1023 1023 application_list_sort = \
1024 1024 gtk.TreeModelSort(application_list_filter)
1025 1025 application_list_sort.set_sort_column_id(
1026 - enumerations.NAME_COLUMN, gtk.SORT_ASCENDING)
1026 + application_sort_column, gtk.SORT_ASCENDING)
1027 1027 application_list_sort.set_sort_func(
1028 1028 enumerations.STATUS_ICON_COLUMN, self.__status_sort_func)
1029 1029 toggle_renderer = gtk.CellRendererToggle()
1030 1030
1031 1031 column = gtk.TreeViewColumn("", toggle_renderer, \
1032 1032 active = enumerations.MARK_COLUMN)
1033 1033 column.set_sort_column_id(enumerations.MARK_COLUMN)
1034 1034 column.set_sort_indicator(True)
1035 1035 column.set_cell_data_func(toggle_renderer, self.cell_data_function, None)
1036 1036 column.connect_after('clicked',
1037 1037 self.__application_treeview_column_sorted, None)
1038 1038 self.w_application_treeview.append_column(column)
1039 1039 name_renderer = gtk.CellRendererText()
1040 1040 column = gtk.TreeViewColumn(_("Name"), name_renderer,
1041 1041 text = enumerations.NAME_COLUMN)
1042 1042 column.set_resizable(True)
1043 + column.set_min_width(150)
1043 1044 column.set_sort_column_id(enumerations.NAME_COLUMN)
1044 1045 column.set_sort_indicator(True)
1045 1046 column.set_cell_data_func(name_renderer, self.cell_data_function, None)
1046 1047 column.connect_after('clicked',
1047 1048 self.__application_treeview_column_sorted, None)
1048 1049 self.w_application_treeview.append_column(column)
1049 1050 column = self.__create_icon_column(_("Status"), True,
1050 1051 enumerations.STATUS_ICON_COLUMN, True)
1051 1052 column.set_sort_column_id(enumerations.STATUS_ICON_COLUMN)
1052 1053 column.set_sort_indicator(True)
1053 1054 column.connect_after('clicked',
1054 1055 self.__application_treeview_column_sorted, None)
1055 1056 self.w_application_treeview.append_column(column)
1056 1057 if self.is_search_all:
1057 1058 repository_renderer = gtk.CellRendererText()
1058 1059 column = gtk.TreeViewColumn(_('Repository'),
1059 1060 repository_renderer,
1060 1061 text = enumerations.AUTHORITY_COLUMN)
1061 1062 column.set_sort_column_id(enumerations.AUTHORITY_COLUMN)
1062 1063 column.set_resizable(True)
1063 1064 column.set_sort_indicator(True)
1064 1065 column.set_cell_data_func(repository_renderer,
1065 1066 self.cell_data_function, None)
1066 1067 column.connect_after('clicked',
1067 1068 self.__application_treeview_column_sorted, None)
1068 1069 self.w_application_treeview.append_column(column)
1069 1070 description_renderer = gtk.CellRendererText()
1070 1071 column = gtk.TreeViewColumn(_('Description'),
1071 1072 description_renderer,
1072 1073 text = enumerations.DESCRIPTION_COLUMN)
1073 1074 column.set_sort_column_id(enumerations.DESCRIPTION_COLUMN)
1074 1075 column.set_resizable(True)
1075 1076 column.set_sort_indicator(True)
1076 1077 column.set_cell_data_func(description_renderer,
1077 1078 self.cell_data_function, None)
1078 1079 column.connect_after('clicked',
1079 1080 self.__application_treeview_column_sorted, None)
1080 1081 self.w_application_treeview.append_column(column)
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
1081 1082 #Added selection listener
1082 1083 self.package_selection = self.w_application_treeview.get_selection()
1083 1084 self.application_list = application_list
1084 1085 self.application_list_filter = application_list_filter
1085 1086 self.application_list_sort = application_list_sort
1086 1087 toggle_renderer.connect('toggled', self.__active_pane_toggle,
1087 1088 application_list_sort)
1088 1089
1089 1090 def __init_tree_views(self, application_list, category_list,
1090 1091 section_list, application_list_filter = None,
1091 - application_list_sort = None):
1092 + application_list_sort = None,
1093 + application_sort_column = enumerations.NAME_COLUMN):
1092 1094 '''This function connects treeviews with their models and also applies
1093 1095 filters'''
1094 1096 if category_list == None:
1095 1097 self.w_application_treeview.set_model(None)
1096 1098 self.__remove_treeview_columns(self.w_application_treeview)
1097 1099 elif application_list == None:
1098 1100 self.w_categories_treeview.set_model(None)
1099 1101 self.__remove_treeview_columns(self.w_categories_treeview)
1100 1102 else:
1101 1103 self.__disconnect_models()
1102 1104 self.__remove_treeview_columns(self.w_application_treeview)
1103 1105 self.__remove_treeview_columns(self.w_categories_treeview)
1104 1106 # The logic for set section needs to be here as some sections
1105 1107 # might be not enabled. In such situation we are setting the set
1106 1108 # section to "All Categories" one.
1107 1109 if section_list != None:
1108 1110 row = section_list[self.set_section]
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1109 1111 if row[enumerations.SECTION_ENABLED] and \
1110 1112 self.set_section >= 0 and \
1111 1113 self.set_section < len(section_list):
1112 1114 if row[enumerations.SECTION_ID] != self.set_section:
1113 1115 self.set_section = 0
1114 1116 else:
1115 1117 self.set_section = 0
1116 1118
1117 1119 if application_list != None:
1118 1120 self.__init_application_tree_view(application_list,
1119 - application_list_filter, application_list_sort)
1121 + application_list_filter, application_list_sort,
1122 + application_sort_column)
1120 1123
1121 1124 if self.first_run:
1122 1125 # When vadj changes we need to set image descriptions
1123 1126 # on visible status icons. This catches moving the scroll bars
1124 1127 # and scrolling up and down using keyboard.
1125 1128 vadj = self.w_application_treeview.get_vadjustment()
1126 1129 vadj.connect('value-changed',
1127 1130 self.__application_treeview_vadjustment_changed, None)
1128 1131 vadj = self.w_categories_treeview.get_vadjustment()
1129 1132 vadj.connect('value-changed',
1130 1133 self.__categories_treeview_vadjustment_changed, None)
1131 1134
1132 1135 # When the size of the application_treeview changes
1133 1136 # we need to set image descriptions on visible status icons.
1134 1137 self.w_application_treeview.connect('size-allocate',
1135 1138 self.__application_treeview_size_allocate, None)
1136 1139 self.w_categories_treeview.connect('size-allocate',
1137 1140 self.__categories_treeview_size_allocate, None)
1138 1141
1139 1142 if category_list != None:
1140 1143 ##CATEGORIES TREEVIEW
1141 1144 #enumerations.CATEGORY_NAME
1142 1145 category_list_filter = category_list.filter_new()
1143 1146 column = self.__create_icon_column("", False,
1144 1147 enumerations.CATEGORY_ICON, False)
1145 1148 self.w_categories_treeview.append_column(column)
1146 1149 enumerations.CATEGORY_NAME_renderer = gtk.CellRendererText()
1147 1150 column = gtk.TreeViewColumn(_('Name'),
1148 1151 enumerations.CATEGORY_NAME_renderer,
1149 1152 text = enumerations.CATEGORY_NAME)
1150 1153 self.w_categories_treeview.append_column(column)
1151 1154 #Added selection listener
1152 1155 category_selection = self.w_categories_treeview.get_selection()
1153 1156 category_selection.set_mode(gtk.SELECTION_SINGLE)
1154 1157
1155 1158 if self.first_run:
1156 1159 ##SECTION COMBOBOX
1157 1160 #enumerations.SECTION_NAME
1158 1161 cell = gtk.CellRendererText()
1159 1162 self.w_sections_combobox.pack_start(cell, True)
1160 1163 self.w_sections_combobox.add_attribute(cell, 'text',
1161 1164 enumerations.SECTION_NAME)
1162 1165 self.w_sections_combobox.set_row_separator_func(
1163 1166 self.combobox_id_separator)
1164 1167 self.w_sections_combobox.add_attribute( cell,
1165 1168 'sensitive', enumerations.SECTION_ENABLED )
1166 1169 ##FILTER COMBOBOX
1167 1170 #enumerations.FILTER_NAME
1168 1171 cell = gtk.CellRendererText()
1169 1172 self.w_filter_combobox.pack_start(cell, True)
1170 1173 self.w_filter_combobox.add_attribute(cell, 'text',
1171 1174 enumerations.FILTER_NAME)
1172 1175 self.w_filter_combobox.set_row_separator_func(
1173 1176 self.combobox_id_separator)
1174 1177
1175 1178 if section_list != None:
1176 1179 self.section_list = section_list
1177 1180 if category_list != None:
1178 1181 self.category_list = category_list
1179 1182 self.category_list_filter = category_list_filter
1180 1183 self.w_categories_treeview.set_model(category_list_filter)
1181 1184 if not self.is_search_all:
1182 1185 category_list_filter.set_visible_func(
1183 1186 self.category_filter)
1184 1187 self.__set_categories_visibility(self.set_section)
1185 1188 self.a11y_categories_treeview = \
1186 1189 self.w_categories_treeview.get_accessible()
1187 1190 if application_list != None:
1188 1191 if category_list != None:
1189 1192 self.w_sections_combobox.set_model(section_list)
1190 1193 self.w_sections_combobox.set_active(self.set_section)
1191 1194 self.w_filter_combobox.set_model(self.filter_list)
1192 1195 self.w_filter_combobox.set_active(self.set_show_filter)
1193 1196 self.w_application_treeview.set_model(
1194 1197 self.application_list_sort)
1195 1198 if not self.in_search_mode:
1196 1199 if application_list_filter == None:
1197 1200 self.application_list_filter.set_visible_func(
1198 1201 self.__application_filter)
1199 1202
1200 1203 category_selection = self.w_categories_treeview.get_selection()
1201 1204 category_model, category_iter = category_selection.get_selected()
1202 1205 self.pylintstub = category_model
1203 1206 if not category_iter and not self.in_search_mode:
1204 1207 #no category was selected, so select "All"
1205 1208 category_selection.select_path(0)
1206 1209 category_model, category_iter = category_selection.get_selected()
1207 1210 if self.first_run:
1208 1211 category_selection.connect("changed",
1209 1212 self.__on_category_selection_changed, None)
1210 1213 self.w_categories_treeview.connect("row-activated",
1211 1214 self.__on_category_row_activated, None)
1212 1215 self.w_categories_treeview.connect("focus-in-event",
1213 1216 self.__on_category_focus_in, None)
1214 1217 self.package_selection.set_mode(gtk.SELECTION_SINGLE)
1215 1218 self.package_selection.connect("changed",
1216 1219 self.__on_package_selection_changed, None)
1217 1220
1218 1221 self.a11y_application_treeview = \
1219 1222 self.w_application_treeview.get_accessible()
1220 1223 self.process_package_list_end()
1221 1224
1222 1225 def __categories_treeview_size_allocate(self, widget, allocation, user_data):
1223 1226 # We ignore any changes in the size during initialization.
1224 1227 if self.categories_treeview_initialized:
1225 1228 if self.categories_status_id == 0:
1226 1229 self.categories_status_id = gobject.idle_add(
1227 1230 self.__set_accessible_categories_visible_status)
1228 1231
1229 1232 def __categories_treeview_vadjustment_changed(self, widget, user_data):
1230 1233 self.__set_accessible_categories_visible_status()
1231 1234
1232 1235 def __set_accessible_categories_status(self, model, itr):
1233 1236 status = model.get_value(itr, enumerations.CATEGORY_ICON)
1234 1237 if status != None:
1235 1238 desc = _("Updates Available")
1236 1239 else:
1237 1240 desc = None
1238 1241 if desc != None:
1239 1242 obj = self.a11y_categories_treeview.ref_at(
1240 1243 int(model.get_string_from_iter(itr)),
1241 1244 CATEGORIES_STATUS_COLUMN_INDEX)
1242 1245 obj.set_image_description(desc)
1243 1246
1244 1247 def __set_accessible_categories_visible_status(self):
1245 1248 self.categories_status_id = 0
1246 1249 if self.a11y_categories_treeview.get_n_accessible_children() == 0:
1247 1250 # accessibility is not enabled
1248 1251 return
1249 1252
1250 1253 visible_range = self.w_categories_treeview.get_visible_range()
1251 1254 if visible_range == None:
1252 1255 return
1253 1256 start = visible_range[0][0]
1254 1257 end = visible_range[1][0]
1255 1258 # We try to minimize the range of accessible objects
1256 1259 # on which we set image descriptions
1257 1260 if self.categories_treeview_range != None:
1258 1261 old_start = self.categories_treeview_range[0][0]
1259 1262 old_end = self.categories_treeview_range[1][0]
1260 1263 # Old range is the same or smaller than new range
1261 1264 # so do nothing
1262 1265 if start >= old_start and end <= old_end:
1263 1266 return
1264 1267 if start < old_end:
1265 1268 if end < old_end:
1266 1269 if end >= old_start:
1267 1270 end = old_start
1268 1271 else:
1269 1272 start = old_end
1270 1273 self.categories_treeview_range = visible_range
1271 1274 model = self.category_list_filter
1272 1275 itr = model.get_iter_from_string(str(start))
1273 1276 while start <= end:
1274 1277 start += 1
1275 1278 self.__set_accessible_categories_status(model, itr)
1276 1279 itr = model.iter_next(itr)
1277 1280
1278 1281 def __application_treeview_column_sorted(self, widget, user_data):
1279 1282 self.__set_visible_status(False)
1280 1283
1281 1284 def __init_repository_tree_view(self):
1282 1285 cell = gtk.CellRendererText()
1283 1286 self.w_repository_combobox.pack_start(cell, True)
1284 1287 self.w_repository_combobox.add_attribute(cell, 'text',
1285 1288 enumerations.REPOSITORY_NAME)
1286 1289 self.w_repository_combobox.set_row_separator_func(
1287 1290 self.combobox_id_separator)
1288 1291
1289 1292 def __application_treeview_size_allocate(self, widget, allocation, user_data):
1290 1293 # We ignore any changes in the size during initialization.
1291 1294 if self.visible_status_id == 0:
1292 1295 self.visible_status_id = gobject.idle_add(
1293 1296 self.__set_visible_status)
1294 1297
1295 1298 def __application_treeview_vadjustment_changed(self, widget, user_data):
1296 1299 self.__set_visible_status()
1297 1300
1298 1301 def __set_accessible_status(self, model, itr):
1299 1302 status = model.get_value(itr, enumerations.STATUS_COLUMN)
1300 1303 if status == enumerations.INSTALLED:
1301 1304 desc = _("Installed")
1302 1305 elif status == enumerations.NOT_INSTALLED:
1303 1306 desc = _("Not Installed")
1304 1307 elif status == enumerations.UPDATABLE:
1305 1308 desc = _("Updates Available")
1306 1309 else:
1307 1310 desc = None
1308 1311 if desc != None:
|
↓ open down ↓ |
179 lines elided |
↑ open up ↑ |
1309 1312 obj = self.a11y_application_treeview.ref_at(
1310 1313 int(model.get_string_from_iter(itr)),
1311 1314 STATUS_COLUMN_INDEX)
1312 1315 obj.set_image_description(desc)
1313 1316
1314 1317 def __set_visible_status(self, check_range = True):
1315 1318 self.visible_status_id = 0
1316 1319 if self.w_main_view_notebook.get_current_page() != \
1317 1320 NOTEBOOK_PACKAGE_LIST_PAGE:
1318 1321 return
1322 + if self.__doing_search():
1323 + return
1324 +
1319 1325 a11y_enabled = False
1320 1326 if self.a11y_application_treeview.get_n_accessible_children() != 0:
1321 1327 a11y_enabled = True
1322 1328
1323 1329 visible_range = self.w_application_treeview.get_visible_range()
1324 1330 if visible_range == None:
1325 1331 return
1326 1332 start = visible_range[0][0]
1327 1333 end = visible_range[1][0]
1328 1334 if debug_descriptions:
1329 1335 print "Range Start: %d End: %d" % (start, end)
1330 1336
1331 1337 # Switching Publishers need to use default range
1332 1338 active_pub = self.__get_active_publisher()
1333 1339 if self.last_active_publisher != active_pub:
1334 1340 check_range = False
1335 1341 self.last_active_publisher = active_pub
1336 1342 if self.in_search_mode:
1337 1343 check_range = False
1338 1344
1339 1345 if self.application_treeview_range != None:
1340 1346 if check_range:
1341 1347 old_start = self.application_treeview_range[0][0]
1342 1348 old_end = self.application_treeview_range[1][0]
1343 1349 # Old range is the same or smaller than new range
1344 1350 # so do nothing
1345 1351 if start >= old_start and end <= old_end:
1346 1352 return
1347 1353 if start < old_end:
1348 1354 if end < old_end:
1349 1355 if end >= old_start:
1350 1356 end = old_start
1351 1357 else:
1352 1358 start = old_end
1353 1359 if debug_descriptions:
1354 1360 print "Adjusted Range Start: %d End: %d" % (start, end)
1355 1361 self.application_treeview_range = visible_range
1356 1362
1357 1363 sort_filt_model = \
1358 1364 self.w_application_treeview.get_model() #gtk.TreeModelSort
1359 1365 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1360 1366 model = filt_model.get_model() #gtk.ListStore
1361 1367 sf_itr = sort_filt_model.get_iter_from_string(str(start))
1362 1368 pkg_stems_and_itr_to_fetch = {}
1363 1369 while start <= end:
1364 1370 filtered_itr = sort_filt_model.convert_iter_to_child_iter(None,
|
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
1365 1371 sf_itr)
1366 1372 app_itr = filt_model.convert_iter_to_child_iter(filtered_itr)
1367 1373
1368 1374 desc = sort_filt_model.get_value(sf_itr,
1369 1375 enumerations.DESCRIPTION_COLUMN)
1370 1376 # Only Fetch description for packages without a
1371 1377 # description
1372 1378 if desc == '...':
1373 1379 fmri = sort_filt_model.get_value(sf_itr,
1374 1380 enumerations.FMRI_COLUMN)
1375 - pkg_stem = fmri.get_pkg_stem(
1376 - include_scheme = True)
1377 - pkg_stems_and_itr_to_fetch[pkg_stem] = \
1378 - model.get_string_from_iter(app_itr)
1381 + if fmri != None:
1382 + pkg_stem = fmri.get_pkg_stem(
1383 + include_scheme = True)
1384 + pkg_stems_and_itr_to_fetch[pkg_stem] = \
1385 + model.get_string_from_iter(app_itr)
1379 1386 if a11y_enabled:
1380 1387 self.__set_accessible_status(sort_filt_model, sf_itr)
1381 1388 start += 1
1382 1389 sf_itr = sort_filt_model.iter_next(sf_itr)
1383 1390
1384 1391 if debug_descriptions:
1385 1392 print "PKGS to FETCH: \n%s" % pkg_stems_and_itr_to_fetch
1386 1393 if len(pkg_stems_and_itr_to_fetch) > 0:
1387 1394 Thread(target = self.__get_pkg_descriptions,
1388 1395 args = [pkg_stems_and_itr_to_fetch, model]).start()
1389 1396
1390 1397 def __doing_search(self):
1391 1398 return self.search_start > 0
1392 1399
1393 1400 def __get_pkg_descriptions(self, pkg_stems_and_itr_to_fetch, orig_model):
1394 1401 # Note: no need to aquire lock even though this can be called from
1395 1402 # multiple threads, it is just creating an update job and dispatching it
1396 1403 # to the idle handler, not modifying any global state
1397 1404 info = None
1398 1405 if not self.__doing_search():
1399 1406 gobject.idle_add(self.__update_statusbar_message,
1400 1407 _("Fetching descriptions..."))
1401 1408 try:
1402 1409 info = self.api_o.info(pkg_stems_and_itr_to_fetch.keys(), False,
1403 1410 frozenset([api.PackageInfo.IDENTITY,
1404 1411 api.PackageInfo.SUMMARY]))
1405 1412 except api_errors.TransportError:
1406 1413 self.update_statusbar()
1407 1414 return
1408 1415 if info and len(info.get(0)) == 0:
1409 1416 self.update_statusbar()
1410 1417 return
1411 1418 pkg_infos = info.get(0)
1412 1419 pkg_descriptions_for_update = []
1413 1420 for pkg_info in pkg_infos:
1414 1421 short_fmri = fmri.PkgFmri(pkg_info.fmri).get_pkg_stem(
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
1415 1422 include_scheme = True)
1416 1423 pkg_descriptions_for_update.append((short_fmri,
1417 1424 pkg_stems_and_itr_to_fetch[short_fmri],
1418 1425 pkg_info.summary))
1419 1426 if debug_descriptions:
1420 1427 print "FETCHED PKGS: \n%s" % pkg_descriptions_for_update
1421 1428 gobject.idle_add(self.__update_description_from_iter,
1422 1429 pkg_descriptions_for_update, orig_model)
1423 1430
1424 1431 def __update_description_from_iter(self, pkg_descriptions_for_update, orig_model):
1432 + #If doing a search abandon description updates
1433 + if self.__doing_search():
1434 + return
1435 +
1425 1436 sort_filt_model = \
1426 1437 self.w_application_treeview.get_model() #gtk.TreeModelSort
1427 1438 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1428 1439 model = filt_model.get_model() #gtk.ListStore
1429 1440
1430 1441 #If model has changed abandon description updates
1431 1442 if orig_model != model:
1432 1443 return
1433 1444
1434 1445 if debug_descriptions:
1435 1446 print "UPDATE DESCRIPTIONS: \n%s" % pkg_descriptions_for_update
1436 1447 for pkg_stem, path, summary in pkg_descriptions_for_update:
1437 1448 itr = model.get_iter_from_string(path)
1438 1449 stored_pkg_fmri = model.get_value(itr, enumerations.FMRI_COLUMN)
1439 1450 stored_pkg_stem = stored_pkg_fmri.get_pkg_stem(
1440 1451 include_scheme = True)
1441 1452
1442 1453 if pkg_stem != stored_pkg_stem:
1443 1454 if debug:
1444 1455 print ("__update_description_from_iter(): "
1445 1456 "model not consistent so abandoning "
1446 1457 "these description updates.")
1447 1458 self.update_statusbar()
1448 1459 return
1449 1460 model.set_value(itr, enumerations.DESCRIPTION_COLUMN, summary)
1450 1461 if not self.__doing_search():
1451 1462 self.update_statusbar()
1452 1463
1453 1464 def __create_icon_column(self, name, expand_pixbuf, enum_value, set_data_func):
1454 1465 column = gtk.TreeViewColumn()
1455 1466 column.set_title(name)
1456 1467 #Commented, since there was funny jumping of the icons
1457 1468 #column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
1458 1469 render_pixbuf = gtk.CellRendererPixbuf()
1459 1470 column.pack_start(render_pixbuf, expand = expand_pixbuf)
1460 1471 column.add_attribute(render_pixbuf, "pixbuf", enum_value)
1461 1472 column.set_fixed_width(32)
1462 1473 if set_data_func:
1463 1474 column.set_cell_data_func(render_pixbuf,
1464 1475 self.cell_data_function, None)
1465 1476 return column
1466 1477
1467 1478 def __disconnect_models(self):
1468 1479 self.w_application_treeview.set_model(None)
1469 1480 self.w_categories_treeview.set_model(None)
1470 1481 self.w_sections_combobox.set_model(None)
1471 1482 self.w_filter_combobox.set_model(None)
1472 1483
1473 1484 def __disconnect_repository_model(self):
1474 1485 self.w_repository_combobox.set_model(None)
1475 1486
1476 1487 @staticmethod
1477 1488 def __status_sort_func(treemodel, iter1, iter2, user_data=None):
1478 1489 get_val = treemodel.get_value
1479 1490 status1 = get_val(iter1, enumerations.STATUS_COLUMN)
1480 1491 status2 = get_val(iter2, enumerations.STATUS_COLUMN)
1481 1492 return cmp(status1, status2)
1482 1493
1483 1494 @staticmethod
1484 1495 def __remove_treeview_columns(treeview):
1485 1496 columns = treeview.get_columns()
1486 1497 if columns:
1487 1498 for column in columns:
1488 1499 treeview.remove_column(column)
1489 1500
1490 1501 @staticmethod
1491 1502 def __init_sections(section_list):
1492 1503 '''This function is for initializing sections combo box, also adds "All"
1493 1504 Category. It sets active section combobox entry "All"'''
1494 1505 cat_path = None
1495 1506 enabled = True
1496 1507 # We enable only first section and later we might enable the rest,
1497 1508 # depending if there are some packages connected with them
1498 1509 section_list.append([0, _('All Categories'), cat_path, enabled ])
1499 1510 section_list.append([-1, "", cat_path, enabled ])
1500 1511 enabled = False
1501 1512 section_list.append([2, _('Meta Packages'), cat_path, enabled ])
1502 1513 section_list.append([3, _('Applications'), cat_path, enabled ])
1503 1514 section_list.append([4, _('Desktop (GNOME)'), cat_path, enabled ])
1504 1515 section_list.append([5, _('Development'), cat_path, enabled ])
1505 1516 section_list.append([6, _('Distributions'), cat_path, enabled ])
1506 1517 section_list.append([7, _('Drivers'), cat_path, enabled ])
1507 1518 section_list.append([8, _('System'), cat_path, enabled ])
1508 1519 section_list.append([9, _('Web Services'), cat_path, enabled ])
1509 1520
1510 1521 def __init_show_filter(self):
1511 1522 self.filter_list.append([enumerations.FILTER_ALL, _('All Packages'), ])
1512 1523 self.filter_list.append([enumerations.FILTER_INSTALLED,
1513 1524 _('Installed Packages'), ])
1514 1525 self.filter_list.append([enumerations.FILTER_UPDATES,
1515 1526 _('Updates'), ])
1516 1527 self.filter_list.append([enumerations.FILTER_NOT_INSTALLED,
1517 1528 _('Non-installed Packages'), ])
1518 1529 self.filter_list.append([-1, "", ])
1519 1530 self.filter_list.append([enumerations.FILTER_SELECTED,
1520 1531 _('Selected Packages'), ])
1521 1532 if self.initial_show_filter >= enumerations.FILTER_ALL and \
1522 1533 self.initial_show_filter < len(self.filter_list):
1523 1534 row = self.filter_list[self.initial_show_filter]
1524 1535 if row[enumerations.SECTION_ID] != self.initial_show_filter:
1525 1536 self.initial_show_filter = enumerations.FILTER_ALL
1526 1537 else:
1527 1538 self.initial_show_filter = enumerations.FILTER_ALL
1528 1539
1529 1540
1530 1541 def __on_cancel_progressdialog_clicked(self, widget):
1531 1542 self.progress_canceled = True
1532 1543 self.progress_stop_timer_thread = True
1533 1544
1534 1545 def __on_mainwindow_delete_event(self, widget, event):
1535 1546 ''' handler for delete event of the main window '''
1536 1547 if self.__check_if_something_was_changed() == True:
1537 1548 # XXX Change this to not quit and show dialog
1538 1549 # XXX if some changes were applied:
1539 1550 self.__main_application_quit()
1540 1551 return True
1541 1552 else:
1542 1553 self.__main_application_quit()
1543 1554
1544 1555 def __on_api_search_error_delete_event(self, widget, event):
1545 1556 self.__on_api_search_button_clicked(None)
1546 1557
1547 1558 def __on_api_search_button_clicked(self, widget):
1548 1559 self.api_search_error_dialog.hide()
1549 1560
1550 1561 def __on_file_quit_activate(self, widget):
1551 1562 ''' handler for quit menu event '''
1552 1563 self.__on_mainwindow_delete_event(None, None)
1553 1564
1554 1565 def __on_ua_completed_close(self, widget):
1555 1566 self.w_ua_completed_dialog.hide()
1556 1567 self.__on_mainwindow_delete_event(None, None)
1557 1568
1558 1569 def __on_edit_repositories_activate(self, widget):
1559 1570 ''' handler for repository menu event '''
1560 1571 repository.Repository(self)
1561 1572
1562 1573 def __on_file_be_activate(self, widget):
1563 1574 ''' handler for be menu event '''
1564 1575 beadm.Beadmin(self)
1565 1576
1566 1577 def __on_searchentry_changed(self, widget):
1567 1578 if widget.get_text_length() > 0:
1568 1579 self.w_clear_search_button.set_sensitive(True)
1569 1580 else:
1570 1581 self.w_clear_search_button.set_sensitive(False)
1571 1582 self.__enable_disable_entry_selection(widget)
1572 1583 if self.is_search_all and not self.changing_search_option:
1573 1584 if self.w_searchentry.get_text() == "":
1574 1585 self.w_infosearch_frame.hide()
1575 1586 self.__link_load_blank()
1576 1587 self.w_main_view_notebook.set_current_page(
1577 1588 NOTEBOOK_START_PAGE)
1578 1589 self.__update_statusbar_for_search()
1579 1590 self.w_searchentry.grab_focus()
1580 1591
1581 1592 def __update_statusbar_for_search(self):
1582 1593 self.__update_statusbar_message(
1583 1594 self.search_options[self.current_search_option][3])
1584 1595
1585 1596 def __update_statusbar_message(self, message):
1586 1597 if self.statusbar_message_id > 0:
1587 1598 self.w_main_statusbar.remove(0, self.statusbar_message_id)
1588 1599 self.statusbar_message_id = 0
1589 1600 self.statusbar_message_id = self.w_main_statusbar.push(0, message)
1590 1601
1591 1602 def __setup_before_search_all_mode(self):
1592 1603 self.is_search_all = True
1593 1604 self.w_infosearch_frame.hide()
1594 1605
1595 1606 self.__save_setup_before_search()
1596 1607 self.w_repository_combobox.set_active(0)
1597 1608 self.__link_load_blank()
1598 1609 self.w_main_view_notebook.set_current_page(
1599 1610 NOTEBOOK_START_PAGE)
1600 1611 self.__update_statusbar_for_search()
1601 1612 self.w_searchentry.grab_focus()
1602 1613 if len(self.w_searchentry.get_text()) > 0:
1603 1614 start, end = self.w_searchentry.get_selection_bounds()
1604 1615 self.w_searchentry.select_region(end, end)
1605 1616 self.__unselect_category()
1606 1617
1607 1618 def __clear_before_search(self):
1608 1619 self.in_setup = True
1609 1620 application_list = self.__get_new_application_liststore()
1610 1621 self.__set_empty_details_panel()
1611 1622 self.__set_main_view_package_list()
1612 1623 self.__init_tree_views(application_list, None, None)
1613 1624 self.__unselect_category()
1614 1625
1615 1626 def __restore_setup_for_browse(self):
1616 1627 self.in_search_mode = False
1617 1628 self.is_search_all = False
1618 1629 self.w_infosearch_frame.hide()
1619 1630
1620 1631 self.set_busy_cursor()
1621 1632 self.w_repository_combobox.set_active(
1622 1633 self.saved_repository_combobox_active)
1623 1634 self.set_section = self.saved_sections_combobox_active
1624 1635 self.set_show_filter = self.saved_filter_combobox_active
1625 1636 if self.saved_category_list == self.category_list:
1626 1637 self.__init_tree_views(self.saved_application_list,
1627 1638 None, None,
1628 1639 self.saved_application_list_filter,
1629 1640 self.saved_application_list_sort)
1630 1641 else:
1631 1642 self.__init_tree_views(self.saved_application_list,
1632 1643 self.saved_category_list, self.saved_section_list,
1633 1644 self.saved_application_list_filter,
1634 1645 self.saved_application_list_sort)
1635 1646
1636 1647 self.__set_main_view_package_list()
1637 1648
1638 1649 def __save_setup_before_search(self, single_search=False):
1639 1650 #Do not save search data models
1640 1651 if self.in_search_mode:
1641 1652 return
1642 1653 self.saved_sections_combobox_active = \
1643 1654 self.w_sections_combobox.get_active()
1644 1655 self.saved_filter_combobox_active = \
1645 1656 self.w_filter_combobox.get_active()
1646 1657 self.saved_application_list = self.application_list
1647 1658 self.saved_application_list_sort = \
1648 1659 self.application_list_sort
1649 1660 self.saved_application_list_filter = \
1650 1661 self.application_list_filter
1651 1662 self.saved_category_list = self.category_list
1652 1663 self.saved_section_list = self.section_list
1653 1664 if single_search:
1654 1665 self.saved_repository_combobox_active = \
1655 1666 self.w_repository_combobox.get_active()
1656 1667 self.w_filter_combobox.set_active(0)
1657 1668
1658 1669 def __do_search(self):
1659 1670 self.search_start = 0
1660 1671 if self.changing_search_option:
1661 1672 return
1662 1673 active = self.w_filter_combobox.get_active()
1663 1674 if active != enumerations.FILTER_SELECTED:
1664 1675 self.saved_filter_combobox_active = active
1665 1676 if len(self.w_searchentry.get_text()) == 0:
1666 1677 return
1667 1678 if not self.is_search_all:
1668 1679 self.__save_setup_before_search(single_search=True)
1669 1680 self.__clear_before_search()
1670 1681 self.set_busy_cursor()
1671 1682 self.in_search_mode = True
1672 1683
1673 1684 self.w_infosearch_frame.hide()
1674 1685 self.__update_statusbar_message(_("Searching..."))
1675 1686 if not self.is_search_all:
1676 1687 Thread(target = self.__do_api_search,
1677 1688 args = (self.is_search_all, )).start()
1678 1689 else:
1679 1690 Thread(target = self.__do_api_search,
1680 1691 args = ()).start()
1681 1692
1682 1693 def __unselect_category(self):
1683 1694 selection = self.w_categories_treeview.get_selection()
1684 1695 model, itr = selection.get_selected()
1685 1696 if itr:
1686 1697 cat_path = model.get_string_from_iter(itr)
1687 1698 selected_section = self.w_sections_combobox.get_active()
1688 1699 section_row = self.section_list[selected_section]
1689 1700 section_row[enumerations.SECTION_SUBCATEGORY] = cat_path
1690 1701 selection.unselect_all()
1691 1702
1692 1703 def __process_after_search_failure(self):
1693 1704 self.search_start = 0
1694 1705 self.search_time_sec = 0
1695 1706 self.application_list = []
1696 1707 self.update_statusbar()
1697 1708 self.unset_busy_cursor()
1698 1709 self.in_setup = False
1699 1710
1700 1711 def __get_origin_uri(self, repo):
1701 1712 if repo == None:
1702 1713 return None
1703 1714 origin_uri = repo.origins[0]
1704 1715 ret_uri = None
1705 1716 if isinstance(origin_uri, str):
1706 1717 if len(origin_uri) > 0:
1707 1718 ret_uri = origin_uri.strip("/")
1708 1719 elif isinstance(origin_uri, publisher.RepositoryURI):
1709 1720 uri = origin_uri.uri
1710 1721 if uri != None and len(uri) > 0:
1711 1722 ret_uri = uri.strip("/")
1712 1723 return ret_uri
1713 1724
1714 1725
1715 1726 def __do_api_search(self, search_all = True):
1716 1727 self.search_start = time.time()
1717 1728 self.search_time_sec = 0
1718 1729 text = self.w_searchentry.get_text()
1719 1730 # Here we call the search API to get the results
1720 1731 searches = []
1721 1732 servers = []
1722 1733 result = []
1723 1734 pargs = []
1724 1735 search_str = SEARCH_STR_FORMAT % text
1725 1736 pargs.append(search_str)
1726 1737 if search_all:
|
↓ open down ↓ |
292 lines elided |
↑ open up ↑ |
1727 1738 servers = None
1728 1739 else:
1729 1740 pub_prefix = self.__get_active_publisher()
1730 1741 if pub_prefix != None:
1731 1742 pub = self.api_o.get_publisher(prefix=pub_prefix)
1732 1743 else:
1733 1744 pub = self.api_o.get_preferred_publisher()
1734 1745 origin_uri = self.__get_origin_uri(pub.selected_repository)
1735 1746 servers.append({"origin": origin_uri})
1736 1747 if debug:
1737 - print "pargs:", pargs
1738 - print "servers:", servers
1739 -
1748 + print "Search: pargs %s servers: %s" % (pargs, servers)
1749 +
1750 + #TBD If we ever search just Installed pkgs should allow for a local search
1740 1751 case_sensitive = False
1752 + return_actions = True
1741 1753 searches.append(self.api_o.remote_search(
1742 - [api.Query(" ".join(pargs), case_sensitive, True, None, None)],
1754 + [api.Query(" ".join(pargs), case_sensitive, return_actions)],
1743 1755 servers=servers))
1744 - result_tuple = {}
1756 + if debug:
1757 + print "Search Args: %s : cs: %s : retact: %s" % \
1758 + ("".join(pargs), case_sensitive, return_actions)
1759 +
1760 + last_name = ""
1761 + self.current_search_publisher = None
1762 +
1763 + # Sorting results by Name gives best overall appearance and flow
1764 + sort_col = enumerations.NAME_COLUMN
1745 1765 try:
1746 1766 for query_num, publisher, (v, return_type, tmp) in \
1747 1767 itertools.chain(*searches):
1748 - if v == 1 and \
1749 - return_type == api.Query.RETURN_PACKAGES:
1750 - repo = None
1751 - if publisher is not None \
1752 - and "prefix" in publisher:
1753 - repo = publisher["prefix"]
1754 - name = fmri.PkgFmri(str(tmp)).get_name()
1755 - result_tuple[(name, repo)] = -1
1756 - if len(result_tuple) == SEARCH_LIMIT:
1757 - break
1758 - else:
1759 - # We are not interested in this error
1768 + if v < 1 or return_type != api.Query.RETURN_PACKAGES:
1760 1769 gobject.idle_add(self.w_progress_dialog.hide)
1761 1770 self.__process_after_search_failure()
1762 1771 return
1772 +
1773 + pub = None
1774 + if publisher is not None \
1775 + and "prefix" in publisher:
1776 + pub = publisher["prefix"]
1777 + name = fmri.PkgFmri(str(tmp)).get_name()
1778 + if last_name != name:
1779 + if debug:
1780 + print "Result Name: %s (%s)" % (name, pub)
1781 + a_res = name, pub
1782 + result.append(a_res)
1783 + #Ignore Status when fetching
1784 + application_list = \
1785 + self.__get_min_list_from_search(result)
1786 + self.current_search_publisher = pub
1787 + self.in_setup = True
1788 + gobject.idle_add(self.__init_tree_views,
1789 + application_list, None, None, None, None,
1790 + sort_col)
1791 + last_name = name
1763 1792 self.pylintstub = query_num
1764 1793 except api_errors.ProblematicSearchServers, ex:
1765 - self.__parse_api_search_error(ex)
1794 + self.__process_api_search_error(ex)
1766 1795 gobject.idle_add(self.w_progress_dialog.hide)
1767 1796 gobject.idle_add(self.__handle_api_search_error)
1768 - if len(result_tuple) == 0:
1797 + if len(result) == 0:
1769 1798 self.__process_after_search_with_zero_results()
1770 1799 return
1771 1800 except Exception, ex:
1772 1801 # We are not interested in this error
1773 1802 gobject.idle_add(self.w_progress_dialog.hide)
1774 1803 self.__process_after_search_failure()
1775 1804 return
1776 1805 if debug:
1777 - print "Number of search results:", len(result_tuple)
1778 - for name, repo in result_tuple:
1779 - a_res = name, repo
1780 - result.append(a_res)
1806 + print "Number of search results:", len(result)
1781 1807 if len(result) == 0:
1782 1808 if debug:
1783 1809 print "No search results"
1784 1810 self.__process_after_search_with_zero_results()
1785 1811 return
1786 1812 # We cannot get status of the packages if catalogs have not
1787 1813 # been loaded so we pause for up to 5 seconds here to
1788 1814 # allow catalogs to be loaded
1789 1815 times = 5
1790 1816 while self.catalog_loaded == False:
1791 1817 if times == 0:
1792 1818 break
1793 1819 time.sleep(1)
1794 1820 times -= 1
1821 +
1822 + #Now fetch full result set with Status
1795 1823 self.in_setup = True
1796 - application_list = self.__get_list_from_search(result)
1824 + application_list = self.__get_full_list_from_search(result)
1825 + gobject.idle_add(self.__init_tree_views, application_list, None, None, \
1826 + None, None, sort_col)
1827 +
1797 1828 if self.search_start > 0:
1798 1829 self.search_time_sec = int(time.time() - self.search_start)
1830 + if debug:
1831 + print "Search time: %d (sec)" % self.search_time_sec
1799 1832 self.search_start = 0
1800 - gobject.idle_add(self.__set_empty_details_panel)
1801 - gobject.idle_add(self.__set_main_view_package_list)
1802 - gobject.idle_add(self.__init_tree_views, application_list,
1803 - None, None)
1804 1833
1805 1834 def __process_after_search_with_zero_results(self):
1806 1835 if self.search_start > 0:
1807 1836 self.search_time_sec = int(time.time() - self.search_start)
1808 1837 self.search_start = 0
1809 1838 self.in_setup = True
1810 1839 application_list = self.__get_new_application_liststore()
1811 1840 gobject.idle_add(self.__set_empty_details_panel)
1812 1841 gobject.idle_add(self.__set_main_view_package_list)
1813 1842 gobject.idle_add(self.__init_tree_views, application_list, None, None)
1814 1843
1815 - def __get_list_from_search(self, search_result):
1844 + def __get_min_list_from_search(self, search_result):
1816 1845 application_list = self.__get_new_application_liststore()
1846 + for name, publisher in search_result:
1847 + application_list.append(
1848 + [False, None, name, '...', enumerations.NOT_INSTALLED, None,
1849 + "pkg://" + publisher + "/" + name, None, True, None,
1850 + publisher])
1851 + return application_list
1852 +
1853 + def __get_full_list_from_search(self, search_result):
1854 + application_list = self.__get_new_application_liststore()
1817 1855 self.__add_pkgs_to_list_from_search(search_result,
1818 1856 application_list)
1819 1857 return application_list
1820 1858
1821 1859 def __add_pkgs_to_list_from_search(self, search_result,
1822 1860 application_list):
1823 1861 pargs = []
1824 1862 default_pub = self.api_o.get_preferred_publisher().prefix
1825 1863 for name, publisher in search_result:
1826 1864 pargs.append("pkg://" + publisher + "/" + name)
1827 1865 # We now need to get the status for each package
1828 1866 if debug_descriptions:
1829 1867 print "pargs:", pargs
1830 1868 try:
1831 1869 pkgs_known = self.__get_inventory_list(pargs,
1832 1870 True, True)
1833 1871 except api_errors.InventoryException:
1834 1872 # This can happen if load_catalogs has not been run
1835 1873 err = _("Unable to get status for search results.\n"
1836 1874 "The catalogs have not been loaded.\n"
1837 1875 "Please try after few seconds.\n")
1838 1876 gobject.idle_add(self.w_progress_dialog.hide)
1839 1877 gobject.idle_add(self.error_occurred, err)
1840 1878 return
1841 1879 return self.__add_pkgs_to_lists(pkgs_known, application_list,
1842 1880 None, None)
1843 1881
1844 1882 def __application_refilter(self):
1845 1883 ''' Disconnecting the model from the treeview improves
1846 1884 performance when assistive technologies are enabled'''
1847 1885 if self.in_setup:
1848 1886 return
1849 1887 self.application_refilter_id = 0
1850 1888 self.application_refilter_idle_id = 0
1851 1889 if not self.in_search_mode:
1852 1890 model = self.w_application_treeview.get_model()
1853 1891 self.w_application_treeview.set_model(None)
1854 1892 self.application_list_filter.refilter()
1855 1893 self.w_application_treeview.set_model(model)
1856 1894 gobject.idle_add(self.__set_empty_details_panel)
1857 1895 gobject.idle_add(self.__enable_disable_selection_menus)
1858 1896 gobject.idle_add(self.__enable_disable_install_remove)
1859 1897 self.application_treeview_initialized = True
1860 1898 self.application_treeview_range = None
1861 1899 if self.visible_status_id == 0:
1862 1900 self.visible_status_id = gobject.idle_add(
1863 1901 self.__set_visible_status)
1864 1902 self.categories_treeview_initialized = True
1865 1903 self.categories_treeview_range = None
1866 1904 if self.categories_status_id == 0:
1867 1905 self.categories_status_id = gobject.idle_add(
1868 1906 self.__set_accessible_categories_visible_status)
1869 1907 return False
1870 1908
1871 1909 def __on_edit_paste(self, widget):
1872 1910 self.w_searchentry.paste_clipboard()
1873 1911
1874 1912 def __on_clear_paste(self, widget):
1875 1913 bounds = self.w_searchentry.get_selection_bounds()
1876 1914 self.w_searchentry.delete_text(bounds[0], bounds[1])
1877 1915 return
1878 1916
1879 1917 def __on_copy(self, widget):
1880 1918 focus_widget = self.w_main_window.get_focus()
1881 1919 if focus_widget == self.w_searchentry:
1882 1920 self.w_searchentry.copy_clipboard()
1883 1921 self.w_paste_menuitem.set_sensitive(True)
1884 1922 elif self.__is_a_textview(focus_widget):
1885 1923 focus_widget.get_buffer().copy_clipboard(
1886 1924 self.w_main_clipboard)
1887 1925
1888 1926 def __on_cut(self, widget):
1889 1927 self.w_searchentry.cut_clipboard()
1890 1928 self.w_paste_menuitem.set_sensitive(True)
1891 1929
1892 1930 def __popup_position_func(self, menu):
1893 1931 ''' Position popup menu immediately below search button'''
1894 1932 root = self.w_main_window.window.get_origin()
1895 1933 alloc = self.search_button.get_allocation()
1896 1934 return (root[0] + alloc.x, root[1] + alloc.y + alloc.height, False)
1897 1935
1898 1936 def __on_set_search(self, widget, event):
1899 1937 if event.type == gtk.gdk.BUTTON_PRESS:
1900 1938 self.searchmenu.popup(None, None, self.__popup_position_func,
1901 1939 event.button, event.time)
1902 1940 return True
1903 1941 return False
1904 1942
1905 1943 def __on_set_search_clicked(self, widget):
1906 1944 self.searchmenu.popup(None, None, self.__popup_position_func,
1907 1945 0, 0)
1908 1946 return True
1909 1947
1910 1948 def __on_edit_search_clicked(self, widget):
1911 1949 self.w_searchentry.grab_focus()
1912 1950
1913 1951 def __on_clear_search(self, widget):
1914 1952 self.w_searchentry.delete_text(0, -1)
1915 1953 self.__do_search()
1916 1954 return
1917 1955
1918 1956 def __on_startpage(self, widget):
1919 1957 self.__load_startpage()
1920 1958 self.w_main_view_notebook.set_current_page(NOTEBOOK_START_PAGE)
1921 1959
1922 1960 def __on_notebook_change(self, widget, event, pagenum):
1923 1961 if (pagenum == INFO_NOTEBOOK_LICENSE_PAGE and
1924 1962 not self.showing_empty_details):
1925 1963 licbuffer = self.w_license_textview.get_buffer()
1926 1964 leg_txt = _("Fetching legal information...")
1927 1965 licbuffer.set_text(leg_txt)
1928 1966 if self.show_licenses_id != 0:
1929 1967 gobject.source_remove(self.show_licenses_id)
1930 1968 self.show_licenses_id = 0
1931 1969 self.last_show_licenses_id = self.show_licenses_id = \
1932 1970 gobject.timeout_add(SHOW_LICENSE_DELAY,
1933 1971 self.__show_licenses)
1934 1972
1935 1973 def __is_a_textview(self, widget):
1936 1974 if (widget == self.w_generalinfo_textview or
1937 1975 widget == self.w_installedfiles_textview or
1938 1976 widget == self.w_dependencies_textview or
1939 1977 widget == self.w_license_textview):
1940 1978 return True
1941 1979 else:
1942 1980 return False
1943 1981
1944 1982
1945 1983 def __on_select_all(self, widget):
1946 1984 focus_widget = self.w_main_window.get_focus()
1947 1985 if self.__is_a_textview(focus_widget):
1948 1986 focus_widget.emit('select-all', True)
1949 1987 self.w_selectall_menuitem.set_sensitive(False)
1950 1988 self.w_deselect_menuitem.set_sensitive(True)
1951 1989 return
1952 1990 elif focus_widget == self.w_searchentry:
1953 1991 focus_widget.select_region(0, -1)
1954 1992 self.w_selectall_menuitem.set_sensitive(False)
1955 1993 self.w_deselect_menuitem.set_sensitive(True)
1956 1994 return
1957 1995
1958 1996 sort_filt_model = \
1959 1997 self.w_application_treeview.get_model() #gtk.TreeModelSort
1960 1998 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1961 1999 model = filt_model.get_model() #gtk.ListStore
1962 2000 iter_next = sort_filt_model.get_iter_first()
1963 2001 list_of_paths = []
1964 2002 while iter_next != None:
1965 2003 sorted_path = sort_filt_model.get_path(iter_next)
1966 2004 filtered_path = \
1967 2005 sort_filt_model.convert_path_to_child_path(sorted_path)
1968 2006 path = filt_model.convert_path_to_child_path(filtered_path)
1969 2007 list_of_paths.append(path)
1970 2008 iter_next = sort_filt_model.iter_next(iter_next)
1971 2009 for path in list_of_paths:
1972 2010 itr = model.get_iter(path)
1973 2011 already_marked = model.get_value(itr, enumerations.MARK_COLUMN)
1974 2012 if not already_marked:
1975 2013 model.set_value(itr, enumerations.MARK_COLUMN, True)
1976 2014 pkg_stem = model.get_value(itr,
1977 2015 enumerations.STEM_COLUMN)
1978 2016 pkg_status = model.get_value(itr,
1979 2017 enumerations.STATUS_COLUMN)
1980 2018 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
1981 2019 self.w_selectall_menuitem.set_sensitive(False)
1982 2020 self.w_deselect_menuitem.set_sensitive(True)
1983 2021 self.__enable_disable_selection_menus()
1984 2022 self.update_statusbar()
1985 2023 self.__enable_disable_install_remove()
1986 2024
1987 2025 def __on_select_updates(self, widget):
1988 2026 sort_filt_model = \
1989 2027 self.w_application_treeview.get_model() #gtk.TreeModelSort
1990 2028 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1991 2029 model = filt_model.get_model() #gtk.ListStore
1992 2030 iter_next = sort_filt_model.get_iter_first()
1993 2031 list_of_paths = []
1994 2032 while iter_next != None:
1995 2033 sorted_path = sort_filt_model.get_path(iter_next)
1996 2034 filtered_iter = sort_filt_model.convert_iter_to_child_iter(None, \
1997 2035 iter_next)
1998 2036 app_iter = filt_model.convert_iter_to_child_iter(filtered_iter)
1999 2037
2000 2038 filtered_path = \
2001 2039 sort_filt_model.convert_path_to_child_path(sorted_path)
2002 2040 path = filt_model.convert_path_to_child_path(filtered_path)
2003 2041 if model.get_value(app_iter, \
2004 2042 enumerations.STATUS_COLUMN) == enumerations.UPDATABLE:
2005 2043 list_of_paths.append(path)
2006 2044 iter_next = sort_filt_model.iter_next(iter_next)
2007 2045 for path in list_of_paths:
2008 2046 itr = model.get_iter(path)
2009 2047 model.set_value(itr, enumerations.MARK_COLUMN, True)
2010 2048 pkg_stem = model.get_value(itr, enumerations.STEM_COLUMN)
2011 2049 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
2012 2050 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
2013 2051 self.__enable_disable_selection_menus()
2014 2052 self.update_statusbar()
2015 2053 self.__enable_disable_install_remove()
2016 2054
2017 2055 def __on_deselect(self, widget):
2018 2056 focus_widget = self.w_main_window.get_focus()
2019 2057 if self.__is_a_textview(focus_widget):
2020 2058 focus_widget.emit('select-all', False)
2021 2059 self.w_deselect_menuitem.set_sensitive(False)
2022 2060 self.w_selectall_menuitem.set_sensitive(True)
2023 2061 return
2024 2062 elif focus_widget == self.w_searchentry:
2025 2063 focus_widget.select_region(0, 0)
2026 2064 self.w_deselect_menuitem.set_sensitive(False)
2027 2065 self.w_selectall_menuitem.set_sensitive(True)
2028 2066 return
2029 2067
2030 2068 sort_filt_model = \
2031 2069 self.w_application_treeview.get_model() #gtk.TreeModelSort
2032 2070 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
2033 2071 model = filt_model.get_model() #gtk.ListStore
2034 2072 iter_next = sort_filt_model.get_iter_first()
2035 2073 list_of_paths = []
2036 2074 while iter_next != None:
2037 2075 sorted_path = sort_filt_model.get_path(iter_next)
2038 2076 filtered_iter = sort_filt_model.convert_iter_to_child_iter(None, \
2039 2077 iter_next)
2040 2078 app_iter = filt_model.convert_iter_to_child_iter(filtered_iter)
2041 2079 filtered_path = \
2042 2080 sort_filt_model.convert_path_to_child_path(sorted_path)
2043 2081 path = filt_model.convert_path_to_child_path(filtered_path)
2044 2082 if model.get_value(app_iter, enumerations.MARK_COLUMN):
2045 2083 list_of_paths.append(path)
2046 2084 iter_next = sort_filt_model.iter_next(iter_next)
2047 2085 for path in list_of_paths:
2048 2086 itr = model.get_iter(path)
2049 2087 already_deselected = not model.get_value(itr,
2050 2088 enumerations.MARK_COLUMN)
2051 2089 if not already_deselected:
2052 2090 model.set_value(itr, enumerations.MARK_COLUMN, False)
2053 2091 self.__remove_pkg_stem_from_list(model.get_value(itr,
2054 2092 enumerations.STEM_COLUMN))
2055 2093 self.w_selectall_menuitem.set_sensitive(True)
2056 2094 self.w_deselect_menuitem.set_sensitive(False)
2057 2095 self.__enable_disable_selection_menus()
2058 2096 self.update_statusbar()
2059 2097 self.__enable_disable_install_remove()
2060 2098
2061 2099 def __on_preferences(self, widget):
2062 2100 self.w_startpage_checkbutton.set_active(self.show_startpage)
2063 2101 self.w_preferencesdialog.show()
2064 2102
2065 2103 def __on_preferencesclose_clicked(self, widget):
2066 2104 self.w_preferencesdialog.hide()
2067 2105
2068 2106 def __on_preferenceshelp_clicked(self, widget):
2069 2107 gui_misc.display_help(self.application_dir, "pm_win")
2070 2108
2071 2109 def __on_startpage_checkbutton_toggled(self, widget):
2072 2110 self.show_startpage = self.w_startpage_checkbutton.get_active()
|
↓ open down ↓ |
246 lines elided |
↑ open up ↑ |
2073 2111 try:
2074 2112 self.client.set_bool(SHOW_STARTPAGE_PREFERENCES,
2075 2113 self.show_startpage)
2076 2114 except GError:
2077 2115 pass
2078 2116
2079 2117 def __on_api_search_checkbox_toggled(self, widget):
2080 2118 active = self.api_search_checkbox.get_active()
2081 2119 if len(self.current_repos_with_search_errors) > 0:
2082 2120 if active:
2083 - for url in self.current_repos_with_search_errors:
2084 - if url not in self.gconf_not_show_repos:
2085 - self.gconf_not_show_repos += url + ","
2121 + for pub, err_type, err_str in \
2122 + self.current_repos_with_search_errors:
2123 + if pub not in self.gconf_not_show_repos:
2124 + self.gconf_not_show_repos += pub + ","
2086 2125 else:
2087 - for url in self.current_repos_with_search_errors:
2126 + for pub, err_type, err_str in \
2127 + self.current_repos_with_search_errors:
2088 2128 self.gconf_not_show_repos = \
2089 2129 self.gconf_not_show_repos.replace(
2090 - url + ",", "")
2130 + pub + ",", "")
2091 2131 try:
2092 2132 self.client.set_string(API_SEARCH_ERROR_PREFERENCES,
2093 2133 self.gconf_not_show_repos)
2094 2134 except GError:
2095 2135 pass
2096 2136
2097 2137 def __on_searchentry_focus_in(self, widget, event):
2098 2138 if self.w_main_clipboard.wait_is_text_available():
2099 2139 self.w_paste_menuitem.set_sensitive(True)
2100 2140 char_count = widget.get_text_length()
2101 2141 if char_count > 0:
2102 2142 self.w_selectall_menuitem.set_sensitive(True)
2103 2143 else:
2104 2144 self.w_selectall_menuitem.set_sensitive(False)
2105 2145 bounds = widget.get_selection_bounds()
2106 2146 if bounds:
2107 2147 offset1 = bounds[0]
2108 2148 offset2 = bounds[1]
2109 2149 if abs(offset2 - offset1) == char_count:
2110 2150 self.w_selectall_menuitem.set_sensitive(False)
2111 2151 self.w_deselect_menuitem.set_sensitive(True)
2112 2152 self.w_copy_menuitem.set_sensitive(True)
2113 2153 else:
2114 2154 self.w_deselect_menuitem.set_sensitive(False)
2115 2155
2116 2156 def __on_searchentry_focus_out(self, widget, event):
2117 2157 self.w_paste_menuitem.set_sensitive(False)
2118 2158 self.__enable_disable_select_all()
2119 2159 self.__enable_disable_deselect()
2120 2160 self.w_cut_menuitem.set_sensitive(False)
2121 2161 self.w_copy_menuitem.set_sensitive(False)
2122 2162 self.w_clear_menuitem.set_sensitive(False)
2123 2163 return False
2124 2164
2125 2165 def __on_searchentry_activate(self, widget):
2126 2166 self.__do_search()
2127 2167
2128 2168 def __on_searchentry_selection(self, widget, pspec):
2129 2169 self.__enable_disable_entry_selection(widget)
2130 2170
2131 2171 def __enable_disable_entry_selection(self, widget):
2132 2172 char_count = widget.get_text_length()
2133 2173 bounds = widget.get_selection_bounds()
2134 2174 if bounds:
2135 2175 #enable selection functions
2136 2176 self.w_cut_menuitem.set_sensitive(True)
2137 2177 self.w_copy_menuitem.set_sensitive(True)
2138 2178 self.w_clear_menuitem.set_sensitive(True)
2139 2179 if char_count == abs(bounds[1] - bounds[0]):
2140 2180 self.w_selectall_menuitem.set_sensitive(False)
2141 2181 else:
2142 2182 self.w_selectall_menuitem.set_sensitive(True)
2143 2183 self.w_deselect_menuitem.set_sensitive(True)
2144 2184 else:
2145 2185 self.w_cut_menuitem.set_sensitive(False)
2146 2186 self.w_copy_menuitem.set_sensitive(False)
2147 2187 self.w_clear_menuitem.set_sensitive(False)
2148 2188 self.w_deselect_menuitem.set_sensitive(False)
2149 2189 if char_count == 0:
2150 2190 self.w_selectall_menuitem.set_sensitive(False)
2151 2191 else:
2152 2192 self.w_selectall_menuitem.set_sensitive(True)
2153 2193
2154 2194 def __refilter_on_idle(self):
2155 2195 if self.application_refilter_id != 0:
2156 2196 gobject.source_remove(self.application_refilter_id)
2157 2197 self.application_refilter_id = 0
2158 2198 if self.application_refilter_idle_id == 0:
2159 2199 self.application_refilter_idle_id = gobject.idle_add(
2160 2200 self.__application_refilter)
2161 2201
2162 2202 def __on_category_focus_in(self, widget, event, user):
2163 2203 self.__on_category_row_activated(None, None, None, user)
2164 2204
2165 2205 def __on_category_row_activated(self, view, path, col, user):
2166 2206 '''This function is for handling category double click activations'''
2167 2207 if self.w_filter_combobox.get_model():
2168 2208 self.w_filter_combobox.set_active(self.saved_filter_combobox_active)
2169 2209 self.w_searchentry.delete_text(0, -1)
2170 2210 if self.in_search_mode or self.is_search_all:
2171 2211 self.__unset_search(True)
2172 2212 if self.selected == 0:
2173 2213 gobject.idle_add(self.__enable_disable_install_remove)
2174 2214 return
2175 2215 self.__set_main_view_package_list()
2176 2216 self.set_busy_cursor()
2177 2217 self.__refilter_on_idle()
2178 2218 if self.selected == 0:
2179 2219 gobject.idle_add(self.__enable_disable_install_remove)
2180 2220
2181 2221 def __set_main_view_package_list(self):
2182 2222 # Only switch from Start Page View to List view if we are not in startup
2183 2223 if not self.in_startpage_startup:
2184 2224 self.w_main_view_notebook.set_current_page(
2185 2225 NOTEBOOK_PACKAGE_LIST_PAGE)
2186 2226
2187 2227 def __on_category_selection_changed(self, selection, widget):
2188 2228 '''This function is for handling category selection changes'''
2189 2229 if self.in_setup or self.changing_search_option:
2190 2230 return
2191 2231 model, itr = selection.get_selected()
2192 2232 if itr:
2193 2233 cat_path = model.get_string_from_iter(itr)
2194 2234 if self.is_search_all:
2195 2235 selected_section = self.set_section
2196 2236 else:
2197 2237 selected_section = self.w_sections_combobox.get_active()
2198 2238 section_row = self.section_list[selected_section]
2199 2239 section_row[enumerations.SECTION_SUBCATEGORY] = cat_path
2200 2240
2201 2241 if self.in_search_mode or self.is_search_all:
2202 2242 return
2203 2243
2204 2244 if self.saved_filter_combobox_active != None:
2205 2245 self.w_filter_combobox.set_active(self.saved_filter_combobox_active)
2206 2246 self.__set_main_view_package_list()
2207 2247
2208 2248 self.set_busy_cursor()
2209 2249 self.__refilter_on_idle()
2210 2250 if self.selected == 0:
2211 2251 gobject.idle_add(self.__enable_disable_install_remove)
2212 2252
2213 2253 def __process_package_selection(self):
2214 2254 model, itr = self.package_selection.get_selected()
2215 2255 if self.show_info_id != 0:
2216 2256 gobject.source_remove(self.show_info_id)
2217 2257 self.show_info_id = 0
2218 2258 if itr:
2219 2259 self.__enable_disable_install_remove()
2220 2260 self.selected_pkgstem = \
2221 2261 model.get_value(itr, enumerations.STEM_COLUMN)
2222 2262 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
2223 2263 gobject.idle_add(self.__show_fetching_package_info, pkg)
2224 2264 self.showing_empty_details = False
2225 2265 self.last_show_info_id = self.show_info_id = \
2226 2266 gobject.timeout_add(SHOW_INFO_DELAY,
2227 2267 self.__show_info, model, model.get_path(itr))
2228 2268 if (self.w_info_notebook.get_current_page() ==
2229 2269 INFO_NOTEBOOK_LICENSE_PAGE):
2230 2270 self.__on_notebook_change(None, None,
2231 2271 INFO_NOTEBOOK_LICENSE_PAGE)
2232 2272 else:
2233 2273 self.selected_model = None
2234 2274 self.selected_path = None
2235 2275 self.selected_pkgstem = None
2236 2276
2237 2277 def __on_package_selection_changed(self, selection, widget):
2238 2278 '''This function is for handling package selection changes'''
2239 2279 if self.in_setup:
2240 2280 return
2241 2281 self.__process_package_selection()
2242 2282
2243 2283 def __on_filtercombobox_changed(self, widget):
2244 2284 '''On filter combobox changed'''
2245 2285 if self.in_setup or self.changing_search_option:
2246 2286 return
2247 2287 active = self.w_filter_combobox.get_active()
2248 2288 if active != enumerations.FILTER_SELECTED:
2249 2289 self.saved_filter_combobox_active = active
2250 2290 self.__set_main_view_package_list()
2251 2291 if self.in_search_mode or self.is_search_all:
2252 2292 self.set_busy_cursor()
2253 2293 self.saved_filter_combobox_active = \
2254 2294 self.w_filter_combobox.get_active()
2255 2295 self.__unset_search(True)
2256 2296 return
2257 2297 self.set_busy_cursor()
2258 2298 self.__refilter_on_idle()
2259 2299 if self.selected == 0:
2260 2300 gobject.idle_add(self.__enable_disable_install_remove)
2261 2301
2262 2302 def __set_categories_visibility(self, selected_section):
2263 2303 self.category_list[0][enumerations.CATEGORY_ICON] = None
2264 2304 if selected_section == 0:
2265 2305 for category in self.category_list:
2266 2306 category[enumerations.CATEGORY_VISIBLE] = True
2267 2307 else:
2268 2308 for category in self.category_list:
2269 2309 if category[enumerations.CATEGORY_ID] == 0:
2270 2310 category[enumerations.CATEGORY_VISIBLE] = True
2271 2311 else:
2272 2312 category_list = \
2273 2313 category[enumerations.SECTION_LIST_OBJECT]
2274 2314 if not category_list:
2275 2315 category[enumerations.CATEGORY_VISIBLE] \
2276 2316 = False
2277 2317 else:
2278 2318 for section in category_list:
2279 2319 if section == selected_section:
2280 2320 category[enumerations. \
2281 2321 CATEGORY_VISIBLE] = \
2282 2322 True
2283 2323 else:
2284 2324 category[enumerations. \
2285 2325 CATEGORY_VISIBLE] = \
2286 2326 False
2287 2327
2288 2328 # Set category icon for All if a visible category has it
2289 2329 for category in self.category_list:
2290 2330 if category[enumerations.CATEGORY_ICON] != None:
2291 2331 self.category_list[0][enumerations.CATEGORY_ICON] = \
2292 2332 category[enumerations.CATEGORY_ICON]
2293 2333 break
2294 2334
2295 2335 section_row = self.section_list[selected_section]
2296 2336 cat_path = section_row[enumerations.SECTION_SUBCATEGORY]
2297 2337 if cat_path != None:
2298 2338 itr = self.category_list_filter.get_iter_from_string(cat_path)
2299 2339 path = self.category_list_filter.get_path(itr)
2300 2340 self.w_categories_treeview.set_cursor(path,
2301 2341 None, start_editing=False)
2302 2342
2303 2343 def __on_sectionscombobox_changed(self, widget):
2304 2344 '''On section combobox changed'''
2305 2345 if self.in_setup:
2306 2346 return
2307 2347 if self.changing_search_option:
2308 2348 return
2309 2349 self.__set_main_view_package_list()
2310 2350 self.set_busy_cursor()
2311 2351 self.__set_first_category_text()
2312 2352 self.__set_categories_visibility(widget.get_active())
2313 2353 self.category_list_filter.refilter()
2314 2354 if self.in_search_mode or self.is_search_all:
2315 2355 self.saved_sections_combobox_active = \
2316 2356 self.w_sections_combobox.get_active()
2317 2357 self.__unset_search(True)
2318 2358 return
2319 2359 self.__refilter_on_idle()
2320 2360 if self.selected == 0:
2321 2361 gobject.idle_add(self.__enable_disable_install_remove)
2322 2362
2323 2363 def __set_first_category_text(self):
2324 2364 active_section = self.w_sections_combobox.get_active()
2325 2365 all_cat_text = _("All")
2326 2366 if active_section != 0:
2327 2367 all_cat_text += " " + self.section_list[active_section][1]
2328 2368 category_model = self.w_categories_treeview.get_model()
2329 2369 if category_model:
2330 2370 list_store = category_model.get_model()
2331 2371 list_store[0][1] = all_cat_text
2332 2372
2333 2373 def __unset_search(self, same_repo):
2334 2374 self.w_infosearch_frame.hide()
2335 2375 self.changing_search_option = True
2336 2376 self.current_search_option = 0
2337 2377 visible_repository = self.__get_visible_repository_name()
2338 2378 if visible_repository in self.selected_pkgs:
2339 2379 self.selected_pkgs.pop(visible_repository)
2340 2380 if visible_repository in self.to_install_update:
2341 2381 self.to_install_update.pop(visible_repository)
2342 2382 if visible_repository in self.to_remove:
2343 2383 self.to_remove.pop(visible_repository)
2344 2384 self.__update_tooltips()
2345 2385 if self.is_search_all:
2346 2386 self.__update_repository_combobox_for_search(False)
2347 2387 pixbuf = self.search_options[0][1]
2348 2388 self.search_image.set_from_pixbuf(pixbuf)
2349 2389 self.in_search_mode = False
2350 2390 self.is_search_all = False
2351 2391 if same_repo:
2352 2392 self.__restore_setup_for_browse()
2353 2393 self.changing_search_option = False
2354 2394
2355 2395 def __on_repositorycombobox_changed(self, widget):
2356 2396 '''On repository combobox changed'''
2357 2397 if self.changing_search_option:
2358 2398 return
2359 2399 self.changing_search_option = True
2360 2400 active_publisher = self.__get_active_publisher()
2361 2401 if self.is_search_all:
2362 2402 same_repo = False
2363 2403 active = self.w_repository_combobox.get_active() - 1
2364 2404 if active == -1:
2365 2405 # We get here is we choose "Add ..." when
2366 2406 # doing api search
2367 2407 self.changing_search_option = False
2368 2408 return
2369 2409 if not active_publisher == _("Add..."):
2370 2410 if self.saved_repository_combobox_active == active:
2371 2411 same_repo = True
2372 2412 self.__unset_search(same_repo)
2373 2413 self.w_repository_combobox.set_active(active)
2374 2414
2375 2415 if same_repo:
2376 2416 self.changing_search_option = False
2377 2417 return
2378 2418 active_publisher = self.__get_active_publisher()
2379 2419 self.changing_search_option = False
2380 2420 if self.visible_repository == active_publisher:
2381 2421 # If we are coming back to the same repository, we do
2382 2422 # not want to setup publishers. This is the case when
2383 2423 # we are calling Add... then we are firing the event for
2384 2424 # Add... case and immediately coming back to the
2385 2425 # previously selected repository.
2386 2426 return
2387 2427 # Checking for Add... is fine enough, as the repository
2388 2428 # name cannot contain "..." in the name.
2389 2429 if active_publisher == _("Add..."):
2390 2430 index = -1
2391 2431 if self.is_search_all:
2392 2432 index = 0
2393 2433 else:
2394 2434 model = self.w_repository_combobox.get_model()
2395 2435 for entry in model:
2396 2436 if entry[1] == self.visible_repository:
2397 2437 index = entry[0]
2398 2438 break
2399 2439 # We do not want to switch permanently to the Add...
2400 2440 self.w_repository_combobox.set_active(index)
2401 2441 self.__on_edit_repositories_activate(None)
2402 2442 return
2403 2443 self.cancelled = True
2404 2444 self.in_setup = True
2405 2445 self.set_busy_cursor()
2406 2446 self.__set_empty_details_panel()
2407 2447 if self.in_search_mode:
2408 2448 self.__unset_search(False)
2409 2449 self.w_searchentry.grab_focus()
2410 2450 if len(self.w_searchentry.get_text()) > 0:
2411 2451 start, end = self.w_searchentry.get_selection_bounds()
2412 2452 self.w_searchentry.select_region(end, end)
2413 2453
2414 2454 pub = [active_publisher, ]
2415 2455 self.set_show_filter = self.initial_show_filter
2416 2456 self.set_section = self.initial_section
2417 2457 Thread(target = self.__setup_publisher, args = [pub]).start()
2418 2458 self.__set_main_view_package_list()
2419 2459
2420 2460 def __get_active_publisher(self):
|
↓ open down ↓ |
320 lines elided |
↑ open up ↑ |
2421 2461 pub_iter = self.w_repository_combobox.get_active_iter()
2422 2462 if pub_iter == None:
2423 2463 return None
2424 2464 return self.repositories_list.get_value(pub_iter, \
2425 2465 enumerations.REPOSITORY_NAME)
2426 2466
2427 2467 def __setup_publisher(self, publishers=[]):
2428 2468 self.saved_filter_combobox_active = self.initial_show_filter
2429 2469 application_list, category_list , section_list = \
2430 2470 self.__get_application_categories_lists(publishers)
2471 + self.__unset_saved()
2431 2472 gobject.idle_add(self.__init_tree_views, application_list,
2432 2473 category_list, section_list)
2433 2474
2475 + def __unset_saved(self):
2476 + self.saved_application_list = None
2477 + self.saved_application_list_filter = None
2478 + self.saved_application_list_sort = None
2479 + self.saved_category_list = None
2480 + self.saved_section_list = None
2481 +
2434 2482 def __get_application_categories_lists(self, publishers=[]):
2435 2483 if not self.visible_repository:
2436 2484 self.visible_repository = self.__get_active_publisher()
2437 2485 application_list = self.__get_new_application_liststore()
2438 2486 category_list = self.__get_new_category_liststore()
2439 2487 section_list = self.__get_new_section_liststore()
2440 2488 first_loop = True
2441 2489 for publisher in publishers:
2442 2490 uptodate = False
2443 2491 try:
2444 2492 uptodate = self.__check_if_cache_uptodate(publisher)
2445 2493 if uptodate:
2446 2494 self.__add_pkgs_to_lists_from_cache(publisher,
2447 2495 application_list, category_list,
2448 2496 section_list)
2449 2497 except (UnpicklingError, EOFError, IOError):
2450 2498 #Most likely cache is corrupted, silently load list
2451 2499 #from api.
2452 2500 application_list = self.__get_new_application_liststore()
2453 2501 category_list = self.__get_new_category_liststore()
2454 2502 uptodate = False
2455 2503 if not uptodate:
2456 2504 if first_loop == True:
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
2457 2505 first_loop = False
2458 2506 gobject.idle_add(self.setup_progressdialog_show)
2459 2507 self.api_o.refresh(pubs=[publisher])
2460 2508 self.__add_pkgs_to_lists_from_api(publisher,
2461 2509 application_list, category_list, section_list)
2462 2510 category_list.prepend([0, _('All'), None, None, False,
2463 2511 True, None])
2464 2512 if self.application_list and self.category_list and \
2465 2513 not self.visible_repository_uptodate:
2466 2514 if self.visible_repository:
2515 + dump_list = self.application_list
2516 + if self.saved_application_list != None:
2517 + dump_list = \
2518 + self.saved_application_list
2467 2519 self.__dump_datamodels(self.visible_repository,
2468 - self.application_list, self.category_list,
2520 + dump_list, self.category_list,
2469 2521 self.section_list)
2470 2522 self.visible_repository = self.__get_active_publisher()
2471 2523 self.visible_repository_uptodate = uptodate
2472 2524 return application_list, category_list, section_list
2473 2525
2474 2526 def __check_if_cache_uptodate(self, publisher):
2475 2527 if self.cache_o:
2476 2528 return self.cache_o.check_if_cache_uptodate(publisher)
2477 2529 return False
2478 2530
2479 2531 def __dump_datamodels(self, publisher, application_list, category_list,
2480 2532 section_list):
2533 + #Consistency check - only dump models if publisher passed in matches
2534 + #publisher in application list
2535 + if application_list == None:
2536 + return
2537 + app_pub = application_list[0][enumerations.AUTHORITY_COLUMN]
2538 + if publisher != app_pub:
2539 + if debug:
2540 + print "ERROR: __dump_data_models(): INCONSISTENT " \
2541 + "pub %s != app_list_pub %s" % \
2542 + (publisher, app_pub)
2543 + return
2544 +
2481 2545 if self.cache_o:
2482 2546 if self.img_timestamp == \
2483 2547 self.cache_o.get_index_timestamp():
2484 2548 Thread(target = self.cache_o.dump_datamodels,
2485 2549 args = (publisher, application_list, category_list,
2486 2550 section_list)).start()
2487 2551 else:
2488 2552 self.__remove_cache()
2489 2553
2490 2554 def __remove_cache(self):
2491 2555 model = self.w_repository_combobox.get_model()
2492 2556 for publisher in model:
2493 2557 pub_name = publisher[1]
2494 2558 if pub_name and pub_name != _("Add..."):
2495 2559 Thread(target = self.cache_o.remove_datamodel,
2496 2560 args = [publisher[1]]).start()
2497 2561
2498 2562 def __on_install_update(self, widget):
2499 2563 self.api_o.reset()
2500 2564 install_update = []
2501 2565 if self.selected == 0:
2502 2566 model, itr = self.package_selection.get_selected()
2503 2567 if itr:
2504 2568 install_update.append(
2505 2569 model.get_value(itr, enumerations.STEM_COLUMN))
2506 2570 else:
2507 2571 visible_repository = self.__get_visible_repository_name()
2508 2572 pkgs = self.selected_pkgs.get(visible_repository)
2509 2573 if pkgs:
2510 2574 for pkg_stem in pkgs:
2511 2575 status = pkgs.get(pkg_stem)
2512 2576 if status == enumerations.NOT_INSTALLED or \
2513 2577 status == enumerations.UPDATABLE:
2514 2578 install_update.append(pkg_stem)
2515 2579
2516 2580 if self.img_timestamp != self.cache_o.get_index_timestamp():
2517 2581 self.img_timestamp = None
2518 2582 self.__remove_cache()
2519 2583
2520 2584 installupdate.InstallUpdate(install_update, self, \
2521 2585 self.api_o, ips_update = False, \
2522 2586 action = enumerations.INSTALL_UPDATE)
2523 2587
2524 2588 def __on_update_all(self, widget):
2525 2589 self.api_o.reset()
2526 2590 installupdate.InstallUpdate([], self,
2527 2591 self.api_o, ips_update = False,
2528 2592 action = enumerations.IMAGE_UPDATE, be_name = self.ua_be_name,
2529 2593 parent_name = _("Package Manager"),
2530 2594 pkg_list = ["SUNWipkg", "SUNWipkg-gui"],
2531 2595 main_window = self.w_main_window)
2532 2596 return
2533 2597
2534 2598 def __on_ua_completed_linkbutton_clicked(self, widget):
2535 2599 try:
2536 2600 gnome.url_show(self.release_notes_url)
2537 2601 except gobject.GError:
2538 2602 self.error_occurred(_("Unable to navigate to:\n\t%s") %
2539 2603 self.release_notes_url)
2540 2604
2541 2605 def __on_help_about(self, widget):
2542 2606 wTreePlan = gtk.glade.XML(self.gladefile, "aboutdialog")
2543 2607 aboutdialog = wTreePlan.get_widget("aboutdialog")
2544 2608 aboutdialog.connect("response", lambda x = None, \
2545 2609 y = None: aboutdialog.destroy())
2546 2610 aboutdialog.run()
2547 2611
2548 2612 def __on_help_help(self, widget):
2549 2613 gui_misc.display_help(self.application_dir)
2550 2614
2551 2615 def __on_remove(self, widget):
2552 2616 self.api_o.reset()
2553 2617 remove_list = []
2554 2618 if self.selected == 0:
2555 2619 model, itr = self.package_selection.get_selected()
2556 2620 if itr:
2557 2621 remove_list.append(
2558 2622 model.get_value(itr, enumerations.STEM_COLUMN))
2559 2623 else:
2560 2624 visible_repository = self.__get_visible_repository_name()
2561 2625 pkgs = self.selected_pkgs.get(visible_repository)
2562 2626 if pkgs:
2563 2627 for pkg_stem in pkgs:
2564 2628 status = pkgs.get(pkg_stem)
2565 2629 if status == enumerations.INSTALLED or \
2566 2630 status == enumerations.UPDATABLE:
2567 2631 remove_list.append(pkg_stem)
2568 2632
2569 2633 if self.img_timestamp != self.cache_o.get_index_timestamp():
2570 2634 self.img_timestamp = None
2571 2635 self.__remove_cache()
2572 2636
2573 2637 installupdate.InstallUpdate(remove_list, self,
2574 2638 self.api_o, ips_update = False,
2575 2639 action = enumerations.REMOVE)
2576 2640
2577 2641 def __on_reload(self, widget):
2578 2642 if self.description_thread_running:
2579 2643 self.cancelled = True
2580 2644 if self.in_search_mode or self.is_search_all:
2581 2645 self.__unset_search(False)
2582 2646 self.__set_empty_details_panel()
2583 2647 self.in_setup = True
2584 2648 self.visible_repository = None
2585 2649 if widget != None:
2586 2650 self.__remove_cache()
2587 2651 self.w_progress_dialog.set_title(_("Refreshing catalogs"))
2588 2652 self.w_progressinfo_label.set_text(_("Refreshing catalogs..."))
2589 2653 self.progress_stop_timer_thread = False
2590 2654 Thread(target = self.__progressdialog_progress_pulse).start()
2591 2655 self.w_progress_dialog.show()
2592 2656 self.w_progress_cancel.hide()
2593 2657 self.__disconnect_models()
2594 2658 self.in_reload = True
2595 2659 Thread(target = self.__catalog_refresh).start()
2596 2660
2597 2661 def __catalog_refresh_done(self):
2598 2662 self.progress_stop_timer_thread = True
2599 2663 #Let the progress_pulse finish. This should be done other way, but at
2600 2664 #The moment this works fine
2601 2665 time.sleep(0.2)
2602 2666 gobject.idle_add(self.w_progress_cancel.show)
2603 2667 gobject.idle_add(self.process_package_list_start,
2604 2668 self.image_directory)
2605 2669
2606 2670 def __main_application_quit(self, be_name = None):
2607 2671 '''quits the main gtk loop'''
2608 2672 self.cancelled = True
|
↓ open down ↓ |
118 lines elided |
↑ open up ↑ |
2609 2673 if self.in_setup:
2610 2674 return
2611 2675
2612 2676 if be_name:
2613 2677 if self.image_dir_arg:
2614 2678 gobject.spawn_async([self.application_path, "-R",
2615 2679 self.image_dir_arg, "-U", be_name])
2616 2680 else:
2617 2681 gobject.spawn_async([self.application_path,
2618 2682 "-U", be_name])
2619 - elif not self.in_search_mode:
2683 + elif self.in_search_mode:
2684 + self.__dump_datamodels(self.visible_repository,
2685 + self.saved_application_list, self.category_list,
2686 + self.section_list)
2687 + else:
2620 2688 visible_repository = self.__get_visible_repository_name()
2621 2689 self.__dump_datamodels(visible_repository,
2622 2690 self.application_list, self.category_list,
2623 2691 self.section_list)
2624 2692
2625 2693 width, height = self.w_main_window.get_size()
2626 2694 hpos = self.w_main_hpaned.get_position()
2627 2695 vpos = self.w_main_vpaned.get_position()
2628 2696 try:
2629 2697 self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
2630 2698 self.client.set_int(INITIAL_APP_HEIGHT_PREFERENCES, height)
2631 2699 self.client.set_int(INITIAL_APP_HPOS_PREFERENCES, hpos)
2632 2700 self.client.set_int(INITIAL_APP_VPOS_PREFERENCES, vpos)
2633 2701 except GError:
2634 2702 pass
2635 2703
2636 2704 self.w_main_window.hide()
2637 2705 while gtk.events_pending():
2638 2706 gtk.main_iteration(False)
2639 2707 gtk.main_quit()
2640 2708 sys.exit(0)
2641 2709 return True
2642 2710
2643 2711 def __check_if_something_was_changed(self):
2644 2712 ''' Returns True if any of the check boxes for package was changed, false
2645 2713 if not'''
2646 2714 if self.application_list:
2647 2715 for pkg in self.application_list:
2648 2716 if pkg[enumerations.MARK_COLUMN] == True:
2649 2717 return True
2650 2718 return False
2651 2719
2652 2720 def __setup_repositories_combobox(self, api_o, repositories_list):
2653 2721 self.__disconnect_repository_model()
2654 2722 default_pub = api_o.get_preferred_publisher().prefix
2655 2723 if self.default_publisher != default_pub:
2656 2724 self.__clear_pkg_selections()
2657 2725 self.default_publisher = default_pub
2658 2726 selected_repos = []
2659 2727 enabled_repos = []
2660 2728 for repo in self.selected_pkgs:
2661 2729 selected_repos.append(repo)
2662 2730 i = 0
2663 2731 active = 0
2664 2732 for pub in api_o.get_publishers():
2665 2733 if pub.disabled:
2666 2734 continue
2667 2735 prefix = pub.prefix
2668 2736 if cmp(prefix, self.default_publisher) == 0:
2669 2737 active = i
2670 2738 repositories_list.append([i, prefix, ])
2671 2739 enabled_repos.append(prefix)
2672 2740 i = i + 1
2673 2741 repositories_list.append([-1, "", ])
2674 2742 repositories_list.append([-1, _("Add..."), ])
2675 2743 pkgs_to_remove = []
2676 2744 for repo_name in selected_repos:
2677 2745 if repo_name not in enabled_repos:
2678 2746 pkg_stems = self.selected_pkgs.get(repo_name)
2679 2747 for pkg_stem in pkg_stems:
2680 2748 pkgs_to_remove.append(pkg_stem)
2681 2749 for pkg_stem in pkgs_to_remove:
2682 2750 self.__remove_pkg_stem_from_list(pkg_stem)
2683 2751 self.w_repository_combobox.set_model(repositories_list)
2684 2752 if self.default_publisher:
2685 2753 self.w_repository_combobox.set_active(active)
2686 2754 else:
2687 2755 self.w_repository_combobox.set_active(0)
2688 2756
2689 2757 def __active_pane_toggle(self, cell, path, model_sort):
2690 2758 '''Toggle function for column enumerations.MARK_COLUMN'''
2691 2759 applicationModel = model_sort.get_model()
2692 2760 applicationPath = model_sort.convert_path_to_child_path(path)
2693 2761 filterModel = applicationModel.get_model()
2694 2762 child_path = applicationModel.convert_path_to_child_path(applicationPath)
2695 2763 itr = filterModel.get_iter(child_path)
2696 2764 if itr:
2697 2765 modified = filterModel.get_value(itr, enumerations.MARK_COLUMN)
2698 2766 filterModel.set_value(itr, enumerations.MARK_COLUMN,
2699 2767 not modified)
2700 2768 pkg_status = filterModel.get_value(itr,
2701 2769 enumerations.STATUS_COLUMN)
2702 2770 pkg_stem = filterModel.get_value(itr, enumerations.STEM_COLUMN)
2703 2771 if modified:
2704 2772 self.__remove_pkg_stem_from_list(pkg_stem)
2705 2773 else:
2706 2774 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
2707 2775 self.update_statusbar()
2708 2776 self.__enable_disable_selection_menus()
2709 2777
2710 2778 def __update_reload_button(self):
2711 2779 if self.user_rights:
2712 2780 self.w_reload_button.set_sensitive(True)
2713 2781 else:
2714 2782 self.w_reload_button.set_sensitive(False)
2715 2783
2716 2784 def __add_pkg_stem_to_list(self, stem, status):
2717 2785 publisher = self.__get_active_publisher()
2718 2786 if self.selected_pkgs.get(publisher) == None:
2719 2787 self.selected_pkgs[publisher] = {}
2720 2788 self.selected_pkgs.get(publisher)[stem] = status
2721 2789 if status == enumerations.NOT_INSTALLED or \
2722 2790 status == enumerations.UPDATABLE:
2723 2791 if self.to_install_update.get(publisher) == None:
2724 2792 self.to_install_update[publisher] = 1
2725 2793 else:
2726 2794 self.to_install_update[publisher] += 1
2727 2795 if status == enumerations.UPDATABLE or status == enumerations.INSTALLED:
2728 2796 if self.to_remove.get(publisher) == None:
2729 2797 self.to_remove[publisher] = 1
2730 2798 else:
2731 2799 self.to_remove[publisher] += 1
2732 2800 self.__update_tooltips()
2733 2801
2734 2802 def __update_tooltips(self):
2735 2803 to_remove = None
2736 2804 to_install = None
2737 2805 no_iter = 0
2738 2806 for publisher in self.to_remove:
2739 2807 packages = self.to_remove.get(publisher)
2740 2808 if packages > 0:
2741 2809 if no_iter == 0:
2742 2810 to_remove = _("Selected for Removal:")
2743 2811 to_remove += "\n %s: %d" % (publisher, packages)
2744 2812 no_iter += 1
2745 2813 no_iter = 0
2746 2814 for publisher in self.to_install_update:
2747 2815 packages = self.to_install_update.get(publisher)
2748 2816 if packages > 0:
2749 2817 if no_iter == 0:
2750 2818 to_install = _("Selected for Install/Update:")
2751 2819 to_install += "\n %s: %d" % (publisher, packages)
2752 2820 no_iter += 1
2753 2821 if not to_install:
2754 2822 to_install = _("Select packages by marking the checkbox "
2755 2823 "and click to Install/Update.")
2756 2824 self.w_installupdate_button.set_tooltip(self.install_button_tooltip,
2757 2825 to_install)
2758 2826 if not to_remove:
2759 2827 to_remove = _("Select packages by marking the checkbox "
2760 2828 "and click to Remove selected.")
2761 2829 self.w_remove_button.set_tooltip(self.remove_button_tooltip, to_remove)
2762 2830
2763 2831 def __remove_pkg_stem_from_list(self, stem):
2764 2832 remove_pub = []
2765 2833 for publisher in self.selected_pkgs:
2766 2834 pkgs = self.selected_pkgs.get(publisher)
2767 2835 status = None
2768 2836 if stem in pkgs:
2769 2837 status = pkgs.pop(stem)
2770 2838 if status == enumerations.NOT_INSTALLED or \
2771 2839 status == enumerations.UPDATABLE:
2772 2840 if self.to_install_update.get(publisher) == None:
2773 2841 self.to_install_update[publisher] = 0
2774 2842 else:
2775 2843 self.to_install_update[publisher] -= 1
2776 2844 if status == enumerations.UPDATABLE or \
2777 2845 status == enumerations.INSTALLED:
2778 2846 if self.to_remove.get(publisher) == None:
2779 2847 self.to_remove[publisher] = 0
2780 2848 else:
2781 2849 self.to_remove[publisher] -= 1
2782 2850 if len(pkgs) == 0:
2783 2851 remove_pub.append(publisher)
2784 2852 for publisher in remove_pub:
2785 2853 self.selected_pkgs.pop(publisher)
2786 2854 self.__update_tooltips()
2787 2855
2788 2856 def __clear_pkg_selections(self):
2789 2857 # We clear the selections as the preffered repository was changed
2790 2858 # and pkg stems are not valid.
2791 2859 remove_pub = []
2792 2860 for publisher in self.selected_pkgs:
2793 2861 stems = self.selected_pkgs.get(publisher)
2794 2862 for pkg_stem in stems:
2795 2863 remove_pub.append(pkg_stem)
2796 2864 for pkg_stem in remove_pub:
2797 2865 self.__remove_pkg_stem_from_list(pkg_stem)
2798 2866
2799 2867 def __set_empty_details_panel(self):
2800 2868 self.showing_empty_details = True
2801 2869 if self.show_info_id != 0:
2802 2870 gobject.source_remove(self.show_info_id)
2803 2871 self.show_info_id = 0
2804 2872 if self.show_licenses_id != 0:
2805 2873 gobject.source_remove(self.show_licenses_id)
2806 2874 self.show_licenses_id = 0
2807 2875 pkg_name = _("Package Name")
2808 2876 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2809 2877 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2810 2878 self.w_installedfiles_textview.get_buffer().set_text("")
2811 2879 self.w_dependencies_textview.get_buffer().set_text("")
2812 2880 self.w_generalinfo_textview.get_buffer().set_text("")
2813 2881 self.w_license_textview.get_buffer().set_text("")
2814 2882 return
2815 2883
2816 2884 def __show_fetching_package_info(self, pkg):
2817 2885 pkg_name = pkg.get_name()
2818 2886 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2819 2887 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2820 2888
2821 2889 pkg_stem = pkg.get_pkg_stem()
2822 2890 if self.__setting_from_cache(pkg_stem):
2823 2891 return
2824 2892
2825 2893 self.w_shortdescription_label.set_text(
2826 2894 _("Fetching description..."))
2827 2895 instbuffer = self.w_installedfiles_textview.get_buffer()
2828 2896 depbuffer = self.w_dependencies_textview.get_buffer()
2829 2897 infobuffer = self.w_generalinfo_textview.get_buffer()
2830 2898 fetching_text = _("Fetching information...")
2831 2899 instbuffer.set_text(fetching_text)
2832 2900 depbuffer.set_text(fetching_text)
2833 2901 infobuffer.set_text(fetching_text)
2834 2902 return
2835 2903
2836 2904 def __setting_from_cache(self, pkg_stem):
2837 2905 if len(self.info_cache) > MAX_INFO_CACHE_LIMIT:
2838 2906 self.info_cache = {}
2839 2907
2840 2908 if self.info_cache.has_key(pkg_stem):
2841 2909 self.w_shortdescription_label.set_text(
2842 2910 self.info_cache[pkg_stem][0])
2843 2911 instbuffer = self.w_installedfiles_textview.get_buffer()
2844 2912 depbuffer = self.w_dependencies_textview.get_buffer()
2845 2913 infobuffer = self.w_generalinfo_textview.get_buffer()
2846 2914 infobuffer.set_text(self.info_cache[pkg_stem][1])
2847 2915 instbuffer.set_text(self.info_cache[pkg_stem][2])
2848 2916 depbuffer.set_text(self.info_cache[pkg_stem][3])
2849 2917 return True
2850 2918 else:
2851 2919 return False
2852 2920
2853 2921 def __update_package_info(self, pkg, local_info, remote_info, info_id):
2854 2922 if self.showing_empty_details or (info_id !=
2855 2923 self.last_show_info_id):
2856 2924 return
2857 2925 pkg_name = pkg.get_name()
2858 2926 pkg_stem = pkg.get_pkg_stem()
2859 2927 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2860 2928 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2861 2929 installed = True
2862 2930
2863 2931 if self.__setting_from_cache(pkg_stem):
2864 2932 return
2865 2933
2866 2934 instbuffer = self.w_installedfiles_textview.get_buffer()
2867 2935 depbuffer = self.w_dependencies_textview.get_buffer()
2868 2936 infobuffer = self.w_generalinfo_textview.get_buffer()
2869 2937
2870 2938 if not local_info and not remote_info:
2871 2939 network_str = \
2872 2940 _("\nThis might be caused by network problem "
2873 2941 "while accessing the repository.")
2874 2942 self.w_shortdescription_label.set_text(
2875 2943 _("Description not available for this package...") +
2876 2944 network_str)
2877 2945 instbuffer.set_text( \
2878 2946 _("Files Details not available for this package...") +
2879 2947 network_str)
2880 2948 depbuffer.set_text(_(
2881 2949 "Dependencies info not available for this package...") +
2882 2950 network_str)
2883 2951 infobuffer.set_text(
2884 2952 _("Information not available for this package...") +
2885 2953 network_str)
2886 2954 return
2887 2955
2888 2956 if not local_info:
2889 2957 # Package is not installed
2890 2958 local_info = remote_info
2891 2959 installed = False
2892 2960
2893 2961 if not remote_info:
2894 2962 remote_info = local_info
2895 2963 installed = True
2896 2964
2897 2965 description = local_info.summary
2898 2966 #XXX long term need to have something more robust here for multi byte
2899 2967 if len(description) > MAX_DESC_LEN:
2900 2968 description = description[:MAX_DESC_LEN] + " ..."
2901 2969 self.w_shortdescription_label.set_text(description)
2902 2970 inst_str = _("Root: %s\n") % self.api_o.img.get_root()
2903 2971 dep_str = _("Dependencies:\n")
2904 2972
2905 2973 if local_info.dependencies:
2906 2974 dep_str += ''.join(
2907 2975 ["\t%s\n" % x for x in local_info.dependencies])
2908 2976 if local_info.dirs:
2909 2977 inst_str += ''.join(["\t%s\n" % x for x in local_info.dirs])
2910 2978 if local_info.files:
2911 2979 inst_str += ''.join(["\t%s\n" % x for x in local_info.files])
2912 2980 if local_info.hardlinks:
2913 2981 inst_str += ''.join(["\t%s\n" % x for x in local_info.hardlinks])
2914 2982 if local_info.links:
2915 2983 inst_str += ''.join(["\t%s\n" % x for x in local_info.links])
2916 2984 info_str = ""
2917 2985 labs = {}
2918 2986 labs["sum"] = _("Summary:\t\t")
2919 2987 labs["size"] = _("Size:\t\t\t")
2920 2988 labs["cat"] = _("Category:\t\t")
2921 2989 labs["ins"] = _("Installed Version:\t")
2922 2990 labs["lat"] = _("Latest Version:\t")
2923 2991 labs["pkg_date"] = _("Packaging Date:\t")
2924 2992 labs["fmri"] = _("FMRI:\t\t\t")
2925 2993 labs["repository"] = _("Repository:\t\t")
2926 2994 max_len = 0
2927 2995 for lab in labs:
2928 2996 if len(labs[lab]) > max_len:
2929 2997 max_len = len(labs[lab])
2930 2998 categories = _("None")
2931 2999 if local_info.category_info_list:
2932 3000 verbose = len(local_info.category_info_list) > 1
2933 3001 categories = ""
2934 3002 categories += local_info.category_info_list[0].__str__(verbose)
2935 3003 if len(local_info.category_info_list) > 1:
2936 3004 for ci in local_info.category_info_list[1:]:
2937 3005 categories += ", " + ci.__str__(verbose)
2938 3006 summary = _("None")
2939 3007 if local_info.summary:
2940 3008 summary = local_info.summary
2941 3009 info_str += " %s %s" % (labs["sum"], summary)
2942 3010 info_str += "\n %s %s" % (labs["size"],
2943 3011 misc.bytes_to_str(local_info.size))
2944 3012 info_str += "\n %s %s" % (labs["cat"], categories)
2945 3013 if installed:
2946 3014 info_str += "\n %s %s,%s-%s" % (labs["ins"], local_info.version,
2947 3015 local_info.build_release, local_info.branch)
2948 3016 info_str += "\n %s %s,%s-%s" % (labs["lat"], remote_info.version,
2949 3017 remote_info.build_release, remote_info.branch)
2950 3018 info_str += "\n %s %s" % (labs["pkg_date"], local_info.packaging_date)
2951 3019 info_str += "\n %s %s" % (labs["fmri"], local_info.fmri)
2952 3020 info_str += "\n %s %s" % (labs["repository"], local_info.publisher)
2953 3021 infobuffer.set_text(info_str)
2954 3022 instbuffer.set_text(inst_str)
2955 3023 depbuffer.set_text(dep_str)
2956 3024 self.info_cache[pkg_stem] = \
2957 3025 (description, info_str, inst_str, dep_str)
2958 3026
2959 3027 def __update_package_license(self, licenses, license_id):
2960 3028 if self.showing_empty_details or (license_id !=
2961 3029 self.last_show_licenses_id):
2962 3030 return
2963 3031 lic = ""
2964 3032 lic_u = ""
2965 3033 if licenses == None:
2966 3034 lic_u = _("Not available")
2967 3035 else:
2968 3036 for licens in licenses:
2969 3037 lic += licens.get_text()
2970 3038 lic += "\n"
2971 3039 try:
2972 3040 lic_u = unicode(lic, "utf-8")
2973 3041 except UnicodeDecodeError:
2974 3042 lic_u += ""
2975 3043 licbuffer = self.w_license_textview.get_buffer()
2976 3044 licbuffer.set_text(lic_u)
2977 3045
2978 3046 def __show_licenses(self):
2979 3047 self.show_licenses_id = 0
2980 3048 if self.catalog_loaded == False:
2981 3049 return
2982 3050 Thread(target = self.__show_package_licenses,
2983 3051 args = (self.selected_pkgstem, self.last_show_licenses_id,)).start()
2984 3052
2985 3053 def __show_package_licenses(self, selected_pkgstem, license_id):
2986 3054 if selected_pkgstem == None:
2987 3055 gobject.idle_add(self.__update_package_license, None,
2988 3056 self.last_show_licenses_id)
2989 3057 return
2990 3058 info = None
2991 3059 try:
2992 3060 info = self.api_o.info([selected_pkgstem],
2993 3061 True, frozenset([api.PackageInfo.LICENSES]))
2994 3062 except (api_errors.TransportError):
2995 3063 pass
2996 3064 if self.showing_empty_details or (license_id !=
2997 3065 self.last_show_licenses_id):
2998 3066 return
2999 3067 if not info or (info and len(info.get(0)) == 0):
3000 3068 try:
3001 3069 # Get license from remote
3002 3070 info = self.api_o.info([selected_pkgstem],
3003 3071 False, frozenset([api.PackageInfo.LICENSES]))
3004 3072 except (api_errors.TransportError):
3005 3073 pass
3006 3074 if self.showing_empty_details or (license_id !=
3007 3075 self.last_show_licenses_id):
3008 3076 return
3009 3077 pkgs_info = None
3010 3078 package_info = None
3011 3079 no_licenses = 0
3012 3080 if info:
3013 3081 pkgs_info = info[0]
3014 3082 if pkgs_info:
3015 3083 package_info = pkgs_info[0]
3016 3084 if package_info:
3017 3085 no_licenses = len(package_info.licenses)
3018 3086 if no_licenses == 0:
3019 3087 gobject.idle_add(self.__update_package_license, None,
3020 3088 license_id)
3021 3089 return
3022 3090 else:
3023 3091 gobject.idle_add(self.__update_package_license,
3024 3092 package_info.licenses, license_id)
3025 3093
3026 3094 def __get_pkg_info(self, pkg_stem, local):
3027 3095 info = None
3028 3096 try:
3029 3097 info = self.api_o.info([pkg_stem], local,
3030 3098 api.PackageInfo.ALL_OPTIONS -
3031 3099 frozenset([api.PackageInfo.LICENSES]))
3032 3100 except (api_errors.TransportError):
3033 3101 return info
3034 3102 pkgs_info = None
3035 3103 package_info = None
3036 3104 if info:
3037 3105 pkgs_info = info[0]
3038 3106 if pkgs_info:
3039 3107 package_info = pkgs_info[0]
3040 3108 if package_info:
3041 3109 return package_info
3042 3110 else:
3043 3111 return None
3044 3112
3045 3113 def __show_info(self, model, path):
3046 3114 self.show_info_id = 0
3047 3115 if self.catalog_loaded == False:
3048 3116 self.selected_model = model
3049 3117 self.selected_path = path
3050 3118 return
3051 3119 if not (model and path):
3052 3120 return
3053 3121 if self.selected_model != None:
3054 3122 if (self.selected_model != model or
3055 3123 self.selected_path != path):
3056 3124 # This can happen after catalogs are loaded in
3057 3125 # enable_disable_update_all and a different
3058 3126 # package is selected before enable_disable_update_all
3059 3127 # calls __show_info. We set these variable to None
3060 3128 # so that when __show_info is called it does nothing.
3061 3129 self.selected_model = None
3062 3130 self.selected_path = None
3063 3131
3064 3132 itr = model.get_iter(path)
3065 3133 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3066 3134 pkg_stem = model.get_value(itr, enumerations.STEM_COLUMN)
3067 3135 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
3068 3136 if self.info_cache.has_key(pkg_stem):
3069 3137 return
3070 3138 Thread(target = self.__show_package_info,
3071 3139 args = (pkg, pkg_stem, pkg_status, self.last_show_info_id)).start()
3072 3140
3073 3141 def __show_package_info(self, pkg, pkg_stem, pkg_status, info_id):
3074 3142 self.api_o.log_operation_start("info")
3075 3143 local_info = None
3076 3144 remote_info = None
3077 3145 if not self.showing_empty_details and (info_id ==
3078 3146 self.last_show_info_id) and (pkg_status ==
3079 3147 enumerations.INSTALLED or pkg_status ==
3080 3148 enumerations.UPDATABLE):
3081 3149 local_info = self.__get_pkg_info(pkg_stem, True)
3082 3150 if not self.showing_empty_details and (info_id ==
3083 3151 self.last_show_info_id) and (pkg_status ==
3084 3152 enumerations.NOT_INSTALLED or pkg_status ==
3085 3153 enumerations.UPDATABLE):
3086 3154 remote_info = self.__get_pkg_info(pkg_stem, False)
3087 3155 if not self.showing_empty_details and (info_id ==
3088 3156 self.last_show_info_id):
3089 3157 gobject.idle_add(self.__update_package_info, pkg,
3090 3158 local_info, remote_info, info_id)
3091 3159 self.api_o.log_operation_end()
3092 3160 return
3093 3161
3094 3162 # This function is ported from pkg.actions.generic.distinguished_name()
3095 3163 @staticmethod
3096 3164 def __locale_distinguished_name(action):
3097 3165 if action.key_attr == None:
3098 3166 return str(action)
3099 3167 return "%s: %s" % \
3100 3168 (_(action.name), action.attrs.get(action.key_attr, "???"))
3101 3169
3102 3170 def __application_filter(self, model, itr):
3103 3171 '''This function is used to filter content in the main
3104 3172 application view'''
3105 3173 if self.in_setup or self.cancelled:
3106 3174 return False
3107 3175 filter_id = self.w_filter_combobox.get_active()
3108 3176 if filter_id == enumerations.FILTER_SELECTED:
3109 3177 return model.get_value(itr, enumerations.MARK_COLUMN)
3110 3178 # XXX Show filter, chenge text to integers
3111 3179 selected_category = 0
3112 3180 category_selection = self.w_categories_treeview.get_selection()
3113 3181 category_model, category_iter = category_selection.get_selected()
3114 3182 if category_iter:
3115 3183 selected_category = category_model.get_value(category_iter,
3116 3184 enumerations.CATEGORY_ID)
3117 3185 category_list = model.get_value(itr, enumerations.CATEGORY_LIST_COLUMN)
3118 3186 selected_section = self.w_sections_combobox.get_active()
3119 3187 category = False
3120 3188 if selected_section == 0 and selected_category == 0:
3121 3189 #For section "All" and category "All" always true
3122 3190 category = True
3123 3191 elif selected_category != 0:
3124 3192 if category_list and selected_category in category_list:
3125 3193 category = True
3126 3194 elif category_list:
3127 3195 #The selected category is "All" so we need to check
3128 3196 #If the package belongs to one of the visible categories
3129 3197 for visible_category in category_model:
3130 3198 visible_id = visible_category[enumerations.CATEGORY_ID]
3131 3199 if visible_id in category_list:
3132 3200 category = True
3133 3201 break
3134 3202 if (model.get_value(itr, enumerations.IS_VISIBLE_COLUMN) == False):
3135 3203 return False
3136 3204 return (category &
3137 3205 self.__is_package_filtered(model, itr, filter_id))
3138 3206
3139 3207 @staticmethod
3140 3208 def __is_package_filtered(model, itr, filter_id):
3141 3209 '''Function for filtercombobox'''
3142 3210 if filter_id == enumerations.FILTER_ALL:
3143 3211 return True
3144 3212 status = model.get_value(itr, enumerations.STATUS_COLUMN)
3145 3213 if filter_id == enumerations.FILTER_INSTALLED:
3146 3214 return (status == enumerations.INSTALLED or status == \
3147 3215 enumerations.UPDATABLE)
3148 3216 elif filter_id == enumerations.FILTER_UPDATES:
3149 3217 return status == enumerations.UPDATABLE
3150 3218 elif filter_id == enumerations.FILTER_NOT_INSTALLED:
3151 3219 return status == enumerations.NOT_INSTALLED
3152 3220
3153 3221 def __is_pkg_repository_visible(self, model, itr):
3154 3222 if len(self.repositories_list) <= 1:
3155 3223 return True
3156 3224 else:
3157 3225 visible_repository = self.__get_visible_repository_name()
3158 3226 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3159 3227 if not pkg:
3160 3228 return False
3161 3229 if cmp(pkg.get_publisher(), visible_repository) == 0:
3162 3230 return True
3163 3231 else:
3164 3232 return False
3165 3233
3166 3234 def __get_visible_repository_name(self):
3167 3235 pub_iter = self.w_repository_combobox.get_active_iter()
3168 3236 if pub_iter == None:
3169 3237 return None
3170 3238 visible = self.repositories_list.get_value(pub_iter, \
3171 3239 enumerations.REPOSITORY_NAME)
3172 3240 return visible
3173 3241
3174 3242 def __enable_disable_selection_menus(self):
3175 3243 if self.in_setup:
3176 3244 return
3177 3245 self.__enable_disable_select_updates()
3178 3246 if not self.__doing_search():
3179 3247 self.unset_busy_cursor()
3180 3248
3181 3249 def __enable_disable_select_all(self):
3182 3250 if self.in_setup:
3183 3251 return
3184 3252 if len(self.w_application_treeview.get_model()) > 0:
3185 3253 for row in self.w_application_treeview.get_model():
3186 3254 if not row[enumerations.MARK_COLUMN]:
3187 3255 self.w_selectall_menuitem.set_sensitive(True)
3188 3256 return
3189 3257 self.w_selectall_menuitem.set_sensitive(False)
3190 3258 else:
3191 3259 self.w_selectall_menuitem.set_sensitive(False)
3192 3260
3193 3261 def __enable_disable_install_remove(self):
3194 3262 if not self.user_rights:
3195 3263 self.w_installupdate_button.set_sensitive(False)
3196 3264 self.w_installupdate_menuitem.set_sensitive(False)
3197 3265 self.w_remove_button.set_sensitive(False)
3198 3266 self.w_remove_menuitem.set_sensitive(False)
3199 3267 return
3200 3268 selected_removal = self.__enable_if_selected_for_removal()
3201 3269 selected_install_update = self.__enable_if_selected_for_install_update()
3202 3270 if selected_removal or selected_install_update:
3203 3271 return
3204 3272 remove = False
3205 3273 install = False
3206 3274 if self.selected == 0:
3207 3275 model, itr = self.package_selection.get_selected()
3208 3276 if itr:
3209 3277 status = \
3210 3278 model.get_value(itr, enumerations.STATUS_COLUMN)
3211 3279 if status == enumerations.NOT_INSTALLED:
3212 3280 remove = False
3213 3281 install = True
3214 3282 elif status == enumerations.UPDATABLE:
3215 3283 remove = True
3216 3284 install = True
3217 3285 elif status == enumerations.INSTALLED:
3218 3286 remove = True
3219 3287 install = False
3220 3288 self.w_installupdate_button.set_sensitive(install)
3221 3289 self.w_installupdate_menuitem.set_sensitive(install)
3222 3290 self.w_remove_button.set_sensitive(remove)
3223 3291 self.w_remove_menuitem.set_sensitive(remove)
3224 3292
3225 3293 def __enable_if_selected_for_removal(self):
3226 3294 sensitive = False
3227 3295 visible_repository = self.__get_visible_repository_name()
3228 3296 selected = self.to_remove.get(visible_repository)
3229 3297 if selected > 0:
3230 3298 sensitive = True
3231 3299 self.w_remove_button.set_sensitive(sensitive)
3232 3300 self.w_remove_menuitem.set_sensitive(sensitive)
3233 3301 return sensitive
3234 3302
3235 3303 def __enable_if_selected_for_install_update(self):
3236 3304 sensitive = False
3237 3305 visible_repository = self.__get_visible_repository_name()
3238 3306 selected = self.to_install_update.get(visible_repository)
3239 3307 if selected > 0:
3240 3308 sensitive = True
3241 3309 self.w_installupdate_button.set_sensitive(sensitive)
3242 3310 self.w_installupdate_menuitem.set_sensitive(sensitive)
3243 3311 return sensitive
3244 3312
3245 3313 def __enable_disable_select_updates(self):
3246 3314 for row in self.w_application_treeview.get_model():
3247 3315 if row[enumerations.STATUS_COLUMN] == enumerations.UPDATABLE:
3248 3316 if not row[enumerations.MARK_COLUMN]:
3249 3317 self.w_selectupdates_menuitem. \
3250 3318 set_sensitive(True)
3251 3319 return
3252 3320 self.w_selectupdates_menuitem.set_sensitive(False)
3253 3321 return
3254 3322
3255 3323 def __get_inventory_list(self, pargs, all_known, all_versions):
3256 3324 self.__image_activity_lock.acquire()
3257 3325 try:
3258 3326 res = misc.get_inventory_list(self.api_o.img,
3259 3327 pargs, all_known, all_versions)
3260 3328 finally:
3261 3329 self.__image_activity_lock.release()
3262 3330 return res
3263 3331
3264 3332 def __enable_disable_update_all(self):
3265 3333 #XXX Api to provide fast information if there are some updates
3266 3334 #available within image
3267 3335 gobject.idle_add(self.w_updateall_button.set_sensitive, False)
3268 3336 gobject.idle_add(self.w_updateall_menuitem.set_sensitive, False)
3269 3337 update_available = self.__check_if_updates_available()
3270 3338 gobject.idle_add(self.__g_enable_disable_update_all, update_available)
3271 3339 gobject.idle_add(self.__show_info_after_catalog_load)
3272 3340 return False
3273 3341
3274 3342 def __show_info_after_catalog_load(self):
3275 3343 self.__show_info(self.selected_model, self.selected_path)
3276 3344 self.selected_model = None
3277 3345 self.selected_path = None
3278 3346 if (self.w_info_notebook.get_current_page() ==
3279 3347 INFO_NOTEBOOK_LICENSE_PAGE and
3280 3348 not self.showing_empty_details):
3281 3349 self.__show_licenses()
3282 3350
3283 3351 def __check_if_updates_available(self):
3284 3352 try:
3285 3353 self.catalog_loaded = False
3286 3354 self.api_o.refresh()
3287 3355 self.catalog_loaded = True
3288 3356 res = self.__get_inventory_list([], False, False)
3289 3357 for pfmri, state in res:
3290 3358 if state["upgradable"]:
3291 3359 self.pylintstub = pfmri
3292 3360 return True
3293 3361
3294 3362 except api_errors.InventoryException:
3295 3363 gobject.idle_add(self.__set_empty_details_panel)
3296 3364 return False
3297 3365 return False
3298 3366
3299 3367 def __g_enable_disable_update_all(self, update_available):
3300 3368 self.w_updateall_button.set_sensitive(update_available)
3301 3369 self.w_updateall_menuitem.set_sensitive(update_available)
3302 3370 self.__enable_disable_install_remove()
3303 3371
3304 3372 def __enable_disable_deselect(self):
3305 3373 if self.w_application_treeview.get_model():
3306 3374 for row in self.w_application_treeview.get_model():
3307 3375 if row[enumerations.MARK_COLUMN]:
3308 3376 self.w_deselect_menuitem.set_sensitive(True)
3309 3377 return
3310 3378 self.w_deselect_menuitem.set_sensitive(False)
3311 3379 return
3312 3380
3313 3381 def __catalog_refresh(self, reload_gui=True):
3314 3382 """Update image's catalogs."""
3315 3383 try:
3316 3384 # Since the user requested the refresh, perform it
3317 3385 # immediately for all publishers.
3318 3386 self.api_o.refresh(immediate=True)
3319 3387 # Refresh will load the catalogs.
3320 3388 self.catalog_loaded = True
3321 3389 except api_errors.PublisherError:
3322 3390 # In current implementation, this will never happen
3323 3391 # We are not refreshing specific publisher
3324 3392 self.__catalog_refresh_done()
3325 3393 raise
3326 3394 except api_errors.PermissionsException:
3327 3395 #Error will already have been reported in
3328 3396 #Manage Repository dialog
3329 3397 self.__catalog_refresh_done()
3330 3398 return -1
3331 3399 except api_errors.CatalogRefreshException, cre:
3332 3400 total = cre.total
3333 3401 succeeded = cre.succeeded
3334 3402 ermsg = _("Network problem.\n\n")
3335 3403 ermsg += _("Details:\n")
3336 3404 ermsg += "%s/%s" % (succeeded, total)
3337 3405 ermsg += _(" catalogs successfully updated:\n")
3338 3406 for pub, err in cre.failed:
3339 3407 if isinstance(err, HTTPError):
3340 3408 ermsg += " %s: %s - %s\n" % \
3341 3409 (err.filename, err.code, err.msg)
3342 3410 elif isinstance(err, URLError):
3343 3411 if err.args[0][0] == 8:
3344 3412 ermsg += " %s: %s\n" % \
3345 3413 (urlparse.urlsplit(
3346 3414 pub["origin"])[1].split(":")[0],
3347 3415 err.args[0][1])
3348 3416 else:
3349 3417 if isinstance(err.args[0], \
3350 3418 socket.timeout):
3351 3419 ermsg += " %s: %s\n" % \
3352 3420 (pub["origin"], "timeout")
3353 3421 else:
3354 3422 ermsg += " %s: %s\n" % \
3355 3423 (pub["origin"], \
3356 3424 err.args[0][1])
3357 3425 elif "data" in err.__dict__ and err.data:
3358 3426 ermsg += err.data
3359 3427 else:
3360 3428 ermsg += _("Unknown error")
3361 3429 ermsg += "\n"
3362 3430
3363 3431 gobject.idle_add(self.error_occurred, ermsg,
3364 3432 None, gtk.MESSAGE_INFO)
3365 3433 self.__catalog_refresh_done()
3366 3434 return -1
3367 3435 except api_errors.InvalidDepotResponseException, idrex:
3368 3436 err = str(idrex)
3369 3437 gobject.idle_add(self.error_occurred, err,
3370 3438 None, gtk.MESSAGE_INFO)
3371 3439 self.__catalog_refresh_done()
3372 3440 return -1
3373 3441 except api_errors.PublisherError:
3374 3442 self.__catalog_refresh_done()
3375 3443 raise
3376 3444 except Exception:
3377 3445 self.__catalog_refresh_done()
3378 3446 raise
3379 3447 if reload_gui:
3380 3448 self.__catalog_refresh_done()
3381 3449 return 0
3382 3450
3383 3451 def __add_pkgs_to_lists_from_cache(self, publisher, application_list,
3384 3452 category_list, section_list):
3385 3453 if self.cache_o:
3386 3454 self.cache_o.load_application_list(publisher, application_list,
3387 3455 self.selected_pkgs)
3388 3456 self.cache_o.load_category_list(publisher, category_list)
3389 3457 self.cache_o.load_section_list(publisher, section_list)
3390 3458
3391 3459 def __add_pkgs_to_lists_from_api(self, publisher, application_list,
3392 3460 category_list, section_list):
3393 3461 """ This method set up image from the given directory and
3394 3462 returns the image object or None"""
3395 3463 pargs = []
3396 3464 pargs.append("pkg://" + publisher + "/*")
3397 3465 try:
3398 3466 pkgs_known = self.__get_inventory_list(pargs,
3399 3467 True, True)
3400 3468 except api_errors.InventoryException:
3401 3469 # This can happen if the repository does not
3402 3470 # contain any packages
3403 3471 err = _("Selected repository does not contain any packages.")
3404 3472 gobject.idle_add(self.w_progress_dialog.hide)
3405 3473 gobject.idle_add(self.error_occurred, err, None,
3406 3474 gtk.MESSAGE_INFO)
3407 3475 self.unset_busy_cursor()
3408 3476 pkgs_known = []
3409 3477
3410 3478 return self.__add_pkgs_to_lists(pkgs_known, application_list,
3411 3479 category_list, section_list)
3412 3480
3413 3481 def __add_pkgs_to_lists(self, pkgs_known, application_list,
3414 3482 category_list, section_list):
3415 3483 if section_list != None:
3416 3484 self.__init_sections(section_list)
3417 3485 #Only one instance of those icons should be in memory
3418 3486 update_available_icon = gui_misc.get_icon(self.icon_theme,
3419 3487 "status_newupdate")
3420 3488 installed_icon = gui_misc.get_icon(self.icon_theme,
3421 3489 "status_installed")
3422 3490 update_for_category_icon = \
3423 3491 self.get_icon_pixbuf_from_glade_dir("legend_newupdate")
3424 3492 #Imageinfo for categories
3425 3493 imginfo = imageinfo.ImageInfo()
3426 3494 sectioninfo = imageinfo.ImageInfo()
3427 3495 pubs = [p.prefix for p in self.api_o.get_publishers()]
3428 3496 categories = {}
3429 3497 sections = {}
3430 3498 share_path = "/usr/share/package-manager/data/"
3431 3499 for pub in pubs:
3432 3500 category = imginfo.read(self.application_dir +
3433 3501 share_path + pub)
3434 3502 if len(category) == 0:
3435 3503 category = imginfo.read(self.application_dir +
3436 3504 share_path + "opensolaris.org")
3437 3505 categories[pub] = category
3438 3506 section = sectioninfo.read(self.application_dir +
3439 3507 share_path + pub + ".sections")
3440 3508 if len(section) == 0:
3441 3509 section = sectioninfo.read(self.application_dir +
3442 3510 share_path + "opensolaris.org.sections")
3443 3511 sections[pub] = section
3444 3512 pkg_count = 0
3445 3513 pkg_add = 0
3446 3514 progress_percent = INITIAL_PROGRESS_TOTAL_PERCENTAGE
3447 3515 total_pkg_count = len(pkgs_known)
3448 3516 progress_increment = \
3449 3517 total_pkg_count / PACKAGE_PROGRESS_TOTAL_INCREMENTS
3450 3518 self.progress_stop_timer_thread = True
3451 3519 while gtk.events_pending():
3452 3520 gtk.main_iteration(False)
3453 3521 prev_stem = ""
3454 3522 prev_pfmri_str = ""
3455 3523 next_app = None
3456 3524 pkg_name = None
3457 3525 pkg_publisher = None
3458 3526 prev_state = None
3459 3527 category_icon = None
3460 3528 for pkg, state in pkgs_known:
3461 3529 if prev_pfmri_str and \
3462 3530 prev_pfmri_str == pkg.get_short_fmri() and \
3463 3531 prev_state == state:
3464 3532 pkg_count += 1
3465 3533 continue
3466 3534 if prev_stem and \
3467 3535 prev_stem == pkg.get_pkg_stem() and \
3468 3536 prev_state["state"] == "known" and \
3469 3537 state["state"] == "installed":
3470 3538 pass
3471 3539 elif next_app != None:
3472 3540 self.__add_package_to_list(next_app,
3473 3541 application_list,
3474 3542 pkg_add, pkg_name,
3475 3543 category_icon,
3476 3544 categories, category_list, pkg_publisher)
3477 3545 pkg_add += 1
3478 3546 prev_stem = pkg.get_pkg_stem()
3479 3547 prev_pfmri_str = pkg.get_short_fmri()
3480 3548 prev_state = state
3481 3549
3482 3550 if progress_increment > 0 and pkg_count % progress_increment == 0:
3483 3551 progress_percent += PACKAGE_PROGRESS_PERCENT_INCREMENT
3484 3552 if progress_percent <= PACKAGE_PROGRESS_PERCENT_TOTAL:
3485 3553 self.__progressdialog_progress_percent(
3486 3554 progress_percent, pkg_count, total_pkg_count)
3487 3555 while gtk.events_pending():
3488 3556 gtk.main_iteration(False)
3489 3557
3490 3558 status_icon = None
3491 3559 category_icon = None
3492 3560 pkg_name = pkg.get_name()
3493 3561 pkg_name = gui_misc.get_pkg_name(pkg_name)
3494 3562 pkg_stem = pkg.get_pkg_stem()
3495 3563 pkg_publisher = pkg.get_publisher()
3496 3564 pkg_state = enumerations.NOT_INSTALLED
3497 3565 if state["state"] == "installed":
3498 3566 pkg_state = enumerations.INSTALLED
3499 3567 if state["upgradable"] == True:
3500 3568 status_icon = update_available_icon
3501 3569 category_icon = update_for_category_icon
3502 3570 pkg_state = enumerations.UPDATABLE
3503 3571 else:
3504 3572 status_icon = installed_icon
3505 3573 marked = False
3506 3574 if not self.is_search_all:
3507 3575 pkgs = self.selected_pkgs.get(pkg_publisher)
3508 3576 if pkgs != None:
3509 3577 if pkg_stem in pkgs:
3510 3578 marked = True
3511 3579 next_app = \
3512 3580 [
3513 3581 marked, status_icon, pkg_name, '...', pkg_state,
3514 3582 pkg, pkg_stem, None, True, None, pkg_publisher
3515 3583 ]
3516 3584 pkg_count += 1
3517 3585
3518 3586 if next_app:
3519 3587 self.__add_package_to_list(next_app, application_list,
3520 3588 pkg_add, pkg_name, category_icon, categories,
3521 3589 category_list, pkg_publisher)
3522 3590 pkg_add += 1
3523 3591 if category_list != None:
3524 3592 self.__add_categories_to_sections(sections,
3525 3593 category_list, section_list)
3526 3594 self.__progressdialog_progress_percent(PACKAGE_PROGRESS_PERCENT_TOTAL,
3527 3595 total_pkg_count, total_pkg_count)
3528 3596 return
3529 3597
3530 3598 def __add_categories_to_sections(self, sections, category_list, section_list):
3531 3599 for publisher in sections:
3532 3600 for section in sections[publisher]:
3533 3601 for category in sections[publisher][section].split(","):
3534 3602 self.__add_category_to_section(_(category),
3535 3603 _(section), category_list, section_list)
3536 3604
3537 3605 #1915 Sort the Categories into alphabetical order and prepend All Category
3538 3606 if len(category_list) > 0:
3539 3607 rows = [tuple(r) + (i,) for i, r in enumerate(category_list)]
3540 3608 rows.sort(self.__sort)
3541 3609 r = []
3542 3610 category_list.reorder([r[-1] for r in rows])
3543 3611 return
3544 3612
3545 3613 def __add_package_to_list(self, app, application_list, pkg_add,
3546 3614 pkg_name, category_icon, categories, category_list, publisher):
3547 3615 row_iter = application_list.insert(pkg_add, app)
3548 3616 if category_list == None:
3549 3617 return
3550 3618 cat_pub = categories.get(publisher)
3551 3619 if pkg_name in cat_pub:
3552 3620 pkg_categories = cat_pub.get(pkg_name)
3553 3621 for pcat in pkg_categories.split(","):
3554 3622 self.__add_package_to_category(_(pcat), None,
3555 3623 category_icon, row_iter, application_list,
3556 3624 category_list)
3557 3625
3558 3626 @staticmethod
3559 3627 def __add_package_to_category(category_name, category_description,
3560 3628 category_icon, package, application_list, category_list):
3561 3629 if not package or category_name == _('All'):
3562 3630 return
3563 3631 if not category_name:
3564 3632 return
3565 3633 category_id = None
3566 3634 icon_visible = False
3567 3635 if category_icon:
3568 3636 icon_visible = True
3569 3637 for category in category_list:
3570 3638 if category[enumerations.CATEGORY_NAME] == category_name:
3571 3639 category_id = category[enumerations.CATEGORY_ID]
3572 3640 if category_icon:
3573 3641 category[enumerations.CATEGORY_ICON] = \
3574 3642 category_icon
3575 3643 category[enumerations.CATEGORY_ICON_VISIBLE] = \
3576 3644 icon_visible
3577 3645 break
3578 3646 if not category_id: # Category not exists
3579 3647 category_id = len(category_list) + 1
3580 3648 category_list.append([category_id, category_name,
3581 3649 category_description, category_icon, icon_visible,
3582 3650 True, None])
3583 3651 if application_list.get_value(package,
3584 3652 enumerations.CATEGORY_LIST_COLUMN):
3585 3653 a = application_list.get_value(package,
3586 3654 enumerations.CATEGORY_LIST_COLUMN)
3587 3655 a.append(category_id)
3588 3656 else:
3589 3657 category_list = []
3590 3658 category_list.append(category_id)
3591 3659 application_list.set(package,
3592 3660 enumerations.CATEGORY_LIST_COLUMN, category_list)
3593 3661
3594 3662 @staticmethod
3595 3663 def __add_category_to_section(category_name, section_name, category_list,
3596 3664 section_list):
3597 3665 '''Adds the section to section list in category. If there is no such
3598 3666 section, than it is not added. If there was already section than it
3599 3667 is skipped. Sections must be case sensitive'''
3600 3668 if not category_name:
3601 3669 return
3602 3670 for section in section_list:
3603 3671 if section[enumerations.SECTION_NAME] == section_name:
3604 3672 section_id = section[enumerations.SECTION_ID]
3605 3673 for category in category_list:
3606 3674 if category[enumerations.CATEGORY_NAME] == \
3607 3675 category_name:
3608 3676 section_lst = category[ \
3609 3677 enumerations.SECTION_LIST_OBJECT]
3610 3678 section[enumerations.SECTION_ENABLED] = \
3611 3679 True
3612 3680 if not section_lst:
3613 3681 category[ \
3614 3682 enumerations.SECTION_LIST_OBJECT] = \
3615 3683 [section_id, ]
3616 3684 else:
3617 3685 if not section_name in \
3618 3686 section_lst:
3619 3687 section_lst.append(
3620 3688 section_id)
3621 3689
3622 3690 def __progressdialog_progress_pulse(self):
3623 3691 while not self.progress_stop_timer_thread:
3624 3692 gobject.idle_add(self.w_progressbar.pulse)
3625 3693 time.sleep(0.1)
3626 3694 gobject.idle_add(self.w_progress_dialog.hide)
3627 3695 self.progress_stop_timer_thread = False
3628 3696
3629 3697 # For initial setup before loading package entries allow 5% of progress bar
3630 3698 # update it on a time base as we have no other way to judge progress at this point
3631 3699 def __progressdialog_progress_time(self):
3632 3700 while not self.progress_stop_timer_thread and \
3633 3701 self.progress_fraction_time_count <= \
3634 3702 INITIAL_PROGRESS_TOTAL_PERCENTAGE:
3635 3703
3636 3704 gobject.idle_add(self.w_progressbar.set_fraction,
3637 3705 self.progress_fraction_time_count)
3638 3706 self.progress_fraction_time_count += \
3639 3707 INITIAL_PROGRESS_TIME_PERCENTAGE
3640 3708 time.sleep(INITIAL_PROGRESS_TIME_INTERVAL)
3641 3709 self.progress_stop_timer_thread = False
3642 3710 self.progress_fraction_time_count = 0
3643 3711
3644 3712 def __progressdialog_progress_percent(self, fraction, count, total):
3645 3713 gobject.idle_add(self.w_progressinfo_label.set_text, _(
3646 3714 "Processing package entries: %d of %d") % (count, total) )
3647 3715 gobject.idle_add(self.w_progressbar.set_fraction, fraction)
3648 3716
3649 3717 def error_occurred(self, error_msg, msg_title=None, msg_type=gtk.MESSAGE_ERROR):
3650 3718 if msg_title:
3651 3719 title = msg_title
3652 3720 else:
3653 3721 title = _("Package Manager")
3654 3722 gui_misc.error_occurred(self.w_main_window, error_msg,
3655 3723 title, msg_type, use_markup=True)
3656 3724
3657 3725
3658 3726 msgbox = gtk.MessageDialog(parent =
3659 3727 self.w_main_window,
3660 3728 buttons = gtk.BUTTONS_CLOSE,
3661 3729 flags = gtk.DIALOG_MODAL,
3662 3730 type = msg_type,
3663 3731 message_format = None)
3664 3732 msgbox.set_property('text', error_msg)
3665 3733 title = None
3666 3734 if msg_title:
3667 3735 title = msg_title
3668 3736 else:
3669 3737 title = _("Package Manager")
3670 3738 msgbox.set_title(title)
3671 3739 msgbox.run()
3672 3740 msgbox.destroy()
3673 3741
3674 3742 #-----------------------------------------------------------------------------#
3675 3743 # Static Methods
3676 3744 #-----------------------------------------------------------------------------#
3677 3745
3678 3746 #@staticmethod
3679 3747 #def N_(message):
3680 3748 # return message
3681 3749
3682 3750 @staticmethod
3683 3751 def __sort(a, b):
3684 3752 return cmp(a[1], b[1])
3685 3753
3686 3754 @staticmethod
3687 3755 def cell_data_function(column, renderer, model, itr, data):
3688 3756 '''Function which sets the background colour to black if package is
3689 3757 selected'''
3690 3758 if itr:
3691 3759 if model.get_value(itr, enumerations.MARK_COLUMN):
3692 3760 renderer.set_property("cell-background", "#ffe5cc")
3693 3761 renderer.set_property("cell-background-set", True)
3694 3762 else:
3695 3763 renderer.set_property("cell-background-set", False)
3696 3764
3697 3765 @staticmethod
3698 3766 def combobox_separator(model, itr):
3699 3767 return model.get_value(itr, enumerations.FILTER_NAME) == ""
3700 3768
3701 3769 @staticmethod
3702 3770 def combobox_id_separator(model, itr):
3703 3771 return model.get_value(itr, 0) == -1 and \
3704 3772 model.get_value(itr, 1) == ""
3705 3773
3706 3774 @staticmethod
3707 3775 def category_filter(model, itr):
3708 3776 '''This function filters category in the main application view'''
3709 3777 return model.get_value(itr, enumerations.CATEGORY_VISIBLE)
3710 3778
3711 3779 @staticmethod
3712 3780 def get_datetime(version):
3713 3781 dt = None
3714 3782 try:
3715 3783 dt = version.get_datetime()
3716 3784 except AttributeError:
3717 3785 dt = version.get_timestamp()
3718 3786 return dt
3719 3787
3720 3788 @staticmethod
3721 3789 def get_installed_version(api_o, pkg):
3722 3790 info = api_o.info([pkg], False, frozenset(
3723 3791 [api.PackageInfo.STATE, api.PackageInfo.IDENTITY]))
3724 3792 found = info[api.ImageInterface.INFO_FOUND]
3725 3793 try:
3726 3794 version = found[0]
3727 3795 except IndexError:
3728 3796 version = None
3729 3797 return version
3730 3798
3731 3799 #-----------------------------------------------------------------------------#
3732 3800 # Public Methods
3733 3801 #-----------------------------------------------------------------------------#
3734 3802 def setup_progressdialog_show(self):
3735 3803 self.w_progress_dialog.set_title(_("Loading Repository Information"))
3736 3804 self.w_progressinfo_label.set_text(
3737 3805 _( "Fetching package entries ..."))
3738 3806 self.w_progress_cancel.hide()
3739 3807 self.w_progress_dialog.show()
3740 3808 Thread(target = self.__progressdialog_progress_time).start()
3741 3809
3742 3810 def setup_progressdialog_hide(self):
3743 3811 self.progress_stop_timer_thread = True
3744 3812 self.w_progress_dialog.hide()
3745 3813
3746 3814 def init_show_filter(self):
3747 3815 self.__init_show_filter() #Initiates filter
3748 3816
3749 3817 def reload_packages(self):
3750 3818 self.api_o = gui_misc.get_api_object(self.image_directory,
3751 3819 self.pr, self.w_main_window)
3752 3820 self.cache_o = self.__get_cache_obj(self.icon_theme,
3753 3821 self.application_dir, self.api_o)
3754 3822 self.__on_reload(None)
3755 3823
3756 3824 def set_busy_cursor(self):
3757 3825 self.gdk_window.show()
3758 3826
3759 3827 def unset_busy_cursor(self):
3760 3828 self.gdk_window.hide()
3761 3829
3762 3830 def process_package_list_start(self, image_directory):
3763 3831 self.image_directory = image_directory
3764 3832 if not self.api_o:
3765 3833 self.api_o = gui_misc.get_api_object(image_directory,
3766 3834 self.pr, self.w_main_window)
3767 3835 self.cache_o = self.__get_cache_obj(self.icon_theme,
3768 3836 self.application_dir, self.api_o)
3769 3837 self.img_timestamp = self.cache_o.get_index_timestamp()
3770 3838 self.repositories_list = self.__get_new_repositories_liststore()
3771 3839 self.__setup_repositories_combobox(self.api_o, self.repositories_list)
3772 3840
3773 3841 @staticmethod
3774 3842 def __get_cache_obj(icon_theme, application_dir, api_o):
3775 3843 cache_o = cache.CacheListStores(icon_theme, application_dir,
3776 3844 api_o)
3777 3845 return cache_o
3778 3846
3779 3847 def process_package_list_end(self):
3780 3848 self.__set_first_category_text()
3781 3849 self.in_startpage_startup = False
3782 3850 if self.update_all_proceed:
3783 3851 # TODO: Handle situation where only SUNWipkg/SUNWipg-gui have been updated
3784 3852 # in update all: bug 6357
3785 3853 self.__on_update_all(None)
3786 3854 self.update_all_proceed = False
3787 3855 self.setup_progressdialog_hide()
3788 3856 self.__enable_disable_install_remove()
3789 3857 self.update_statusbar()
3790 3858 self.in_setup = False
3791 3859 self.cancelled = False
3792 3860 if self.set_section != 0 or \
3793 3861 self.set_show_filter != enumerations.FILTER_ALL:
3794 3862 self.__application_refilter()
3795 3863 else:
3796 3864 self.unset_busy_cursor()
3797 3865
3798 3866 if self.first_run or self.in_reload:
3799 3867 Thread(target = self.__enable_disable_update_all).start()
3800 3868 self.first_run = False
3801 3869 self.in_reload = False
3802 3870
|
↓ open down ↓ |
1173 lines elided |
↑ open up ↑ |
3803 3871 def get_icon_pixbuf_from_glade_dir(self, icon_name):
3804 3872 return gui_misc.get_pixbuf_from_path(self.application_dir +
3805 3873 "/usr/share/package-manager/", icon_name)
3806 3874
3807 3875 def update_statusbar(self):
3808 3876 '''Function which updates statusbar'''
3809 3877 if self.statusbar_message_id > 0:
3810 3878 self.w_main_statusbar.remove(0, self.statusbar_message_id)
3811 3879 self.statusbar_message_id = 0
3812 3880 search_text = self.w_searchentry.get_text()
3813 - if self.in_search_mode:
3814 - if self.is_search_all:
3815 - opt_str = _('Searched All for "%s"') % (search_text)
3816 - else:
3817 - opt_str = \
3818 - _('Searched %(last_active)s '
3819 - 'for "%(search_text)s"') \
3820 - % {"last_active" : self.last_active_publisher,
3821 - "search_text" : search_text}
3822 - if len(self.application_list) == SEARCH_LIMIT:
3823 - fmt_str = _("%(option_str)s: first %(number)d "
3824 - "found %(time)s")
3825 - else:
3826 - fmt_str = _("%(option_str)s: %(number)d found %(time)s")
3827 - time_str = ""
3828 - if self.search_time_sec > 0:
3829 - time_str = _("in %d seconds") % self.search_time_sec
3830 - status_str = fmt_str % {"option_str" : opt_str,
3831 - "number" : len(self.application_list), "time" : time_str}
3881 +
3882 + if not self.in_search_mode:
3883 + installed = 0
3884 + self.selected = 0
3885 + sel = 0
3886 + if self.application_list == None:
3887 + return
3888 + visible_repository = self.__get_visible_repository_name()
3889 + pkgs = self.selected_pkgs.get(visible_repository)
3890 + if pkgs:
3891 + self.selected = len(pkgs)
3892 + for pkg_row in self.application_list:
3893 + if pkg_row[enumerations.STATUS_COLUMN] == \
3894 + enumerations.INSTALLED \
3895 + or pkg_row[enumerations.STATUS_COLUMN] == \
3896 + enumerations.UPDATABLE:
3897 + installed = installed + 1
3898 + if pkg_row[enumerations.MARK_COLUMN]:
3899 + sel = sel + 1
3900 + listed_str = _('%d listed') % len(self.application_list)
3901 + sel_str = _('%d selected') % sel
3902 + inst_str = _('%d installed') % installed
3903 + status_str = _("%s: %s , %s, %s.") % (visible_repository,
3904 + listed_str, inst_str, sel_str)
3832 3905 self.w_main_statusbar.push(0, status_str)
3833 3906 return
3834 - installed = 0
3835 - self.selected = 0
3836 - sel = 0
3837 - if self.application_list == None:
3838 - return
3839 - visible_repository = self.__get_visible_repository_name()
3840 - pkgs = self.selected_pkgs.get(visible_repository)
3841 - if pkgs:
3842 - self.selected = len(pkgs)
3843 - for pkg_row in self.application_list:
3844 - if pkg_row[enumerations.STATUS_COLUMN] == enumerations.INSTALLED \
3845 - or pkg_row[enumerations.STATUS_COLUMN] == \
3846 - enumerations.UPDATABLE:
3847 - installed = installed + 1
3848 - if pkg_row[enumerations.MARK_COLUMN]:
3849 - sel = sel + 1
3850 - listed_str = _('%d listed') % len(self.application_list)
3851 - sel_str = _('%d selected') % sel
3852 - inst_str = _('%d installed') % installed
3853 - status_str = _("%s: %s , %s, %s.") % (visible_repository, listed_str,
3854 - inst_str, sel_str)
3907 +
3908 + # In Search Mode
3909 + active = ""
3910 + if self.is_search_all:
3911 + if self.__doing_search():
3912 + if self.current_search_publisher != None:
3913 + active = "(" + self.current_search_publisher + \
3914 + ") "
3915 + opt_str = _('Searching... '
3916 + '%(active)sfor "%(search_text)s"') % \
3917 + {"active": active, "search_text": search_text}
3918 + else:
3919 + opt_str = _('Searched All for "%s"') % (search_text)
3920 + else:
3921 + search_str = _("Searched")
3922 + if self.__doing_search():
3923 + search_str = _("Searching...")
3924 + if self.last_active_publisher != None:
3925 + active = "(" + self.last_active_publisher + ") "
3926 + opt_str = \
3927 + _('%(search)s %(last_active)sfor "%(search_text)s"') \
3928 + % {"search": search_str, "last_active" : active,
3929 + "search_text" : search_text}
3930 + fmt_str = _("%(option_str)s: %(number)d found %(time)s")
3931 + time_str = ""
3932 + if self.search_time_sec > 0:
3933 + time_str = _("in %d seconds") % self.search_time_sec
3934 + status_str = fmt_str % {"option_str" : opt_str, "number" :
3935 + len(self.application_list), "time" : time_str}
3855 3936 self.w_main_statusbar.push(0, status_str)
3856 3937
3857 3938 def update_package_list(self, update_list):
3858 3939 if update_list == None and self.img_timestamp:
3859 3940 return
3860 3941 visible_repository = self.__get_visible_repository_name()
3861 3942 default_publisher = self.default_publisher
3862 3943 self.api_o.refresh()
3863 3944 if not self.img_timestamp:
3864 3945 self.img_timestamp = self.cache_o.get_index_timestamp()
3865 3946 self.__on_reload(None)
3866 3947 return
3867 3948 self.img_timestamp = self.cache_o.get_index_timestamp()
3868 3949 installed_icon = gui_misc.get_icon(self.icon_theme,
3869 3950 "status_installed")
3870 3951 visible_list = update_list.get(visible_repository)
3871 3952 if visible_list:
3872 3953 i = 0
3873 3954 while i < len(visible_list):
3874 3955 visible_list[i] = gui_misc.get_pkg_name(
3875 3956 visible_list[i])
3876 3957 i += 1
3877 3958 for row in self.application_list:
3878 3959 if row[enumerations.NAME_COLUMN] in visible_list:
3879 3960 pkg = row[enumerations.FMRI_COLUMN]
3880 3961 pkg_stem = row[enumerations.STEM_COLUMN]
3881 3962 self.__remove_pkg_stem_from_list(pkg_stem)
3882 3963 if self.info_cache.has_key(pkg_stem):
3883 3964 del self.info_cache[pkg_stem]
3884 3965 package_info = self.get_installed_version(
3885 3966 self.api_o, pkg_stem)
3886 3967 package_installed = (package_info.state
3887 3968 == api.PackageInfo.INSTALLED)
3888 3969 print pkg_stem, package_installed
3889 3970 if package_installed:
3890 3971 row[enumerations.STATUS_COLUMN] = \
3891 3972 enumerations.INSTALLED
3892 3973 row[enumerations.STATUS_ICON_COLUMN] = \
3893 3974 installed_icon
3894 3975 else:
3895 3976 row[enumerations.STATUS_COLUMN] = \
3896 3977 enumerations.NOT_INSTALLED
3897 3978 row[enumerations.STATUS_ICON_COLUMN] = \
3898 3979 None
3899 3980 row[enumerations.MARK_COLUMN] = False
3900 3981 self.__dump_datamodels(visible_repository,
3901 3982 self.application_list, self.category_list,
3902 3983 self.section_list)
3903 3984 for publisher in update_list:
3904 3985 if publisher != visible_repository:
3905 3986 pkg_list = update_list.get(publisher)
3906 3987 for pkg in pkg_list:
3907 3988 pkg_stem = None
3908 3989 if publisher != default_publisher:
3909 3990 pkg_stem = "pkg://%s/%s" % \
3910 3991 (publisher, pkg)
3911 3992 else:
3912 3993 pkg_stem = "pkg:/%s" % pkg
3913 3994 if pkg_stem:
3914 3995 if self.info_cache.has_key(pkg_stem):
3915 3996 del self.info_cache[pkg_stem]
3916 3997 self.__remove_pkg_stem_from_list(pkg_stem)
3917 3998 self.__process_package_selection()
3918 3999 self.__enable_disable_selection_menus()
3919 4000 self.__enable_disable_install_remove()
3920 4001 self.update_statusbar()
3921 4002 Thread(target = self.__enable_disable_update_all).start()
3922 4003
3923 4004 @staticmethod
3924 4005 def __find_root_home_dir():
3925 4006 return_str = '/var/tmp'
3926 4007
3927 4008 try:
3928 4009 lines = pwd.getpwnam('root')
3929 4010 except KeyError:
3930 4011 if debug:
3931 4012 print "Error getting passwd database entry for root"
3932 4013 return return_str
3933 4014 try:
3934 4015 return_str = lines[5]
3935 4016 except IndexError:
3936 4017 if debug:
3937 4018 print "Error getting home directory for root"
3938 4019 return return_str
3939 4020
3940 4021 def restart_after_ips_update(self, be_name):
3941 4022 self.__main_application_quit(be_name)
3942 4023
3943 4024 def shutdown_after_image_update(self):
3944 4025 info_str = _("The Update All action is now complete and "
3945 4026 "Package Manager will close.\n\nReview the posted release notes "
3946 4027 "before rebooting your system:\n\n"
3947 4028 )
3948 4029 self.w_ua_completed_release_label.set_text(info_str.strip('\n'))
3949 4030
3950 4031 info_str = misc.get_release_notes_url()
3951 4032 self.w_ua_completed_linkbutton.set_uri(info_str)
3952 4033 self.w_ua_completed_linkbutton.set_label(info_str)
3953 4034 self.release_notes_url = info_str
3954 4035
3955 4036 self.w_ua_completed_dialog.set_title(_("Update All Complete"))
3956 4037 self.w_ua_completed_dialog.show()
3957 4038
3958 4039 ###############################################################################
3959 4040 #-----------------------------------------------------------------------------#
3960 4041 # Main
3961 4042 #-----------------------------------------------------------------------------#
3962 4043
3963 4044 def main():
3964 4045 gtk.main()
3965 4046 return 0
3966 4047
3967 4048 if __name__ == '__main__':
3968 4049 debug = False
3969 4050 debug_descriptions = False
3970 4051 update_all_proceed = False
3971 4052 ua_be_name = None
3972 4053 app_path = None
3973 4054 image_dir = None
3974 4055 info_install_arg = None
3975 4056 save_selected = _("Save selected...")
3976 4057 save_selected_pkgs = _("Save selected packages...")
3977 4058 reboot_needed = _("The installed package(s) require a reboot before "
3978 4059 "installation can be completed.")
3979 4060
3980 4061 try:
3981 4062 opts, args = getopt.getopt(sys.argv[1:], "hR:U:i:", \
3982 4063 ["help", "image-dir=", "update-all=", "info-install="])
3983 4064 except getopt.error, msg:
3984 4065 print "%s, for help use --help" % msg
3985 4066 sys.exit(2)
3986 4067
3987 4068 if os.path.isabs(sys.argv[0]):
3988 4069 app_path = sys.argv[0]
3989 4070 else:
3990 4071 cmd = os.path.join(os.getcwd(), sys.argv[0])
3991 4072 app_path = os.path.realpath(cmd)
3992 4073
3993 4074 for option, argument in opts:
3994 4075 if option in ("-h", "--help"):
3995 4076 print """\
3996 4077 Use -R (--image-dir) to specify image directory.
3997 4078 Use -U (--update-all) to proceed with Update All"""
3998 4079 sys.exit(0)
3999 4080 if option in ("-R", "--image-dir"):
4000 4081 image_dir = argument
4001 4082 if option in ("-U", "--update-all"):
4002 4083 update_all_proceed = True
4003 4084 ua_be_name = argument
4004 4085 if option in ("-i", "--info-install"):
4005 4086 info_install_arg = argument
4006 4087
4007 4088 if image_dir == None:
4008 4089 try:
4009 4090 image_dir = os.environ["PKG_IMAGE"]
4010 4091 except KeyError:
4011 4092 image_dir = os.getcwd()
4012 4093 try:
4013 4094 gtk.init_check()
4014 4095 except RuntimeError, e:
4015 4096 print _("Unable to initialize gtk")
4016 4097 print str(e)
4017 4098 sys.exit(1)
4018 4099
4019 4100 # Setup webinstall
4020 4101 if info_install_arg or len(sys.argv) == 2:
4021 4102 webinstall = webinstall.Webinstall(image_dir)
4022 4103 if len(sys.argv) == 2:
4023 4104 info_install_arg = sys.argv[1]
4024 4105 webinstall.process_param(info_install_arg)
4025 4106 main()
4026 4107 sys.exit(0)
4027 4108
4028 4109 # Setup packagemanager
4029 4110 packagemanager = PackageManager()
4030 4111 packagemanager.application_path = app_path
4031 4112 packagemanager.image_dir_arg = image_dir
4032 4113 packagemanager.update_all_proceed = update_all_proceed
4033 4114 packagemanager.ua_be_name = ua_be_name
4034 4115
4035 4116 while gtk.events_pending():
4036 4117 gtk.main_iteration(False)
4037 4118
4038 4119 packagemanager.init_show_filter()
4039 4120
4040 4121 packagemanager.process_package_list_start(image_dir)
4041 4122
4042 4123 main()
|
↓ open down ↓ |
178 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX