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=[]):
2483 + print "__get_application_categories_lists: ", self.visible_repository
2435 2484 if not self.visible_repository:
2436 2485 self.visible_repository = self.__get_active_publisher()
2486 + print "** __get_application_categories_lists: ", self.visible_repository
2437 2487 application_list = self.__get_new_application_liststore()
2438 2488 category_list = self.__get_new_category_liststore()
2439 2489 section_list = self.__get_new_section_liststore()
2440 2490 first_loop = True
2441 2491 for publisher in publishers:
2442 2492 uptodate = False
2443 2493 try:
2444 2494 uptodate = self.__check_if_cache_uptodate(publisher)
2445 2495 if uptodate:
2446 2496 self.__add_pkgs_to_lists_from_cache(publisher,
2447 2497 application_list, category_list,
2448 2498 section_list)
2449 2499 except (UnpicklingError, EOFError, IOError):
2450 2500 #Most likely cache is corrupted, silently load list
2451 2501 #from api.
2452 2502 application_list = self.__get_new_application_liststore()
2453 2503 category_list = self.__get_new_category_liststore()
2454 2504 uptodate = False
2455 2505 if not uptodate:
2456 2506 if first_loop == True:
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2457 2507 first_loop = False
2458 2508 gobject.idle_add(self.setup_progressdialog_show)
2459 2509 self.api_o.refresh(pubs=[publisher])
2460 2510 self.__add_pkgs_to_lists_from_api(publisher,
2461 2511 application_list, category_list, section_list)
2462 2512 category_list.prepend([0, _('All'), None, None, False,
2463 2513 True, None])
2464 2514 if self.application_list and self.category_list and \
2465 2515 not self.visible_repository_uptodate:
2466 2516 if self.visible_repository:
2517 + dump_list = self.application_list
2518 + if self.saved_application_list != None:
2519 + dump_list = \
2520 + self.saved_application_list
2467 2521 self.__dump_datamodels(self.visible_repository,
2468 - self.application_list, self.category_list,
2522 + dump_list, self.category_list,
2469 2523 self.section_list)
2470 2524 self.visible_repository = self.__get_active_publisher()
2471 2525 self.visible_repository_uptodate = uptodate
2472 2526 return application_list, category_list, section_list
2473 2527
2474 2528 def __check_if_cache_uptodate(self, publisher):
2475 2529 if self.cache_o:
2476 2530 return self.cache_o.check_if_cache_uptodate(publisher)
2477 2531 return False
2478 2532
2479 2533 def __dump_datamodels(self, publisher, application_list, category_list,
2480 2534 section_list):
2535 + #Consistency check - only dump models if publisher passed in matches
2536 + #publisher in application list
2537 + if application_list == None:
2538 + return
2539 + app_pub = application_list[0][enumerations.AUTHORITY_COLUMN]
2540 + if publisher != app_pub:
2541 + if debug:
2542 + print "ERROR: __dump_data_models(): INCONSISTENT " \
2543 + "pub %s != app_list_pub %s" % \
2544 + (publisher, app_pub)
2545 + return
2546 +
2481 2547 if self.cache_o:
2482 2548 if self.img_timestamp == \
2483 2549 self.cache_o.get_index_timestamp():
2484 2550 Thread(target = self.cache_o.dump_datamodels,
2485 2551 args = (publisher, application_list, category_list,
2486 2552 section_list)).start()
2487 2553 else:
2488 2554 self.__remove_cache()
2489 2555
2490 2556 def __remove_cache(self):
2491 2557 model = self.w_repository_combobox.get_model()
2492 2558 for publisher in model:
2493 2559 pub_name = publisher[1]
2494 2560 if pub_name and pub_name != _("Add..."):
2495 2561 Thread(target = self.cache_o.remove_datamodel,
2496 2562 args = [publisher[1]]).start()
2497 2563
2498 2564 def __on_install_update(self, widget):
2499 2565 self.api_o.reset()
2500 2566 install_update = []
2501 2567 if self.selected == 0:
2502 2568 model, itr = self.package_selection.get_selected()
2503 2569 if itr:
2504 2570 install_update.append(
2505 2571 model.get_value(itr, enumerations.STEM_COLUMN))
2506 2572 else:
2507 2573 visible_repository = self.__get_visible_repository_name()
2508 2574 pkgs = self.selected_pkgs.get(visible_repository)
2509 2575 if pkgs:
2510 2576 for pkg_stem in pkgs:
2511 2577 status = pkgs.get(pkg_stem)
2512 2578 if status == enumerations.NOT_INSTALLED or \
2513 2579 status == enumerations.UPDATABLE:
2514 2580 install_update.append(pkg_stem)
2515 2581
2516 2582 if self.img_timestamp != self.cache_o.get_index_timestamp():
2517 2583 self.img_timestamp = None
2518 2584 self.__remove_cache()
2519 2585
2520 2586 installupdate.InstallUpdate(install_update, self, \
2521 2587 self.api_o, ips_update = False, \
2522 2588 action = enumerations.INSTALL_UPDATE)
2523 2589
2524 2590 def __on_update_all(self, widget):
2525 2591 self.api_o.reset()
2526 2592 installupdate.InstallUpdate([], self,
2527 2593 self.api_o, ips_update = False,
2528 2594 action = enumerations.IMAGE_UPDATE, be_name = self.ua_be_name,
2529 2595 parent_name = _("Package Manager"),
2530 2596 pkg_list = ["SUNWipkg", "SUNWipkg-gui"],
2531 2597 main_window = self.w_main_window)
2532 2598 return
2533 2599
2534 2600 def __on_ua_completed_linkbutton_clicked(self, widget):
2535 2601 try:
2536 2602 gnome.url_show(self.release_notes_url)
2537 2603 except gobject.GError:
2538 2604 self.error_occurred(_("Unable to navigate to:\n\t%s") %
2539 2605 self.release_notes_url)
2540 2606
2541 2607 def __on_help_about(self, widget):
2542 2608 wTreePlan = gtk.glade.XML(self.gladefile, "aboutdialog")
2543 2609 aboutdialog = wTreePlan.get_widget("aboutdialog")
2544 2610 aboutdialog.connect("response", lambda x = None, \
2545 2611 y = None: aboutdialog.destroy())
2546 2612 aboutdialog.run()
2547 2613
2548 2614 def __on_help_help(self, widget):
2549 2615 gui_misc.display_help(self.application_dir)
2550 2616
2551 2617 def __on_remove(self, widget):
2552 2618 self.api_o.reset()
2553 2619 remove_list = []
2554 2620 if self.selected == 0:
2555 2621 model, itr = self.package_selection.get_selected()
2556 2622 if itr:
2557 2623 remove_list.append(
2558 2624 model.get_value(itr, enumerations.STEM_COLUMN))
2559 2625 else:
2560 2626 visible_repository = self.__get_visible_repository_name()
2561 2627 pkgs = self.selected_pkgs.get(visible_repository)
2562 2628 if pkgs:
2563 2629 for pkg_stem in pkgs:
2564 2630 status = pkgs.get(pkg_stem)
2565 2631 if status == enumerations.INSTALLED or \
2566 2632 status == enumerations.UPDATABLE:
2567 2633 remove_list.append(pkg_stem)
2568 2634
2569 2635 if self.img_timestamp != self.cache_o.get_index_timestamp():
2570 2636 self.img_timestamp = None
2571 2637 self.__remove_cache()
2572 2638
2573 2639 installupdate.InstallUpdate(remove_list, self,
2574 2640 self.api_o, ips_update = False,
2575 2641 action = enumerations.REMOVE)
2576 2642
2577 2643 def __on_reload(self, widget):
2578 2644 if self.description_thread_running:
2579 2645 self.cancelled = True
2580 2646 if self.in_search_mode or self.is_search_all:
2581 2647 self.__unset_search(False)
2582 2648 self.__set_empty_details_panel()
2583 2649 self.in_setup = True
2584 2650 self.visible_repository = None
2585 2651 if widget != None:
2586 2652 self.__remove_cache()
2587 2653 self.w_progress_dialog.set_title(_("Refreshing catalogs"))
2588 2654 self.w_progressinfo_label.set_text(_("Refreshing catalogs..."))
2589 2655 self.progress_stop_timer_thread = False
2590 2656 Thread(target = self.__progressdialog_progress_pulse).start()
2591 2657 self.w_progress_dialog.show()
2592 2658 self.w_progress_cancel.hide()
2593 2659 self.__disconnect_models()
2594 2660 self.in_reload = True
2595 2661 Thread(target = self.__catalog_refresh).start()
2596 2662
2597 2663 def __catalog_refresh_done(self):
2598 2664 self.progress_stop_timer_thread = True
2599 2665 #Let the progress_pulse finish. This should be done other way, but at
2600 2666 #The moment this works fine
2601 2667 time.sleep(0.2)
2602 2668 gobject.idle_add(self.w_progress_cancel.show)
2603 2669 gobject.idle_add(self.process_package_list_start,
2604 2670 self.image_directory)
2605 2671
2606 2672 def __main_application_quit(self, be_name = None):
2607 2673 '''quits the main gtk loop'''
2608 2674 self.cancelled = True
|
↓ open down ↓ |
118 lines elided |
↑ open up ↑ |
2609 2675 if self.in_setup:
2610 2676 return
2611 2677
2612 2678 if be_name:
2613 2679 if self.image_dir_arg:
2614 2680 gobject.spawn_async([self.application_path, "-R",
2615 2681 self.image_dir_arg, "-U", be_name])
2616 2682 else:
2617 2683 gobject.spawn_async([self.application_path,
2618 2684 "-U", be_name])
2619 - elif not self.in_search_mode:
2685 + elif self.in_search_mode:
2686 + self.__dump_datamodels(self.visible_repository,
2687 + self.saved_application_list, self.category_list,
2688 + self.section_list)
2689 + else:
2620 2690 visible_repository = self.__get_visible_repository_name()
2621 2691 self.__dump_datamodels(visible_repository,
2622 2692 self.application_list, self.category_list,
2623 2693 self.section_list)
2624 2694
2625 2695 width, height = self.w_main_window.get_size()
2626 2696 hpos = self.w_main_hpaned.get_position()
2627 2697 vpos = self.w_main_vpaned.get_position()
2628 2698 try:
2629 2699 self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
2630 2700 self.client.set_int(INITIAL_APP_HEIGHT_PREFERENCES, height)
2631 2701 self.client.set_int(INITIAL_APP_HPOS_PREFERENCES, hpos)
2632 2702 self.client.set_int(INITIAL_APP_VPOS_PREFERENCES, vpos)
2633 2703 except GError:
2634 2704 pass
2635 2705
2636 2706 self.w_main_window.hide()
2637 2707 while gtk.events_pending():
2638 2708 gtk.main_iteration(False)
2639 2709 gtk.main_quit()
2640 2710 sys.exit(0)
2641 2711 return True
2642 2712
2643 2713 def __check_if_something_was_changed(self):
2644 2714 ''' Returns True if any of the check boxes for package was changed, false
2645 2715 if not'''
2646 2716 if self.application_list:
2647 2717 for pkg in self.application_list:
2648 2718 if pkg[enumerations.MARK_COLUMN] == True:
2649 2719 return True
2650 2720 return False
2651 2721
2652 2722 def __setup_repositories_combobox(self, api_o, repositories_list):
2653 2723 self.__disconnect_repository_model()
2654 2724 default_pub = api_o.get_preferred_publisher().prefix
2655 2725 if self.default_publisher != default_pub:
2656 2726 self.__clear_pkg_selections()
2657 2727 self.default_publisher = default_pub
2658 2728 selected_repos = []
2659 2729 enabled_repos = []
2660 2730 for repo in self.selected_pkgs:
2661 2731 selected_repos.append(repo)
2662 2732 i = 0
2663 2733 active = 0
2664 2734 for pub in api_o.get_publishers():
2665 2735 if pub.disabled:
2666 2736 continue
2667 2737 prefix = pub.prefix
2668 2738 if cmp(prefix, self.default_publisher) == 0:
2669 2739 active = i
2670 2740 repositories_list.append([i, prefix, ])
2671 2741 enabled_repos.append(prefix)
2672 2742 i = i + 1
2673 2743 repositories_list.append([-1, "", ])
2674 2744 repositories_list.append([-1, _("Add..."), ])
2675 2745 pkgs_to_remove = []
2676 2746 for repo_name in selected_repos:
2677 2747 if repo_name not in enabled_repos:
2678 2748 pkg_stems = self.selected_pkgs.get(repo_name)
2679 2749 for pkg_stem in pkg_stems:
2680 2750 pkgs_to_remove.append(pkg_stem)
2681 2751 for pkg_stem in pkgs_to_remove:
2682 2752 self.__remove_pkg_stem_from_list(pkg_stem)
2683 2753 self.w_repository_combobox.set_model(repositories_list)
2684 2754 if self.default_publisher:
2685 2755 self.w_repository_combobox.set_active(active)
2686 2756 else:
2687 2757 self.w_repository_combobox.set_active(0)
2688 2758
2689 2759 def __active_pane_toggle(self, cell, path, model_sort):
2690 2760 '''Toggle function for column enumerations.MARK_COLUMN'''
2691 2761 applicationModel = model_sort.get_model()
2692 2762 applicationPath = model_sort.convert_path_to_child_path(path)
2693 2763 filterModel = applicationModel.get_model()
2694 2764 child_path = applicationModel.convert_path_to_child_path(applicationPath)
2695 2765 itr = filterModel.get_iter(child_path)
2696 2766 if itr:
2697 2767 modified = filterModel.get_value(itr, enumerations.MARK_COLUMN)
2698 2768 filterModel.set_value(itr, enumerations.MARK_COLUMN,
2699 2769 not modified)
2700 2770 pkg_status = filterModel.get_value(itr,
2701 2771 enumerations.STATUS_COLUMN)
2702 2772 pkg_stem = filterModel.get_value(itr, enumerations.STEM_COLUMN)
2703 2773 if modified:
2704 2774 self.__remove_pkg_stem_from_list(pkg_stem)
2705 2775 else:
2706 2776 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
2707 2777 self.update_statusbar()
2708 2778 self.__enable_disable_selection_menus()
2709 2779
2710 2780 def __update_reload_button(self):
2711 2781 if self.user_rights:
2712 2782 self.w_reload_button.set_sensitive(True)
2713 2783 else:
2714 2784 self.w_reload_button.set_sensitive(False)
2715 2785
2716 2786 def __add_pkg_stem_to_list(self, stem, status):
2717 2787 publisher = self.__get_active_publisher()
2718 2788 if self.selected_pkgs.get(publisher) == None:
2719 2789 self.selected_pkgs[publisher] = {}
2720 2790 self.selected_pkgs.get(publisher)[stem] = status
2721 2791 if status == enumerations.NOT_INSTALLED or \
2722 2792 status == enumerations.UPDATABLE:
2723 2793 if self.to_install_update.get(publisher) == None:
2724 2794 self.to_install_update[publisher] = 1
2725 2795 else:
2726 2796 self.to_install_update[publisher] += 1
2727 2797 if status == enumerations.UPDATABLE or status == enumerations.INSTALLED:
2728 2798 if self.to_remove.get(publisher) == None:
2729 2799 self.to_remove[publisher] = 1
2730 2800 else:
2731 2801 self.to_remove[publisher] += 1
2732 2802 self.__update_tooltips()
2733 2803
2734 2804 def __update_tooltips(self):
2735 2805 to_remove = None
2736 2806 to_install = None
2737 2807 no_iter = 0
2738 2808 for publisher in self.to_remove:
2739 2809 packages = self.to_remove.get(publisher)
2740 2810 if packages > 0:
2741 2811 if no_iter == 0:
2742 2812 to_remove = _("Selected for Removal:")
2743 2813 to_remove += "\n %s: %d" % (publisher, packages)
2744 2814 no_iter += 1
2745 2815 no_iter = 0
2746 2816 for publisher in self.to_install_update:
2747 2817 packages = self.to_install_update.get(publisher)
2748 2818 if packages > 0:
2749 2819 if no_iter == 0:
2750 2820 to_install = _("Selected for Install/Update:")
2751 2821 to_install += "\n %s: %d" % (publisher, packages)
2752 2822 no_iter += 1
2753 2823 if not to_install:
2754 2824 to_install = _("Select packages by marking the checkbox "
2755 2825 "and click to Install/Update.")
2756 2826 self.w_installupdate_button.set_tooltip(self.install_button_tooltip,
2757 2827 to_install)
2758 2828 if not to_remove:
2759 2829 to_remove = _("Select packages by marking the checkbox "
2760 2830 "and click to Remove selected.")
2761 2831 self.w_remove_button.set_tooltip(self.remove_button_tooltip, to_remove)
2762 2832
2763 2833 def __remove_pkg_stem_from_list(self, stem):
2764 2834 remove_pub = []
2765 2835 for publisher in self.selected_pkgs:
2766 2836 pkgs = self.selected_pkgs.get(publisher)
2767 2837 status = None
2768 2838 if stem in pkgs:
2769 2839 status = pkgs.pop(stem)
2770 2840 if status == enumerations.NOT_INSTALLED or \
2771 2841 status == enumerations.UPDATABLE:
2772 2842 if self.to_install_update.get(publisher) == None:
2773 2843 self.to_install_update[publisher] = 0
2774 2844 else:
2775 2845 self.to_install_update[publisher] -= 1
2776 2846 if status == enumerations.UPDATABLE or \
2777 2847 status == enumerations.INSTALLED:
2778 2848 if self.to_remove.get(publisher) == None:
2779 2849 self.to_remove[publisher] = 0
2780 2850 else:
2781 2851 self.to_remove[publisher] -= 1
2782 2852 if len(pkgs) == 0:
2783 2853 remove_pub.append(publisher)
2784 2854 for publisher in remove_pub:
2785 2855 self.selected_pkgs.pop(publisher)
2786 2856 self.__update_tooltips()
2787 2857
2788 2858 def __clear_pkg_selections(self):
2789 2859 # We clear the selections as the preffered repository was changed
2790 2860 # and pkg stems are not valid.
2791 2861 remove_pub = []
2792 2862 for publisher in self.selected_pkgs:
2793 2863 stems = self.selected_pkgs.get(publisher)
2794 2864 for pkg_stem in stems:
2795 2865 remove_pub.append(pkg_stem)
2796 2866 for pkg_stem in remove_pub:
2797 2867 self.__remove_pkg_stem_from_list(pkg_stem)
2798 2868
2799 2869 def __set_empty_details_panel(self):
2800 2870 self.showing_empty_details = True
2801 2871 if self.show_info_id != 0:
2802 2872 gobject.source_remove(self.show_info_id)
2803 2873 self.show_info_id = 0
2804 2874 if self.show_licenses_id != 0:
2805 2875 gobject.source_remove(self.show_licenses_id)
2806 2876 self.show_licenses_id = 0
2807 2877 pkg_name = _("Package Name")
2808 2878 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2809 2879 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2810 2880 self.w_installedfiles_textview.get_buffer().set_text("")
2811 2881 self.w_dependencies_textview.get_buffer().set_text("")
2812 2882 self.w_generalinfo_textview.get_buffer().set_text("")
2813 2883 self.w_license_textview.get_buffer().set_text("")
2814 2884 return
2815 2885
2816 2886 def __show_fetching_package_info(self, pkg):
2817 2887 pkg_name = pkg.get_name()
2818 2888 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2819 2889 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2820 2890
2821 2891 pkg_stem = pkg.get_pkg_stem()
2822 2892 if self.__setting_from_cache(pkg_stem):
2823 2893 return
2824 2894
2825 2895 self.w_shortdescription_label.set_text(
2826 2896 _("Fetching description..."))
2827 2897 instbuffer = self.w_installedfiles_textview.get_buffer()
2828 2898 depbuffer = self.w_dependencies_textview.get_buffer()
2829 2899 infobuffer = self.w_generalinfo_textview.get_buffer()
2830 2900 fetching_text = _("Fetching information...")
2831 2901 instbuffer.set_text(fetching_text)
2832 2902 depbuffer.set_text(fetching_text)
2833 2903 infobuffer.set_text(fetching_text)
2834 2904 return
2835 2905
2836 2906 def __setting_from_cache(self, pkg_stem):
2837 2907 if len(self.info_cache) > MAX_INFO_CACHE_LIMIT:
2838 2908 self.info_cache = {}
2839 2909
2840 2910 if self.info_cache.has_key(pkg_stem):
2841 2911 self.w_shortdescription_label.set_text(
2842 2912 self.info_cache[pkg_stem][0])
2843 2913 instbuffer = self.w_installedfiles_textview.get_buffer()
2844 2914 depbuffer = self.w_dependencies_textview.get_buffer()
2845 2915 infobuffer = self.w_generalinfo_textview.get_buffer()
2846 2916 infobuffer.set_text(self.info_cache[pkg_stem][1])
2847 2917 instbuffer.set_text(self.info_cache[pkg_stem][2])
2848 2918 depbuffer.set_text(self.info_cache[pkg_stem][3])
2849 2919 return True
2850 2920 else:
2851 2921 return False
2852 2922
2853 2923 def __update_package_info(self, pkg, local_info, remote_info, info_id):
2854 2924 if self.showing_empty_details or (info_id !=
2855 2925 self.last_show_info_id):
2856 2926 return
2857 2927 pkg_name = pkg.get_name()
2858 2928 pkg_stem = pkg.get_pkg_stem()
2859 2929 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2860 2930 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2861 2931 installed = True
2862 2932
2863 2933 if self.__setting_from_cache(pkg_stem):
2864 2934 return
2865 2935
2866 2936 instbuffer = self.w_installedfiles_textview.get_buffer()
2867 2937 depbuffer = self.w_dependencies_textview.get_buffer()
2868 2938 infobuffer = self.w_generalinfo_textview.get_buffer()
2869 2939
2870 2940 if not local_info and not remote_info:
2871 2941 network_str = \
2872 2942 _("\nThis might be caused by network problem "
2873 2943 "while accessing the repository.")
2874 2944 self.w_shortdescription_label.set_text(
2875 2945 _("Description not available for this package...") +
2876 2946 network_str)
2877 2947 instbuffer.set_text( \
2878 2948 _("Files Details not available for this package...") +
2879 2949 network_str)
2880 2950 depbuffer.set_text(_(
2881 2951 "Dependencies info not available for this package...") +
2882 2952 network_str)
2883 2953 infobuffer.set_text(
2884 2954 _("Information not available for this package...") +
2885 2955 network_str)
2886 2956 return
2887 2957
2888 2958 if not local_info:
2889 2959 # Package is not installed
2890 2960 local_info = remote_info
2891 2961 installed = False
2892 2962
2893 2963 if not remote_info:
2894 2964 remote_info = local_info
2895 2965 installed = True
2896 2966
2897 2967 description = local_info.summary
2898 2968 #XXX long term need to have something more robust here for multi byte
2899 2969 if len(description) > MAX_DESC_LEN:
2900 2970 description = description[:MAX_DESC_LEN] + " ..."
2901 2971 self.w_shortdescription_label.set_text(description)
2902 2972 inst_str = _("Root: %s\n") % self.api_o.img.get_root()
2903 2973 dep_str = _("Dependencies:\n")
2904 2974
2905 2975 if local_info.dependencies:
2906 2976 dep_str += ''.join(
2907 2977 ["\t%s\n" % x for x in local_info.dependencies])
2908 2978 if local_info.dirs:
2909 2979 inst_str += ''.join(["\t%s\n" % x for x in local_info.dirs])
2910 2980 if local_info.files:
2911 2981 inst_str += ''.join(["\t%s\n" % x for x in local_info.files])
2912 2982 if local_info.hardlinks:
2913 2983 inst_str += ''.join(["\t%s\n" % x for x in local_info.hardlinks])
2914 2984 if local_info.links:
2915 2985 inst_str += ''.join(["\t%s\n" % x for x in local_info.links])
2916 2986 info_str = ""
2917 2987 labs = {}
2918 2988 labs["sum"] = _("Summary:\t\t")
2919 2989 labs["size"] = _("Size:\t\t\t")
2920 2990 labs["cat"] = _("Category:\t\t")
2921 2991 labs["ins"] = _("Installed Version:\t")
2922 2992 labs["lat"] = _("Latest Version:\t")
2923 2993 labs["pkg_date"] = _("Packaging Date:\t")
2924 2994 labs["fmri"] = _("FMRI:\t\t\t")
2925 2995 labs["repository"] = _("Repository:\t\t")
2926 2996 max_len = 0
2927 2997 for lab in labs:
2928 2998 if len(labs[lab]) > max_len:
2929 2999 max_len = len(labs[lab])
2930 3000 categories = _("None")
2931 3001 if local_info.category_info_list:
2932 3002 verbose = len(local_info.category_info_list) > 1
2933 3003 categories = ""
2934 3004 categories += local_info.category_info_list[0].__str__(verbose)
2935 3005 if len(local_info.category_info_list) > 1:
2936 3006 for ci in local_info.category_info_list[1:]:
2937 3007 categories += ", " + ci.__str__(verbose)
2938 3008 summary = _("None")
2939 3009 if local_info.summary:
2940 3010 summary = local_info.summary
2941 3011 info_str += " %s %s" % (labs["sum"], summary)
2942 3012 info_str += "\n %s %s" % (labs["size"],
2943 3013 misc.bytes_to_str(local_info.size))
2944 3014 info_str += "\n %s %s" % (labs["cat"], categories)
2945 3015 if installed:
2946 3016 info_str += "\n %s %s,%s-%s" % (labs["ins"], local_info.version,
2947 3017 local_info.build_release, local_info.branch)
2948 3018 info_str += "\n %s %s,%s-%s" % (labs["lat"], remote_info.version,
2949 3019 remote_info.build_release, remote_info.branch)
2950 3020 info_str += "\n %s %s" % (labs["pkg_date"], local_info.packaging_date)
2951 3021 info_str += "\n %s %s" % (labs["fmri"], local_info.fmri)
2952 3022 info_str += "\n %s %s" % (labs["repository"], local_info.publisher)
2953 3023 infobuffer.set_text(info_str)
2954 3024 instbuffer.set_text(inst_str)
2955 3025 depbuffer.set_text(dep_str)
2956 3026 self.info_cache[pkg_stem] = \
2957 3027 (description, info_str, inst_str, dep_str)
2958 3028
2959 3029 def __update_package_license(self, licenses, license_id):
2960 3030 if self.showing_empty_details or (license_id !=
2961 3031 self.last_show_licenses_id):
2962 3032 return
2963 3033 lic = ""
2964 3034 lic_u = ""
2965 3035 if licenses == None:
2966 3036 lic_u = _("Not available")
2967 3037 else:
2968 3038 for licens in licenses:
2969 3039 lic += licens.get_text()
2970 3040 lic += "\n"
2971 3041 try:
2972 3042 lic_u = unicode(lic, "utf-8")
2973 3043 except UnicodeDecodeError:
2974 3044 lic_u += ""
2975 3045 licbuffer = self.w_license_textview.get_buffer()
2976 3046 licbuffer.set_text(lic_u)
2977 3047
2978 3048 def __show_licenses(self):
2979 3049 self.show_licenses_id = 0
2980 3050 if self.catalog_loaded == False:
2981 3051 return
2982 3052 Thread(target = self.__show_package_licenses,
2983 3053 args = (self.selected_pkgstem, self.last_show_licenses_id,)).start()
2984 3054
2985 3055 def __show_package_licenses(self, selected_pkgstem, license_id):
2986 3056 if selected_pkgstem == None:
2987 3057 gobject.idle_add(self.__update_package_license, None,
2988 3058 self.last_show_licenses_id)
2989 3059 return
2990 3060 info = None
2991 3061 try:
2992 3062 info = self.api_o.info([selected_pkgstem],
2993 3063 True, frozenset([api.PackageInfo.LICENSES]))
2994 3064 except (api_errors.TransportError):
2995 3065 pass
2996 3066 if self.showing_empty_details or (license_id !=
2997 3067 self.last_show_licenses_id):
2998 3068 return
2999 3069 if not info or (info and len(info.get(0)) == 0):
3000 3070 try:
3001 3071 # Get license from remote
3002 3072 info = self.api_o.info([selected_pkgstem],
3003 3073 False, frozenset([api.PackageInfo.LICENSES]))
3004 3074 except (api_errors.TransportError):
3005 3075 pass
3006 3076 if self.showing_empty_details or (license_id !=
3007 3077 self.last_show_licenses_id):
3008 3078 return
3009 3079 pkgs_info = None
3010 3080 package_info = None
3011 3081 no_licenses = 0
3012 3082 if info:
3013 3083 pkgs_info = info[0]
3014 3084 if pkgs_info:
3015 3085 package_info = pkgs_info[0]
3016 3086 if package_info:
3017 3087 no_licenses = len(package_info.licenses)
3018 3088 if no_licenses == 0:
3019 3089 gobject.idle_add(self.__update_package_license, None,
3020 3090 license_id)
3021 3091 return
3022 3092 else:
3023 3093 gobject.idle_add(self.__update_package_license,
3024 3094 package_info.licenses, license_id)
3025 3095
3026 3096 def __get_pkg_info(self, pkg_stem, local):
3027 3097 info = None
3028 3098 try:
3029 3099 info = self.api_o.info([pkg_stem], local,
3030 3100 api.PackageInfo.ALL_OPTIONS -
3031 3101 frozenset([api.PackageInfo.LICENSES]))
3032 3102 except (api_errors.TransportError):
3033 3103 return info
3034 3104 pkgs_info = None
3035 3105 package_info = None
3036 3106 if info:
3037 3107 pkgs_info = info[0]
3038 3108 if pkgs_info:
3039 3109 package_info = pkgs_info[0]
3040 3110 if package_info:
3041 3111 return package_info
3042 3112 else:
3043 3113 return None
3044 3114
3045 3115 def __show_info(self, model, path):
3046 3116 self.show_info_id = 0
3047 3117 if self.catalog_loaded == False:
3048 3118 self.selected_model = model
3049 3119 self.selected_path = path
3050 3120 return
3051 3121 if not (model and path):
3052 3122 return
3053 3123 if self.selected_model != None:
3054 3124 if (self.selected_model != model or
3055 3125 self.selected_path != path):
3056 3126 # This can happen after catalogs are loaded in
3057 3127 # enable_disable_update_all and a different
3058 3128 # package is selected before enable_disable_update_all
3059 3129 # calls __show_info. We set these variable to None
3060 3130 # so that when __show_info is called it does nothing.
3061 3131 self.selected_model = None
3062 3132 self.selected_path = None
3063 3133
3064 3134 itr = model.get_iter(path)
3065 3135 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3066 3136 pkg_stem = model.get_value(itr, enumerations.STEM_COLUMN)
3067 3137 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
3068 3138 if self.info_cache.has_key(pkg_stem):
3069 3139 return
3070 3140 Thread(target = self.__show_package_info,
3071 3141 args = (pkg, pkg_stem, pkg_status, self.last_show_info_id)).start()
3072 3142
3073 3143 def __show_package_info(self, pkg, pkg_stem, pkg_status, info_id):
3074 3144 self.api_o.log_operation_start("info")
3075 3145 local_info = None
3076 3146 remote_info = None
3077 3147 if not self.showing_empty_details and (info_id ==
3078 3148 self.last_show_info_id) and (pkg_status ==
3079 3149 enumerations.INSTALLED or pkg_status ==
3080 3150 enumerations.UPDATABLE):
3081 3151 local_info = self.__get_pkg_info(pkg_stem, True)
3082 3152 if not self.showing_empty_details and (info_id ==
3083 3153 self.last_show_info_id) and (pkg_status ==
3084 3154 enumerations.NOT_INSTALLED or pkg_status ==
3085 3155 enumerations.UPDATABLE):
3086 3156 remote_info = self.__get_pkg_info(pkg_stem, False)
3087 3157 if not self.showing_empty_details and (info_id ==
3088 3158 self.last_show_info_id):
3089 3159 gobject.idle_add(self.__update_package_info, pkg,
3090 3160 local_info, remote_info, info_id)
3091 3161 self.api_o.log_operation_end()
3092 3162 return
3093 3163
3094 3164 # This function is ported from pkg.actions.generic.distinguished_name()
3095 3165 @staticmethod
3096 3166 def __locale_distinguished_name(action):
3097 3167 if action.key_attr == None:
3098 3168 return str(action)
3099 3169 return "%s: %s" % \
3100 3170 (_(action.name), action.attrs.get(action.key_attr, "???"))
3101 3171
3102 3172 def __application_filter(self, model, itr):
3103 3173 '''This function is used to filter content in the main
3104 3174 application view'''
3105 3175 if self.in_setup or self.cancelled:
3106 3176 return False
3107 3177 filter_id = self.w_filter_combobox.get_active()
3108 3178 if filter_id == enumerations.FILTER_SELECTED:
3109 3179 return model.get_value(itr, enumerations.MARK_COLUMN)
3110 3180 # XXX Show filter, chenge text to integers
3111 3181 selected_category = 0
3112 3182 category_selection = self.w_categories_treeview.get_selection()
3113 3183 category_model, category_iter = category_selection.get_selected()
3114 3184 if category_iter:
3115 3185 selected_category = category_model.get_value(category_iter,
3116 3186 enumerations.CATEGORY_ID)
3117 3187 category_list = model.get_value(itr, enumerations.CATEGORY_LIST_COLUMN)
3118 3188 selected_section = self.w_sections_combobox.get_active()
3119 3189 category = False
3120 3190 if selected_section == 0 and selected_category == 0:
3121 3191 #For section "All" and category "All" always true
3122 3192 category = True
3123 3193 elif selected_category != 0:
3124 3194 if category_list and selected_category in category_list:
3125 3195 category = True
3126 3196 elif category_list:
3127 3197 #The selected category is "All" so we need to check
3128 3198 #If the package belongs to one of the visible categories
3129 3199 for visible_category in category_model:
3130 3200 visible_id = visible_category[enumerations.CATEGORY_ID]
3131 3201 if visible_id in category_list:
3132 3202 category = True
3133 3203 break
3134 3204 if (model.get_value(itr, enumerations.IS_VISIBLE_COLUMN) == False):
3135 3205 return False
3136 3206 return (category &
3137 3207 self.__is_package_filtered(model, itr, filter_id))
3138 3208
3139 3209 @staticmethod
3140 3210 def __is_package_filtered(model, itr, filter_id):
3141 3211 '''Function for filtercombobox'''
3142 3212 if filter_id == enumerations.FILTER_ALL:
3143 3213 return True
3144 3214 status = model.get_value(itr, enumerations.STATUS_COLUMN)
3145 3215 if filter_id == enumerations.FILTER_INSTALLED:
3146 3216 return (status == enumerations.INSTALLED or status == \
3147 3217 enumerations.UPDATABLE)
3148 3218 elif filter_id == enumerations.FILTER_UPDATES:
3149 3219 return status == enumerations.UPDATABLE
3150 3220 elif filter_id == enumerations.FILTER_NOT_INSTALLED:
3151 3221 return status == enumerations.NOT_INSTALLED
3152 3222
3153 3223 def __is_pkg_repository_visible(self, model, itr):
3154 3224 if len(self.repositories_list) <= 1:
3155 3225 return True
3156 3226 else:
3157 3227 visible_repository = self.__get_visible_repository_name()
3158 3228 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3159 3229 if not pkg:
3160 3230 return False
3161 3231 if cmp(pkg.get_publisher(), visible_repository) == 0:
3162 3232 return True
3163 3233 else:
3164 3234 return False
3165 3235
3166 3236 def __get_visible_repository_name(self):
3167 3237 pub_iter = self.w_repository_combobox.get_active_iter()
3168 3238 if pub_iter == None:
3169 3239 return None
3170 3240 visible = self.repositories_list.get_value(pub_iter, \
3171 3241 enumerations.REPOSITORY_NAME)
3172 3242 return visible
3173 3243
3174 3244 def __enable_disable_selection_menus(self):
3175 3245 if self.in_setup:
3176 3246 return
3177 3247 self.__enable_disable_select_updates()
3178 3248 if not self.__doing_search():
3179 3249 self.unset_busy_cursor()
3180 3250
3181 3251 def __enable_disable_select_all(self):
3182 3252 if self.in_setup:
3183 3253 return
3184 3254 if len(self.w_application_treeview.get_model()) > 0:
3185 3255 for row in self.w_application_treeview.get_model():
3186 3256 if not row[enumerations.MARK_COLUMN]:
3187 3257 self.w_selectall_menuitem.set_sensitive(True)
3188 3258 return
3189 3259 self.w_selectall_menuitem.set_sensitive(False)
3190 3260 else:
3191 3261 self.w_selectall_menuitem.set_sensitive(False)
3192 3262
3193 3263 def __enable_disable_install_remove(self):
3194 3264 if not self.user_rights:
3195 3265 self.w_installupdate_button.set_sensitive(False)
3196 3266 self.w_installupdate_menuitem.set_sensitive(False)
3197 3267 self.w_remove_button.set_sensitive(False)
3198 3268 self.w_remove_menuitem.set_sensitive(False)
3199 3269 return
3200 3270 selected_removal = self.__enable_if_selected_for_removal()
3201 3271 selected_install_update = self.__enable_if_selected_for_install_update()
3202 3272 if selected_removal or selected_install_update:
3203 3273 return
3204 3274 remove = False
3205 3275 install = False
3206 3276 if self.selected == 0:
3207 3277 model, itr = self.package_selection.get_selected()
3208 3278 if itr:
3209 3279 status = \
3210 3280 model.get_value(itr, enumerations.STATUS_COLUMN)
3211 3281 if status == enumerations.NOT_INSTALLED:
3212 3282 remove = False
3213 3283 install = True
3214 3284 elif status == enumerations.UPDATABLE:
3215 3285 remove = True
3216 3286 install = True
3217 3287 elif status == enumerations.INSTALLED:
3218 3288 remove = True
3219 3289 install = False
3220 3290 self.w_installupdate_button.set_sensitive(install)
3221 3291 self.w_installupdate_menuitem.set_sensitive(install)
3222 3292 self.w_remove_button.set_sensitive(remove)
3223 3293 self.w_remove_menuitem.set_sensitive(remove)
3224 3294
3225 3295 def __enable_if_selected_for_removal(self):
3226 3296 sensitive = False
3227 3297 visible_repository = self.__get_visible_repository_name()
3228 3298 selected = self.to_remove.get(visible_repository)
3229 3299 if selected > 0:
3230 3300 sensitive = True
3231 3301 self.w_remove_button.set_sensitive(sensitive)
3232 3302 self.w_remove_menuitem.set_sensitive(sensitive)
3233 3303 return sensitive
3234 3304
3235 3305 def __enable_if_selected_for_install_update(self):
3236 3306 sensitive = False
3237 3307 visible_repository = self.__get_visible_repository_name()
3238 3308 selected = self.to_install_update.get(visible_repository)
3239 3309 if selected > 0:
3240 3310 sensitive = True
3241 3311 self.w_installupdate_button.set_sensitive(sensitive)
3242 3312 self.w_installupdate_menuitem.set_sensitive(sensitive)
3243 3313 return sensitive
3244 3314
3245 3315 def __enable_disable_select_updates(self):
3246 3316 for row in self.w_application_treeview.get_model():
3247 3317 if row[enumerations.STATUS_COLUMN] == enumerations.UPDATABLE:
3248 3318 if not row[enumerations.MARK_COLUMN]:
3249 3319 self.w_selectupdates_menuitem. \
3250 3320 set_sensitive(True)
3251 3321 return
3252 3322 self.w_selectupdates_menuitem.set_sensitive(False)
3253 3323 return
3254 3324
3255 3325 def __get_inventory_list(self, pargs, all_known, all_versions):
3256 3326 self.__image_activity_lock.acquire()
3257 3327 try:
3258 3328 res = misc.get_inventory_list(self.api_o.img,
3259 3329 pargs, all_known, all_versions)
3260 3330 finally:
3261 3331 self.__image_activity_lock.release()
3262 3332 return res
3263 3333
3264 3334 def __enable_disable_update_all(self):
3265 3335 #XXX Api to provide fast information if there are some updates
3266 3336 #available within image
3267 3337 gobject.idle_add(self.w_updateall_button.set_sensitive, False)
3268 3338 gobject.idle_add(self.w_updateall_menuitem.set_sensitive, False)
3269 3339 update_available = self.__check_if_updates_available()
3270 3340 gobject.idle_add(self.__g_enable_disable_update_all, update_available)
3271 3341 gobject.idle_add(self.__show_info_after_catalog_load)
3272 3342 return False
3273 3343
3274 3344 def __show_info_after_catalog_load(self):
3275 3345 self.__show_info(self.selected_model, self.selected_path)
3276 3346 self.selected_model = None
3277 3347 self.selected_path = None
3278 3348 if (self.w_info_notebook.get_current_page() ==
3279 3349 INFO_NOTEBOOK_LICENSE_PAGE and
3280 3350 not self.showing_empty_details):
3281 3351 self.__show_licenses()
3282 3352
3283 3353 def __check_if_updates_available(self):
3284 3354 try:
3285 3355 self.catalog_loaded = False
3286 3356 self.api_o.refresh()
3287 3357 self.catalog_loaded = True
3288 3358 res = self.__get_inventory_list([], False, False)
3289 3359 for pfmri, state in res:
3290 3360 if state["upgradable"]:
3291 3361 self.pylintstub = pfmri
3292 3362 return True
3293 3363
3294 3364 except api_errors.InventoryException:
3295 3365 gobject.idle_add(self.__set_empty_details_panel)
3296 3366 return False
3297 3367 return False
3298 3368
3299 3369 def __g_enable_disable_update_all(self, update_available):
3300 3370 self.w_updateall_button.set_sensitive(update_available)
3301 3371 self.w_updateall_menuitem.set_sensitive(update_available)
3302 3372 self.__enable_disable_install_remove()
3303 3373
3304 3374 def __enable_disable_deselect(self):
3305 3375 if self.w_application_treeview.get_model():
3306 3376 for row in self.w_application_treeview.get_model():
3307 3377 if row[enumerations.MARK_COLUMN]:
3308 3378 self.w_deselect_menuitem.set_sensitive(True)
3309 3379 return
3310 3380 self.w_deselect_menuitem.set_sensitive(False)
3311 3381 return
3312 3382
3313 3383 def __catalog_refresh(self, reload_gui=True):
3314 3384 """Update image's catalogs."""
3315 3385 try:
3316 3386 # Since the user requested the refresh, perform it
3317 3387 # immediately for all publishers.
3318 3388 self.api_o.refresh(immediate=True)
3319 3389 # Refresh will load the catalogs.
3320 3390 self.catalog_loaded = True
3321 3391 except api_errors.PublisherError:
3322 3392 # In current implementation, this will never happen
3323 3393 # We are not refreshing specific publisher
3324 3394 self.__catalog_refresh_done()
3325 3395 raise
3326 3396 except api_errors.PermissionsException:
3327 3397 #Error will already have been reported in
3328 3398 #Manage Repository dialog
3329 3399 self.__catalog_refresh_done()
3330 3400 return -1
3331 3401 except api_errors.CatalogRefreshException, cre:
3332 3402 total = cre.total
3333 3403 succeeded = cre.succeeded
3334 3404 ermsg = _("Network problem.\n\n")
3335 3405 ermsg += _("Details:\n")
3336 3406 ermsg += "%s/%s" % (succeeded, total)
3337 3407 ermsg += _(" catalogs successfully updated:\n")
3338 3408 for pub, err in cre.failed:
3339 3409 if isinstance(err, HTTPError):
3340 3410 ermsg += " %s: %s - %s\n" % \
3341 3411 (err.filename, err.code, err.msg)
3342 3412 elif isinstance(err, URLError):
3343 3413 if err.args[0][0] == 8:
3344 3414 ermsg += " %s: %s\n" % \
3345 3415 (urlparse.urlsplit(
3346 3416 pub["origin"])[1].split(":")[0],
3347 3417 err.args[0][1])
3348 3418 else:
3349 3419 if isinstance(err.args[0], \
3350 3420 socket.timeout):
3351 3421 ermsg += " %s: %s\n" % \
3352 3422 (pub["origin"], "timeout")
3353 3423 else:
3354 3424 ermsg += " %s: %s\n" % \
3355 3425 (pub["origin"], \
3356 3426 err.args[0][1])
3357 3427 elif "data" in err.__dict__ and err.data:
3358 3428 ermsg += err.data
3359 3429 else:
3360 3430 ermsg += _("Unknown error")
3361 3431 ermsg += "\n"
3362 3432
3363 3433 gobject.idle_add(self.error_occurred, ermsg,
3364 3434 None, gtk.MESSAGE_INFO)
3365 3435 self.__catalog_refresh_done()
3366 3436 return -1
3367 3437 except api_errors.InvalidDepotResponseException, idrex:
3368 3438 err = str(idrex)
3369 3439 gobject.idle_add(self.error_occurred, err,
3370 3440 None, gtk.MESSAGE_INFO)
3371 3441 self.__catalog_refresh_done()
3372 3442 return -1
3373 3443 except api_errors.PublisherError:
3374 3444 self.__catalog_refresh_done()
3375 3445 raise
3376 3446 except Exception:
3377 3447 self.__catalog_refresh_done()
3378 3448 raise
3379 3449 if reload_gui:
3380 3450 self.__catalog_refresh_done()
3381 3451 return 0
3382 3452
3383 3453 def __add_pkgs_to_lists_from_cache(self, publisher, application_list,
3384 3454 category_list, section_list):
3385 3455 if self.cache_o:
3386 3456 self.cache_o.load_application_list(publisher, application_list,
3387 3457 self.selected_pkgs)
3388 3458 self.cache_o.load_category_list(publisher, category_list)
3389 3459 self.cache_o.load_section_list(publisher, section_list)
3390 3460
3391 3461 def __add_pkgs_to_lists_from_api(self, publisher, application_list,
3392 3462 category_list, section_list):
3393 3463 """ This method set up image from the given directory and
3394 3464 returns the image object or None"""
3395 3465 pargs = []
3396 3466 pargs.append("pkg://" + publisher + "/*")
3397 3467 try:
3398 3468 pkgs_known = self.__get_inventory_list(pargs,
3399 3469 True, True)
3400 3470 except api_errors.InventoryException:
3401 3471 # This can happen if the repository does not
3402 3472 # contain any packages
3403 3473 err = _("Selected repository does not contain any packages.")
3404 3474 gobject.idle_add(self.w_progress_dialog.hide)
3405 3475 gobject.idle_add(self.error_occurred, err, None,
3406 3476 gtk.MESSAGE_INFO)
3407 3477 self.unset_busy_cursor()
3408 3478 pkgs_known = []
3409 3479
3410 3480 return self.__add_pkgs_to_lists(pkgs_known, application_list,
3411 3481 category_list, section_list)
3412 3482
3413 3483 def __add_pkgs_to_lists(self, pkgs_known, application_list,
3414 3484 category_list, section_list):
3415 3485 if section_list != None:
3416 3486 self.__init_sections(section_list)
3417 3487 #Only one instance of those icons should be in memory
3418 3488 update_available_icon = gui_misc.get_icon(self.icon_theme,
3419 3489 "status_newupdate")
3420 3490 installed_icon = gui_misc.get_icon(self.icon_theme,
3421 3491 "status_installed")
3422 3492 update_for_category_icon = \
3423 3493 self.get_icon_pixbuf_from_glade_dir("legend_newupdate")
3424 3494 #Imageinfo for categories
3425 3495 imginfo = imageinfo.ImageInfo()
3426 3496 sectioninfo = imageinfo.ImageInfo()
3427 3497 pubs = [p.prefix for p in self.api_o.get_publishers()]
3428 3498 categories = {}
3429 3499 sections = {}
3430 3500 share_path = "/usr/share/package-manager/data/"
3431 3501 for pub in pubs:
3432 3502 category = imginfo.read(self.application_dir +
3433 3503 share_path + pub)
3434 3504 if len(category) == 0:
3435 3505 category = imginfo.read(self.application_dir +
3436 3506 share_path + "opensolaris.org")
3437 3507 categories[pub] = category
3438 3508 section = sectioninfo.read(self.application_dir +
3439 3509 share_path + pub + ".sections")
3440 3510 if len(section) == 0:
3441 3511 section = sectioninfo.read(self.application_dir +
3442 3512 share_path + "opensolaris.org.sections")
3443 3513 sections[pub] = section
3444 3514 pkg_count = 0
3445 3515 pkg_add = 0
3446 3516 progress_percent = INITIAL_PROGRESS_TOTAL_PERCENTAGE
3447 3517 total_pkg_count = len(pkgs_known)
3448 3518 progress_increment = \
3449 3519 total_pkg_count / PACKAGE_PROGRESS_TOTAL_INCREMENTS
3450 3520 self.progress_stop_timer_thread = True
3451 3521 while gtk.events_pending():
3452 3522 gtk.main_iteration(False)
3453 3523 prev_stem = ""
3454 3524 prev_pfmri_str = ""
3455 3525 next_app = None
3456 3526 pkg_name = None
3457 3527 pkg_publisher = None
3458 3528 prev_state = None
3459 3529 category_icon = None
3460 3530 for pkg, state in pkgs_known:
3461 3531 if prev_pfmri_str and \
3462 3532 prev_pfmri_str == pkg.get_short_fmri() and \
3463 3533 prev_state == state:
3464 3534 pkg_count += 1
3465 3535 continue
3466 3536 if prev_stem and \
3467 3537 prev_stem == pkg.get_pkg_stem() and \
3468 3538 prev_state["state"] == "known" and \
3469 3539 state["state"] == "installed":
3470 3540 pass
3471 3541 elif next_app != None:
3472 3542 self.__add_package_to_list(next_app,
3473 3543 application_list,
3474 3544 pkg_add, pkg_name,
3475 3545 category_icon,
3476 3546 categories, category_list, pkg_publisher)
3477 3547 pkg_add += 1
3478 3548 prev_stem = pkg.get_pkg_stem()
3479 3549 prev_pfmri_str = pkg.get_short_fmri()
3480 3550 prev_state = state
3481 3551
3482 3552 if progress_increment > 0 and pkg_count % progress_increment == 0:
3483 3553 progress_percent += PACKAGE_PROGRESS_PERCENT_INCREMENT
3484 3554 if progress_percent <= PACKAGE_PROGRESS_PERCENT_TOTAL:
3485 3555 self.__progressdialog_progress_percent(
3486 3556 progress_percent, pkg_count, total_pkg_count)
3487 3557 while gtk.events_pending():
3488 3558 gtk.main_iteration(False)
3489 3559
3490 3560 status_icon = None
3491 3561 category_icon = None
3492 3562 pkg_name = pkg.get_name()
3493 3563 pkg_name = gui_misc.get_pkg_name(pkg_name)
3494 3564 pkg_stem = pkg.get_pkg_stem()
3495 3565 pkg_publisher = pkg.get_publisher()
3496 3566 pkg_state = enumerations.NOT_INSTALLED
3497 3567 if state["state"] == "installed":
3498 3568 pkg_state = enumerations.INSTALLED
3499 3569 if state["upgradable"] == True:
3500 3570 status_icon = update_available_icon
3501 3571 category_icon = update_for_category_icon
3502 3572 pkg_state = enumerations.UPDATABLE
3503 3573 else:
3504 3574 status_icon = installed_icon
3505 3575 marked = False
3506 3576 if not self.is_search_all:
3507 3577 pkgs = self.selected_pkgs.get(pkg_publisher)
3508 3578 if pkgs != None:
3509 3579 if pkg_stem in pkgs:
3510 3580 marked = True
3511 3581 next_app = \
3512 3582 [
3513 3583 marked, status_icon, pkg_name, '...', pkg_state,
3514 3584 pkg, pkg_stem, None, True, None, pkg_publisher
3515 3585 ]
3516 3586 pkg_count += 1
3517 3587
3518 3588 if next_app:
3519 3589 self.__add_package_to_list(next_app, application_list,
3520 3590 pkg_add, pkg_name, category_icon, categories,
3521 3591 category_list, pkg_publisher)
3522 3592 pkg_add += 1
3523 3593 if category_list != None:
3524 3594 self.__add_categories_to_sections(sections,
3525 3595 category_list, section_list)
3526 3596 self.__progressdialog_progress_percent(PACKAGE_PROGRESS_PERCENT_TOTAL,
3527 3597 total_pkg_count, total_pkg_count)
3528 3598 return
3529 3599
3530 3600 def __add_categories_to_sections(self, sections, category_list, section_list):
3531 3601 for publisher in sections:
3532 3602 for section in sections[publisher]:
3533 3603 for category in sections[publisher][section].split(","):
3534 3604 self.__add_category_to_section(_(category),
3535 3605 _(section), category_list, section_list)
3536 3606
3537 3607 #1915 Sort the Categories into alphabetical order and prepend All Category
3538 3608 if len(category_list) > 0:
3539 3609 rows = [tuple(r) + (i,) for i, r in enumerate(category_list)]
3540 3610 rows.sort(self.__sort)
3541 3611 r = []
3542 3612 category_list.reorder([r[-1] for r in rows])
3543 3613 return
3544 3614
3545 3615 def __add_package_to_list(self, app, application_list, pkg_add,
3546 3616 pkg_name, category_icon, categories, category_list, publisher):
3547 3617 row_iter = application_list.insert(pkg_add, app)
3548 3618 if category_list == None:
3549 3619 return
3550 3620 cat_pub = categories.get(publisher)
3551 3621 if pkg_name in cat_pub:
3552 3622 pkg_categories = cat_pub.get(pkg_name)
3553 3623 for pcat in pkg_categories.split(","):
3554 3624 self.__add_package_to_category(_(pcat), None,
3555 3625 category_icon, row_iter, application_list,
3556 3626 category_list)
3557 3627
3558 3628 @staticmethod
3559 3629 def __add_package_to_category(category_name, category_description,
3560 3630 category_icon, package, application_list, category_list):
3561 3631 if not package or category_name == _('All'):
3562 3632 return
3563 3633 if not category_name:
3564 3634 return
3565 3635 category_id = None
3566 3636 icon_visible = False
3567 3637 if category_icon:
3568 3638 icon_visible = True
3569 3639 for category in category_list:
3570 3640 if category[enumerations.CATEGORY_NAME] == category_name:
3571 3641 category_id = category[enumerations.CATEGORY_ID]
3572 3642 if category_icon:
3573 3643 category[enumerations.CATEGORY_ICON] = \
3574 3644 category_icon
3575 3645 category[enumerations.CATEGORY_ICON_VISIBLE] = \
3576 3646 icon_visible
3577 3647 break
3578 3648 if not category_id: # Category not exists
3579 3649 category_id = len(category_list) + 1
3580 3650 category_list.append([category_id, category_name,
3581 3651 category_description, category_icon, icon_visible,
3582 3652 True, None])
3583 3653 if application_list.get_value(package,
3584 3654 enumerations.CATEGORY_LIST_COLUMN):
3585 3655 a = application_list.get_value(package,
3586 3656 enumerations.CATEGORY_LIST_COLUMN)
3587 3657 a.append(category_id)
3588 3658 else:
3589 3659 category_list = []
3590 3660 category_list.append(category_id)
3591 3661 application_list.set(package,
3592 3662 enumerations.CATEGORY_LIST_COLUMN, category_list)
3593 3663
3594 3664 @staticmethod
3595 3665 def __add_category_to_section(category_name, section_name, category_list,
3596 3666 section_list):
3597 3667 '''Adds the section to section list in category. If there is no such
3598 3668 section, than it is not added. If there was already section than it
3599 3669 is skipped. Sections must be case sensitive'''
3600 3670 if not category_name:
3601 3671 return
3602 3672 for section in section_list:
3603 3673 if section[enumerations.SECTION_NAME] == section_name:
3604 3674 section_id = section[enumerations.SECTION_ID]
3605 3675 for category in category_list:
3606 3676 if category[enumerations.CATEGORY_NAME] == \
3607 3677 category_name:
3608 3678 section_lst = category[ \
3609 3679 enumerations.SECTION_LIST_OBJECT]
3610 3680 section[enumerations.SECTION_ENABLED] = \
3611 3681 True
3612 3682 if not section_lst:
3613 3683 category[ \
3614 3684 enumerations.SECTION_LIST_OBJECT] = \
3615 3685 [section_id, ]
3616 3686 else:
3617 3687 if not section_name in \
3618 3688 section_lst:
3619 3689 section_lst.append(
3620 3690 section_id)
3621 3691
3622 3692 def __progressdialog_progress_pulse(self):
3623 3693 while not self.progress_stop_timer_thread:
3624 3694 gobject.idle_add(self.w_progressbar.pulse)
3625 3695 time.sleep(0.1)
3626 3696 gobject.idle_add(self.w_progress_dialog.hide)
3627 3697 self.progress_stop_timer_thread = False
3628 3698
3629 3699 # For initial setup before loading package entries allow 5% of progress bar
3630 3700 # update it on a time base as we have no other way to judge progress at this point
3631 3701 def __progressdialog_progress_time(self):
3632 3702 while not self.progress_stop_timer_thread and \
3633 3703 self.progress_fraction_time_count <= \
3634 3704 INITIAL_PROGRESS_TOTAL_PERCENTAGE:
3635 3705
3636 3706 gobject.idle_add(self.w_progressbar.set_fraction,
3637 3707 self.progress_fraction_time_count)
3638 3708 self.progress_fraction_time_count += \
3639 3709 INITIAL_PROGRESS_TIME_PERCENTAGE
3640 3710 time.sleep(INITIAL_PROGRESS_TIME_INTERVAL)
3641 3711 self.progress_stop_timer_thread = False
3642 3712 self.progress_fraction_time_count = 0
3643 3713
3644 3714 def __progressdialog_progress_percent(self, fraction, count, total):
3645 3715 gobject.idle_add(self.w_progressinfo_label.set_text, _(
3646 3716 "Processing package entries: %d of %d") % (count, total) )
3647 3717 gobject.idle_add(self.w_progressbar.set_fraction, fraction)
3648 3718
3649 3719 def error_occurred(self, error_msg, msg_title=None, msg_type=gtk.MESSAGE_ERROR):
3650 3720 if msg_title:
3651 3721 title = msg_title
3652 3722 else:
3653 3723 title = _("Package Manager")
3654 3724 gui_misc.error_occurred(self.w_main_window, error_msg,
3655 3725 title, msg_type, use_markup=True)
3656 3726
3657 3727
3658 3728 msgbox = gtk.MessageDialog(parent =
3659 3729 self.w_main_window,
3660 3730 buttons = gtk.BUTTONS_CLOSE,
3661 3731 flags = gtk.DIALOG_MODAL,
3662 3732 type = msg_type,
3663 3733 message_format = None)
3664 3734 msgbox.set_property('text', error_msg)
3665 3735 title = None
3666 3736 if msg_title:
3667 3737 title = msg_title
3668 3738 else:
3669 3739 title = _("Package Manager")
3670 3740 msgbox.set_title(title)
3671 3741 msgbox.run()
3672 3742 msgbox.destroy()
3673 3743
3674 3744 #-----------------------------------------------------------------------------#
3675 3745 # Static Methods
3676 3746 #-----------------------------------------------------------------------------#
3677 3747
3678 3748 #@staticmethod
3679 3749 #def N_(message):
3680 3750 # return message
3681 3751
3682 3752 @staticmethod
3683 3753 def __sort(a, b):
3684 3754 return cmp(a[1], b[1])
3685 3755
3686 3756 @staticmethod
3687 3757 def cell_data_function(column, renderer, model, itr, data):
3688 3758 '''Function which sets the background colour to black if package is
3689 3759 selected'''
3690 3760 if itr:
3691 3761 if model.get_value(itr, enumerations.MARK_COLUMN):
3692 3762 renderer.set_property("cell-background", "#ffe5cc")
3693 3763 renderer.set_property("cell-background-set", True)
3694 3764 else:
3695 3765 renderer.set_property("cell-background-set", False)
3696 3766
3697 3767 @staticmethod
3698 3768 def combobox_separator(model, itr):
3699 3769 return model.get_value(itr, enumerations.FILTER_NAME) == ""
3700 3770
3701 3771 @staticmethod
3702 3772 def combobox_id_separator(model, itr):
3703 3773 return model.get_value(itr, 0) == -1 and \
3704 3774 model.get_value(itr, 1) == ""
3705 3775
3706 3776 @staticmethod
3707 3777 def category_filter(model, itr):
3708 3778 '''This function filters category in the main application view'''
3709 3779 return model.get_value(itr, enumerations.CATEGORY_VISIBLE)
3710 3780
3711 3781 @staticmethod
3712 3782 def get_datetime(version):
3713 3783 dt = None
3714 3784 try:
3715 3785 dt = version.get_datetime()
3716 3786 except AttributeError:
3717 3787 dt = version.get_timestamp()
3718 3788 return dt
3719 3789
3720 3790 @staticmethod
3721 3791 def get_installed_version(api_o, pkg):
3722 3792 info = api_o.info([pkg], False, frozenset(
3723 3793 [api.PackageInfo.STATE, api.PackageInfo.IDENTITY]))
3724 3794 found = info[api.ImageInterface.INFO_FOUND]
3725 3795 try:
3726 3796 version = found[0]
3727 3797 except IndexError:
3728 3798 version = None
3729 3799 return version
3730 3800
3731 3801 #-----------------------------------------------------------------------------#
3732 3802 # Public Methods
3733 3803 #-----------------------------------------------------------------------------#
3734 3804 def setup_progressdialog_show(self):
3735 3805 self.w_progress_dialog.set_title(_("Loading Repository Information"))
3736 3806 self.w_progressinfo_label.set_text(
3737 3807 _( "Fetching package entries ..."))
3738 3808 self.w_progress_cancel.hide()
3739 3809 self.w_progress_dialog.show()
3740 3810 Thread(target = self.__progressdialog_progress_time).start()
3741 3811
3742 3812 def setup_progressdialog_hide(self):
3743 3813 self.progress_stop_timer_thread = True
3744 3814 self.w_progress_dialog.hide()
3745 3815
3746 3816 def init_show_filter(self):
3747 3817 self.__init_show_filter() #Initiates filter
3748 3818
3749 3819 def reload_packages(self):
3750 3820 self.api_o = gui_misc.get_api_object(self.image_directory,
3751 3821 self.pr, self.w_main_window)
3752 3822 self.cache_o = self.__get_cache_obj(self.icon_theme,
3753 3823 self.application_dir, self.api_o)
3754 3824 self.__on_reload(None)
3755 3825
3756 3826 def set_busy_cursor(self):
3757 3827 self.gdk_window.show()
3758 3828
3759 3829 def unset_busy_cursor(self):
3760 3830 self.gdk_window.hide()
3761 3831
3762 3832 def process_package_list_start(self, image_directory):
3763 3833 self.image_directory = image_directory
3764 3834 if not self.api_o:
3765 3835 self.api_o = gui_misc.get_api_object(image_directory,
3766 3836 self.pr, self.w_main_window)
3767 3837 self.cache_o = self.__get_cache_obj(self.icon_theme,
3768 3838 self.application_dir, self.api_o)
3769 3839 self.img_timestamp = self.cache_o.get_index_timestamp()
3770 3840 self.repositories_list = self.__get_new_repositories_liststore()
3771 3841 self.__setup_repositories_combobox(self.api_o, self.repositories_list)
3772 3842
3773 3843 @staticmethod
3774 3844 def __get_cache_obj(icon_theme, application_dir, api_o):
3775 3845 cache_o = cache.CacheListStores(icon_theme, application_dir,
3776 3846 api_o)
3777 3847 return cache_o
3778 3848
3779 3849 def process_package_list_end(self):
3780 3850 self.__set_first_category_text()
3781 3851 self.in_startpage_startup = False
3782 3852 if self.update_all_proceed:
3783 3853 # TODO: Handle situation where only SUNWipkg/SUNWipg-gui have been updated
3784 3854 # in update all: bug 6357
3785 3855 self.__on_update_all(None)
3786 3856 self.update_all_proceed = False
3787 3857 self.setup_progressdialog_hide()
3788 3858 self.__enable_disable_install_remove()
3789 3859 self.update_statusbar()
3790 3860 self.in_setup = False
3791 3861 self.cancelled = False
3792 3862 if self.set_section != 0 or \
3793 3863 self.set_show_filter != enumerations.FILTER_ALL:
3794 3864 self.__application_refilter()
3795 3865 else:
3796 3866 self.unset_busy_cursor()
3797 3867
3798 3868 if self.first_run or self.in_reload:
3799 3869 Thread(target = self.__enable_disable_update_all).start()
3800 3870 self.first_run = False
3801 3871 self.in_reload = False
3802 3872
|
↓ open down ↓ |
1173 lines elided |
↑ open up ↑ |
3803 3873 def get_icon_pixbuf_from_glade_dir(self, icon_name):
3804 3874 return gui_misc.get_pixbuf_from_path(self.application_dir +
3805 3875 "/usr/share/package-manager/", icon_name)
3806 3876
3807 3877 def update_statusbar(self):
3808 3878 '''Function which updates statusbar'''
3809 3879 if self.statusbar_message_id > 0:
3810 3880 self.w_main_statusbar.remove(0, self.statusbar_message_id)
3811 3881 self.statusbar_message_id = 0
3812 3882 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}
3883 +
3884 + if not self.in_search_mode:
3885 + installed = 0
3886 + self.selected = 0
3887 + sel = 0
3888 + if self.application_list == None:
3889 + return
3890 + visible_repository = self.__get_visible_repository_name()
3891 + pkgs = self.selected_pkgs.get(visible_repository)
3892 + if pkgs:
3893 + self.selected = len(pkgs)
3894 + for pkg_row in self.application_list:
3895 + if pkg_row[enumerations.STATUS_COLUMN] == \
3896 + enumerations.INSTALLED \
3897 + or pkg_row[enumerations.STATUS_COLUMN] == \
3898 + enumerations.UPDATABLE:
3899 + installed = installed + 1
3900 + if pkg_row[enumerations.MARK_COLUMN]:
3901 + sel = sel + 1
3902 + listed_str = _('%d listed') % len(self.application_list)
3903 + sel_str = _('%d selected') % sel
3904 + inst_str = _('%d installed') % installed
3905 + status_str = _("%s: %s , %s, %s.") % (visible_repository,
3906 + listed_str, inst_str, sel_str)
3832 3907 self.w_main_statusbar.push(0, status_str)
3833 3908 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)
3909 +
3910 + # In Search Mode
3911 + active = ""
3912 + if self.is_search_all:
3913 + if self.__doing_search():
3914 + if self.current_search_publisher != None:
3915 + active = "(" + self.current_search_publisher + \
3916 + ") "
3917 + opt_str = _('Searching... '
3918 + '%(active)sfor "%(search_text)s"') % \
3919 + {"active": active, "search_text": search_text}
3920 + else:
3921 + opt_str = _('Searched All for "%s"') % (search_text)
3922 + else:
3923 + search_str = _("Searched")
3924 + if self.__doing_search():
3925 + search_str = _("Searching...")
3926 + if self.last_active_publisher != None:
3927 + active = "(" + self.last_active_publisher + ") "
3928 + opt_str = \
3929 + _('%(search)s %(last_active)sfor "%(search_text)s"') \
3930 + % {"search": search_str, "last_active" : active,
3931 + "search_text" : search_text}
3932 + fmt_str = _("%(option_str)s: %(number)d found %(time)s")
3933 + time_str = ""
3934 + if self.search_time_sec > 0:
3935 + time_str = _("in %d seconds") % self.search_time_sec
3936 + status_str = fmt_str % {"option_str" : opt_str, "number" :
3937 + len(self.application_list), "time" : time_str}
3855 3938 self.w_main_statusbar.push(0, status_str)
3856 3939
3857 3940 def update_package_list(self, update_list):
3858 3941 if update_list == None and self.img_timestamp:
3859 3942 return
3860 3943 visible_repository = self.__get_visible_repository_name()
3861 3944 default_publisher = self.default_publisher
3862 3945 self.api_o.refresh()
3863 3946 if not self.img_timestamp:
3864 3947 self.img_timestamp = self.cache_o.get_index_timestamp()
3865 3948 self.__on_reload(None)
3866 3949 return
3867 3950 self.img_timestamp = self.cache_o.get_index_timestamp()
3868 3951 installed_icon = gui_misc.get_icon(self.icon_theme,
3869 3952 "status_installed")
3870 3953 visible_list = update_list.get(visible_repository)
3871 3954 if visible_list:
3872 3955 i = 0
3873 3956 while i < len(visible_list):
3874 3957 visible_list[i] = gui_misc.get_pkg_name(
3875 3958 visible_list[i])
3876 3959 i += 1
3877 3960 for row in self.application_list:
3878 3961 if row[enumerations.NAME_COLUMN] in visible_list:
3879 3962 pkg = row[enumerations.FMRI_COLUMN]
3880 3963 pkg_stem = row[enumerations.STEM_COLUMN]
3881 3964 self.__remove_pkg_stem_from_list(pkg_stem)
3882 3965 if self.info_cache.has_key(pkg_stem):
3883 3966 del self.info_cache[pkg_stem]
3884 3967 package_info = self.get_installed_version(
3885 3968 self.api_o, pkg_stem)
3886 3969 package_installed = (package_info.state
3887 3970 == api.PackageInfo.INSTALLED)
3888 3971 print pkg_stem, package_installed
3889 3972 if package_installed:
3890 3973 row[enumerations.STATUS_COLUMN] = \
3891 3974 enumerations.INSTALLED
3892 3975 row[enumerations.STATUS_ICON_COLUMN] = \
3893 3976 installed_icon
3894 3977 else:
3895 3978 row[enumerations.STATUS_COLUMN] = \
3896 3979 enumerations.NOT_INSTALLED
3897 3980 row[enumerations.STATUS_ICON_COLUMN] = \
3898 3981 None
3899 3982 row[enumerations.MARK_COLUMN] = False
3900 3983 self.__dump_datamodels(visible_repository,
3901 3984 self.application_list, self.category_list,
3902 3985 self.section_list)
3903 3986 for publisher in update_list:
3904 3987 if publisher != visible_repository:
3905 3988 pkg_list = update_list.get(publisher)
3906 3989 for pkg in pkg_list:
3907 3990 pkg_stem = None
3908 3991 if publisher != default_publisher:
3909 3992 pkg_stem = "pkg://%s/%s" % \
3910 3993 (publisher, pkg)
3911 3994 else:
3912 3995 pkg_stem = "pkg:/%s" % pkg
3913 3996 if pkg_stem:
3914 3997 if self.info_cache.has_key(pkg_stem):
3915 3998 del self.info_cache[pkg_stem]
3916 3999 self.__remove_pkg_stem_from_list(pkg_stem)
3917 4000 self.__process_package_selection()
3918 4001 self.__enable_disable_selection_menus()
3919 4002 self.__enable_disable_install_remove()
3920 4003 self.update_statusbar()
3921 4004 Thread(target = self.__enable_disable_update_all).start()
3922 4005
3923 4006 @staticmethod
3924 4007 def __find_root_home_dir():
3925 4008 return_str = '/var/tmp'
3926 4009
3927 4010 try:
3928 4011 lines = pwd.getpwnam('root')
3929 4012 except KeyError:
3930 4013 if debug:
3931 4014 print "Error getting passwd database entry for root"
3932 4015 return return_str
3933 4016 try:
3934 4017 return_str = lines[5]
3935 4018 except IndexError:
3936 4019 if debug:
3937 4020 print "Error getting home directory for root"
3938 4021 return return_str
3939 4022
3940 4023 def restart_after_ips_update(self, be_name):
3941 4024 self.__main_application_quit(be_name)
3942 4025
3943 4026 def shutdown_after_image_update(self):
3944 4027 info_str = _("The Update All action is now complete and "
3945 4028 "Package Manager will close.\n\nReview the posted release notes "
3946 4029 "before rebooting your system:\n\n"
3947 4030 )
3948 4031 self.w_ua_completed_release_label.set_text(info_str.strip('\n'))
3949 4032
3950 4033 info_str = misc.get_release_notes_url()
3951 4034 self.w_ua_completed_linkbutton.set_uri(info_str)
3952 4035 self.w_ua_completed_linkbutton.set_label(info_str)
3953 4036 self.release_notes_url = info_str
3954 4037
3955 4038 self.w_ua_completed_dialog.set_title(_("Update All Complete"))
3956 4039 self.w_ua_completed_dialog.show()
3957 4040
|
↓ open down ↓ |
93 lines elided |
↑ open up ↑ |
3958 4041 ###############################################################################
3959 4042 #-----------------------------------------------------------------------------#
3960 4043 # Main
3961 4044 #-----------------------------------------------------------------------------#
3962 4045
3963 4046 def main():
3964 4047 gtk.main()
3965 4048 return 0
3966 4049
3967 4050 if __name__ == '__main__':
3968 - debug = False
4051 + debug = True
3969 4052 debug_descriptions = False
3970 4053 update_all_proceed = False
3971 4054 ua_be_name = None
3972 4055 app_path = None
3973 4056 image_dir = None
3974 4057 info_install_arg = None
3975 4058 save_selected = _("Save selected...")
3976 4059 save_selected_pkgs = _("Save selected packages...")
3977 4060 reboot_needed = _("The installed package(s) require a reboot before "
3978 4061 "installation can be completed.")
3979 4062
3980 4063 try:
3981 4064 opts, args = getopt.getopt(sys.argv[1:], "hR:U:i:", \
3982 4065 ["help", "image-dir=", "update-all=", "info-install="])
3983 4066 except getopt.error, msg:
3984 4067 print "%s, for help use --help" % msg
3985 4068 sys.exit(2)
3986 4069
3987 4070 if os.path.isabs(sys.argv[0]):
3988 4071 app_path = sys.argv[0]
3989 4072 else:
3990 4073 cmd = os.path.join(os.getcwd(), sys.argv[0])
3991 4074 app_path = os.path.realpath(cmd)
3992 4075
3993 4076 for option, argument in opts:
3994 4077 if option in ("-h", "--help"):
3995 4078 print """\
3996 4079 Use -R (--image-dir) to specify image directory.
3997 4080 Use -U (--update-all) to proceed with Update All"""
3998 4081 sys.exit(0)
3999 4082 if option in ("-R", "--image-dir"):
4000 4083 image_dir = argument
4001 4084 if option in ("-U", "--update-all"):
4002 4085 update_all_proceed = True
4003 4086 ua_be_name = argument
4004 4087 if option in ("-i", "--info-install"):
4005 4088 info_install_arg = argument
4006 4089
4007 4090 if image_dir == None:
4008 4091 try:
4009 4092 image_dir = os.environ["PKG_IMAGE"]
4010 4093 except KeyError:
4011 4094 image_dir = os.getcwd()
4012 4095 try:
4013 4096 gtk.init_check()
4014 4097 except RuntimeError, e:
4015 4098 print _("Unable to initialize gtk")
4016 4099 print str(e)
4017 4100 sys.exit(1)
4018 4101
4019 4102 # Setup webinstall
4020 4103 if info_install_arg or len(sys.argv) == 2:
4021 4104 webinstall = webinstall.Webinstall(image_dir)
4022 4105 if len(sys.argv) == 2:
4023 4106 info_install_arg = sys.argv[1]
4024 4107 webinstall.process_param(info_install_arg)
4025 4108 main()
4026 4109 sys.exit(0)
4027 4110
4028 4111 # Setup packagemanager
4029 4112 packagemanager = PackageManager()
4030 4113 packagemanager.application_path = app_path
4031 4114 packagemanager.image_dir_arg = image_dir
4032 4115 packagemanager.update_all_proceed = update_all_proceed
4033 4116 packagemanager.ua_be_name = ua_be_name
4034 4117
4035 4118 while gtk.events_pending():
4036 4119 gtk.main_iteration(False)
4037 4120
4038 4121 packagemanager.init_show_filter()
4039 4122
4040 4123 packagemanager.process_package_list_start(image_dir)
4041 4124
4042 4125 main()
|
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX