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:
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 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 ↓ |
472 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
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 1017 application_list_filter, application_list_sort):
1019 1018 ##APPLICATION MAIN TREEVIEW
1020 1019 if application_list_filter == None:
1021 1020 application_list_filter = application_list.filter_new()
1022 1021 if application_list_sort == None:
1023 1022 application_list_sort = \
1024 1023 gtk.TreeModelSort(application_list_filter)
1025 1024 application_list_sort.set_sort_column_id(
1026 1025 enumerations.NAME_COLUMN, gtk.SORT_ASCENDING)
1027 1026 application_list_sort.set_sort_func(
1028 1027 enumerations.STATUS_ICON_COLUMN, self.__status_sort_func)
1029 1028 toggle_renderer = gtk.CellRendererToggle()
1030 1029
1031 1030 column = gtk.TreeViewColumn("", toggle_renderer, \
1032 1031 active = enumerations.MARK_COLUMN)
|
↓ open down ↓ |
215 lines elided |
↑ open up ↑ |
1033 1032 column.set_sort_column_id(enumerations.MARK_COLUMN)
1034 1033 column.set_sort_indicator(True)
1035 1034 column.set_cell_data_func(toggle_renderer, self.cell_data_function, None)
1036 1035 column.connect_after('clicked',
1037 1036 self.__application_treeview_column_sorted, None)
1038 1037 self.w_application_treeview.append_column(column)
1039 1038 name_renderer = gtk.CellRendererText()
1040 1039 column = gtk.TreeViewColumn(_("Name"), name_renderer,
1041 1040 text = enumerations.NAME_COLUMN)
1042 1041 column.set_resizable(True)
1042 + column.set_min_width(150)
1043 1043 column.set_sort_column_id(enumerations.NAME_COLUMN)
1044 1044 column.set_sort_indicator(True)
1045 1045 column.set_cell_data_func(name_renderer, self.cell_data_function, None)
1046 1046 column.connect_after('clicked',
1047 1047 self.__application_treeview_column_sorted, None)
1048 1048 self.w_application_treeview.append_column(column)
1049 1049 column = self.__create_icon_column(_("Status"), True,
1050 1050 enumerations.STATUS_ICON_COLUMN, True)
1051 1051 column.set_sort_column_id(enumerations.STATUS_ICON_COLUMN)
1052 1052 column.set_sort_indicator(True)
1053 1053 column.connect_after('clicked',
1054 1054 self.__application_treeview_column_sorted, None)
1055 1055 self.w_application_treeview.append_column(column)
1056 1056 if self.is_search_all:
1057 1057 repository_renderer = gtk.CellRendererText()
1058 1058 column = gtk.TreeViewColumn(_('Repository'),
1059 1059 repository_renderer,
1060 1060 text = enumerations.AUTHORITY_COLUMN)
1061 1061 column.set_sort_column_id(enumerations.AUTHORITY_COLUMN)
1062 1062 column.set_resizable(True)
1063 1063 column.set_sort_indicator(True)
1064 1064 column.set_cell_data_func(repository_renderer,
1065 1065 self.cell_data_function, None)
1066 1066 column.connect_after('clicked',
1067 1067 self.__application_treeview_column_sorted, None)
1068 1068 self.w_application_treeview.append_column(column)
1069 1069 description_renderer = gtk.CellRendererText()
1070 1070 column = gtk.TreeViewColumn(_('Description'),
1071 1071 description_renderer,
1072 1072 text = enumerations.DESCRIPTION_COLUMN)
1073 1073 column.set_sort_column_id(enumerations.DESCRIPTION_COLUMN)
1074 1074 column.set_resizable(True)
1075 1075 column.set_sort_indicator(True)
1076 1076 column.set_cell_data_func(description_renderer,
1077 1077 self.cell_data_function, None)
1078 1078 column.connect_after('clicked',
1079 1079 self.__application_treeview_column_sorted, None)
1080 1080 self.w_application_treeview.append_column(column)
1081 1081 #Added selection listener
1082 1082 self.package_selection = self.w_application_treeview.get_selection()
1083 1083 self.application_list = application_list
1084 1084 self.application_list_filter = application_list_filter
1085 1085 self.application_list_sort = application_list_sort
1086 1086 toggle_renderer.connect('toggled', self.__active_pane_toggle,
1087 1087 application_list_sort)
1088 1088
1089 1089 def __init_tree_views(self, application_list, category_list,
1090 1090 section_list, application_list_filter = None,
1091 1091 application_list_sort = None):
1092 1092 '''This function connects treeviews with their models and also applies
1093 1093 filters'''
1094 1094 if category_list == None:
1095 1095 self.w_application_treeview.set_model(None)
1096 1096 self.__remove_treeview_columns(self.w_application_treeview)
1097 1097 elif application_list == None:
1098 1098 self.w_categories_treeview.set_model(None)
1099 1099 self.__remove_treeview_columns(self.w_categories_treeview)
1100 1100 else:
1101 1101 self.__disconnect_models()
1102 1102 self.__remove_treeview_columns(self.w_application_treeview)
1103 1103 self.__remove_treeview_columns(self.w_categories_treeview)
1104 1104 # The logic for set section needs to be here as some sections
1105 1105 # might be not enabled. In such situation we are setting the set
1106 1106 # section to "All Categories" one.
1107 1107 if section_list != None:
1108 1108 row = section_list[self.set_section]
1109 1109 if row[enumerations.SECTION_ENABLED] and \
1110 1110 self.set_section >= 0 and \
1111 1111 self.set_section < len(section_list):
1112 1112 if row[enumerations.SECTION_ID] != self.set_section:
1113 1113 self.set_section = 0
1114 1114 else:
1115 1115 self.set_section = 0
1116 1116
1117 1117 if application_list != None:
1118 1118 self.__init_application_tree_view(application_list,
1119 1119 application_list_filter, application_list_sort)
1120 1120
1121 1121 if self.first_run:
1122 1122 # When vadj changes we need to set image descriptions
1123 1123 # on visible status icons. This catches moving the scroll bars
1124 1124 # and scrolling up and down using keyboard.
1125 1125 vadj = self.w_application_treeview.get_vadjustment()
1126 1126 vadj.connect('value-changed',
1127 1127 self.__application_treeview_vadjustment_changed, None)
1128 1128 vadj = self.w_categories_treeview.get_vadjustment()
1129 1129 vadj.connect('value-changed',
1130 1130 self.__categories_treeview_vadjustment_changed, None)
1131 1131
1132 1132 # When the size of the application_treeview changes
1133 1133 # we need to set image descriptions on visible status icons.
1134 1134 self.w_application_treeview.connect('size-allocate',
1135 1135 self.__application_treeview_size_allocate, None)
1136 1136 self.w_categories_treeview.connect('size-allocate',
1137 1137 self.__categories_treeview_size_allocate, None)
1138 1138
1139 1139 if category_list != None:
1140 1140 ##CATEGORIES TREEVIEW
1141 1141 #enumerations.CATEGORY_NAME
1142 1142 category_list_filter = category_list.filter_new()
1143 1143 column = self.__create_icon_column("", False,
1144 1144 enumerations.CATEGORY_ICON, False)
1145 1145 self.w_categories_treeview.append_column(column)
1146 1146 enumerations.CATEGORY_NAME_renderer = gtk.CellRendererText()
1147 1147 column = gtk.TreeViewColumn(_('Name'),
1148 1148 enumerations.CATEGORY_NAME_renderer,
1149 1149 text = enumerations.CATEGORY_NAME)
1150 1150 self.w_categories_treeview.append_column(column)
1151 1151 #Added selection listener
1152 1152 category_selection = self.w_categories_treeview.get_selection()
1153 1153 category_selection.set_mode(gtk.SELECTION_SINGLE)
1154 1154
1155 1155 if self.first_run:
1156 1156 ##SECTION COMBOBOX
1157 1157 #enumerations.SECTION_NAME
1158 1158 cell = gtk.CellRendererText()
1159 1159 self.w_sections_combobox.pack_start(cell, True)
1160 1160 self.w_sections_combobox.add_attribute(cell, 'text',
1161 1161 enumerations.SECTION_NAME)
1162 1162 self.w_sections_combobox.set_row_separator_func(
1163 1163 self.combobox_id_separator)
1164 1164 self.w_sections_combobox.add_attribute( cell,
1165 1165 'sensitive', enumerations.SECTION_ENABLED )
1166 1166 ##FILTER COMBOBOX
1167 1167 #enumerations.FILTER_NAME
1168 1168 cell = gtk.CellRendererText()
1169 1169 self.w_filter_combobox.pack_start(cell, True)
1170 1170 self.w_filter_combobox.add_attribute(cell, 'text',
1171 1171 enumerations.FILTER_NAME)
1172 1172 self.w_filter_combobox.set_row_separator_func(
1173 1173 self.combobox_id_separator)
1174 1174
1175 1175 if section_list != None:
1176 1176 self.section_list = section_list
1177 1177 if category_list != None:
1178 1178 self.category_list = category_list
1179 1179 self.category_list_filter = category_list_filter
1180 1180 self.w_categories_treeview.set_model(category_list_filter)
1181 1181 if not self.is_search_all:
1182 1182 category_list_filter.set_visible_func(
1183 1183 self.category_filter)
1184 1184 self.__set_categories_visibility(self.set_section)
1185 1185 self.a11y_categories_treeview = \
1186 1186 self.w_categories_treeview.get_accessible()
1187 1187 if application_list != None:
1188 1188 if category_list != None:
1189 1189 self.w_sections_combobox.set_model(section_list)
1190 1190 self.w_sections_combobox.set_active(self.set_section)
1191 1191 self.w_filter_combobox.set_model(self.filter_list)
1192 1192 self.w_filter_combobox.set_active(self.set_show_filter)
1193 1193 self.w_application_treeview.set_model(
1194 1194 self.application_list_sort)
1195 1195 if not self.in_search_mode:
1196 1196 if application_list_filter == None:
1197 1197 self.application_list_filter.set_visible_func(
1198 1198 self.__application_filter)
1199 1199
1200 1200 category_selection = self.w_categories_treeview.get_selection()
1201 1201 category_model, category_iter = category_selection.get_selected()
1202 1202 self.pylintstub = category_model
1203 1203 if not category_iter and not self.in_search_mode:
1204 1204 #no category was selected, so select "All"
1205 1205 category_selection.select_path(0)
1206 1206 category_model, category_iter = category_selection.get_selected()
1207 1207 if self.first_run:
1208 1208 category_selection.connect("changed",
1209 1209 self.__on_category_selection_changed, None)
1210 1210 self.w_categories_treeview.connect("row-activated",
1211 1211 self.__on_category_row_activated, None)
1212 1212 self.w_categories_treeview.connect("focus-in-event",
1213 1213 self.__on_category_focus_in, None)
1214 1214 self.package_selection.set_mode(gtk.SELECTION_SINGLE)
1215 1215 self.package_selection.connect("changed",
1216 1216 self.__on_package_selection_changed, None)
1217 1217
1218 1218 self.a11y_application_treeview = \
1219 1219 self.w_application_treeview.get_accessible()
1220 1220 self.process_package_list_end()
1221 1221
1222 1222 def __categories_treeview_size_allocate(self, widget, allocation, user_data):
1223 1223 # We ignore any changes in the size during initialization.
1224 1224 if self.categories_treeview_initialized:
1225 1225 if self.categories_status_id == 0:
1226 1226 self.categories_status_id = gobject.idle_add(
1227 1227 self.__set_accessible_categories_visible_status)
1228 1228
1229 1229 def __categories_treeview_vadjustment_changed(self, widget, user_data):
1230 1230 self.__set_accessible_categories_visible_status()
1231 1231
1232 1232 def __set_accessible_categories_status(self, model, itr):
1233 1233 status = model.get_value(itr, enumerations.CATEGORY_ICON)
1234 1234 if status != None:
1235 1235 desc = _("Updates Available")
1236 1236 else:
1237 1237 desc = None
1238 1238 if desc != None:
1239 1239 obj = self.a11y_categories_treeview.ref_at(
1240 1240 int(model.get_string_from_iter(itr)),
1241 1241 CATEGORIES_STATUS_COLUMN_INDEX)
1242 1242 obj.set_image_description(desc)
1243 1243
1244 1244 def __set_accessible_categories_visible_status(self):
1245 1245 self.categories_status_id = 0
1246 1246 if self.a11y_categories_treeview.get_n_accessible_children() == 0:
1247 1247 # accessibility is not enabled
1248 1248 return
1249 1249
1250 1250 visible_range = self.w_categories_treeview.get_visible_range()
1251 1251 if visible_range == None:
1252 1252 return
1253 1253 start = visible_range[0][0]
1254 1254 end = visible_range[1][0]
1255 1255 # We try to minimize the range of accessible objects
1256 1256 # on which we set image descriptions
1257 1257 if self.categories_treeview_range != None:
1258 1258 old_start = self.categories_treeview_range[0][0]
1259 1259 old_end = self.categories_treeview_range[1][0]
1260 1260 # Old range is the same or smaller than new range
1261 1261 # so do nothing
1262 1262 if start >= old_start and end <= old_end:
1263 1263 return
1264 1264 if start < old_end:
1265 1265 if end < old_end:
1266 1266 if end >= old_start:
1267 1267 end = old_start
1268 1268 else:
1269 1269 start = old_end
1270 1270 self.categories_treeview_range = visible_range
1271 1271 model = self.category_list_filter
1272 1272 itr = model.get_iter_from_string(str(start))
1273 1273 while start <= end:
1274 1274 start += 1
1275 1275 self.__set_accessible_categories_status(model, itr)
1276 1276 itr = model.iter_next(itr)
1277 1277
1278 1278 def __application_treeview_column_sorted(self, widget, user_data):
1279 1279 self.__set_visible_status(False)
1280 1280
1281 1281 def __init_repository_tree_view(self):
1282 1282 cell = gtk.CellRendererText()
1283 1283 self.w_repository_combobox.pack_start(cell, True)
1284 1284 self.w_repository_combobox.add_attribute(cell, 'text',
1285 1285 enumerations.REPOSITORY_NAME)
1286 1286 self.w_repository_combobox.set_row_separator_func(
1287 1287 self.combobox_id_separator)
1288 1288
1289 1289 def __application_treeview_size_allocate(self, widget, allocation, user_data):
1290 1290 # We ignore any changes in the size during initialization.
1291 1291 if self.visible_status_id == 0:
1292 1292 self.visible_status_id = gobject.idle_add(
1293 1293 self.__set_visible_status)
1294 1294
1295 1295 def __application_treeview_vadjustment_changed(self, widget, user_data):
1296 1296 self.__set_visible_status()
1297 1297
1298 1298 def __set_accessible_status(self, model, itr):
1299 1299 status = model.get_value(itr, enumerations.STATUS_COLUMN)
1300 1300 if status == enumerations.INSTALLED:
1301 1301 desc = _("Installed")
1302 1302 elif status == enumerations.NOT_INSTALLED:
1303 1303 desc = _("Not Installed")
1304 1304 elif status == enumerations.UPDATABLE:
1305 1305 desc = _("Updates Available")
1306 1306 else:
1307 1307 desc = None
1308 1308 if desc != None:
|
↓ open down ↓ |
256 lines elided |
↑ open up ↑ |
1309 1309 obj = self.a11y_application_treeview.ref_at(
1310 1310 int(model.get_string_from_iter(itr)),
1311 1311 STATUS_COLUMN_INDEX)
1312 1312 obj.set_image_description(desc)
1313 1313
1314 1314 def __set_visible_status(self, check_range = True):
1315 1315 self.visible_status_id = 0
1316 1316 if self.w_main_view_notebook.get_current_page() != \
1317 1317 NOTEBOOK_PACKAGE_LIST_PAGE:
1318 1318 return
1319 + if self.__doing_search():
1320 + return
1321 +
1319 1322 a11y_enabled = False
1320 1323 if self.a11y_application_treeview.get_n_accessible_children() != 0:
1321 1324 a11y_enabled = True
1322 1325
1323 1326 visible_range = self.w_application_treeview.get_visible_range()
1324 1327 if visible_range == None:
1325 1328 return
1326 1329 start = visible_range[0][0]
1327 1330 end = visible_range[1][0]
1328 1331 if debug_descriptions:
1329 1332 print "Range Start: %d End: %d" % (start, end)
1330 1333
1331 1334 # Switching Publishers need to use default range
1332 1335 active_pub = self.__get_active_publisher()
1333 1336 if self.last_active_publisher != active_pub:
1334 1337 check_range = False
1335 1338 self.last_active_publisher = active_pub
1336 1339 if self.in_search_mode:
1337 1340 check_range = False
1338 1341
1339 1342 if self.application_treeview_range != None:
1340 1343 if check_range:
1341 1344 old_start = self.application_treeview_range[0][0]
1342 1345 old_end = self.application_treeview_range[1][0]
1343 1346 # Old range is the same or smaller than new range
1344 1347 # so do nothing
1345 1348 if start >= old_start and end <= old_end:
1346 1349 return
1347 1350 if start < old_end:
1348 1351 if end < old_end:
1349 1352 if end >= old_start:
1350 1353 end = old_start
1351 1354 else:
1352 1355 start = old_end
1353 1356 if debug_descriptions:
1354 1357 print "Adjusted Range Start: %d End: %d" % (start, end)
1355 1358 self.application_treeview_range = visible_range
1356 1359
1357 1360 sort_filt_model = \
1358 1361 self.w_application_treeview.get_model() #gtk.TreeModelSort
1359 1362 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1360 1363 model = filt_model.get_model() #gtk.ListStore
1361 1364 sf_itr = sort_filt_model.get_iter_from_string(str(start))
1362 1365 pkg_stems_and_itr_to_fetch = {}
1363 1366 while start <= end:
1364 1367 filtered_itr = sort_filt_model.convert_iter_to_child_iter(None,
|
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
1365 1368 sf_itr)
1366 1369 app_itr = filt_model.convert_iter_to_child_iter(filtered_itr)
1367 1370
1368 1371 desc = sort_filt_model.get_value(sf_itr,
1369 1372 enumerations.DESCRIPTION_COLUMN)
1370 1373 # Only Fetch description for packages without a
1371 1374 # description
1372 1375 if desc == '...':
1373 1376 fmri = sort_filt_model.get_value(sf_itr,
1374 1377 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)
1378 + if fmri != None:
1379 + pkg_stem = fmri.get_pkg_stem(
1380 + include_scheme = True)
1381 + pkg_stems_and_itr_to_fetch[pkg_stem] = \
1382 + model.get_string_from_iter(app_itr)
1379 1383 if a11y_enabled:
1380 1384 self.__set_accessible_status(sort_filt_model, sf_itr)
1381 1385 start += 1
1382 1386 sf_itr = sort_filt_model.iter_next(sf_itr)
1383 1387
1384 1388 if debug_descriptions:
1385 1389 print "PKGS to FETCH: \n%s" % pkg_stems_and_itr_to_fetch
1386 1390 if len(pkg_stems_and_itr_to_fetch) > 0:
1387 1391 Thread(target = self.__get_pkg_descriptions,
1388 1392 args = [pkg_stems_and_itr_to_fetch, model]).start()
1389 1393
1390 1394 def __doing_search(self):
1391 1395 return self.search_start > 0
1392 1396
1393 1397 def __get_pkg_descriptions(self, pkg_stems_and_itr_to_fetch, orig_model):
1394 1398 # Note: no need to aquire lock even though this can be called from
1395 1399 # multiple threads, it is just creating an update job and dispatching it
1396 1400 # to the idle handler, not modifying any global state
1397 1401 info = None
1398 1402 if not self.__doing_search():
1399 1403 gobject.idle_add(self.__update_statusbar_message,
1400 1404 _("Fetching descriptions..."))
1401 1405 try:
1402 1406 info = self.api_o.info(pkg_stems_and_itr_to_fetch.keys(), False,
1403 1407 frozenset([api.PackageInfo.IDENTITY,
1404 1408 api.PackageInfo.SUMMARY]))
1405 1409 except api_errors.TransportError:
1406 1410 self.update_statusbar()
1407 1411 return
1408 1412 if info and len(info.get(0)) == 0:
1409 1413 self.update_statusbar()
1410 1414 return
1411 1415 pkg_infos = info.get(0)
1412 1416 pkg_descriptions_for_update = []
1413 1417 for pkg_info in pkg_infos:
1414 1418 short_fmri = fmri.PkgFmri(pkg_info.fmri).get_pkg_stem(
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
1415 1419 include_scheme = True)
1416 1420 pkg_descriptions_for_update.append((short_fmri,
1417 1421 pkg_stems_and_itr_to_fetch[short_fmri],
1418 1422 pkg_info.summary))
1419 1423 if debug_descriptions:
1420 1424 print "FETCHED PKGS: \n%s" % pkg_descriptions_for_update
1421 1425 gobject.idle_add(self.__update_description_from_iter,
1422 1426 pkg_descriptions_for_update, orig_model)
1423 1427
1424 1428 def __update_description_from_iter(self, pkg_descriptions_for_update, orig_model):
1429 + #If doing a search abandon description updates
1430 + if self.__doing_search():
1431 + return
1432 +
1425 1433 sort_filt_model = \
1426 1434 self.w_application_treeview.get_model() #gtk.TreeModelSort
1427 1435 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1428 1436 model = filt_model.get_model() #gtk.ListStore
1429 1437
1430 - #If model has changed abandon description updates
1438 + #If model has changed
1431 1439 if orig_model != model:
1432 1440 return
1433 1441
1434 1442 if debug_descriptions:
1435 1443 print "UPDATE DESCRIPTIONS: \n%s" % pkg_descriptions_for_update
1436 1444 for pkg_stem, path, summary in pkg_descriptions_for_update:
1437 1445 itr = model.get_iter_from_string(path)
1438 1446 stored_pkg_fmri = model.get_value(itr, enumerations.FMRI_COLUMN)
1439 1447 stored_pkg_stem = stored_pkg_fmri.get_pkg_stem(
1440 1448 include_scheme = True)
1441 1449
1442 1450 if pkg_stem != stored_pkg_stem:
1443 1451 if debug:
1444 1452 print ("__update_description_from_iter(): "
1445 1453 "model not consistent so abandoning "
1446 1454 "these description updates.")
1447 1455 self.update_statusbar()
1448 1456 return
1449 1457 model.set_value(itr, enumerations.DESCRIPTION_COLUMN, summary)
1450 1458 if not self.__doing_search():
1451 1459 self.update_statusbar()
1452 1460
1453 1461 def __create_icon_column(self, name, expand_pixbuf, enum_value, set_data_func):
1454 1462 column = gtk.TreeViewColumn()
1455 1463 column.set_title(name)
1456 1464 #Commented, since there was funny jumping of the icons
1457 1465 #column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
1458 1466 render_pixbuf = gtk.CellRendererPixbuf()
1459 1467 column.pack_start(render_pixbuf, expand = expand_pixbuf)
1460 1468 column.add_attribute(render_pixbuf, "pixbuf", enum_value)
1461 1469 column.set_fixed_width(32)
1462 1470 if set_data_func:
1463 1471 column.set_cell_data_func(render_pixbuf,
1464 1472 self.cell_data_function, None)
1465 1473 return column
1466 1474
1467 1475 def __disconnect_models(self):
1468 1476 self.w_application_treeview.set_model(None)
1469 1477 self.w_categories_treeview.set_model(None)
1470 1478 self.w_sections_combobox.set_model(None)
1471 1479 self.w_filter_combobox.set_model(None)
1472 1480
1473 1481 def __disconnect_repository_model(self):
1474 1482 self.w_repository_combobox.set_model(None)
1475 1483
1476 1484 @staticmethod
1477 1485 def __status_sort_func(treemodel, iter1, iter2, user_data=None):
1478 1486 get_val = treemodel.get_value
1479 1487 status1 = get_val(iter1, enumerations.STATUS_COLUMN)
1480 1488 status2 = get_val(iter2, enumerations.STATUS_COLUMN)
1481 1489 return cmp(status1, status2)
1482 1490
1483 1491 @staticmethod
1484 1492 def __remove_treeview_columns(treeview):
1485 1493 columns = treeview.get_columns()
1486 1494 if columns:
1487 1495 for column in columns:
1488 1496 treeview.remove_column(column)
1489 1497
1490 1498 @staticmethod
1491 1499 def __init_sections(section_list):
1492 1500 '''This function is for initializing sections combo box, also adds "All"
1493 1501 Category. It sets active section combobox entry "All"'''
1494 1502 cat_path = None
1495 1503 enabled = True
1496 1504 # We enable only first section and later we might enable the rest,
1497 1505 # depending if there are some packages connected with them
1498 1506 section_list.append([0, _('All Categories'), cat_path, enabled ])
1499 1507 section_list.append([-1, "", cat_path, enabled ])
1500 1508 enabled = False
1501 1509 section_list.append([2, _('Meta Packages'), cat_path, enabled ])
1502 1510 section_list.append([3, _('Applications'), cat_path, enabled ])
1503 1511 section_list.append([4, _('Desktop (GNOME)'), cat_path, enabled ])
1504 1512 section_list.append([5, _('Development'), cat_path, enabled ])
1505 1513 section_list.append([6, _('Distributions'), cat_path, enabled ])
1506 1514 section_list.append([7, _('Drivers'), cat_path, enabled ])
1507 1515 section_list.append([8, _('System'), cat_path, enabled ])
1508 1516 section_list.append([9, _('Web Services'), cat_path, enabled ])
1509 1517
1510 1518 def __init_show_filter(self):
1511 1519 self.filter_list.append([enumerations.FILTER_ALL, _('All Packages'), ])
1512 1520 self.filter_list.append([enumerations.FILTER_INSTALLED,
1513 1521 _('Installed Packages'), ])
1514 1522 self.filter_list.append([enumerations.FILTER_UPDATES,
1515 1523 _('Updates'), ])
1516 1524 self.filter_list.append([enumerations.FILTER_NOT_INSTALLED,
1517 1525 _('Non-installed Packages'), ])
1518 1526 self.filter_list.append([-1, "", ])
1519 1527 self.filter_list.append([enumerations.FILTER_SELECTED,
1520 1528 _('Selected Packages'), ])
1521 1529 if self.initial_show_filter >= enumerations.FILTER_ALL and \
1522 1530 self.initial_show_filter < len(self.filter_list):
1523 1531 row = self.filter_list[self.initial_show_filter]
1524 1532 if row[enumerations.SECTION_ID] != self.initial_show_filter:
1525 1533 self.initial_show_filter = enumerations.FILTER_ALL
1526 1534 else:
1527 1535 self.initial_show_filter = enumerations.FILTER_ALL
1528 1536
1529 1537
1530 1538 def __on_cancel_progressdialog_clicked(self, widget):
1531 1539 self.progress_canceled = True
1532 1540 self.progress_stop_timer_thread = True
1533 1541
1534 1542 def __on_mainwindow_delete_event(self, widget, event):
1535 1543 ''' handler for delete event of the main window '''
1536 1544 if self.__check_if_something_was_changed() == True:
1537 1545 # XXX Change this to not quit and show dialog
1538 1546 # XXX if some changes were applied:
1539 1547 self.__main_application_quit()
1540 1548 return True
1541 1549 else:
1542 1550 self.__main_application_quit()
1543 1551
1544 1552 def __on_api_search_error_delete_event(self, widget, event):
1545 1553 self.__on_api_search_button_clicked(None)
1546 1554
1547 1555 def __on_api_search_button_clicked(self, widget):
1548 1556 self.api_search_error_dialog.hide()
1549 1557
1550 1558 def __on_file_quit_activate(self, widget):
1551 1559 ''' handler for quit menu event '''
1552 1560 self.__on_mainwindow_delete_event(None, None)
1553 1561
1554 1562 def __on_ua_completed_close(self, widget):
1555 1563 self.w_ua_completed_dialog.hide()
1556 1564 self.__on_mainwindow_delete_event(None, None)
1557 1565
1558 1566 def __on_edit_repositories_activate(self, widget):
1559 1567 ''' handler for repository menu event '''
1560 1568 repository.Repository(self)
1561 1569
1562 1570 def __on_file_be_activate(self, widget):
1563 1571 ''' handler for be menu event '''
1564 1572 beadm.Beadmin(self)
1565 1573
1566 1574 def __on_searchentry_changed(self, widget):
1567 1575 if widget.get_text_length() > 0:
1568 1576 self.w_clear_search_button.set_sensitive(True)
1569 1577 else:
1570 1578 self.w_clear_search_button.set_sensitive(False)
1571 1579 self.__enable_disable_entry_selection(widget)
1572 1580 if self.is_search_all and not self.changing_search_option:
1573 1581 if self.w_searchentry.get_text() == "":
1574 1582 self.w_infosearch_frame.hide()
1575 1583 self.__link_load_blank()
1576 1584 self.w_main_view_notebook.set_current_page(
1577 1585 NOTEBOOK_START_PAGE)
1578 1586 self.__update_statusbar_for_search()
1579 1587 self.w_searchentry.grab_focus()
1580 1588
1581 1589 def __update_statusbar_for_search(self):
1582 1590 self.__update_statusbar_message(
1583 1591 self.search_options[self.current_search_option][3])
1584 1592
1585 1593 def __update_statusbar_message(self, message):
1586 1594 if self.statusbar_message_id > 0:
1587 1595 self.w_main_statusbar.remove(0, self.statusbar_message_id)
1588 1596 self.statusbar_message_id = 0
1589 1597 self.statusbar_message_id = self.w_main_statusbar.push(0, message)
1590 1598
1591 1599 def __setup_before_search_all_mode(self):
1592 1600 self.is_search_all = True
1593 1601 self.w_infosearch_frame.hide()
1594 1602
1595 1603 self.__save_setup_before_search()
1596 1604 self.w_repository_combobox.set_active(0)
1597 1605 self.__link_load_blank()
1598 1606 self.w_main_view_notebook.set_current_page(
1599 1607 NOTEBOOK_START_PAGE)
1600 1608 self.__update_statusbar_for_search()
1601 1609 self.w_searchentry.grab_focus()
1602 1610 if len(self.w_searchentry.get_text()) > 0:
1603 1611 start, end = self.w_searchentry.get_selection_bounds()
1604 1612 self.w_searchentry.select_region(end, end)
1605 1613 self.__unselect_category()
1606 1614
1607 1615 def __clear_before_search(self):
1608 1616 self.in_setup = True
1609 1617 application_list = self.__get_new_application_liststore()
1610 1618 self.__set_empty_details_panel()
1611 1619 self.__set_main_view_package_list()
1612 1620 self.__init_tree_views(application_list, None, None)
1613 1621 self.__unselect_category()
1614 1622
1615 1623 def __restore_setup_for_browse(self):
1616 1624 self.in_search_mode = False
1617 1625 self.is_search_all = False
1618 1626 self.w_infosearch_frame.hide()
1619 1627
1620 1628 self.set_busy_cursor()
1621 1629 self.w_repository_combobox.set_active(
1622 1630 self.saved_repository_combobox_active)
1623 1631 self.set_section = self.saved_sections_combobox_active
1624 1632 self.set_show_filter = self.saved_filter_combobox_active
1625 1633 if self.saved_category_list == self.category_list:
1626 1634 self.__init_tree_views(self.saved_application_list,
1627 1635 None, None,
1628 1636 self.saved_application_list_filter,
1629 1637 self.saved_application_list_sort)
1630 1638 else:
1631 1639 self.__init_tree_views(self.saved_application_list,
1632 1640 self.saved_category_list, self.saved_section_list,
1633 1641 self.saved_application_list_filter,
1634 1642 self.saved_application_list_sort)
1635 1643
1636 1644 self.__set_main_view_package_list()
1637 1645
1638 1646 def __save_setup_before_search(self, single_search=False):
1639 1647 #Do not save search data models
1640 1648 if self.in_search_mode:
1641 1649 return
1642 1650 self.saved_sections_combobox_active = \
1643 1651 self.w_sections_combobox.get_active()
1644 1652 self.saved_filter_combobox_active = \
1645 1653 self.w_filter_combobox.get_active()
1646 1654 self.saved_application_list = self.application_list
1647 1655 self.saved_application_list_sort = \
1648 1656 self.application_list_sort
1649 1657 self.saved_application_list_filter = \
1650 1658 self.application_list_filter
1651 1659 self.saved_category_list = self.category_list
1652 1660 self.saved_section_list = self.section_list
1653 1661 if single_search:
1654 1662 self.saved_repository_combobox_active = \
1655 1663 self.w_repository_combobox.get_active()
1656 1664 self.w_filter_combobox.set_active(0)
1657 1665
1658 1666 def __do_search(self):
1659 1667 self.search_start = 0
1660 1668 if self.changing_search_option:
1661 1669 return
1662 1670 active = self.w_filter_combobox.get_active()
1663 1671 if active != enumerations.FILTER_SELECTED:
1664 1672 self.saved_filter_combobox_active = active
1665 1673 if len(self.w_searchentry.get_text()) == 0:
1666 1674 return
1667 1675 if not self.is_search_all:
1668 1676 self.__save_setup_before_search(single_search=True)
1669 1677 self.__clear_before_search()
1670 1678 self.set_busy_cursor()
1671 1679 self.in_search_mode = True
1672 1680
1673 1681 self.w_infosearch_frame.hide()
1674 1682 self.__update_statusbar_message(_("Searching..."))
1675 1683 if not self.is_search_all:
1676 1684 Thread(target = self.__do_api_search,
1677 1685 args = (self.is_search_all, )).start()
1678 1686 else:
1679 1687 Thread(target = self.__do_api_search,
1680 1688 args = ()).start()
1681 1689
1682 1690 def __unselect_category(self):
1683 1691 selection = self.w_categories_treeview.get_selection()
1684 1692 model, itr = selection.get_selected()
1685 1693 if itr:
1686 1694 cat_path = model.get_string_from_iter(itr)
1687 1695 selected_section = self.w_sections_combobox.get_active()
1688 1696 section_row = self.section_list[selected_section]
1689 1697 section_row[enumerations.SECTION_SUBCATEGORY] = cat_path
1690 1698 selection.unselect_all()
1691 1699
1692 1700 def __process_after_search_failure(self):
1693 1701 self.search_start = 0
1694 1702 self.search_time_sec = 0
1695 1703 self.application_list = []
1696 1704 self.update_statusbar()
1697 1705 self.unset_busy_cursor()
1698 1706 self.in_setup = False
1699 1707
1700 1708 def __get_origin_uri(self, repo):
1701 1709 if repo == None:
1702 1710 return None
1703 1711 origin_uri = repo.origins[0]
1704 1712 ret_uri = None
1705 1713 if isinstance(origin_uri, str):
1706 1714 if len(origin_uri) > 0:
1707 1715 ret_uri = origin_uri.strip("/")
1708 1716 elif isinstance(origin_uri, publisher.RepositoryURI):
1709 1717 uri = origin_uri.uri
1710 1718 if uri != None and len(uri) > 0:
1711 1719 ret_uri = uri.strip("/")
1712 1720 return ret_uri
1713 1721
1714 1722
1715 1723 def __do_api_search(self, search_all = True):
1716 1724 self.search_start = time.time()
1717 1725 self.search_time_sec = 0
1718 1726 text = self.w_searchentry.get_text()
1719 1727 # Here we call the search API to get the results
1720 1728 searches = []
1721 1729 servers = []
1722 1730 result = []
1723 1731 pargs = []
1724 1732 search_str = SEARCH_STR_FORMAT % text
1725 1733 pargs.append(search_str)
1726 1734 if search_all:
|
↓ open down ↓ |
286 lines elided |
↑ open up ↑ |
1727 1735 servers = None
1728 1736 else:
1729 1737 pub_prefix = self.__get_active_publisher()
1730 1738 if pub_prefix != None:
1731 1739 pub = self.api_o.get_publisher(prefix=pub_prefix)
1732 1740 else:
1733 1741 pub = self.api_o.get_preferred_publisher()
1734 1742 origin_uri = self.__get_origin_uri(pub.selected_repository)
1735 1743 servers.append({"origin": origin_uri})
1736 1744 if debug:
1737 - print "pargs:", pargs
1738 - print "servers:", servers
1739 -
1745 + print "Search: pargs %s servers: %s" % (pargs, servers)
1746 +
1747 + #TBD If we ever search just Installed pkgs should allow for a local search
1740 1748 case_sensitive = False
1749 + return_actions = True
1741 1750 searches.append(self.api_o.remote_search(
1742 - [api.Query(" ".join(pargs), case_sensitive, True, None, None)],
1751 + [api.Query(" ".join(pargs), case_sensitive, return_actions)],
1743 1752 servers=servers))
1744 - result_tuple = {}
1753 + if debug:
1754 + print "Search Args: %s : cs: %s : retact: %s" % \
1755 + ("".join(pargs), case_sensitive, return_actions)
1756 +
1757 + last_name = ""
1758 + self.current_search_publisher = None
1745 1759 try:
1746 1760 for query_num, publisher, (v, return_type, tmp) in \
1747 1761 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
1762 + if v < 1 or return_type != api.Query.RETURN_PACKAGES:
1760 1763 gobject.idle_add(self.w_progress_dialog.hide)
1761 1764 self.__process_after_search_failure()
1762 1765 return
1766 +
1767 + pub = None
1768 + if publisher is not None \
1769 + and "prefix" in publisher:
1770 + pub = publisher["prefix"]
1771 + name = fmri.PkgFmri(str(tmp)).get_name()
1772 + if last_name != name:
1773 + if debug:
1774 + print "Result Name: %s (%s)" % (name, pub)
1775 + a_res = name, pub
1776 + result.append(a_res)
1777 + #Ignore Status when fetching
1778 + application_list = \
1779 + self.__get_min_list_from_search(result)
1780 + self.current_search_publisher = pub
1781 + self.in_setup = True
1782 + gobject.idle_add(self.__init_tree_views,
1783 + application_list, None, None)
1784 + last_name = name
1763 1785 self.pylintstub = query_num
1764 1786 except api_errors.ProblematicSearchServers, ex:
1765 - self.__parse_api_search_error(ex)
1787 + self.__process_api_search_error(ex)
1766 1788 gobject.idle_add(self.w_progress_dialog.hide)
1767 1789 gobject.idle_add(self.__handle_api_search_error)
1768 - if len(result_tuple) == 0:
1790 + if len(result) == 0:
1769 1791 self.__process_after_search_with_zero_results()
1770 1792 return
1771 1793 except Exception, ex:
1772 1794 # We are not interested in this error
1773 1795 gobject.idle_add(self.w_progress_dialog.hide)
1774 1796 self.__process_after_search_failure()
1775 1797 return
1776 1798 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)
1799 + print "Number of search results:", len(result)
1781 1800 if len(result) == 0:
1782 1801 if debug:
1783 1802 print "No search results"
1784 1803 self.__process_after_search_with_zero_results()
1785 1804 return
1786 1805 # We cannot get status of the packages if catalogs have not
1787 1806 # been loaded so we pause for up to 5 seconds here to
1788 1807 # allow catalogs to be loaded
1789 1808 times = 5
1790 1809 while self.catalog_loaded == False:
1791 1810 if times == 0:
1792 1811 break
1793 1812 time.sleep(1)
1794 1813 times -= 1
1814 +
1815 + #Now fetch full result set with Status
1795 1816 self.in_setup = True
1796 - application_list = self.__get_list_from_search(result)
1817 + application_list = self.__get_full_list_from_search(result)
1818 + gobject.idle_add(self.__init_tree_views, application_list, None, None)
1819 +
1797 1820 if self.search_start > 0:
1798 1821 self.search_time_sec = int(time.time() - self.search_start)
1822 + if debug:
1823 + print "Search time: %d (sec)" % self.search_time_sec
1799 1824 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 1825
1805 1826 def __process_after_search_with_zero_results(self):
1806 1827 if self.search_start > 0:
1807 1828 self.search_time_sec = int(time.time() - self.search_start)
1808 1829 self.search_start = 0
1809 1830 self.in_setup = True
1810 1831 application_list = self.__get_new_application_liststore()
1811 1832 gobject.idle_add(self.__set_empty_details_panel)
1812 1833 gobject.idle_add(self.__set_main_view_package_list)
1813 1834 gobject.idle_add(self.__init_tree_views, application_list, None, None)
1814 1835
1815 - def __get_list_from_search(self, search_result):
1836 + def __get_min_list_from_search(self, search_result):
1816 1837 application_list = self.__get_new_application_liststore()
1838 + for name, publisher in search_result:
1839 + application_list.append(
1840 + [False, None, name, '...', enumerations.NOT_INSTALLED, None,
1841 + "pkg://" + publisher + "/" + name, None, True, None,
1842 + publisher])
1843 + return application_list
1844 +
1845 + def __get_full_list_from_search(self, search_result):
1846 + application_list = self.__get_new_application_liststore()
1817 1847 self.__add_pkgs_to_list_from_search(search_result,
1818 1848 application_list)
1819 1849 return application_list
1820 1850
1821 1851 def __add_pkgs_to_list_from_search(self, search_result,
1822 1852 application_list):
1823 1853 pargs = []
1824 1854 default_pub = self.api_o.get_preferred_publisher().prefix
1825 1855 for name, publisher in search_result:
1826 1856 pargs.append("pkg://" + publisher + "/" + name)
1827 1857 # We now need to get the status for each package
1828 1858 if debug_descriptions:
1829 1859 print "pargs:", pargs
1830 1860 try:
1831 1861 pkgs_known = self.__get_inventory_list(pargs,
1832 1862 True, True)
1833 1863 except api_errors.InventoryException:
1834 1864 # This can happen if load_catalogs has not been run
1835 1865 err = _("Unable to get status for search results.\n"
1836 1866 "The catalogs have not been loaded.\n"
1837 1867 "Please try after few seconds.\n")
1838 1868 gobject.idle_add(self.w_progress_dialog.hide)
1839 1869 gobject.idle_add(self.error_occurred, err)
1840 1870 return
1841 1871 return self.__add_pkgs_to_lists(pkgs_known, application_list,
1842 1872 None, None)
1843 1873
1844 1874 def __application_refilter(self):
1845 1875 ''' Disconnecting the model from the treeview improves
1846 1876 performance when assistive technologies are enabled'''
1847 1877 if self.in_setup:
1848 1878 return
1849 1879 self.application_refilter_id = 0
1850 1880 self.application_refilter_idle_id = 0
1851 1881 if not self.in_search_mode:
1852 1882 model = self.w_application_treeview.get_model()
1853 1883 self.w_application_treeview.set_model(None)
1854 1884 self.application_list_filter.refilter()
1855 1885 self.w_application_treeview.set_model(model)
1856 1886 gobject.idle_add(self.__set_empty_details_panel)
1857 1887 gobject.idle_add(self.__enable_disable_selection_menus)
1858 1888 gobject.idle_add(self.__enable_disable_install_remove)
1859 1889 self.application_treeview_initialized = True
1860 1890 self.application_treeview_range = None
1861 1891 if self.visible_status_id == 0:
1862 1892 self.visible_status_id = gobject.idle_add(
1863 1893 self.__set_visible_status)
1864 1894 self.categories_treeview_initialized = True
1865 1895 self.categories_treeview_range = None
1866 1896 if self.categories_status_id == 0:
1867 1897 self.categories_status_id = gobject.idle_add(
1868 1898 self.__set_accessible_categories_visible_status)
1869 1899 return False
1870 1900
1871 1901 def __on_edit_paste(self, widget):
1872 1902 self.w_searchentry.paste_clipboard()
1873 1903
1874 1904 def __on_clear_paste(self, widget):
1875 1905 bounds = self.w_searchentry.get_selection_bounds()
1876 1906 self.w_searchentry.delete_text(bounds[0], bounds[1])
1877 1907 return
1878 1908
1879 1909 def __on_copy(self, widget):
1880 1910 focus_widget = self.w_main_window.get_focus()
1881 1911 if focus_widget == self.w_searchentry:
1882 1912 self.w_searchentry.copy_clipboard()
1883 1913 self.w_paste_menuitem.set_sensitive(True)
1884 1914 elif self.__is_a_textview(focus_widget):
1885 1915 focus_widget.get_buffer().copy_clipboard(
1886 1916 self.w_main_clipboard)
1887 1917
1888 1918 def __on_cut(self, widget):
1889 1919 self.w_searchentry.cut_clipboard()
1890 1920 self.w_paste_menuitem.set_sensitive(True)
1891 1921
1892 1922 def __popup_position_func(self, menu):
1893 1923 ''' Position popup menu immediately below search button'''
1894 1924 root = self.w_main_window.window.get_origin()
1895 1925 alloc = self.search_button.get_allocation()
1896 1926 return (root[0] + alloc.x, root[1] + alloc.y + alloc.height, False)
1897 1927
1898 1928 def __on_set_search(self, widget, event):
1899 1929 if event.type == gtk.gdk.BUTTON_PRESS:
1900 1930 self.searchmenu.popup(None, None, self.__popup_position_func,
1901 1931 event.button, event.time)
1902 1932 return True
1903 1933 return False
1904 1934
1905 1935 def __on_set_search_clicked(self, widget):
1906 1936 self.searchmenu.popup(None, None, self.__popup_position_func,
1907 1937 0, 0)
1908 1938 return True
1909 1939
1910 1940 def __on_edit_search_clicked(self, widget):
1911 1941 self.w_searchentry.grab_focus()
1912 1942
1913 1943 def __on_clear_search(self, widget):
1914 1944 self.w_searchentry.delete_text(0, -1)
1915 1945 self.__do_search()
1916 1946 return
1917 1947
1918 1948 def __on_startpage(self, widget):
1919 1949 self.__load_startpage()
1920 1950 self.w_main_view_notebook.set_current_page(NOTEBOOK_START_PAGE)
1921 1951
1922 1952 def __on_notebook_change(self, widget, event, pagenum):
1923 1953 if (pagenum == INFO_NOTEBOOK_LICENSE_PAGE and
1924 1954 not self.showing_empty_details):
1925 1955 licbuffer = self.w_license_textview.get_buffer()
1926 1956 leg_txt = _("Fetching legal information...")
1927 1957 licbuffer.set_text(leg_txt)
1928 1958 if self.show_licenses_id != 0:
1929 1959 gobject.source_remove(self.show_licenses_id)
1930 1960 self.show_licenses_id = 0
1931 1961 self.last_show_licenses_id = self.show_licenses_id = \
1932 1962 gobject.timeout_add(SHOW_LICENSE_DELAY,
1933 1963 self.__show_licenses)
1934 1964
1935 1965 def __is_a_textview(self, widget):
1936 1966 if (widget == self.w_generalinfo_textview or
1937 1967 widget == self.w_installedfiles_textview or
1938 1968 widget == self.w_dependencies_textview or
1939 1969 widget == self.w_license_textview):
1940 1970 return True
1941 1971 else:
1942 1972 return False
1943 1973
1944 1974
1945 1975 def __on_select_all(self, widget):
1946 1976 focus_widget = self.w_main_window.get_focus()
1947 1977 if self.__is_a_textview(focus_widget):
1948 1978 focus_widget.emit('select-all', True)
1949 1979 self.w_selectall_menuitem.set_sensitive(False)
1950 1980 self.w_deselect_menuitem.set_sensitive(True)
1951 1981 return
1952 1982 elif focus_widget == self.w_searchentry:
1953 1983 focus_widget.select_region(0, -1)
1954 1984 self.w_selectall_menuitem.set_sensitive(False)
1955 1985 self.w_deselect_menuitem.set_sensitive(True)
1956 1986 return
1957 1987
1958 1988 sort_filt_model = \
1959 1989 self.w_application_treeview.get_model() #gtk.TreeModelSort
1960 1990 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1961 1991 model = filt_model.get_model() #gtk.ListStore
1962 1992 iter_next = sort_filt_model.get_iter_first()
1963 1993 list_of_paths = []
1964 1994 while iter_next != None:
1965 1995 sorted_path = sort_filt_model.get_path(iter_next)
1966 1996 filtered_path = \
1967 1997 sort_filt_model.convert_path_to_child_path(sorted_path)
1968 1998 path = filt_model.convert_path_to_child_path(filtered_path)
1969 1999 list_of_paths.append(path)
1970 2000 iter_next = sort_filt_model.iter_next(iter_next)
1971 2001 for path in list_of_paths:
1972 2002 itr = model.get_iter(path)
1973 2003 already_marked = model.get_value(itr, enumerations.MARK_COLUMN)
1974 2004 if not already_marked:
1975 2005 model.set_value(itr, enumerations.MARK_COLUMN, True)
1976 2006 pkg_stem = model.get_value(itr,
1977 2007 enumerations.STEM_COLUMN)
1978 2008 pkg_status = model.get_value(itr,
1979 2009 enumerations.STATUS_COLUMN)
1980 2010 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
1981 2011 self.w_selectall_menuitem.set_sensitive(False)
1982 2012 self.w_deselect_menuitem.set_sensitive(True)
1983 2013 self.__enable_disable_selection_menus()
1984 2014 self.update_statusbar()
1985 2015 self.__enable_disable_install_remove()
1986 2016
1987 2017 def __on_select_updates(self, widget):
1988 2018 sort_filt_model = \
1989 2019 self.w_application_treeview.get_model() #gtk.TreeModelSort
1990 2020 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1991 2021 model = filt_model.get_model() #gtk.ListStore
1992 2022 iter_next = sort_filt_model.get_iter_first()
1993 2023 list_of_paths = []
1994 2024 while iter_next != None:
1995 2025 sorted_path = sort_filt_model.get_path(iter_next)
1996 2026 filtered_iter = sort_filt_model.convert_iter_to_child_iter(None, \
1997 2027 iter_next)
1998 2028 app_iter = filt_model.convert_iter_to_child_iter(filtered_iter)
1999 2029
2000 2030 filtered_path = \
2001 2031 sort_filt_model.convert_path_to_child_path(sorted_path)
2002 2032 path = filt_model.convert_path_to_child_path(filtered_path)
2003 2033 if model.get_value(app_iter, \
2004 2034 enumerations.STATUS_COLUMN) == enumerations.UPDATABLE:
2005 2035 list_of_paths.append(path)
2006 2036 iter_next = sort_filt_model.iter_next(iter_next)
2007 2037 for path in list_of_paths:
2008 2038 itr = model.get_iter(path)
2009 2039 model.set_value(itr, enumerations.MARK_COLUMN, True)
2010 2040 pkg_stem = model.get_value(itr, enumerations.STEM_COLUMN)
2011 2041 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
2012 2042 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
2013 2043 self.__enable_disable_selection_menus()
2014 2044 self.update_statusbar()
2015 2045 self.__enable_disable_install_remove()
2016 2046
2017 2047 def __on_deselect(self, widget):
2018 2048 focus_widget = self.w_main_window.get_focus()
2019 2049 if self.__is_a_textview(focus_widget):
2020 2050 focus_widget.emit('select-all', False)
2021 2051 self.w_deselect_menuitem.set_sensitive(False)
2022 2052 self.w_selectall_menuitem.set_sensitive(True)
2023 2053 return
2024 2054 elif focus_widget == self.w_searchentry:
2025 2055 focus_widget.select_region(0, 0)
2026 2056 self.w_deselect_menuitem.set_sensitive(False)
2027 2057 self.w_selectall_menuitem.set_sensitive(True)
2028 2058 return
2029 2059
2030 2060 sort_filt_model = \
2031 2061 self.w_application_treeview.get_model() #gtk.TreeModelSort
2032 2062 filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
2033 2063 model = filt_model.get_model() #gtk.ListStore
2034 2064 iter_next = sort_filt_model.get_iter_first()
2035 2065 list_of_paths = []
2036 2066 while iter_next != None:
2037 2067 sorted_path = sort_filt_model.get_path(iter_next)
2038 2068 filtered_iter = sort_filt_model.convert_iter_to_child_iter(None, \
2039 2069 iter_next)
2040 2070 app_iter = filt_model.convert_iter_to_child_iter(filtered_iter)
2041 2071 filtered_path = \
2042 2072 sort_filt_model.convert_path_to_child_path(sorted_path)
2043 2073 path = filt_model.convert_path_to_child_path(filtered_path)
2044 2074 if model.get_value(app_iter, enumerations.MARK_COLUMN):
2045 2075 list_of_paths.append(path)
2046 2076 iter_next = sort_filt_model.iter_next(iter_next)
2047 2077 for path in list_of_paths:
2048 2078 itr = model.get_iter(path)
2049 2079 already_deselected = not model.get_value(itr,
2050 2080 enumerations.MARK_COLUMN)
2051 2081 if not already_deselected:
2052 2082 model.set_value(itr, enumerations.MARK_COLUMN, False)
2053 2083 self.__remove_pkg_stem_from_list(model.get_value(itr,
2054 2084 enumerations.STEM_COLUMN))
2055 2085 self.w_selectall_menuitem.set_sensitive(True)
2056 2086 self.w_deselect_menuitem.set_sensitive(False)
2057 2087 self.__enable_disable_selection_menus()
2058 2088 self.update_statusbar()
2059 2089 self.__enable_disable_install_remove()
2060 2090
2061 2091 def __on_preferences(self, widget):
2062 2092 self.w_startpage_checkbutton.set_active(self.show_startpage)
2063 2093 self.w_preferencesdialog.show()
2064 2094
2065 2095 def __on_preferencesclose_clicked(self, widget):
2066 2096 self.w_preferencesdialog.hide()
2067 2097
2068 2098 def __on_preferenceshelp_clicked(self, widget):
2069 2099 gui_misc.display_help(self.application_dir, "pm_win")
2070 2100
2071 2101 def __on_startpage_checkbutton_toggled(self, widget):
2072 2102 self.show_startpage = self.w_startpage_checkbutton.get_active()
|
↓ open down ↓ |
246 lines elided |
↑ open up ↑ |
2073 2103 try:
2074 2104 self.client.set_bool(SHOW_STARTPAGE_PREFERENCES,
2075 2105 self.show_startpage)
2076 2106 except GError:
2077 2107 pass
2078 2108
2079 2109 def __on_api_search_checkbox_toggled(self, widget):
2080 2110 active = self.api_search_checkbox.get_active()
2081 2111 if len(self.current_repos_with_search_errors) > 0:
2082 2112 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 + ","
2113 + for pub, err_type, err_str in \
2114 + self.current_repos_with_search_errors:
2115 + if pub not in self.gconf_not_show_repos:
2116 + self.gconf_not_show_repos += pub + ","
2086 2117 else:
2087 - for url in self.current_repos_with_search_errors:
2118 + for pub, err_type, err_str in \
2119 + self.current_repos_with_search_errors:
2088 2120 self.gconf_not_show_repos = \
2089 2121 self.gconf_not_show_repos.replace(
2090 - url + ",", "")
2122 + pub + ",", "")
2091 2123 try:
2092 2124 self.client.set_string(API_SEARCH_ERROR_PREFERENCES,
2093 2125 self.gconf_not_show_repos)
2094 2126 except GError:
2095 2127 pass
2096 2128
2097 2129 def __on_searchentry_focus_in(self, widget, event):
2098 2130 if self.w_main_clipboard.wait_is_text_available():
2099 2131 self.w_paste_menuitem.set_sensitive(True)
2100 2132 char_count = widget.get_text_length()
2101 2133 if char_count > 0:
2102 2134 self.w_selectall_menuitem.set_sensitive(True)
2103 2135 else:
2104 2136 self.w_selectall_menuitem.set_sensitive(False)
2105 2137 bounds = widget.get_selection_bounds()
2106 2138 if bounds:
2107 2139 offset1 = bounds[0]
2108 2140 offset2 = bounds[1]
2109 2141 if abs(offset2 - offset1) == char_count:
2110 2142 self.w_selectall_menuitem.set_sensitive(False)
2111 2143 self.w_deselect_menuitem.set_sensitive(True)
2112 2144 self.w_copy_menuitem.set_sensitive(True)
2113 2145 else:
2114 2146 self.w_deselect_menuitem.set_sensitive(False)
2115 2147
2116 2148 def __on_searchentry_focus_out(self, widget, event):
2117 2149 self.w_paste_menuitem.set_sensitive(False)
2118 2150 self.__enable_disable_select_all()
2119 2151 self.__enable_disable_deselect()
2120 2152 self.w_cut_menuitem.set_sensitive(False)
2121 2153 self.w_copy_menuitem.set_sensitive(False)
2122 2154 self.w_clear_menuitem.set_sensitive(False)
2123 2155 return False
2124 2156
2125 2157 def __on_searchentry_activate(self, widget):
2126 2158 self.__do_search()
2127 2159
2128 2160 def __on_searchentry_selection(self, widget, pspec):
2129 2161 self.__enable_disable_entry_selection(widget)
2130 2162
2131 2163 def __enable_disable_entry_selection(self, widget):
2132 2164 char_count = widget.get_text_length()
2133 2165 bounds = widget.get_selection_bounds()
2134 2166 if bounds:
2135 2167 #enable selection functions
2136 2168 self.w_cut_menuitem.set_sensitive(True)
2137 2169 self.w_copy_menuitem.set_sensitive(True)
2138 2170 self.w_clear_menuitem.set_sensitive(True)
2139 2171 if char_count == abs(bounds[1] - bounds[0]):
2140 2172 self.w_selectall_menuitem.set_sensitive(False)
2141 2173 else:
2142 2174 self.w_selectall_menuitem.set_sensitive(True)
2143 2175 self.w_deselect_menuitem.set_sensitive(True)
2144 2176 else:
2145 2177 self.w_cut_menuitem.set_sensitive(False)
2146 2178 self.w_copy_menuitem.set_sensitive(False)
2147 2179 self.w_clear_menuitem.set_sensitive(False)
2148 2180 self.w_deselect_menuitem.set_sensitive(False)
2149 2181 if char_count == 0:
2150 2182 self.w_selectall_menuitem.set_sensitive(False)
2151 2183 else:
2152 2184 self.w_selectall_menuitem.set_sensitive(True)
2153 2185
2154 2186 def __refilter_on_idle(self):
2155 2187 if self.application_refilter_id != 0:
2156 2188 gobject.source_remove(self.application_refilter_id)
2157 2189 self.application_refilter_id = 0
2158 2190 if self.application_refilter_idle_id == 0:
2159 2191 self.application_refilter_idle_id = gobject.idle_add(
2160 2192 self.__application_refilter)
2161 2193
2162 2194 def __on_category_focus_in(self, widget, event, user):
2163 2195 self.__on_category_row_activated(None, None, None, user)
2164 2196
2165 2197 def __on_category_row_activated(self, view, path, col, user):
2166 2198 '''This function is for handling category double click activations'''
2167 2199 if self.w_filter_combobox.get_model():
2168 2200 self.w_filter_combobox.set_active(self.saved_filter_combobox_active)
2169 2201 self.w_searchentry.delete_text(0, -1)
2170 2202 if self.in_search_mode or self.is_search_all:
2171 2203 self.__unset_search(True)
2172 2204 if self.selected == 0:
2173 2205 gobject.idle_add(self.__enable_disable_install_remove)
2174 2206 return
2175 2207 self.__set_main_view_package_list()
2176 2208 self.set_busy_cursor()
2177 2209 self.__refilter_on_idle()
2178 2210 if self.selected == 0:
2179 2211 gobject.idle_add(self.__enable_disable_install_remove)
2180 2212
2181 2213 def __set_main_view_package_list(self):
2182 2214 # Only switch from Start Page View to List view if we are not in startup
2183 2215 if not self.in_startpage_startup:
2184 2216 self.w_main_view_notebook.set_current_page(
2185 2217 NOTEBOOK_PACKAGE_LIST_PAGE)
2186 2218
2187 2219 def __on_category_selection_changed(self, selection, widget):
2188 2220 '''This function is for handling category selection changes'''
2189 2221 if self.in_setup or self.changing_search_option:
2190 2222 return
2191 2223 model, itr = selection.get_selected()
2192 2224 if itr:
2193 2225 cat_path = model.get_string_from_iter(itr)
2194 2226 if self.is_search_all:
2195 2227 selected_section = self.set_section
2196 2228 else:
2197 2229 selected_section = self.w_sections_combobox.get_active()
2198 2230 section_row = self.section_list[selected_section]
2199 2231 section_row[enumerations.SECTION_SUBCATEGORY] = cat_path
2200 2232
2201 2233 if self.in_search_mode or self.is_search_all:
2202 2234 return
2203 2235
2204 2236 if self.saved_filter_combobox_active != None:
2205 2237 self.w_filter_combobox.set_active(self.saved_filter_combobox_active)
2206 2238 self.__set_main_view_package_list()
2207 2239
2208 2240 self.set_busy_cursor()
2209 2241 self.__refilter_on_idle()
2210 2242 if self.selected == 0:
2211 2243 gobject.idle_add(self.__enable_disable_install_remove)
2212 2244
2213 2245 def __process_package_selection(self):
2214 2246 model, itr = self.package_selection.get_selected()
2215 2247 if self.show_info_id != 0:
2216 2248 gobject.source_remove(self.show_info_id)
2217 2249 self.show_info_id = 0
2218 2250 if itr:
2219 2251 self.__enable_disable_install_remove()
2220 2252 self.selected_pkgstem = \
2221 2253 model.get_value(itr, enumerations.STEM_COLUMN)
2222 2254 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
2223 2255 gobject.idle_add(self.__show_fetching_package_info, pkg)
2224 2256 self.showing_empty_details = False
2225 2257 self.last_show_info_id = self.show_info_id = \
2226 2258 gobject.timeout_add(SHOW_INFO_DELAY,
2227 2259 self.__show_info, model, model.get_path(itr))
2228 2260 if (self.w_info_notebook.get_current_page() ==
2229 2261 INFO_NOTEBOOK_LICENSE_PAGE):
2230 2262 self.__on_notebook_change(None, None,
2231 2263 INFO_NOTEBOOK_LICENSE_PAGE)
2232 2264 else:
2233 2265 self.selected_model = None
2234 2266 self.selected_path = None
2235 2267 self.selected_pkgstem = None
2236 2268
2237 2269 def __on_package_selection_changed(self, selection, widget):
2238 2270 '''This function is for handling package selection changes'''
2239 2271 if self.in_setup:
2240 2272 return
2241 2273 self.__process_package_selection()
2242 2274
2243 2275 def __on_filtercombobox_changed(self, widget):
2244 2276 '''On filter combobox changed'''
2245 2277 if self.in_setup or self.changing_search_option:
2246 2278 return
2247 2279 active = self.w_filter_combobox.get_active()
2248 2280 if active != enumerations.FILTER_SELECTED:
2249 2281 self.saved_filter_combobox_active = active
2250 2282 self.__set_main_view_package_list()
2251 2283 if self.in_search_mode or self.is_search_all:
2252 2284 self.set_busy_cursor()
2253 2285 self.saved_filter_combobox_active = \
2254 2286 self.w_filter_combobox.get_active()
2255 2287 self.__unset_search(True)
2256 2288 return
2257 2289 self.set_busy_cursor()
2258 2290 self.__refilter_on_idle()
2259 2291 if self.selected == 0:
2260 2292 gobject.idle_add(self.__enable_disable_install_remove)
2261 2293
2262 2294 def __set_categories_visibility(self, selected_section):
2263 2295 self.category_list[0][enumerations.CATEGORY_ICON] = None
2264 2296 if selected_section == 0:
2265 2297 for category in self.category_list:
2266 2298 category[enumerations.CATEGORY_VISIBLE] = True
2267 2299 else:
2268 2300 for category in self.category_list:
2269 2301 if category[enumerations.CATEGORY_ID] == 0:
2270 2302 category[enumerations.CATEGORY_VISIBLE] = True
2271 2303 else:
2272 2304 category_list = \
2273 2305 category[enumerations.SECTION_LIST_OBJECT]
2274 2306 if not category_list:
2275 2307 category[enumerations.CATEGORY_VISIBLE] \
2276 2308 = False
2277 2309 else:
2278 2310 for section in category_list:
2279 2311 if section == selected_section:
2280 2312 category[enumerations. \
2281 2313 CATEGORY_VISIBLE] = \
2282 2314 True
2283 2315 else:
2284 2316 category[enumerations. \
2285 2317 CATEGORY_VISIBLE] = \
2286 2318 False
2287 2319
2288 2320 # Set category icon for All if a visible category has it
2289 2321 for category in self.category_list:
2290 2322 if category[enumerations.CATEGORY_ICON] != None:
2291 2323 self.category_list[0][enumerations.CATEGORY_ICON] = \
2292 2324 category[enumerations.CATEGORY_ICON]
2293 2325 break
2294 2326
2295 2327 section_row = self.section_list[selected_section]
2296 2328 cat_path = section_row[enumerations.SECTION_SUBCATEGORY]
2297 2329 if cat_path != None:
2298 2330 itr = self.category_list_filter.get_iter_from_string(cat_path)
2299 2331 path = self.category_list_filter.get_path(itr)
2300 2332 self.w_categories_treeview.set_cursor(path,
2301 2333 None, start_editing=False)
2302 2334
2303 2335 def __on_sectionscombobox_changed(self, widget):
2304 2336 '''On section combobox changed'''
2305 2337 if self.in_setup:
2306 2338 return
2307 2339 if self.changing_search_option:
2308 2340 return
2309 2341 self.__set_main_view_package_list()
2310 2342 self.set_busy_cursor()
2311 2343 self.__set_first_category_text()
2312 2344 self.__set_categories_visibility(widget.get_active())
2313 2345 self.category_list_filter.refilter()
2314 2346 if self.in_search_mode or self.is_search_all:
2315 2347 self.saved_sections_combobox_active = \
2316 2348 self.w_sections_combobox.get_active()
2317 2349 self.__unset_search(True)
2318 2350 return
2319 2351 self.__refilter_on_idle()
2320 2352 if self.selected == 0:
2321 2353 gobject.idle_add(self.__enable_disable_install_remove)
2322 2354
2323 2355 def __set_first_category_text(self):
2324 2356 active_section = self.w_sections_combobox.get_active()
2325 2357 all_cat_text = _("All")
2326 2358 if active_section != 0:
2327 2359 all_cat_text += " " + self.section_list[active_section][1]
2328 2360 category_model = self.w_categories_treeview.get_model()
2329 2361 if category_model:
2330 2362 list_store = category_model.get_model()
2331 2363 list_store[0][1] = all_cat_text
2332 2364
2333 2365 def __unset_search(self, same_repo):
2334 2366 self.w_infosearch_frame.hide()
2335 2367 self.changing_search_option = True
2336 2368 self.current_search_option = 0
2337 2369 visible_repository = self.__get_visible_repository_name()
2338 2370 if visible_repository in self.selected_pkgs:
2339 2371 self.selected_pkgs.pop(visible_repository)
2340 2372 if visible_repository in self.to_install_update:
2341 2373 self.to_install_update.pop(visible_repository)
2342 2374 if visible_repository in self.to_remove:
2343 2375 self.to_remove.pop(visible_repository)
2344 2376 self.__update_tooltips()
2345 2377 if self.is_search_all:
2346 2378 self.__update_repository_combobox_for_search(False)
2347 2379 pixbuf = self.search_options[0][1]
2348 2380 self.search_image.set_from_pixbuf(pixbuf)
2349 2381 self.in_search_mode = False
2350 2382 self.is_search_all = False
2351 2383 if same_repo:
2352 2384 self.__restore_setup_for_browse()
2353 2385 self.changing_search_option = False
2354 2386
2355 2387 def __on_repositorycombobox_changed(self, widget):
2356 2388 '''On repository combobox changed'''
2357 2389 if self.changing_search_option:
2358 2390 return
2359 2391 self.changing_search_option = True
2360 2392 active_publisher = self.__get_active_publisher()
2361 2393 if self.is_search_all:
2362 2394 same_repo = False
2363 2395 active = self.w_repository_combobox.get_active() - 1
2364 2396 if active == -1:
2365 2397 # We get here is we choose "Add ..." when
2366 2398 # doing api search
2367 2399 self.changing_search_option = False
2368 2400 return
2369 2401 if not active_publisher == _("Add..."):
2370 2402 if self.saved_repository_combobox_active == active:
2371 2403 same_repo = True
2372 2404 self.__unset_search(same_repo)
2373 2405 self.w_repository_combobox.set_active(active)
2374 2406
2375 2407 if same_repo:
2376 2408 self.changing_search_option = False
2377 2409 return
2378 2410 active_publisher = self.__get_active_publisher()
2379 2411 self.changing_search_option = False
2380 2412 if self.visible_repository == active_publisher:
2381 2413 # If we are coming back to the same repository, we do
2382 2414 # not want to setup publishers. This is the case when
2383 2415 # we are calling Add... then we are firing the event for
2384 2416 # Add... case and immediately coming back to the
2385 2417 # previously selected repository.
2386 2418 return
2387 2419 # Checking for Add... is fine enough, as the repository
2388 2420 # name cannot contain "..." in the name.
2389 2421 if active_publisher == _("Add..."):
2390 2422 index = -1
2391 2423 if self.is_search_all:
2392 2424 index = 0
2393 2425 else:
2394 2426 model = self.w_repository_combobox.get_model()
2395 2427 for entry in model:
2396 2428 if entry[1] == self.visible_repository:
2397 2429 index = entry[0]
2398 2430 break
2399 2431 # We do not want to switch permanently to the Add...
2400 2432 self.w_repository_combobox.set_active(index)
2401 2433 self.__on_edit_repositories_activate(None)
2402 2434 return
2403 2435 self.cancelled = True
2404 2436 self.in_setup = True
2405 2437 self.set_busy_cursor()
2406 2438 self.__set_empty_details_panel()
2407 2439 if self.in_search_mode:
2408 2440 self.__unset_search(False)
2409 2441 self.w_searchentry.grab_focus()
2410 2442 if len(self.w_searchentry.get_text()) > 0:
2411 2443 start, end = self.w_searchentry.get_selection_bounds()
2412 2444 self.w_searchentry.select_region(end, end)
2413 2445
2414 2446 pub = [active_publisher, ]
2415 2447 self.set_show_filter = self.initial_show_filter
2416 2448 self.set_section = self.initial_section
2417 2449 Thread(target = self.__setup_publisher, args = [pub]).start()
2418 2450 self.__set_main_view_package_list()
2419 2451
2420 2452 def __get_active_publisher(self):
|
↓ open down ↓ |
320 lines elided |
↑ open up ↑ |
2421 2453 pub_iter = self.w_repository_combobox.get_active_iter()
2422 2454 if pub_iter == None:
2423 2455 return None
2424 2456 return self.repositories_list.get_value(pub_iter, \
2425 2457 enumerations.REPOSITORY_NAME)
2426 2458
2427 2459 def __setup_publisher(self, publishers=[]):
2428 2460 self.saved_filter_combobox_active = self.initial_show_filter
2429 2461 application_list, category_list , section_list = \
2430 2462 self.__get_application_categories_lists(publishers)
2463 + self.__unset_saved()
2431 2464 gobject.idle_add(self.__init_tree_views, application_list,
2432 2465 category_list, section_list)
2433 2466
2467 + def __unset_saved(self):
2468 + self.saved_application_list = None
2469 + self.saved_application_list_filter = None
2470 + self.saved_application_list_sort = None
2471 + self.saved_category_list = None
2472 + self.saved_section_list = None
2473 +
2434 2474 def __get_application_categories_lists(self, publishers=[]):
2435 2475 if not self.visible_repository:
2436 2476 self.visible_repository = self.__get_active_publisher()
2437 2477 application_list = self.__get_new_application_liststore()
2438 2478 category_list = self.__get_new_category_liststore()
2439 2479 section_list = self.__get_new_section_liststore()
2440 2480 first_loop = True
2441 2481 for publisher in publishers:
2442 2482 uptodate = False
2443 2483 try:
2444 2484 uptodate = self.__check_if_cache_uptodate(publisher)
2445 2485 if uptodate:
2446 2486 self.__add_pkgs_to_lists_from_cache(publisher,
2447 2487 application_list, category_list,
2448 2488 section_list)
2449 2489 except (UnpicklingError, EOFError, IOError):
2450 2490 #Most likely cache is corrupted, silently load list
2451 2491 #from api.
2452 2492 application_list = self.__get_new_application_liststore()
2453 2493 category_list = self.__get_new_category_liststore()
2454 2494 uptodate = False
2455 2495 if not uptodate:
2456 2496 if first_loop == True:
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
2457 2497 first_loop = False
2458 2498 gobject.idle_add(self.setup_progressdialog_show)
2459 2499 self.api_o.refresh(pubs=[publisher])
2460 2500 self.__add_pkgs_to_lists_from_api(publisher,
2461 2501 application_list, category_list, section_list)
2462 2502 category_list.prepend([0, _('All'), None, None, False,
2463 2503 True, None])
2464 2504 if self.application_list and self.category_list and \
2465 2505 not self.visible_repository_uptodate:
2466 2506 if self.visible_repository:
2507 + dump_list = self.application_list
2508 + if self.saved_application_list != None:
2509 + dump_list = \
2510 + self.saved_application_list
2467 2511 self.__dump_datamodels(self.visible_repository,
2468 - self.application_list, self.category_list,
2512 + dump_list, self.category_list,
2469 2513 self.section_list)
2470 2514 self.visible_repository = self.__get_active_publisher()
2471 2515 self.visible_repository_uptodate = uptodate
2472 2516 return application_list, category_list, section_list
2473 2517
2474 2518 def __check_if_cache_uptodate(self, publisher):
2475 2519 if self.cache_o:
2476 2520 return self.cache_o.check_if_cache_uptodate(publisher)
2477 2521 return False
2478 2522
2479 2523 def __dump_datamodels(self, publisher, application_list, category_list,
2480 2524 section_list):
2525 + #Consistency check - only dump models if publisher passed in matches
2526 + #publisher in application list
2527 + if application_list == None:
2528 + return
2529 + app_pub = application_list[0][enumerations.AUTHORITY_COLUMN]
2530 + if publisher != app_pub:
2531 + if debug:
2532 + print "ERROR: __dump_data_models(): INCONSISTENT " \
2533 + "pub %s != app_list_pub %s" % \
2534 + (publisher, app_pub)
2535 + return
2536 +
2481 2537 if self.cache_o:
2482 2538 if self.img_timestamp == \
2483 2539 self.cache_o.get_index_timestamp():
2484 2540 Thread(target = self.cache_o.dump_datamodels,
2485 2541 args = (publisher, application_list, category_list,
2486 2542 section_list)).start()
2487 2543 else:
2488 2544 self.__remove_cache()
2489 2545
2490 2546 def __remove_cache(self):
2491 2547 model = self.w_repository_combobox.get_model()
2492 2548 for publisher in model:
2493 2549 pub_name = publisher[1]
2494 2550 if pub_name and pub_name != _("Add..."):
2495 2551 Thread(target = self.cache_o.remove_datamodel,
2496 2552 args = [publisher[1]]).start()
2497 2553
2498 2554 def __on_install_update(self, widget):
2499 2555 self.api_o.reset()
2500 2556 install_update = []
2501 2557 if self.selected == 0:
2502 2558 model, itr = self.package_selection.get_selected()
2503 2559 if itr:
2504 2560 install_update.append(
2505 2561 model.get_value(itr, enumerations.STEM_COLUMN))
2506 2562 else:
2507 2563 visible_repository = self.__get_visible_repository_name()
2508 2564 pkgs = self.selected_pkgs.get(visible_repository)
2509 2565 if pkgs:
2510 2566 for pkg_stem in pkgs:
2511 2567 status = pkgs.get(pkg_stem)
2512 2568 if status == enumerations.NOT_INSTALLED or \
2513 2569 status == enumerations.UPDATABLE:
2514 2570 install_update.append(pkg_stem)
2515 2571
2516 2572 if self.img_timestamp != self.cache_o.get_index_timestamp():
2517 2573 self.img_timestamp = None
2518 2574 self.__remove_cache()
2519 2575
2520 2576 installupdate.InstallUpdate(install_update, self, \
2521 2577 self.api_o, ips_update = False, \
2522 2578 action = enumerations.INSTALL_UPDATE)
2523 2579
2524 2580 def __on_update_all(self, widget):
2525 2581 self.api_o.reset()
2526 2582 installupdate.InstallUpdate([], self,
2527 2583 self.api_o, ips_update = False,
2528 2584 action = enumerations.IMAGE_UPDATE, be_name = self.ua_be_name,
2529 2585 parent_name = _("Package Manager"),
2530 2586 pkg_list = ["SUNWipkg", "SUNWipkg-gui"],
2531 2587 main_window = self.w_main_window)
2532 2588 return
2533 2589
2534 2590 def __on_ua_completed_linkbutton_clicked(self, widget):
2535 2591 try:
2536 2592 gnome.url_show(self.release_notes_url)
2537 2593 except gobject.GError:
2538 2594 self.error_occurred(_("Unable to navigate to:\n\t%s") %
2539 2595 self.release_notes_url)
2540 2596
2541 2597 def __on_help_about(self, widget):
2542 2598 wTreePlan = gtk.glade.XML(self.gladefile, "aboutdialog")
2543 2599 aboutdialog = wTreePlan.get_widget("aboutdialog")
2544 2600 aboutdialog.connect("response", lambda x = None, \
2545 2601 y = None: aboutdialog.destroy())
2546 2602 aboutdialog.run()
2547 2603
2548 2604 def __on_help_help(self, widget):
2549 2605 gui_misc.display_help(self.application_dir)
2550 2606
2551 2607 def __on_remove(self, widget):
2552 2608 self.api_o.reset()
2553 2609 remove_list = []
2554 2610 if self.selected == 0:
2555 2611 model, itr = self.package_selection.get_selected()
2556 2612 if itr:
2557 2613 remove_list.append(
2558 2614 model.get_value(itr, enumerations.STEM_COLUMN))
2559 2615 else:
2560 2616 visible_repository = self.__get_visible_repository_name()
2561 2617 pkgs = self.selected_pkgs.get(visible_repository)
2562 2618 if pkgs:
2563 2619 for pkg_stem in pkgs:
2564 2620 status = pkgs.get(pkg_stem)
2565 2621 if status == enumerations.INSTALLED or \
2566 2622 status == enumerations.UPDATABLE:
2567 2623 remove_list.append(pkg_stem)
2568 2624
2569 2625 if self.img_timestamp != self.cache_o.get_index_timestamp():
2570 2626 self.img_timestamp = None
2571 2627 self.__remove_cache()
2572 2628
2573 2629 installupdate.InstallUpdate(remove_list, self,
2574 2630 self.api_o, ips_update = False,
2575 2631 action = enumerations.REMOVE)
2576 2632
2577 2633 def __on_reload(self, widget):
2578 2634 if self.description_thread_running:
2579 2635 self.cancelled = True
2580 2636 if self.in_search_mode or self.is_search_all:
2581 2637 self.__unset_search(False)
2582 2638 self.__set_empty_details_panel()
2583 2639 self.in_setup = True
2584 2640 self.visible_repository = None
2585 2641 if widget != None:
2586 2642 self.__remove_cache()
2587 2643 self.w_progress_dialog.set_title(_("Refreshing catalogs"))
2588 2644 self.w_progressinfo_label.set_text(_("Refreshing catalogs..."))
2589 2645 self.progress_stop_timer_thread = False
2590 2646 Thread(target = self.__progressdialog_progress_pulse).start()
2591 2647 self.w_progress_dialog.show()
2592 2648 self.w_progress_cancel.hide()
2593 2649 self.__disconnect_models()
2594 2650 self.in_reload = True
2595 2651 Thread(target = self.__catalog_refresh).start()
2596 2652
2597 2653 def __catalog_refresh_done(self):
2598 2654 self.progress_stop_timer_thread = True
2599 2655 #Let the progress_pulse finish. This should be done other way, but at
2600 2656 #The moment this works fine
2601 2657 time.sleep(0.2)
2602 2658 gobject.idle_add(self.w_progress_cancel.show)
2603 2659 gobject.idle_add(self.process_package_list_start,
2604 2660 self.image_directory)
2605 2661
2606 2662 def __main_application_quit(self, be_name = None):
2607 2663 '''quits the main gtk loop'''
2608 2664 self.cancelled = True
2609 2665 if self.in_setup:
2610 2666 return
2611 2667
2612 2668 if be_name:
2613 2669 if self.image_dir_arg:
2614 2670 gobject.spawn_async([self.application_path, "-R",
2615 2671 self.image_dir_arg, "-U", be_name])
2616 2672 else:
2617 2673 gobject.spawn_async([self.application_path,
2618 2674 "-U", be_name])
2619 2675 elif not self.in_search_mode:
2620 2676 visible_repository = self.__get_visible_repository_name()
2621 2677 self.__dump_datamodels(visible_repository,
2622 2678 self.application_list, self.category_list,
2623 2679 self.section_list)
2624 2680
2625 2681 width, height = self.w_main_window.get_size()
2626 2682 hpos = self.w_main_hpaned.get_position()
2627 2683 vpos = self.w_main_vpaned.get_position()
2628 2684 try:
2629 2685 self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
2630 2686 self.client.set_int(INITIAL_APP_HEIGHT_PREFERENCES, height)
2631 2687 self.client.set_int(INITIAL_APP_HPOS_PREFERENCES, hpos)
2632 2688 self.client.set_int(INITIAL_APP_VPOS_PREFERENCES, vpos)
2633 2689 except GError:
2634 2690 pass
2635 2691
2636 2692 self.w_main_window.hide()
2637 2693 while gtk.events_pending():
2638 2694 gtk.main_iteration(False)
2639 2695 gtk.main_quit()
2640 2696 sys.exit(0)
2641 2697 return True
2642 2698
2643 2699 def __check_if_something_was_changed(self):
2644 2700 ''' Returns True if any of the check boxes for package was changed, false
2645 2701 if not'''
2646 2702 if self.application_list:
2647 2703 for pkg in self.application_list:
2648 2704 if pkg[enumerations.MARK_COLUMN] == True:
2649 2705 return True
2650 2706 return False
2651 2707
2652 2708 def __setup_repositories_combobox(self, api_o, repositories_list):
2653 2709 self.__disconnect_repository_model()
2654 2710 default_pub = api_o.get_preferred_publisher().prefix
2655 2711 if self.default_publisher != default_pub:
2656 2712 self.__clear_pkg_selections()
2657 2713 self.default_publisher = default_pub
2658 2714 selected_repos = []
2659 2715 enabled_repos = []
2660 2716 for repo in self.selected_pkgs:
2661 2717 selected_repos.append(repo)
2662 2718 i = 0
2663 2719 active = 0
2664 2720 for pub in api_o.get_publishers():
2665 2721 if pub.disabled:
2666 2722 continue
2667 2723 prefix = pub.prefix
2668 2724 if cmp(prefix, self.default_publisher) == 0:
2669 2725 active = i
2670 2726 repositories_list.append([i, prefix, ])
2671 2727 enabled_repos.append(prefix)
2672 2728 i = i + 1
2673 2729 repositories_list.append([-1, "", ])
2674 2730 repositories_list.append([-1, _("Add..."), ])
2675 2731 pkgs_to_remove = []
2676 2732 for repo_name in selected_repos:
2677 2733 if repo_name not in enabled_repos:
2678 2734 pkg_stems = self.selected_pkgs.get(repo_name)
2679 2735 for pkg_stem in pkg_stems:
2680 2736 pkgs_to_remove.append(pkg_stem)
2681 2737 for pkg_stem in pkgs_to_remove:
2682 2738 self.__remove_pkg_stem_from_list(pkg_stem)
2683 2739 self.w_repository_combobox.set_model(repositories_list)
2684 2740 if self.default_publisher:
2685 2741 self.w_repository_combobox.set_active(active)
2686 2742 else:
2687 2743 self.w_repository_combobox.set_active(0)
2688 2744
2689 2745 def __active_pane_toggle(self, cell, path, model_sort):
2690 2746 '''Toggle function for column enumerations.MARK_COLUMN'''
2691 2747 applicationModel = model_sort.get_model()
2692 2748 applicationPath = model_sort.convert_path_to_child_path(path)
2693 2749 filterModel = applicationModel.get_model()
2694 2750 child_path = applicationModel.convert_path_to_child_path(applicationPath)
2695 2751 itr = filterModel.get_iter(child_path)
2696 2752 if itr:
2697 2753 modified = filterModel.get_value(itr, enumerations.MARK_COLUMN)
2698 2754 filterModel.set_value(itr, enumerations.MARK_COLUMN,
2699 2755 not modified)
2700 2756 pkg_status = filterModel.get_value(itr,
2701 2757 enumerations.STATUS_COLUMN)
2702 2758 pkg_stem = filterModel.get_value(itr, enumerations.STEM_COLUMN)
2703 2759 if modified:
2704 2760 self.__remove_pkg_stem_from_list(pkg_stem)
2705 2761 else:
2706 2762 self.__add_pkg_stem_to_list(pkg_stem, pkg_status)
2707 2763 self.update_statusbar()
2708 2764 self.__enable_disable_selection_menus()
2709 2765
2710 2766 def __update_reload_button(self):
2711 2767 if self.user_rights:
2712 2768 self.w_reload_button.set_sensitive(True)
2713 2769 else:
2714 2770 self.w_reload_button.set_sensitive(False)
2715 2771
2716 2772 def __add_pkg_stem_to_list(self, stem, status):
2717 2773 publisher = self.__get_active_publisher()
2718 2774 if self.selected_pkgs.get(publisher) == None:
2719 2775 self.selected_pkgs[publisher] = {}
2720 2776 self.selected_pkgs.get(publisher)[stem] = status
2721 2777 if status == enumerations.NOT_INSTALLED or \
2722 2778 status == enumerations.UPDATABLE:
2723 2779 if self.to_install_update.get(publisher) == None:
2724 2780 self.to_install_update[publisher] = 1
2725 2781 else:
2726 2782 self.to_install_update[publisher] += 1
2727 2783 if status == enumerations.UPDATABLE or status == enumerations.INSTALLED:
2728 2784 if self.to_remove.get(publisher) == None:
2729 2785 self.to_remove[publisher] = 1
2730 2786 else:
2731 2787 self.to_remove[publisher] += 1
2732 2788 self.__update_tooltips()
2733 2789
2734 2790 def __update_tooltips(self):
2735 2791 to_remove = None
2736 2792 to_install = None
2737 2793 no_iter = 0
2738 2794 for publisher in self.to_remove:
2739 2795 packages = self.to_remove.get(publisher)
2740 2796 if packages > 0:
2741 2797 if no_iter == 0:
2742 2798 to_remove = _("Selected for Removal:")
2743 2799 to_remove += "\n %s: %d" % (publisher, packages)
2744 2800 no_iter += 1
2745 2801 no_iter = 0
2746 2802 for publisher in self.to_install_update:
2747 2803 packages = self.to_install_update.get(publisher)
2748 2804 if packages > 0:
2749 2805 if no_iter == 0:
2750 2806 to_install = _("Selected for Install/Update:")
2751 2807 to_install += "\n %s: %d" % (publisher, packages)
2752 2808 no_iter += 1
2753 2809 if not to_install:
2754 2810 to_install = _("Select packages by marking the checkbox "
2755 2811 "and click to Install/Update.")
2756 2812 self.w_installupdate_button.set_tooltip(self.install_button_tooltip,
2757 2813 to_install)
2758 2814 if not to_remove:
2759 2815 to_remove = _("Select packages by marking the checkbox "
2760 2816 "and click to Remove selected.")
2761 2817 self.w_remove_button.set_tooltip(self.remove_button_tooltip, to_remove)
2762 2818
2763 2819 def __remove_pkg_stem_from_list(self, stem):
2764 2820 remove_pub = []
2765 2821 for publisher in self.selected_pkgs:
2766 2822 pkgs = self.selected_pkgs.get(publisher)
2767 2823 status = None
2768 2824 if stem in pkgs:
2769 2825 status = pkgs.pop(stem)
2770 2826 if status == enumerations.NOT_INSTALLED or \
2771 2827 status == enumerations.UPDATABLE:
2772 2828 if self.to_install_update.get(publisher) == None:
2773 2829 self.to_install_update[publisher] = 0
2774 2830 else:
2775 2831 self.to_install_update[publisher] -= 1
2776 2832 if status == enumerations.UPDATABLE or \
2777 2833 status == enumerations.INSTALLED:
2778 2834 if self.to_remove.get(publisher) == None:
2779 2835 self.to_remove[publisher] = 0
2780 2836 else:
2781 2837 self.to_remove[publisher] -= 1
2782 2838 if len(pkgs) == 0:
2783 2839 remove_pub.append(publisher)
2784 2840 for publisher in remove_pub:
2785 2841 self.selected_pkgs.pop(publisher)
2786 2842 self.__update_tooltips()
2787 2843
2788 2844 def __clear_pkg_selections(self):
2789 2845 # We clear the selections as the preffered repository was changed
2790 2846 # and pkg stems are not valid.
2791 2847 remove_pub = []
2792 2848 for publisher in self.selected_pkgs:
2793 2849 stems = self.selected_pkgs.get(publisher)
2794 2850 for pkg_stem in stems:
2795 2851 remove_pub.append(pkg_stem)
2796 2852 for pkg_stem in remove_pub:
2797 2853 self.__remove_pkg_stem_from_list(pkg_stem)
2798 2854
2799 2855 def __set_empty_details_panel(self):
2800 2856 self.showing_empty_details = True
2801 2857 if self.show_info_id != 0:
2802 2858 gobject.source_remove(self.show_info_id)
2803 2859 self.show_info_id = 0
2804 2860 if self.show_licenses_id != 0:
2805 2861 gobject.source_remove(self.show_licenses_id)
2806 2862 self.show_licenses_id = 0
2807 2863 pkg_name = _("Package Name")
2808 2864 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2809 2865 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2810 2866 self.w_installedfiles_textview.get_buffer().set_text("")
2811 2867 self.w_dependencies_textview.get_buffer().set_text("")
2812 2868 self.w_generalinfo_textview.get_buffer().set_text("")
2813 2869 self.w_license_textview.get_buffer().set_text("")
2814 2870 return
2815 2871
2816 2872 def __show_fetching_package_info(self, pkg):
2817 2873 pkg_name = pkg.get_name()
2818 2874 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2819 2875 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2820 2876
2821 2877 pkg_stem = pkg.get_pkg_stem()
2822 2878 if self.__setting_from_cache(pkg_stem):
2823 2879 return
2824 2880
2825 2881 self.w_shortdescription_label.set_text(
2826 2882 _("Fetching description..."))
2827 2883 instbuffer = self.w_installedfiles_textview.get_buffer()
2828 2884 depbuffer = self.w_dependencies_textview.get_buffer()
2829 2885 infobuffer = self.w_generalinfo_textview.get_buffer()
2830 2886 fetching_text = _("Fetching information...")
2831 2887 instbuffer.set_text(fetching_text)
2832 2888 depbuffer.set_text(fetching_text)
2833 2889 infobuffer.set_text(fetching_text)
2834 2890 return
2835 2891
2836 2892 def __setting_from_cache(self, pkg_stem):
2837 2893 if len(self.info_cache) > MAX_INFO_CACHE_LIMIT:
2838 2894 self.info_cache = {}
2839 2895
2840 2896 if self.info_cache.has_key(pkg_stem):
2841 2897 self.w_shortdescription_label.set_text(
2842 2898 self.info_cache[pkg_stem][0])
2843 2899 instbuffer = self.w_installedfiles_textview.get_buffer()
2844 2900 depbuffer = self.w_dependencies_textview.get_buffer()
2845 2901 infobuffer = self.w_generalinfo_textview.get_buffer()
2846 2902 infobuffer.set_text(self.info_cache[pkg_stem][1])
2847 2903 instbuffer.set_text(self.info_cache[pkg_stem][2])
2848 2904 depbuffer.set_text(self.info_cache[pkg_stem][3])
2849 2905 return True
2850 2906 else:
2851 2907 return False
2852 2908
2853 2909 def __update_package_info(self, pkg, local_info, remote_info, info_id):
2854 2910 if self.showing_empty_details or (info_id !=
2855 2911 self.last_show_info_id):
2856 2912 return
2857 2913 pkg_name = pkg.get_name()
2858 2914 pkg_stem = pkg.get_pkg_stem()
2859 2915 self.w_packagename_label.set_markup("<b>" + pkg_name + "</b>")
2860 2916 self.w_general_info_label.set_markup("<b>" + pkg_name + "</b>")
2861 2917 installed = True
2862 2918
2863 2919 if self.__setting_from_cache(pkg_stem):
2864 2920 return
2865 2921
2866 2922 instbuffer = self.w_installedfiles_textview.get_buffer()
2867 2923 depbuffer = self.w_dependencies_textview.get_buffer()
2868 2924 infobuffer = self.w_generalinfo_textview.get_buffer()
2869 2925
2870 2926 if not local_info and not remote_info:
2871 2927 network_str = \
2872 2928 _("\nThis might be caused by network problem "
2873 2929 "while accessing the repository.")
2874 2930 self.w_shortdescription_label.set_text(
2875 2931 _("Description not available for this package...") +
2876 2932 network_str)
2877 2933 instbuffer.set_text( \
2878 2934 _("Files Details not available for this package...") +
2879 2935 network_str)
2880 2936 depbuffer.set_text(_(
2881 2937 "Dependencies info not available for this package...") +
2882 2938 network_str)
2883 2939 infobuffer.set_text(
2884 2940 _("Information not available for this package...") +
2885 2941 network_str)
2886 2942 return
2887 2943
2888 2944 if not local_info:
2889 2945 # Package is not installed
2890 2946 local_info = remote_info
2891 2947 installed = False
2892 2948
2893 2949 if not remote_info:
2894 2950 remote_info = local_info
2895 2951 installed = True
2896 2952
2897 2953 description = local_info.summary
2898 2954 #XXX long term need to have something more robust here for multi byte
2899 2955 if len(description) > MAX_DESC_LEN:
2900 2956 description = description[:MAX_DESC_LEN] + " ..."
2901 2957 self.w_shortdescription_label.set_text(description)
2902 2958 inst_str = _("Root: %s\n") % self.api_o.img.get_root()
2903 2959 dep_str = _("Dependencies:\n")
2904 2960
2905 2961 if local_info.dependencies:
2906 2962 dep_str += ''.join(
2907 2963 ["\t%s\n" % x for x in local_info.dependencies])
2908 2964 if local_info.dirs:
2909 2965 inst_str += ''.join(["\t%s\n" % x for x in local_info.dirs])
2910 2966 if local_info.files:
2911 2967 inst_str += ''.join(["\t%s\n" % x for x in local_info.files])
2912 2968 if local_info.hardlinks:
2913 2969 inst_str += ''.join(["\t%s\n" % x for x in local_info.hardlinks])
2914 2970 if local_info.links:
2915 2971 inst_str += ''.join(["\t%s\n" % x for x in local_info.links])
2916 2972 info_str = ""
2917 2973 labs = {}
2918 2974 labs["sum"] = _("Summary:\t\t")
2919 2975 labs["size"] = _("Size:\t\t\t")
2920 2976 labs["cat"] = _("Category:\t\t")
2921 2977 labs["ins"] = _("Installed Version:\t")
2922 2978 labs["lat"] = _("Latest Version:\t")
2923 2979 labs["pkg_date"] = _("Packaging Date:\t")
2924 2980 labs["fmri"] = _("FMRI:\t\t\t")
2925 2981 labs["repository"] = _("Repository:\t\t")
2926 2982 max_len = 0
2927 2983 for lab in labs:
2928 2984 if len(labs[lab]) > max_len:
2929 2985 max_len = len(labs[lab])
2930 2986 categories = _("None")
2931 2987 if local_info.category_info_list:
2932 2988 verbose = len(local_info.category_info_list) > 1
2933 2989 categories = ""
2934 2990 categories += local_info.category_info_list[0].__str__(verbose)
2935 2991 if len(local_info.category_info_list) > 1:
2936 2992 for ci in local_info.category_info_list[1:]:
2937 2993 categories += ", " + ci.__str__(verbose)
2938 2994 summary = _("None")
2939 2995 if local_info.summary:
2940 2996 summary = local_info.summary
2941 2997 info_str += " %s %s" % (labs["sum"], summary)
2942 2998 info_str += "\n %s %s" % (labs["size"],
2943 2999 misc.bytes_to_str(local_info.size))
2944 3000 info_str += "\n %s %s" % (labs["cat"], categories)
2945 3001 if installed:
2946 3002 info_str += "\n %s %s,%s-%s" % (labs["ins"], local_info.version,
2947 3003 local_info.build_release, local_info.branch)
2948 3004 info_str += "\n %s %s,%s-%s" % (labs["lat"], remote_info.version,
2949 3005 remote_info.build_release, remote_info.branch)
2950 3006 info_str += "\n %s %s" % (labs["pkg_date"], local_info.packaging_date)
2951 3007 info_str += "\n %s %s" % (labs["fmri"], local_info.fmri)
2952 3008 info_str += "\n %s %s" % (labs["repository"], local_info.publisher)
2953 3009 infobuffer.set_text(info_str)
2954 3010 instbuffer.set_text(inst_str)
2955 3011 depbuffer.set_text(dep_str)
2956 3012 self.info_cache[pkg_stem] = \
2957 3013 (description, info_str, inst_str, dep_str)
2958 3014
2959 3015 def __update_package_license(self, licenses, license_id):
2960 3016 if self.showing_empty_details or (license_id !=
2961 3017 self.last_show_licenses_id):
2962 3018 return
2963 3019 lic = ""
2964 3020 lic_u = ""
2965 3021 if licenses == None:
2966 3022 lic_u = _("Not available")
2967 3023 else:
2968 3024 for licens in licenses:
2969 3025 lic += licens.get_text()
2970 3026 lic += "\n"
2971 3027 try:
2972 3028 lic_u = unicode(lic, "utf-8")
2973 3029 except UnicodeDecodeError:
2974 3030 lic_u += ""
2975 3031 licbuffer = self.w_license_textview.get_buffer()
2976 3032 licbuffer.set_text(lic_u)
2977 3033
2978 3034 def __show_licenses(self):
2979 3035 self.show_licenses_id = 0
2980 3036 if self.catalog_loaded == False:
2981 3037 return
2982 3038 Thread(target = self.__show_package_licenses,
2983 3039 args = (self.selected_pkgstem, self.last_show_licenses_id,)).start()
2984 3040
2985 3041 def __show_package_licenses(self, selected_pkgstem, license_id):
2986 3042 if selected_pkgstem == None:
2987 3043 gobject.idle_add(self.__update_package_license, None,
2988 3044 self.last_show_licenses_id)
2989 3045 return
2990 3046 info = None
2991 3047 try:
2992 3048 info = self.api_o.info([selected_pkgstem],
2993 3049 True, frozenset([api.PackageInfo.LICENSES]))
2994 3050 except (api_errors.TransportError):
2995 3051 pass
2996 3052 if self.showing_empty_details or (license_id !=
2997 3053 self.last_show_licenses_id):
2998 3054 return
2999 3055 if not info or (info and len(info.get(0)) == 0):
3000 3056 try:
3001 3057 # Get license from remote
3002 3058 info = self.api_o.info([selected_pkgstem],
3003 3059 False, frozenset([api.PackageInfo.LICENSES]))
3004 3060 except (api_errors.TransportError):
3005 3061 pass
3006 3062 if self.showing_empty_details or (license_id !=
3007 3063 self.last_show_licenses_id):
3008 3064 return
3009 3065 pkgs_info = None
3010 3066 package_info = None
3011 3067 no_licenses = 0
3012 3068 if info:
3013 3069 pkgs_info = info[0]
3014 3070 if pkgs_info:
3015 3071 package_info = pkgs_info[0]
3016 3072 if package_info:
3017 3073 no_licenses = len(package_info.licenses)
3018 3074 if no_licenses == 0:
3019 3075 gobject.idle_add(self.__update_package_license, None,
3020 3076 license_id)
3021 3077 return
3022 3078 else:
3023 3079 gobject.idle_add(self.__update_package_license,
3024 3080 package_info.licenses, license_id)
3025 3081
3026 3082 def __get_pkg_info(self, pkg_stem, local):
3027 3083 info = None
3028 3084 try:
3029 3085 info = self.api_o.info([pkg_stem], local,
3030 3086 api.PackageInfo.ALL_OPTIONS -
3031 3087 frozenset([api.PackageInfo.LICENSES]))
3032 3088 except (api_errors.TransportError):
3033 3089 return info
3034 3090 pkgs_info = None
3035 3091 package_info = None
3036 3092 if info:
3037 3093 pkgs_info = info[0]
3038 3094 if pkgs_info:
3039 3095 package_info = pkgs_info[0]
3040 3096 if package_info:
3041 3097 return package_info
3042 3098 else:
3043 3099 return None
3044 3100
3045 3101 def __show_info(self, model, path):
3046 3102 self.show_info_id = 0
3047 3103 if self.catalog_loaded == False:
3048 3104 self.selected_model = model
3049 3105 self.selected_path = path
3050 3106 return
3051 3107 if not (model and path):
3052 3108 return
3053 3109 if self.selected_model != None:
3054 3110 if (self.selected_model != model or
3055 3111 self.selected_path != path):
3056 3112 # This can happen after catalogs are loaded in
3057 3113 # enable_disable_update_all and a different
3058 3114 # package is selected before enable_disable_update_all
3059 3115 # calls __show_info. We set these variable to None
3060 3116 # so that when __show_info is called it does nothing.
3061 3117 self.selected_model = None
3062 3118 self.selected_path = None
3063 3119
3064 3120 itr = model.get_iter(path)
3065 3121 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3066 3122 pkg_stem = model.get_value(itr, enumerations.STEM_COLUMN)
3067 3123 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
3068 3124 if self.info_cache.has_key(pkg_stem):
3069 3125 return
3070 3126 Thread(target = self.__show_package_info,
3071 3127 args = (pkg, pkg_stem, pkg_status, self.last_show_info_id)).start()
3072 3128
3073 3129 def __show_package_info(self, pkg, pkg_stem, pkg_status, info_id):
3074 3130 self.api_o.log_operation_start("info")
3075 3131 local_info = None
3076 3132 remote_info = None
3077 3133 if not self.showing_empty_details and (info_id ==
3078 3134 self.last_show_info_id) and (pkg_status ==
3079 3135 enumerations.INSTALLED or pkg_status ==
3080 3136 enumerations.UPDATABLE):
3081 3137 local_info = self.__get_pkg_info(pkg_stem, True)
3082 3138 if not self.showing_empty_details and (info_id ==
3083 3139 self.last_show_info_id) and (pkg_status ==
3084 3140 enumerations.NOT_INSTALLED or pkg_status ==
3085 3141 enumerations.UPDATABLE):
3086 3142 remote_info = self.__get_pkg_info(pkg_stem, False)
3087 3143 if not self.showing_empty_details and (info_id ==
3088 3144 self.last_show_info_id):
3089 3145 gobject.idle_add(self.__update_package_info, pkg,
3090 3146 local_info, remote_info, info_id)
3091 3147 self.api_o.log_operation_end()
3092 3148 return
3093 3149
3094 3150 # This function is ported from pkg.actions.generic.distinguished_name()
3095 3151 @staticmethod
3096 3152 def __locale_distinguished_name(action):
3097 3153 if action.key_attr == None:
3098 3154 return str(action)
3099 3155 return "%s: %s" % \
3100 3156 (_(action.name), action.attrs.get(action.key_attr, "???"))
3101 3157
3102 3158 def __application_filter(self, model, itr):
3103 3159 '''This function is used to filter content in the main
3104 3160 application view'''
3105 3161 if self.in_setup or self.cancelled:
3106 3162 return False
3107 3163 filter_id = self.w_filter_combobox.get_active()
3108 3164 if filter_id == enumerations.FILTER_SELECTED:
3109 3165 return model.get_value(itr, enumerations.MARK_COLUMN)
3110 3166 # XXX Show filter, chenge text to integers
3111 3167 selected_category = 0
3112 3168 category_selection = self.w_categories_treeview.get_selection()
3113 3169 category_model, category_iter = category_selection.get_selected()
3114 3170 if category_iter:
3115 3171 selected_category = category_model.get_value(category_iter,
3116 3172 enumerations.CATEGORY_ID)
3117 3173 category_list = model.get_value(itr, enumerations.CATEGORY_LIST_COLUMN)
3118 3174 selected_section = self.w_sections_combobox.get_active()
3119 3175 category = False
3120 3176 if selected_section == 0 and selected_category == 0:
3121 3177 #For section "All" and category "All" always true
3122 3178 category = True
3123 3179 elif selected_category != 0:
3124 3180 if category_list and selected_category in category_list:
3125 3181 category = True
3126 3182 elif category_list:
3127 3183 #The selected category is "All" so we need to check
3128 3184 #If the package belongs to one of the visible categories
3129 3185 for visible_category in category_model:
3130 3186 visible_id = visible_category[enumerations.CATEGORY_ID]
3131 3187 if visible_id in category_list:
3132 3188 category = True
3133 3189 break
3134 3190 if (model.get_value(itr, enumerations.IS_VISIBLE_COLUMN) == False):
3135 3191 return False
3136 3192 return (category &
3137 3193 self.__is_package_filtered(model, itr, filter_id))
3138 3194
3139 3195 @staticmethod
3140 3196 def __is_package_filtered(model, itr, filter_id):
3141 3197 '''Function for filtercombobox'''
3142 3198 if filter_id == enumerations.FILTER_ALL:
3143 3199 return True
3144 3200 status = model.get_value(itr, enumerations.STATUS_COLUMN)
3145 3201 if filter_id == enumerations.FILTER_INSTALLED:
3146 3202 return (status == enumerations.INSTALLED or status == \
3147 3203 enumerations.UPDATABLE)
3148 3204 elif filter_id == enumerations.FILTER_UPDATES:
3149 3205 return status == enumerations.UPDATABLE
3150 3206 elif filter_id == enumerations.FILTER_NOT_INSTALLED:
3151 3207 return status == enumerations.NOT_INSTALLED
3152 3208
3153 3209 def __is_pkg_repository_visible(self, model, itr):
3154 3210 if len(self.repositories_list) <= 1:
3155 3211 return True
3156 3212 else:
3157 3213 visible_repository = self.__get_visible_repository_name()
3158 3214 pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
3159 3215 if not pkg:
3160 3216 return False
3161 3217 if cmp(pkg.get_publisher(), visible_repository) == 0:
3162 3218 return True
3163 3219 else:
3164 3220 return False
3165 3221
3166 3222 def __get_visible_repository_name(self):
3167 3223 pub_iter = self.w_repository_combobox.get_active_iter()
3168 3224 if pub_iter == None:
3169 3225 return None
3170 3226 visible = self.repositories_list.get_value(pub_iter, \
3171 3227 enumerations.REPOSITORY_NAME)
3172 3228 return visible
3173 3229
3174 3230 def __enable_disable_selection_menus(self):
3175 3231 if self.in_setup:
3176 3232 return
3177 3233 self.__enable_disable_select_updates()
3178 3234 if not self.__doing_search():
3179 3235 self.unset_busy_cursor()
3180 3236
3181 3237 def __enable_disable_select_all(self):
3182 3238 if self.in_setup:
3183 3239 return
3184 3240 if len(self.w_application_treeview.get_model()) > 0:
3185 3241 for row in self.w_application_treeview.get_model():
3186 3242 if not row[enumerations.MARK_COLUMN]:
3187 3243 self.w_selectall_menuitem.set_sensitive(True)
3188 3244 return
3189 3245 self.w_selectall_menuitem.set_sensitive(False)
3190 3246 else:
3191 3247 self.w_selectall_menuitem.set_sensitive(False)
3192 3248
3193 3249 def __enable_disable_install_remove(self):
3194 3250 if not self.user_rights:
3195 3251 self.w_installupdate_button.set_sensitive(False)
3196 3252 self.w_installupdate_menuitem.set_sensitive(False)
3197 3253 self.w_remove_button.set_sensitive(False)
3198 3254 self.w_remove_menuitem.set_sensitive(False)
3199 3255 return
3200 3256 selected_removal = self.__enable_if_selected_for_removal()
3201 3257 selected_install_update = self.__enable_if_selected_for_install_update()
3202 3258 if selected_removal or selected_install_update:
3203 3259 return
3204 3260 remove = False
3205 3261 install = False
3206 3262 if self.selected == 0:
3207 3263 model, itr = self.package_selection.get_selected()
3208 3264 if itr:
3209 3265 status = \
3210 3266 model.get_value(itr, enumerations.STATUS_COLUMN)
3211 3267 if status == enumerations.NOT_INSTALLED:
3212 3268 remove = False
3213 3269 install = True
3214 3270 elif status == enumerations.UPDATABLE:
3215 3271 remove = True
3216 3272 install = True
3217 3273 elif status == enumerations.INSTALLED:
3218 3274 remove = True
3219 3275 install = False
3220 3276 self.w_installupdate_button.set_sensitive(install)
3221 3277 self.w_installupdate_menuitem.set_sensitive(install)
3222 3278 self.w_remove_button.set_sensitive(remove)
3223 3279 self.w_remove_menuitem.set_sensitive(remove)
3224 3280
3225 3281 def __enable_if_selected_for_removal(self):
3226 3282 sensitive = False
3227 3283 visible_repository = self.__get_visible_repository_name()
3228 3284 selected = self.to_remove.get(visible_repository)
3229 3285 if selected > 0:
3230 3286 sensitive = True
3231 3287 self.w_remove_button.set_sensitive(sensitive)
3232 3288 self.w_remove_menuitem.set_sensitive(sensitive)
3233 3289 return sensitive
3234 3290
3235 3291 def __enable_if_selected_for_install_update(self):
3236 3292 sensitive = False
3237 3293 visible_repository = self.__get_visible_repository_name()
3238 3294 selected = self.to_install_update.get(visible_repository)
3239 3295 if selected > 0:
3240 3296 sensitive = True
3241 3297 self.w_installupdate_button.set_sensitive(sensitive)
3242 3298 self.w_installupdate_menuitem.set_sensitive(sensitive)
3243 3299 return sensitive
3244 3300
3245 3301 def __enable_disable_select_updates(self):
3246 3302 for row in self.w_application_treeview.get_model():
3247 3303 if row[enumerations.STATUS_COLUMN] == enumerations.UPDATABLE:
3248 3304 if not row[enumerations.MARK_COLUMN]:
3249 3305 self.w_selectupdates_menuitem. \
3250 3306 set_sensitive(True)
3251 3307 return
3252 3308 self.w_selectupdates_menuitem.set_sensitive(False)
3253 3309 return
3254 3310
3255 3311 def __get_inventory_list(self, pargs, all_known, all_versions):
3256 3312 self.__image_activity_lock.acquire()
3257 3313 try:
3258 3314 res = misc.get_inventory_list(self.api_o.img,
3259 3315 pargs, all_known, all_versions)
3260 3316 finally:
3261 3317 self.__image_activity_lock.release()
3262 3318 return res
3263 3319
3264 3320 def __enable_disable_update_all(self):
3265 3321 #XXX Api to provide fast information if there are some updates
3266 3322 #available within image
3267 3323 gobject.idle_add(self.w_updateall_button.set_sensitive, False)
3268 3324 gobject.idle_add(self.w_updateall_menuitem.set_sensitive, False)
3269 3325 update_available = self.__check_if_updates_available()
3270 3326 gobject.idle_add(self.__g_enable_disable_update_all, update_available)
3271 3327 gobject.idle_add(self.__show_info_after_catalog_load)
3272 3328 return False
3273 3329
3274 3330 def __show_info_after_catalog_load(self):
3275 3331 self.__show_info(self.selected_model, self.selected_path)
3276 3332 self.selected_model = None
3277 3333 self.selected_path = None
3278 3334 if (self.w_info_notebook.get_current_page() ==
3279 3335 INFO_NOTEBOOK_LICENSE_PAGE and
3280 3336 not self.showing_empty_details):
3281 3337 self.__show_licenses()
3282 3338
3283 3339 def __check_if_updates_available(self):
3284 3340 try:
3285 3341 self.catalog_loaded = False
3286 3342 self.api_o.refresh()
3287 3343 self.catalog_loaded = True
3288 3344 res = self.__get_inventory_list([], False, False)
3289 3345 for pfmri, state in res:
3290 3346 if state["upgradable"]:
3291 3347 self.pylintstub = pfmri
3292 3348 return True
3293 3349
3294 3350 except api_errors.InventoryException:
3295 3351 gobject.idle_add(self.__set_empty_details_panel)
3296 3352 return False
3297 3353 return False
3298 3354
3299 3355 def __g_enable_disable_update_all(self, update_available):
3300 3356 self.w_updateall_button.set_sensitive(update_available)
3301 3357 self.w_updateall_menuitem.set_sensitive(update_available)
3302 3358 self.__enable_disable_install_remove()
3303 3359
3304 3360 def __enable_disable_deselect(self):
3305 3361 if self.w_application_treeview.get_model():
3306 3362 for row in self.w_application_treeview.get_model():
3307 3363 if row[enumerations.MARK_COLUMN]:
3308 3364 self.w_deselect_menuitem.set_sensitive(True)
3309 3365 return
3310 3366 self.w_deselect_menuitem.set_sensitive(False)
3311 3367 return
3312 3368
3313 3369 def __catalog_refresh(self, reload_gui=True):
3314 3370 """Update image's catalogs."""
3315 3371 try:
3316 3372 # Since the user requested the refresh, perform it
3317 3373 # immediately for all publishers.
3318 3374 self.api_o.refresh(immediate=True)
3319 3375 # Refresh will load the catalogs.
3320 3376 self.catalog_loaded = True
3321 3377 except api_errors.PublisherError:
3322 3378 # In current implementation, this will never happen
3323 3379 # We are not refreshing specific publisher
3324 3380 self.__catalog_refresh_done()
3325 3381 raise
3326 3382 except api_errors.PermissionsException:
3327 3383 #Error will already have been reported in
3328 3384 #Manage Repository dialog
3329 3385 self.__catalog_refresh_done()
3330 3386 return -1
3331 3387 except api_errors.CatalogRefreshException, cre:
3332 3388 total = cre.total
3333 3389 succeeded = cre.succeeded
3334 3390 ermsg = _("Network problem.\n\n")
3335 3391 ermsg += _("Details:\n")
3336 3392 ermsg += "%s/%s" % (succeeded, total)
3337 3393 ermsg += _(" catalogs successfully updated:\n")
3338 3394 for pub, err in cre.failed:
3339 3395 if isinstance(err, HTTPError):
3340 3396 ermsg += " %s: %s - %s\n" % \
3341 3397 (err.filename, err.code, err.msg)
3342 3398 elif isinstance(err, URLError):
3343 3399 if err.args[0][0] == 8:
3344 3400 ermsg += " %s: %s\n" % \
3345 3401 (urlparse.urlsplit(
3346 3402 pub["origin"])[1].split(":")[0],
3347 3403 err.args[0][1])
3348 3404 else:
3349 3405 if isinstance(err.args[0], \
3350 3406 socket.timeout):
3351 3407 ermsg += " %s: %s\n" % \
3352 3408 (pub["origin"], "timeout")
3353 3409 else:
3354 3410 ermsg += " %s: %s\n" % \
3355 3411 (pub["origin"], \
3356 3412 err.args[0][1])
3357 3413 elif "data" in err.__dict__ and err.data:
3358 3414 ermsg += err.data
3359 3415 else:
3360 3416 ermsg += _("Unknown error")
3361 3417 ermsg += "\n"
3362 3418
3363 3419 gobject.idle_add(self.error_occurred, ermsg,
3364 3420 None, gtk.MESSAGE_INFO)
3365 3421 self.__catalog_refresh_done()
3366 3422 return -1
3367 3423 except api_errors.InvalidDepotResponseException, idrex:
3368 3424 err = str(idrex)
3369 3425 gobject.idle_add(self.error_occurred, err,
3370 3426 None, gtk.MESSAGE_INFO)
3371 3427 self.__catalog_refresh_done()
3372 3428 return -1
3373 3429 except api_errors.PublisherError:
3374 3430 self.__catalog_refresh_done()
3375 3431 raise
3376 3432 except Exception:
3377 3433 self.__catalog_refresh_done()
3378 3434 raise
3379 3435 if reload_gui:
3380 3436 self.__catalog_refresh_done()
3381 3437 return 0
3382 3438
3383 3439 def __add_pkgs_to_lists_from_cache(self, publisher, application_list,
3384 3440 category_list, section_list):
3385 3441 if self.cache_o:
3386 3442 self.cache_o.load_application_list(publisher, application_list,
3387 3443 self.selected_pkgs)
3388 3444 self.cache_o.load_category_list(publisher, category_list)
3389 3445 self.cache_o.load_section_list(publisher, section_list)
3390 3446
3391 3447 def __add_pkgs_to_lists_from_api(self, publisher, application_list,
3392 3448 category_list, section_list):
3393 3449 """ This method set up image from the given directory and
3394 3450 returns the image object or None"""
3395 3451 pargs = []
3396 3452 pargs.append("pkg://" + publisher + "/*")
3397 3453 try:
3398 3454 pkgs_known = self.__get_inventory_list(pargs,
3399 3455 True, True)
3400 3456 except api_errors.InventoryException:
3401 3457 # This can happen if the repository does not
3402 3458 # contain any packages
3403 3459 err = _("Selected repository does not contain any packages.")
3404 3460 gobject.idle_add(self.w_progress_dialog.hide)
3405 3461 gobject.idle_add(self.error_occurred, err, None,
3406 3462 gtk.MESSAGE_INFO)
3407 3463 self.unset_busy_cursor()
3408 3464 pkgs_known = []
3409 3465
3410 3466 return self.__add_pkgs_to_lists(pkgs_known, application_list,
3411 3467 category_list, section_list)
3412 3468
3413 3469 def __add_pkgs_to_lists(self, pkgs_known, application_list,
3414 3470 category_list, section_list):
3415 3471 if section_list != None:
3416 3472 self.__init_sections(section_list)
3417 3473 #Only one instance of those icons should be in memory
3418 3474 update_available_icon = gui_misc.get_icon(self.icon_theme,
3419 3475 "status_newupdate")
3420 3476 installed_icon = gui_misc.get_icon(self.icon_theme,
3421 3477 "status_installed")
3422 3478 update_for_category_icon = \
3423 3479 self.get_icon_pixbuf_from_glade_dir("legend_newupdate")
3424 3480 #Imageinfo for categories
3425 3481 imginfo = imageinfo.ImageInfo()
3426 3482 sectioninfo = imageinfo.ImageInfo()
3427 3483 pubs = [p.prefix for p in self.api_o.get_publishers()]
3428 3484 categories = {}
3429 3485 sections = {}
3430 3486 share_path = "/usr/share/package-manager/data/"
3431 3487 for pub in pubs:
3432 3488 category = imginfo.read(self.application_dir +
3433 3489 share_path + pub)
3434 3490 if len(category) == 0:
3435 3491 category = imginfo.read(self.application_dir +
3436 3492 share_path + "opensolaris.org")
3437 3493 categories[pub] = category
3438 3494 section = sectioninfo.read(self.application_dir +
3439 3495 share_path + pub + ".sections")
3440 3496 if len(section) == 0:
3441 3497 section = sectioninfo.read(self.application_dir +
3442 3498 share_path + "opensolaris.org.sections")
3443 3499 sections[pub] = section
3444 3500 pkg_count = 0
3445 3501 pkg_add = 0
3446 3502 progress_percent = INITIAL_PROGRESS_TOTAL_PERCENTAGE
3447 3503 total_pkg_count = len(pkgs_known)
3448 3504 progress_increment = \
3449 3505 total_pkg_count / PACKAGE_PROGRESS_TOTAL_INCREMENTS
3450 3506 self.progress_stop_timer_thread = True
3451 3507 while gtk.events_pending():
3452 3508 gtk.main_iteration(False)
3453 3509 prev_stem = ""
3454 3510 prev_pfmri_str = ""
3455 3511 next_app = None
3456 3512 pkg_name = None
3457 3513 pkg_publisher = None
3458 3514 prev_state = None
3459 3515 category_icon = None
3460 3516 for pkg, state in pkgs_known:
3461 3517 if prev_pfmri_str and \
3462 3518 prev_pfmri_str == pkg.get_short_fmri() and \
3463 3519 prev_state == state:
3464 3520 pkg_count += 1
3465 3521 continue
3466 3522 if prev_stem and \
3467 3523 prev_stem == pkg.get_pkg_stem() and \
3468 3524 prev_state["state"] == "known" and \
3469 3525 state["state"] == "installed":
3470 3526 pass
3471 3527 elif next_app != None:
3472 3528 self.__add_package_to_list(next_app,
3473 3529 application_list,
3474 3530 pkg_add, pkg_name,
3475 3531 category_icon,
3476 3532 categories, category_list, pkg_publisher)
3477 3533 pkg_add += 1
3478 3534 prev_stem = pkg.get_pkg_stem()
3479 3535 prev_pfmri_str = pkg.get_short_fmri()
3480 3536 prev_state = state
3481 3537
3482 3538 if progress_increment > 0 and pkg_count % progress_increment == 0:
3483 3539 progress_percent += PACKAGE_PROGRESS_PERCENT_INCREMENT
3484 3540 if progress_percent <= PACKAGE_PROGRESS_PERCENT_TOTAL:
3485 3541 self.__progressdialog_progress_percent(
3486 3542 progress_percent, pkg_count, total_pkg_count)
3487 3543 while gtk.events_pending():
3488 3544 gtk.main_iteration(False)
3489 3545
3490 3546 status_icon = None
3491 3547 category_icon = None
3492 3548 pkg_name = pkg.get_name()
3493 3549 pkg_name = gui_misc.get_pkg_name(pkg_name)
3494 3550 pkg_stem = pkg.get_pkg_stem()
3495 3551 pkg_publisher = pkg.get_publisher()
3496 3552 pkg_state = enumerations.NOT_INSTALLED
3497 3553 if state["state"] == "installed":
3498 3554 pkg_state = enumerations.INSTALLED
3499 3555 if state["upgradable"] == True:
3500 3556 status_icon = update_available_icon
3501 3557 category_icon = update_for_category_icon
3502 3558 pkg_state = enumerations.UPDATABLE
3503 3559 else:
3504 3560 status_icon = installed_icon
3505 3561 marked = False
3506 3562 if not self.is_search_all:
3507 3563 pkgs = self.selected_pkgs.get(pkg_publisher)
3508 3564 if pkgs != None:
3509 3565 if pkg_stem in pkgs:
3510 3566 marked = True
3511 3567 next_app = \
3512 3568 [
3513 3569 marked, status_icon, pkg_name, '...', pkg_state,
3514 3570 pkg, pkg_stem, None, True, None, pkg_publisher
3515 3571 ]
3516 3572 pkg_count += 1
3517 3573
3518 3574 if next_app:
3519 3575 self.__add_package_to_list(next_app, application_list,
3520 3576 pkg_add, pkg_name, category_icon, categories,
3521 3577 category_list, pkg_publisher)
3522 3578 pkg_add += 1
3523 3579 if category_list != None:
3524 3580 self.__add_categories_to_sections(sections,
3525 3581 category_list, section_list)
3526 3582 self.__progressdialog_progress_percent(PACKAGE_PROGRESS_PERCENT_TOTAL,
3527 3583 total_pkg_count, total_pkg_count)
3528 3584 return
3529 3585
3530 3586 def __add_categories_to_sections(self, sections, category_list, section_list):
3531 3587 for publisher in sections:
3532 3588 for section in sections[publisher]:
3533 3589 for category in sections[publisher][section].split(","):
3534 3590 self.__add_category_to_section(_(category),
3535 3591 _(section), category_list, section_list)
3536 3592
3537 3593 #1915 Sort the Categories into alphabetical order and prepend All Category
3538 3594 if len(category_list) > 0:
3539 3595 rows = [tuple(r) + (i,) for i, r in enumerate(category_list)]
3540 3596 rows.sort(self.__sort)
3541 3597 r = []
3542 3598 category_list.reorder([r[-1] for r in rows])
3543 3599 return
3544 3600
3545 3601 def __add_package_to_list(self, app, application_list, pkg_add,
3546 3602 pkg_name, category_icon, categories, category_list, publisher):
3547 3603 row_iter = application_list.insert(pkg_add, app)
3548 3604 if category_list == None:
3549 3605 return
3550 3606 cat_pub = categories.get(publisher)
3551 3607 if pkg_name in cat_pub:
3552 3608 pkg_categories = cat_pub.get(pkg_name)
3553 3609 for pcat in pkg_categories.split(","):
3554 3610 self.__add_package_to_category(_(pcat), None,
3555 3611 category_icon, row_iter, application_list,
3556 3612 category_list)
3557 3613
3558 3614 @staticmethod
3559 3615 def __add_package_to_category(category_name, category_description,
3560 3616 category_icon, package, application_list, category_list):
3561 3617 if not package or category_name == _('All'):
3562 3618 return
3563 3619 if not category_name:
3564 3620 return
3565 3621 category_id = None
3566 3622 icon_visible = False
3567 3623 if category_icon:
3568 3624 icon_visible = True
3569 3625 for category in category_list:
3570 3626 if category[enumerations.CATEGORY_NAME] == category_name:
3571 3627 category_id = category[enumerations.CATEGORY_ID]
3572 3628 if category_icon:
3573 3629 category[enumerations.CATEGORY_ICON] = \
3574 3630 category_icon
3575 3631 category[enumerations.CATEGORY_ICON_VISIBLE] = \
3576 3632 icon_visible
3577 3633 break
3578 3634 if not category_id: # Category not exists
3579 3635 category_id = len(category_list) + 1
3580 3636 category_list.append([category_id, category_name,
3581 3637 category_description, category_icon, icon_visible,
3582 3638 True, None])
3583 3639 if application_list.get_value(package,
3584 3640 enumerations.CATEGORY_LIST_COLUMN):
3585 3641 a = application_list.get_value(package,
3586 3642 enumerations.CATEGORY_LIST_COLUMN)
3587 3643 a.append(category_id)
3588 3644 else:
3589 3645 category_list = []
3590 3646 category_list.append(category_id)
3591 3647 application_list.set(package,
3592 3648 enumerations.CATEGORY_LIST_COLUMN, category_list)
3593 3649
3594 3650 @staticmethod
3595 3651 def __add_category_to_section(category_name, section_name, category_list,
3596 3652 section_list):
3597 3653 '''Adds the section to section list in category. If there is no such
3598 3654 section, than it is not added. If there was already section than it
3599 3655 is skipped. Sections must be case sensitive'''
3600 3656 if not category_name:
3601 3657 return
3602 3658 for section in section_list:
3603 3659 if section[enumerations.SECTION_NAME] == section_name:
3604 3660 section_id = section[enumerations.SECTION_ID]
3605 3661 for category in category_list:
3606 3662 if category[enumerations.CATEGORY_NAME] == \
3607 3663 category_name:
3608 3664 section_lst = category[ \
3609 3665 enumerations.SECTION_LIST_OBJECT]
3610 3666 section[enumerations.SECTION_ENABLED] = \
3611 3667 True
3612 3668 if not section_lst:
3613 3669 category[ \
3614 3670 enumerations.SECTION_LIST_OBJECT] = \
3615 3671 [section_id, ]
3616 3672 else:
3617 3673 if not section_name in \
3618 3674 section_lst:
3619 3675 section_lst.append(
3620 3676 section_id)
3621 3677
3622 3678 def __progressdialog_progress_pulse(self):
3623 3679 while not self.progress_stop_timer_thread:
3624 3680 gobject.idle_add(self.w_progressbar.pulse)
3625 3681 time.sleep(0.1)
3626 3682 gobject.idle_add(self.w_progress_dialog.hide)
3627 3683 self.progress_stop_timer_thread = False
3628 3684
3629 3685 # For initial setup before loading package entries allow 5% of progress bar
3630 3686 # update it on a time base as we have no other way to judge progress at this point
3631 3687 def __progressdialog_progress_time(self):
3632 3688 while not self.progress_stop_timer_thread and \
3633 3689 self.progress_fraction_time_count <= \
3634 3690 INITIAL_PROGRESS_TOTAL_PERCENTAGE:
3635 3691
3636 3692 gobject.idle_add(self.w_progressbar.set_fraction,
3637 3693 self.progress_fraction_time_count)
3638 3694 self.progress_fraction_time_count += \
3639 3695 INITIAL_PROGRESS_TIME_PERCENTAGE
3640 3696 time.sleep(INITIAL_PROGRESS_TIME_INTERVAL)
3641 3697 self.progress_stop_timer_thread = False
3642 3698 self.progress_fraction_time_count = 0
3643 3699
3644 3700 def __progressdialog_progress_percent(self, fraction, count, total):
3645 3701 gobject.idle_add(self.w_progressinfo_label.set_text, _(
3646 3702 "Processing package entries: %d of %d") % (count, total) )
3647 3703 gobject.idle_add(self.w_progressbar.set_fraction, fraction)
3648 3704
3649 3705 def error_occurred(self, error_msg, msg_title=None, msg_type=gtk.MESSAGE_ERROR):
3650 3706 if msg_title:
3651 3707 title = msg_title
3652 3708 else:
3653 3709 title = _("Package Manager")
3654 3710 gui_misc.error_occurred(self.w_main_window, error_msg,
3655 3711 title, msg_type, use_markup=True)
3656 3712
3657 3713
3658 3714 msgbox = gtk.MessageDialog(parent =
3659 3715 self.w_main_window,
3660 3716 buttons = gtk.BUTTONS_CLOSE,
3661 3717 flags = gtk.DIALOG_MODAL,
3662 3718 type = msg_type,
3663 3719 message_format = None)
3664 3720 msgbox.set_property('text', error_msg)
3665 3721 title = None
3666 3722 if msg_title:
3667 3723 title = msg_title
3668 3724 else:
3669 3725 title = _("Package Manager")
3670 3726 msgbox.set_title(title)
3671 3727 msgbox.run()
3672 3728 msgbox.destroy()
3673 3729
3674 3730 #-----------------------------------------------------------------------------#
3675 3731 # Static Methods
3676 3732 #-----------------------------------------------------------------------------#
3677 3733
3678 3734 #@staticmethod
3679 3735 #def N_(message):
3680 3736 # return message
3681 3737
3682 3738 @staticmethod
3683 3739 def __sort(a, b):
3684 3740 return cmp(a[1], b[1])
3685 3741
3686 3742 @staticmethod
3687 3743 def cell_data_function(column, renderer, model, itr, data):
3688 3744 '''Function which sets the background colour to black if package is
3689 3745 selected'''
3690 3746 if itr:
3691 3747 if model.get_value(itr, enumerations.MARK_COLUMN):
3692 3748 renderer.set_property("cell-background", "#ffe5cc")
3693 3749 renderer.set_property("cell-background-set", True)
3694 3750 else:
3695 3751 renderer.set_property("cell-background-set", False)
3696 3752
3697 3753 @staticmethod
3698 3754 def combobox_separator(model, itr):
3699 3755 return model.get_value(itr, enumerations.FILTER_NAME) == ""
3700 3756
3701 3757 @staticmethod
3702 3758 def combobox_id_separator(model, itr):
3703 3759 return model.get_value(itr, 0) == -1 and \
3704 3760 model.get_value(itr, 1) == ""
3705 3761
3706 3762 @staticmethod
3707 3763 def category_filter(model, itr):
3708 3764 '''This function filters category in the main application view'''
3709 3765 return model.get_value(itr, enumerations.CATEGORY_VISIBLE)
3710 3766
3711 3767 @staticmethod
3712 3768 def get_datetime(version):
3713 3769 dt = None
3714 3770 try:
3715 3771 dt = version.get_datetime()
3716 3772 except AttributeError:
3717 3773 dt = version.get_timestamp()
3718 3774 return dt
3719 3775
3720 3776 @staticmethod
3721 3777 def get_installed_version(api_o, pkg):
3722 3778 info = api_o.info([pkg], False, frozenset(
3723 3779 [api.PackageInfo.STATE, api.PackageInfo.IDENTITY]))
3724 3780 found = info[api.ImageInterface.INFO_FOUND]
3725 3781 try:
3726 3782 version = found[0]
3727 3783 except IndexError:
3728 3784 version = None
3729 3785 return version
3730 3786
3731 3787 #-----------------------------------------------------------------------------#
3732 3788 # Public Methods
3733 3789 #-----------------------------------------------------------------------------#
3734 3790 def setup_progressdialog_show(self):
3735 3791 self.w_progress_dialog.set_title(_("Loading Repository Information"))
3736 3792 self.w_progressinfo_label.set_text(
3737 3793 _( "Fetching package entries ..."))
3738 3794 self.w_progress_cancel.hide()
3739 3795 self.w_progress_dialog.show()
3740 3796 Thread(target = self.__progressdialog_progress_time).start()
3741 3797
3742 3798 def setup_progressdialog_hide(self):
3743 3799 self.progress_stop_timer_thread = True
3744 3800 self.w_progress_dialog.hide()
3745 3801
3746 3802 def init_show_filter(self):
3747 3803 self.__init_show_filter() #Initiates filter
3748 3804
3749 3805 def reload_packages(self):
3750 3806 self.api_o = gui_misc.get_api_object(self.image_directory,
3751 3807 self.pr, self.w_main_window)
3752 3808 self.cache_o = self.__get_cache_obj(self.icon_theme,
3753 3809 self.application_dir, self.api_o)
3754 3810 self.__on_reload(None)
3755 3811
3756 3812 def set_busy_cursor(self):
3757 3813 self.gdk_window.show()
3758 3814
3759 3815 def unset_busy_cursor(self):
3760 3816 self.gdk_window.hide()
3761 3817
3762 3818 def process_package_list_start(self, image_directory):
3763 3819 self.image_directory = image_directory
3764 3820 if not self.api_o:
3765 3821 self.api_o = gui_misc.get_api_object(image_directory,
3766 3822 self.pr, self.w_main_window)
3767 3823 self.cache_o = self.__get_cache_obj(self.icon_theme,
3768 3824 self.application_dir, self.api_o)
3769 3825 self.img_timestamp = self.cache_o.get_index_timestamp()
3770 3826 self.repositories_list = self.__get_new_repositories_liststore()
3771 3827 self.__setup_repositories_combobox(self.api_o, self.repositories_list)
3772 3828
3773 3829 @staticmethod
3774 3830 def __get_cache_obj(icon_theme, application_dir, api_o):
3775 3831 cache_o = cache.CacheListStores(icon_theme, application_dir,
3776 3832 api_o)
3777 3833 return cache_o
3778 3834
3779 3835 def process_package_list_end(self):
3780 3836 self.__set_first_category_text()
3781 3837 self.in_startpage_startup = False
3782 3838 if self.update_all_proceed:
3783 3839 # TODO: Handle situation where only SUNWipkg/SUNWipg-gui have been updated
3784 3840 # in update all: bug 6357
3785 3841 self.__on_update_all(None)
3786 3842 self.update_all_proceed = False
3787 3843 self.setup_progressdialog_hide()
3788 3844 self.__enable_disable_install_remove()
3789 3845 self.update_statusbar()
3790 3846 self.in_setup = False
3791 3847 self.cancelled = False
3792 3848 if self.set_section != 0 or \
3793 3849 self.set_show_filter != enumerations.FILTER_ALL:
3794 3850 self.__application_refilter()
3795 3851 else:
3796 3852 self.unset_busy_cursor()
3797 3853
3798 3854 if self.first_run or self.in_reload:
3799 3855 Thread(target = self.__enable_disable_update_all).start()
3800 3856 self.first_run = False
3801 3857 self.in_reload = False
3802 3858
|
↓ open down ↓ |
1312 lines elided |
↑ open up ↑ |
3803 3859 def get_icon_pixbuf_from_glade_dir(self, icon_name):
3804 3860 return gui_misc.get_pixbuf_from_path(self.application_dir +
3805 3861 "/usr/share/package-manager/", icon_name)
3806 3862
3807 3863 def update_statusbar(self):
3808 3864 '''Function which updates statusbar'''
3809 3865 if self.statusbar_message_id > 0:
3810 3866 self.w_main_statusbar.remove(0, self.statusbar_message_id)
3811 3867 self.statusbar_message_id = 0
3812 3868 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}
3869 +
3870 + if not self.in_search_mode:
3871 + installed = 0
3872 + self.selected = 0
3873 + sel = 0
3874 + if self.application_list == None:
3875 + return
3876 + visible_repository = self.__get_visible_repository_name()
3877 + pkgs = self.selected_pkgs.get(visible_repository)
3878 + if pkgs:
3879 + self.selected = len(pkgs)
3880 + for pkg_row in self.application_list:
3881 + if pkg_row[enumerations.STATUS_COLUMN] == \
3882 + enumerations.INSTALLED \
3883 + or pkg_row[enumerations.STATUS_COLUMN] == \
3884 + enumerations.UPDATABLE:
3885 + installed = installed + 1
3886 + if pkg_row[enumerations.MARK_COLUMN]:
3887 + sel = sel + 1
3888 + listed_str = _('%d listed') % len(self.application_list)
3889 + sel_str = _('%d selected') % sel
3890 + inst_str = _('%d installed') % installed
3891 + status_str = _("%s: %s , %s, %s.") % (visible_repository,
3892 + listed_str, inst_str, sel_str)
3832 3893 self.w_main_statusbar.push(0, status_str)
3833 3894 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)
3895 +
3896 + # In Search Mode
3897 + active = ""
3898 + if self.is_search_all:
3899 + if self.__doing_search():
3900 + if self.current_search_publisher != None:
3901 + active = "(" + self.current_search_publisher + \
3902 + ") "
3903 + opt_str = _('Searching... '
3904 + '%(active)sfor "%(search_text)s"') % \
3905 + {"active": active, "search_text": search_text}
3906 + else:
3907 + opt_str = _('Searched All for "%s"') % (search_text)
3908 + else:
3909 + search_str = _("Searched")
3910 + if self.__doing_search():
3911 + search_str = _("Searching...")
3912 + if self.last_active_publisher != None:
3913 + active = "(" + self.last_active_publisher + ") "
3914 + opt_str = \
3915 + _('%(search)s %(last_active)sfor "%(search_text)s"') \
3916 + % {"search": search_str, "last_active" : active,
3917 + "search_text" : search_text}
3918 + fmt_str = _("%(option_str)s: %(number)d found %(time)s")
3919 + time_str = ""
3920 + if self.search_time_sec > 0:
3921 + time_str = _("in %d seconds") % self.search_time_sec
3922 + status_str = fmt_str % {"option_str" : opt_str, "number" :
3923 + len(self.application_list), "time" : time_str}
3855 3924 self.w_main_statusbar.push(0, status_str)
3856 3925
3857 3926 def update_package_list(self, update_list):
3858 3927 if update_list == None and self.img_timestamp:
3859 3928 return
3860 3929 visible_repository = self.__get_visible_repository_name()
3861 3930 default_publisher = self.default_publisher
3862 3931 self.api_o.refresh()
3863 3932 if not self.img_timestamp:
3864 3933 self.img_timestamp = self.cache_o.get_index_timestamp()
3865 3934 self.__on_reload(None)
3866 3935 return
3867 3936 self.img_timestamp = self.cache_o.get_index_timestamp()
3868 3937 installed_icon = gui_misc.get_icon(self.icon_theme,
3869 3938 "status_installed")
3870 3939 visible_list = update_list.get(visible_repository)
3871 3940 if visible_list:
3872 3941 i = 0
3873 3942 while i < len(visible_list):
3874 3943 visible_list[i] = gui_misc.get_pkg_name(
3875 3944 visible_list[i])
3876 3945 i += 1
3877 3946 for row in self.application_list:
3878 3947 if row[enumerations.NAME_COLUMN] in visible_list:
3879 3948 pkg = row[enumerations.FMRI_COLUMN]
3880 3949 pkg_stem = row[enumerations.STEM_COLUMN]
3881 3950 self.__remove_pkg_stem_from_list(pkg_stem)
3882 3951 if self.info_cache.has_key(pkg_stem):
3883 3952 del self.info_cache[pkg_stem]
3884 3953 package_info = self.get_installed_version(
3885 3954 self.api_o, pkg_stem)
3886 3955 package_installed = (package_info.state
3887 3956 == api.PackageInfo.INSTALLED)
3888 3957 print pkg_stem, package_installed
3889 3958 if package_installed:
3890 3959 row[enumerations.STATUS_COLUMN] = \
3891 3960 enumerations.INSTALLED
3892 3961 row[enumerations.STATUS_ICON_COLUMN] = \
3893 3962 installed_icon
3894 3963 else:
3895 3964 row[enumerations.STATUS_COLUMN] = \
3896 3965 enumerations.NOT_INSTALLED
3897 3966 row[enumerations.STATUS_ICON_COLUMN] = \
3898 3967 None
3899 3968 row[enumerations.MARK_COLUMN] = False
3900 3969 self.__dump_datamodels(visible_repository,
3901 3970 self.application_list, self.category_list,
3902 3971 self.section_list)
3903 3972 for publisher in update_list:
3904 3973 if publisher != visible_repository:
3905 3974 pkg_list = update_list.get(publisher)
3906 3975 for pkg in pkg_list:
3907 3976 pkg_stem = None
3908 3977 if publisher != default_publisher:
3909 3978 pkg_stem = "pkg://%s/%s" % \
3910 3979 (publisher, pkg)
3911 3980 else:
3912 3981 pkg_stem = "pkg:/%s" % pkg
3913 3982 if pkg_stem:
3914 3983 if self.info_cache.has_key(pkg_stem):
3915 3984 del self.info_cache[pkg_stem]
3916 3985 self.__remove_pkg_stem_from_list(pkg_stem)
3917 3986 self.__process_package_selection()
3918 3987 self.__enable_disable_selection_menus()
3919 3988 self.__enable_disable_install_remove()
3920 3989 self.update_statusbar()
3921 3990 Thread(target = self.__enable_disable_update_all).start()
3922 3991
3923 3992 @staticmethod
3924 3993 def __find_root_home_dir():
3925 3994 return_str = '/var/tmp'
3926 3995
3927 3996 try:
3928 3997 lines = pwd.getpwnam('root')
3929 3998 except KeyError:
3930 3999 if debug:
3931 4000 print "Error getting passwd database entry for root"
3932 4001 return return_str
3933 4002 try:
3934 4003 return_str = lines[5]
3935 4004 except IndexError:
3936 4005 if debug:
3937 4006 print "Error getting home directory for root"
3938 4007 return return_str
3939 4008
3940 4009 def restart_after_ips_update(self, be_name):
3941 4010 self.__main_application_quit(be_name)
3942 4011
3943 4012 def shutdown_after_image_update(self):
3944 4013 info_str = _("The Update All action is now complete and "
3945 4014 "Package Manager will close.\n\nReview the posted release notes "
3946 4015 "before rebooting your system:\n\n"
3947 4016 )
3948 4017 self.w_ua_completed_release_label.set_text(info_str.strip('\n'))
3949 4018
3950 4019 info_str = misc.get_release_notes_url()
3951 4020 self.w_ua_completed_linkbutton.set_uri(info_str)
3952 4021 self.w_ua_completed_linkbutton.set_label(info_str)
3953 4022 self.release_notes_url = info_str
3954 4023
3955 4024 self.w_ua_completed_dialog.set_title(_("Update All Complete"))
3956 4025 self.w_ua_completed_dialog.show()
3957 4026
3958 4027 ###############################################################################
3959 4028 #-----------------------------------------------------------------------------#
3960 4029 # Main
3961 4030 #-----------------------------------------------------------------------------#
3962 4031
3963 4032 def main():
3964 4033 gtk.main()
3965 4034 return 0
3966 4035
3967 4036 if __name__ == '__main__':
3968 4037 debug = False
3969 4038 debug_descriptions = False
3970 4039 update_all_proceed = False
3971 4040 ua_be_name = None
3972 4041 app_path = None
3973 4042 image_dir = None
3974 4043 info_install_arg = None
3975 4044 save_selected = _("Save selected...")
3976 4045 save_selected_pkgs = _("Save selected packages...")
3977 4046 reboot_needed = _("The installed package(s) require a reboot before "
3978 4047 "installation can be completed.")
3979 4048
3980 4049 try:
3981 4050 opts, args = getopt.getopt(sys.argv[1:], "hR:U:i:", \
3982 4051 ["help", "image-dir=", "update-all=", "info-install="])
3983 4052 except getopt.error, msg:
3984 4053 print "%s, for help use --help" % msg
3985 4054 sys.exit(2)
3986 4055
3987 4056 if os.path.isabs(sys.argv[0]):
3988 4057 app_path = sys.argv[0]
3989 4058 else:
3990 4059 cmd = os.path.join(os.getcwd(), sys.argv[0])
3991 4060 app_path = os.path.realpath(cmd)
3992 4061
3993 4062 for option, argument in opts:
3994 4063 if option in ("-h", "--help"):
3995 4064 print """\
3996 4065 Use -R (--image-dir) to specify image directory.
3997 4066 Use -U (--update-all) to proceed with Update All"""
3998 4067 sys.exit(0)
3999 4068 if option in ("-R", "--image-dir"):
4000 4069 image_dir = argument
4001 4070 if option in ("-U", "--update-all"):
4002 4071 update_all_proceed = True
4003 4072 ua_be_name = argument
4004 4073 if option in ("-i", "--info-install"):
4005 4074 info_install_arg = argument
4006 4075
4007 4076 if image_dir == None:
4008 4077 try:
4009 4078 image_dir = os.environ["PKG_IMAGE"]
4010 4079 except KeyError:
4011 4080 image_dir = os.getcwd()
4012 4081 try:
4013 4082 gtk.init_check()
4014 4083 except RuntimeError, e:
4015 4084 print _("Unable to initialize gtk")
4016 4085 print str(e)
4017 4086 sys.exit(1)
4018 4087
4019 4088 # Setup webinstall
4020 4089 if info_install_arg or len(sys.argv) == 2:
4021 4090 webinstall = webinstall.Webinstall(image_dir)
4022 4091 if len(sys.argv) == 2:
4023 4092 info_install_arg = sys.argv[1]
4024 4093 webinstall.process_param(info_install_arg)
4025 4094 main()
4026 4095 sys.exit(0)
4027 4096
4028 4097 # Setup packagemanager
4029 4098 packagemanager = PackageManager()
4030 4099 packagemanager.application_path = app_path
4031 4100 packagemanager.image_dir_arg = image_dir
4032 4101 packagemanager.update_all_proceed = update_all_proceed
4033 4102 packagemanager.ua_be_name = ua_be_name
4034 4103
4035 4104 while gtk.events_pending():
4036 4105 gtk.main_iteration(False)
4037 4106
4038 4107 packagemanager.init_show_filter()
4039 4108
4040 4109 packagemanager.process_package_list_start(image_dir)
4041 4110
4042 4111 main()
|
↓ open down ↓ |
178 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX