Print this page
*** NO COMMENTS ***

Split Close
Expand all
Collapse all
          --- old/src/packagemanager.py
          +++ new/src/packagemanager.py
↓ 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"
↓ 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
↓ open down ↓ 385 lines elided ↑ open up ↑
 668  667                          self.saved_repository_combobox_active = \
 669  668                              self.w_repository_combobox.get_active()
 670  669                  self.__disconnect_repository_model()
 671  670                  if is_search_all:
 672  671                          self.repositories_list.prepend(
 673  672                              [-1, _("All Repositories Search Results"), ])
 674  673                  else:
 675  674                          self.repositories_list.remove(
 676  675                              self.repositories_list.get_iter_first())
 677  676                  self.w_repository_combobox.set_model(self.repositories_list)
 678      -                self.visible_repository = None
      677 +                #self.visible_repository = None
 679  678  
 680  679  
 681  680          def __link_load_blank(self):
 682  681                  self.document.clear()
 683  682                  self.document.open_stream('text/html')
 684  683                  self.document.write_stream(_(
 685  684                      "<html><head></head><body></body></html>"))
 686  685                  self.document.close_stream()
 687  686  
 688  687          def __search_menu_item_activate(self, widget):
↓ open down ↓ 66 lines elided ↑ open up ↑
 755  754          def __handle_startpage_load_error(self, start_page_url):
 756  755                  self.document.open_stream('text/html')
 757  756                  self.document.write_stream(_(
 758  757                      "<html><head></head><body><H2>Welcome to"
 759  758                      "PackageManager!</H2><br>"
 760  759                      "<font color='#0000FF'>Warning: Unable to "
 761  760                      "load Start Page:<br>%s</font></body></html>"
 762  761                      % (start_page_url)))
 763  762                  self.document.close_stream()
 764  763  
 765      -        def __parse_api_search_error(self, error):
      764 +        def __process_api_search_error(self, error):
 766  765                  self.current_repos_with_search_errors = []
 767      -                if "failed_servers" in error.__dict__ and len(error.failed_servers) > 0:
 768      -                        #TBD we should not have to parse the error output
 769      -                        rem_str = " doesn't speak a known version of search operation"
 770      -                        timeout_str = "urlopen error timed out"
 771      -                        repos = []
 772      -                        for err in error.failed_servers:
 773      -                                err_str = str(err[1])
 774      -                                if rem_str in err_str:
 775      -                                        repo = err_str.replace(rem_str,"")
 776      -                                        self.current_repos_with_search_errors.append(repo)
 777      -                                elif timeout_str in err_str:
 778      -                                        repo = err[0].repositories[0].origins[0].uri
 779      -                                        self.current_repos_with_search_errors.append(repo)
 780  766  
      767 +                for pub, err in error.failed_servers:
      768 +                        self.current_repos_with_search_errors.append(
      769 +                            (pub, _("failed to respond"), err))
      770 +                for pub in error.invalid_servers:
      771 +                        self.current_repos_with_search_errors.append(
      772 +                            (pub, _("invalid response"),
      773 +                                _("A valid response was not returned.")))
      774 +                for pub, err in error.unsupported_servers:
      775 +                        self.current_repos_with_search_errors.append(
      776 +                            (pub, _("unsupported search"), err))
      777 +
 781  778          def __on_infosearch_button_clicked(self, widget):
 782  779                  self.__handle_api_search_error(True)
 783  780  
 784  781          def __handle_api_search_error(self, show_all=False):
 785  782                  if len(self.current_repos_with_search_errors) == 0:
 786  783                          self.w_infosearch_frame.hide()
 787  784                          return
 788      -                else:
 789      -                        self.w_infosearch_button.set_size_request(26, 22)
 790      -                        self.w_infosearch_frame.show()
 791  785  
 792      -                repo_pubs = self.__get_repo_publishers()
 793  786                  repo_count = 0
 794      -                for url in self.current_repos_with_search_errors:
 795      -                        if show_all or (url not in self.gconf_not_show_repos):
      787 +                for pub, err_type, err_str in self.current_repos_with_search_errors:
      788 +                        if show_all or (pub not in self.gconf_not_show_repos):
 796  789                                  repo_count += 1
 797  790                  if repo_count == 0:
      791 +                        self.w_infosearch_frame.hide()
 798  792                          return
 799  793  
      794 +                self.w_infosearch_button.set_size_request(26, 22)
      795 +                self.w_infosearch_frame.show()
 800  796                  infobuffer = self.api_search_error_textview.get_buffer()
 801  797                  infobuffer.set_text("")
 802  798                  textiter = infobuffer.get_end_iter()
 803      -                for url in self.current_repos_with_search_errors:
 804      -                        if show_all or (url not in self.gconf_not_show_repos):
      799 +                for pub, err_type, err_str in self.current_repos_with_search_errors:
      800 +
      801 +                        if show_all or (pub not in self.gconf_not_show_repos):
 805  802                                  infobuffer.insert_with_tags_by_name(textiter,
 806      -                                        "%s" % repo_pubs[url], "bold")
 807      -                                infobuffer.insert(textiter, " (%s)\n" % url)
      803 +                                    "%(pub)s (%(err_type)s)\n" % {"pub": pub,
      804 +                                    "err_type": err_type}, "bold")
      805 +                                infobuffer.insert(textiter, "%s\n" % (err_str))
      806 +
 808  807                  self.api_search_checkbox.set_active(False)
 809  808                  self.api_search_error_dialog.show()
 810  809                  self.api_search_button.grab_focus()
 811  810  
 812  811          def __get_repo_publishers(self):
 813  812                  repo_pub_dict = {}
 814  813                  pubs = self.api_o.get_publishers()
 815  814                  for pub in pubs:
 816  815                          repo = pub.selected_repository
 817  816                          origin = repo.origins[0]
↓ open down ↓ 190 lines elided ↑ open up ↑
1008 1007                          )
1009 1008  
1010 1009          @staticmethod
1011 1010          def __get_new_repositories_liststore():
1012 1011                  return gtk.ListStore(
1013 1012                          gobject.TYPE_INT,         # enumerations.REPOSITORY_ID
1014 1013                          gobject.TYPE_STRING,      # enumerations.REPOSITORY_NAME
1015 1014                          )
1016 1015  
1017 1016          def __init_application_tree_view(self, application_list,
1018      -            application_list_filter, application_list_sort):
     1017 +            application_list_filter, application_list_sort,
     1018 +            application_sort_column):
1019 1019                  ##APPLICATION MAIN TREEVIEW
1020 1020                  if application_list_filter == None:
1021 1021                          application_list_filter = application_list.filter_new()
1022 1022                  if application_list_sort == None:
1023 1023                          application_list_sort = \
1024 1024                              gtk.TreeModelSort(application_list_filter)
1025 1025                          application_list_sort.set_sort_column_id(
1026      -                            enumerations.NAME_COLUMN, gtk.SORT_ASCENDING)
     1026 +                            application_sort_column, gtk.SORT_ASCENDING)
1027 1027                          application_list_sort.set_sort_func(
1028 1028                              enumerations.STATUS_ICON_COLUMN, self.__status_sort_func)
1029 1029                  toggle_renderer = gtk.CellRendererToggle()
1030 1030  
1031 1031                  column = gtk.TreeViewColumn("", toggle_renderer, \
1032 1032                      active = enumerations.MARK_COLUMN)
1033 1033                  column.set_sort_column_id(enumerations.MARK_COLUMN)
1034 1034                  column.set_sort_indicator(True)
1035 1035                  column.set_cell_data_func(toggle_renderer, self.cell_data_function, None)
1036 1036                  column.connect_after('clicked',
1037 1037                      self.__application_treeview_column_sorted, None)
1038 1038                  self.w_application_treeview.append_column(column)
1039 1039                  name_renderer = gtk.CellRendererText()
1040 1040                  column = gtk.TreeViewColumn(_("Name"), name_renderer,
1041 1041                      text = enumerations.NAME_COLUMN)
1042 1042                  column.set_resizable(True)
     1043 +                column.set_min_width(150)
1043 1044                  column.set_sort_column_id(enumerations.NAME_COLUMN)
1044 1045                  column.set_sort_indicator(True)
1045 1046                  column.set_cell_data_func(name_renderer, self.cell_data_function, None)
1046 1047                  column.connect_after('clicked',
1047 1048                      self.__application_treeview_column_sorted, None)
1048 1049                  self.w_application_treeview.append_column(column)
1049 1050                  column = self.__create_icon_column(_("Status"), True,
1050 1051                      enumerations.STATUS_ICON_COLUMN, True)
1051 1052                  column.set_sort_column_id(enumerations.STATUS_ICON_COLUMN)
1052 1053                  column.set_sort_indicator(True)
↓ open down ↓ 28 lines elided ↑ open up ↑
1081 1082                  #Added selection listener
1082 1083                  self.package_selection = self.w_application_treeview.get_selection()
1083 1084                  self.application_list = application_list
1084 1085                  self.application_list_filter = application_list_filter
1085 1086                  self.application_list_sort = application_list_sort
1086 1087                  toggle_renderer.connect('toggled', self.__active_pane_toggle,
1087 1088                      application_list_sort)
1088 1089  
1089 1090          def __init_tree_views(self, application_list, category_list, 
1090 1091              section_list, application_list_filter = None, 
1091      -            application_list_sort = None):
     1092 +            application_list_sort = None, 
     1093 +            application_sort_column = enumerations.NAME_COLUMN):
1092 1094                  '''This function connects treeviews with their models and also applies
1093 1095                  filters'''
1094 1096                  if category_list == None:
1095 1097                          self.w_application_treeview.set_model(None)
1096 1098                          self.__remove_treeview_columns(self.w_application_treeview)
1097 1099                  elif application_list == None:
1098 1100                          self.w_categories_treeview.set_model(None)
1099 1101                          self.__remove_treeview_columns(self.w_categories_treeview)
1100 1102                  else:
1101 1103                          self.__disconnect_models()
↓ open down ↓ 7 lines elided ↑ open up ↑
1109 1111                          if row[enumerations.SECTION_ENABLED] and \
1110 1112                              self.set_section >= 0 and \
1111 1113                              self.set_section < len(section_list):
1112 1114                                  if row[enumerations.SECTION_ID] != self.set_section:
1113 1115                                          self.set_section = 0
1114 1116                          else:
1115 1117                                  self.set_section = 0
1116 1118  
1117 1119                  if application_list != None:
1118 1120                          self.__init_application_tree_view(application_list,
1119      -                            application_list_filter, application_list_sort)
     1121 +                            application_list_filter, application_list_sort, 
     1122 +                            application_sort_column)
1120 1123  
1121 1124                  if self.first_run:
1122 1125                          # When vadj changes we need to set image descriptions
1123 1126                          # on visible status icons. This catches moving the scroll bars
1124 1127                          # and scrolling up and down using keyboard.
1125 1128                          vadj = self.w_application_treeview.get_vadjustment()
1126 1129                          vadj.connect('value-changed',
1127 1130                              self.__application_treeview_vadjustment_changed, None)
1128 1131                          vadj = self.w_categories_treeview.get_vadjustment()
1129 1132                          vadj.connect('value-changed',
↓ open down ↓ 179 lines elided ↑ open up ↑
1309 1312                          obj = self.a11y_application_treeview.ref_at(
1310 1313                              int(model.get_string_from_iter(itr)),
1311 1314                              STATUS_COLUMN_INDEX)
1312 1315                          obj.set_image_description(desc)
1313 1316  
1314 1317          def __set_visible_status(self, check_range = True):
1315 1318                  self.visible_status_id = 0
1316 1319                  if self.w_main_view_notebook.get_current_page() != \
1317 1320                      NOTEBOOK_PACKAGE_LIST_PAGE:
1318 1321                          return
     1322 +                if self.__doing_search():
     1323 +                        return
     1324 +
1319 1325                  a11y_enabled = False
1320 1326                  if self.a11y_application_treeview.get_n_accessible_children() != 0:
1321 1327                          a11y_enabled = True
1322 1328  
1323 1329                  visible_range = self.w_application_treeview.get_visible_range()
1324 1330                  if visible_range == None:
1325 1331                          return
1326 1332                  start = visible_range[0][0]
1327 1333                  end = visible_range[1][0]
1328 1334                  if debug_descriptions:
↓ open down ↓ 36 lines elided ↑ open up ↑
1365 1371                              sf_itr)
1366 1372                          app_itr = filt_model.convert_iter_to_child_iter(filtered_itr)
1367 1373  
1368 1374                          desc = sort_filt_model.get_value(sf_itr,
1369 1375                              enumerations.DESCRIPTION_COLUMN)
1370 1376                          # Only Fetch description for packages without a
1371 1377                          # description
1372 1378                          if desc == '...':
1373 1379                                  fmri = sort_filt_model.get_value(sf_itr,
1374 1380                                      enumerations.FMRI_COLUMN)
1375      -                                pkg_stem = fmri.get_pkg_stem(
1376      -                                    include_scheme = True)
1377      -                                pkg_stems_and_itr_to_fetch[pkg_stem] = \
1378      -                                    model.get_string_from_iter(app_itr)
     1381 +                                if fmri != None:
     1382 +                                        pkg_stem = fmri.get_pkg_stem(
     1383 +                                            include_scheme = True)
     1384 +                                        pkg_stems_and_itr_to_fetch[pkg_stem] = \
     1385 +                                            model.get_string_from_iter(app_itr)
1379 1386                          if a11y_enabled:
1380 1387                                  self.__set_accessible_status(sort_filt_model, sf_itr)
1381 1388                          start += 1
1382 1389                          sf_itr = sort_filt_model.iter_next(sf_itr)
1383 1390  
1384 1391                  if debug_descriptions:
1385 1392                          print "PKGS to FETCH: \n%s" % pkg_stems_and_itr_to_fetch
1386 1393                  if len(pkg_stems_and_itr_to_fetch) > 0:
1387 1394                          Thread(target = self.__get_pkg_descriptions,
1388 1395                              args = [pkg_stems_and_itr_to_fetch, model]).start() 
↓ open down ↓ 26 lines elided ↑ open up ↑
1415 1422                              include_scheme = True)
1416 1423                          pkg_descriptions_for_update.append((short_fmri,
1417 1424                              pkg_stems_and_itr_to_fetch[short_fmri],
1418 1425                              pkg_info.summary))
1419 1426                  if debug_descriptions:
1420 1427                          print "FETCHED PKGS: \n%s" % pkg_descriptions_for_update
1421 1428                  gobject.idle_add(self.__update_description_from_iter,
1422 1429                      pkg_descriptions_for_update, orig_model)
1423 1430  
1424 1431          def __update_description_from_iter(self, pkg_descriptions_for_update, orig_model):
     1432 +                #If doing a search abandon description updates
     1433 +                if self.__doing_search():
     1434 +                        return
     1435 +
1425 1436                  sort_filt_model = \
1426 1437                      self.w_application_treeview.get_model() #gtk.TreeModelSort
1427 1438                  filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
1428 1439                  model = filt_model.get_model() #gtk.ListStore
1429 1440  
1430 1441                  #If model has changed abandon description updates
1431 1442                  if orig_model != model:
1432 1443                          return
1433 1444  
1434 1445                  if debug_descriptions:
↓ open down ↓ 292 lines elided ↑ open up ↑
1727 1738                          servers = None
1728 1739                  else:
1729 1740                          pub_prefix = self.__get_active_publisher()
1730 1741                          if pub_prefix != None:
1731 1742                                  pub = self.api_o.get_publisher(prefix=pub_prefix)
1732 1743                          else:
1733 1744                                  pub = self.api_o.get_preferred_publisher()
1734 1745                          origin_uri = self.__get_origin_uri(pub.selected_repository)
1735 1746                          servers.append({"origin": origin_uri})
1736 1747                  if debug:
1737      -                        print "pargs:", pargs
1738      -                        print "servers:", servers
1739      -                        
     1748 +                        print "Search: pargs %s servers: %s" % (pargs, servers)
     1749 +
     1750 +                #TBD If we ever search just Installed pkgs should allow for a local search
1740 1751                  case_sensitive = False
     1752 +                return_actions = True
1741 1753                  searches.append(self.api_o.remote_search(
1742      -                    [api.Query(" ".join(pargs), case_sensitive, True, None, None)],
     1754 +                    [api.Query(" ".join(pargs), case_sensitive, return_actions)],
1743 1755                      servers=servers))
1744      -                result_tuple = {}
     1756 +                if debug:
     1757 +                        print "Search Args: %s : cs: %s : retact: %s" % \
     1758 +                                ("".join(pargs), case_sensitive, return_actions)
     1759 +
     1760 +                last_name = ""
     1761 +                self.current_search_publisher = None
     1762 +
     1763 +                # Sorting results by Name gives best overall appearance and flow
     1764 +                sort_col = enumerations.NAME_COLUMN
1745 1765                  try:
1746 1766                          for query_num, publisher, (v, return_type, tmp) in \
1747 1767                              itertools.chain(*searches):
1748      -                                if v == 1 and \
1749      -                                    return_type == api.Query.RETURN_PACKAGES:
1750      -                                        repo = None
1751      -                                        if publisher is not None \
1752      -                                            and "prefix" in publisher:
1753      -                                                repo = publisher["prefix"]
1754      -                                        name = fmri.PkgFmri(str(tmp)).get_name()
1755      -                                        result_tuple[(name, repo)] = -1
1756      -                                        if len(result_tuple) == SEARCH_LIMIT:
1757      -                                                break
1758      -                                else:
1759      -                                        # We are not interested in this error
     1768 +                                if v < 1 or return_type != api.Query.RETURN_PACKAGES:
1760 1769                                          gobject.idle_add(self.w_progress_dialog.hide)
1761 1770                                          self.__process_after_search_failure()
1762 1771                                          return
     1772 +
     1773 +                                pub = None
     1774 +                                if publisher is not None \
     1775 +                                    and "prefix" in publisher:
     1776 +                                        pub = publisher["prefix"]
     1777 +                                name = fmri.PkgFmri(str(tmp)).get_name()
     1778 +                                if last_name != name:
     1779 +                                        if debug:
     1780 +                                                print "Result Name: %s (%s)" % (name, pub)
     1781 +                                        a_res = name, pub
     1782 +                                        result.append(a_res)
     1783 +                                        #Ignore Status when fetching
     1784 +                                        application_list = \
     1785 +                                                self.__get_min_list_from_search(result)
     1786 +                                        self.current_search_publisher = pub
     1787 +                                        self.in_setup = True
     1788 +                                        gobject.idle_add(self.__init_tree_views, 
     1789 +                                            application_list, None, None, None, None,
     1790 +                                            sort_col)
     1791 +                                last_name = name
1763 1792                                  self.pylintstub = query_num
1764 1793                  except api_errors.ProblematicSearchServers, ex:
1765      -                        self.__parse_api_search_error(ex)
     1794 +                        self.__process_api_search_error(ex)
1766 1795                          gobject.idle_add(self.w_progress_dialog.hide)
1767 1796                          gobject.idle_add(self.__handle_api_search_error)
1768      -                        if len(result_tuple) == 0:
     1797 +                        if len(result) == 0:
1769 1798                                  self.__process_after_search_with_zero_results()
1770 1799                                  return
1771 1800                  except Exception, ex:
1772 1801                          # We are not interested in this error
1773 1802                          gobject.idle_add(self.w_progress_dialog.hide)
1774 1803                          self.__process_after_search_failure()
1775 1804                          return
1776 1805                  if debug:
1777      -                        print "Number of search results:", len(result_tuple)
1778      -                for name, repo in result_tuple:
1779      -                        a_res = name, repo
1780      -                        result.append(a_res)
     1806 +                        print "Number of search results:", len(result)
1781 1807                  if len(result) == 0:
1782 1808                          if debug:
1783 1809                                  print "No search results"
1784 1810                          self.__process_after_search_with_zero_results()
1785 1811                          return
1786 1812                  # We cannot get status of the packages if catalogs have not
1787 1813                  # been loaded so we pause for up to 5 seconds here to
1788 1814                  # allow catalogs to be loaded
1789 1815                  times = 5
1790 1816                  while self.catalog_loaded == False:
1791 1817                          if times == 0:
1792 1818                                  break
1793 1819                          time.sleep(1)
1794 1820                          times -= 1
     1821 +
     1822 +                #Now fetch full result set with Status
1795 1823                  self.in_setup = True
1796      -                application_list = self.__get_list_from_search(result)
     1824 +                application_list = self.__get_full_list_from_search(result)
     1825 +                gobject.idle_add(self.__init_tree_views, application_list, None, None, \
     1826 +                    None, None, sort_col)
     1827 +
1797 1828                  if self.search_start > 0:
1798 1829                          self.search_time_sec = int(time.time() - self.search_start)
     1830 +                        if debug:
     1831 +                                print "Search time: %d (sec)" % self.search_time_sec
1799 1832                  self.search_start = 0
1800      -                gobject.idle_add(self.__set_empty_details_panel)
1801      -                gobject.idle_add(self.__set_main_view_package_list)
1802      -                gobject.idle_add(self.__init_tree_views, application_list,
1803      -                    None, None)
1804 1833  
1805 1834          def __process_after_search_with_zero_results(self):
1806 1835                  if self.search_start > 0:
1807 1836                          self.search_time_sec = int(time.time() - self.search_start)
1808 1837                  self.search_start = 0
1809 1838                  self.in_setup = True
1810 1839                  application_list = self.__get_new_application_liststore()
1811 1840                  gobject.idle_add(self.__set_empty_details_panel)
1812 1841                  gobject.idle_add(self.__set_main_view_package_list)
1813 1842                  gobject.idle_add(self.__init_tree_views, application_list, None, None)
1814 1843  
1815      -        def __get_list_from_search(self, search_result):
     1844 +        def __get_min_list_from_search(self, search_result):
1816 1845                  application_list = self.__get_new_application_liststore()
     1846 +                for name, publisher in search_result:
     1847 +                        application_list.append(
     1848 +                            [False, None, name, '...', enumerations.NOT_INSTALLED, None, 
     1849 +                            "pkg://" + publisher + "/" + name, None, True, None, 
     1850 +                            publisher])
     1851 +                return application_list
     1852 +
     1853 +        def __get_full_list_from_search(self, search_result):
     1854 +                application_list = self.__get_new_application_liststore()
1817 1855                  self.__add_pkgs_to_list_from_search(search_result,
1818 1856                      application_list)
1819 1857                  return application_list
1820 1858  
1821 1859          def __add_pkgs_to_list_from_search(self, search_result,
1822 1860              application_list):
1823 1861                  pargs = []
1824 1862                  default_pub = self.api_o.get_preferred_publisher().prefix
1825 1863                  for name, publisher in search_result:
1826 1864                          pargs.append("pkg://" + publisher + "/" + name)
↓ open down ↓ 246 lines elided ↑ open up ↑
2073 2111                  try:
2074 2112                          self.client.set_bool(SHOW_STARTPAGE_PREFERENCES,
2075 2113                              self.show_startpage)
2076 2114                  except GError:
2077 2115                          pass
2078 2116  
2079 2117          def __on_api_search_checkbox_toggled(self, widget):
2080 2118                  active = self.api_search_checkbox.get_active()
2081 2119                  if len(self.current_repos_with_search_errors) > 0:
2082 2120                          if active:
2083      -                                for url in self.current_repos_with_search_errors:
2084      -                                        if url not in self.gconf_not_show_repos:
2085      -                                                self.gconf_not_show_repos += url + ","
     2121 +                                for pub, err_type, err_str in \
     2122 +                                        self.current_repos_with_search_errors:
     2123 +                                        if pub not in self.gconf_not_show_repos:
     2124 +                                                self.gconf_not_show_repos += pub + ","
2086 2125                          else:
2087      -                                for url in self.current_repos_with_search_errors:
     2126 +                                for pub, err_type, err_str in \
     2127 +                                        self.current_repos_with_search_errors:
2088 2128                                          self.gconf_not_show_repos = \
2089 2129                                              self.gconf_not_show_repos.replace(
2090      -                                            url + ",", "")
     2130 +                                            pub + ",", "")
2091 2131                          try:
2092 2132                                  self.client.set_string(API_SEARCH_ERROR_PREFERENCES,
2093 2133                                      self.gconf_not_show_repos)
2094 2134                          except GError:
2095 2135                                  pass
2096 2136  
2097 2137          def __on_searchentry_focus_in(self, widget, event):
2098 2138                  if self.w_main_clipboard.wait_is_text_available():
2099 2139                          self.w_paste_menuitem.set_sensitive(True)
2100 2140                  char_count = widget.get_text_length()
↓ open down ↓ 320 lines elided ↑ open up ↑
2421 2461                  pub_iter = self.w_repository_combobox.get_active_iter()
2422 2462                  if pub_iter == None:
2423 2463                          return None
2424 2464                  return self.repositories_list.get_value(pub_iter, \
2425 2465                              enumerations.REPOSITORY_NAME)
2426 2466  
2427 2467          def __setup_publisher(self, publishers=[]):
2428 2468                  self.saved_filter_combobox_active = self.initial_show_filter
2429 2469                  application_list, category_list , section_list = \
2430 2470                      self.__get_application_categories_lists(publishers)
     2471 +                self.__unset_saved()
2431 2472                  gobject.idle_add(self.__init_tree_views, application_list,
2432 2473                      category_list, section_list)
2433 2474  
     2475 +        def __unset_saved(self):
     2476 +                self.saved_application_list = None
     2477 +                self.saved_application_list_filter = None
     2478 +                self.saved_application_list_sort = None
     2479 +                self.saved_category_list = None
     2480 +                self.saved_section_list = None
     2481 +
2434 2482          def __get_application_categories_lists(self, publishers=[]):
2435 2483                  if not self.visible_repository:
2436 2484                          self.visible_repository = self.__get_active_publisher()
2437 2485                  application_list = self.__get_new_application_liststore()
2438 2486                  category_list = self.__get_new_category_liststore()
2439 2487                  section_list = self.__get_new_section_liststore()
2440 2488                  first_loop = True
2441 2489                  for publisher in publishers:
2442 2490                          uptodate = False
2443 2491                          try:
↓ open down ↓ 13 lines elided ↑ open up ↑
2457 2505                                          first_loop = False
2458 2506                                          gobject.idle_add(self.setup_progressdialog_show)
2459 2507                                  self.api_o.refresh(pubs=[publisher])
2460 2508                                  self.__add_pkgs_to_lists_from_api(publisher,
2461 2509                                      application_list, category_list, section_list)
2462 2510                                  category_list.prepend([0, _('All'), None, None, False,
2463 2511                                      True, None])
2464 2512                          if self.application_list and self.category_list and \
2465 2513                              not self.visible_repository_uptodate:
2466 2514                                  if self.visible_repository:
     2515 +                                        dump_list = self.application_list
     2516 +                                        if self.saved_application_list != None:
     2517 +                                                dump_list = \
     2518 +                                                    self.saved_application_list
2467 2519                                          self.__dump_datamodels(self.visible_repository,
2468      -                                            self.application_list, self.category_list,
     2520 +                                            dump_list, self.category_list,
2469 2521                                              self.section_list)
2470 2522                          self.visible_repository = self.__get_active_publisher()
2471 2523                          self.visible_repository_uptodate = uptodate
2472 2524                  return application_list, category_list, section_list
2473 2525  
2474 2526          def __check_if_cache_uptodate(self, publisher):
2475 2527                  if self.cache_o:
2476 2528                          return self.cache_o.check_if_cache_uptodate(publisher)
2477 2529                  return False
2478 2530  
2479 2531          def __dump_datamodels(self, publisher, application_list, category_list,
2480 2532              section_list):
     2533 +                #Consistency check - only dump models if publisher passed in matches 
     2534 +                #publisher in application list
     2535 +                if application_list == None:
     2536 +                        return
     2537 +                app_pub = application_list[0][enumerations.AUTHORITY_COLUMN]
     2538 +                if publisher != app_pub:
     2539 +                        if debug:
     2540 +                                print "ERROR: __dump_data_models(): INCONSISTENT " \
     2541 +                                        "pub %s != app_list_pub %s" % \
     2542 +                                        (publisher,  app_pub)
     2543 +                        return
     2544 +
2481 2545                  if self.cache_o:
2482 2546                          if self.img_timestamp == \
2483 2547                              self.cache_o.get_index_timestamp():
2484 2548                                  Thread(target = self.cache_o.dump_datamodels,
2485 2549                                      args = (publisher, application_list, category_list,
2486 2550                                      section_list)).start()
2487 2551                          else:
2488 2552                                  self.__remove_cache()
2489 2553  
2490 2554          def __remove_cache(self):
↓ open down ↓ 118 lines elided ↑ open up ↑
2609 2673                  if self.in_setup:
2610 2674                          return
2611 2675  
2612 2676                  if be_name:
2613 2677                          if self.image_dir_arg:
2614 2678                                  gobject.spawn_async([self.application_path, "-R",
2615 2679                                      self.image_dir_arg, "-U", be_name])
2616 2680                          else:
2617 2681                                  gobject.spawn_async([self.application_path,
2618 2682                                      "-U", be_name])
2619      -                elif not self.in_search_mode:
     2683 +                elif self.in_search_mode:
     2684 +                        self.__dump_datamodels(self.visible_repository,
     2685 +                            self.saved_application_list, self.category_list,
     2686 +                            self.section_list)
     2687 +                else:
2620 2688                          visible_repository = self.__get_visible_repository_name()
2621 2689                          self.__dump_datamodels(visible_repository,
2622 2690                                  self.application_list, self.category_list,
2623 2691                                  self.section_list)
2624 2692  
2625 2693                  width, height = self.w_main_window.get_size()
2626 2694                  hpos = self.w_main_hpaned.get_position()
2627 2695                  vpos = self.w_main_vpaned.get_position()
2628 2696                  try:
2629 2697                          self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
↓ open down ↓ 1173 lines elided ↑ open up ↑
3803 3871          def get_icon_pixbuf_from_glade_dir(self, icon_name):
3804 3872                  return gui_misc.get_pixbuf_from_path(self.application_dir +
3805 3873                      "/usr/share/package-manager/", icon_name)
3806 3874  
3807 3875          def update_statusbar(self):
3808 3876                  '''Function which updates statusbar'''
3809 3877                  if self.statusbar_message_id > 0:
3810 3878                          self.w_main_statusbar.remove(0, self.statusbar_message_id)
3811 3879                          self.statusbar_message_id = 0
3812 3880                  search_text = self.w_searchentry.get_text()
3813      -                if self.in_search_mode:
3814      -                        if self.is_search_all:
3815      -                                opt_str = _('Searched All for "%s"') % (search_text)
3816      -                        else:
3817      -                                opt_str = \
3818      -                                        _('Searched %(last_active)s '
3819      -                                            'for "%(search_text)s"') \
3820      -                                        % {"last_active" : self.last_active_publisher,
3821      -                                            "search_text" : search_text}
3822      -                        if len(self.application_list) == SEARCH_LIMIT:
3823      -                                fmt_str = _("%(option_str)s:  first %(number)d "
3824      -                                    "found %(time)s")
3825      -                        else:
3826      -                                fmt_str = _("%(option_str)s:  %(number)d found %(time)s")
3827      -                        time_str = ""
3828      -                        if self.search_time_sec > 0:
3829      -                                time_str = _("in %d seconds") % self.search_time_sec
3830      -                        status_str = fmt_str % {"option_str" : opt_str,
3831      -                            "number" : len(self.application_list), "time" : time_str}
     3881 +
     3882 +                if not self.in_search_mode:
     3883 +                        installed = 0
     3884 +                        self.selected = 0
     3885 +                        sel = 0
     3886 +                        if self.application_list == None:
     3887 +                                return
     3888 +                        visible_repository = self.__get_visible_repository_name()
     3889 +                        pkgs = self.selected_pkgs.get(visible_repository)
     3890 +                        if pkgs:
     3891 +                                self.selected = len(pkgs)
     3892 +                        for pkg_row in self.application_list:
     3893 +                                if pkg_row[enumerations.STATUS_COLUMN] == \
     3894 +                                        enumerations.INSTALLED \
     3895 +                                        or pkg_row[enumerations.STATUS_COLUMN] == \
     3896 +                                    enumerations.UPDATABLE:
     3897 +                                        installed = installed + 1
     3898 +                                if pkg_row[enumerations.MARK_COLUMN]:
     3899 +                                        sel = sel + 1
     3900 +                        listed_str = _('%d listed') % len(self.application_list)
     3901 +                        sel_str = _('%d selected') % sel
     3902 +                        inst_str = _('%d installed') % installed
     3903 +                        status_str = _("%s: %s , %s, %s.") % (visible_repository,
     3904 +                            listed_str, inst_str, sel_str)
3832 3905                          self.w_main_statusbar.push(0, status_str)
3833 3906                          return
3834      -                installed = 0
3835      -                self.selected = 0
3836      -                sel = 0
3837      -                if self.application_list == None:
3838      -                        return
3839      -                visible_repository = self.__get_visible_repository_name()
3840      -                pkgs = self.selected_pkgs.get(visible_repository)
3841      -                if pkgs:
3842      -                        self.selected = len(pkgs)
3843      -                for pkg_row in self.application_list:
3844      -                        if pkg_row[enumerations.STATUS_COLUMN] == enumerations.INSTALLED \
3845      -                            or pkg_row[enumerations.STATUS_COLUMN] == \
3846      -                            enumerations.UPDATABLE:
3847      -                                installed = installed + 1
3848      -                        if pkg_row[enumerations.MARK_COLUMN]:
3849      -                                sel = sel + 1
3850      -                listed_str = _('%d listed') % len(self.application_list)
3851      -                sel_str = _('%d selected') % sel
3852      -                inst_str = _('%d installed') % installed
3853      -                status_str = _("%s: %s , %s, %s.") % (visible_repository, listed_str,
3854      -                        inst_str, sel_str)
     3907 +
     3908 +                # In Search Mode
     3909 +                active = ""
     3910 +                if self.is_search_all:
     3911 +                        if self.__doing_search():
     3912 +                                if self.current_search_publisher != None:
     3913 +                                        active = "(" + self.current_search_publisher + \
     3914 +                                                ") "
     3915 +                                opt_str = _('Searching... '
     3916 +                                    '%(active)sfor "%(search_text)s"') % \
     3917 +                                        {"active": active, "search_text": search_text}
     3918 +                        else:
     3919 +                                opt_str = _('Searched All for "%s"') % (search_text)
     3920 +                else:
     3921 +                        search_str = _("Searched")
     3922 +                        if self.__doing_search():
     3923 +                                search_str = _("Searching...")
     3924 +                        if self.last_active_publisher != None:
     3925 +                                active = "(" + self.last_active_publisher + ") "
     3926 +                        opt_str = \
     3927 +                                _('%(search)s %(last_active)sfor "%(search_text)s"') \
     3928 +                                % {"search": search_str, "last_active" : active,
     3929 +                                    "search_text" : search_text}
     3930 +                fmt_str = _("%(option_str)s:  %(number)d found %(time)s")
     3931 +                time_str = ""
     3932 +                if self.search_time_sec > 0:
     3933 +                        time_str = _("in %d seconds") % self.search_time_sec
     3934 +                status_str = fmt_str % {"option_str" : opt_str, "number" :
     3935 +                    len(self.application_list), "time" : time_str}
3855 3936                  self.w_main_statusbar.push(0, status_str)
3856 3937  
3857 3938          def update_package_list(self, update_list):
3858 3939                  if update_list == None and self.img_timestamp:
3859 3940                          return
3860 3941                  visible_repository = self.__get_visible_repository_name()
3861 3942                  default_publisher = self.default_publisher
3862 3943                  self.api_o.refresh()
3863 3944                  if not self.img_timestamp:
3864 3945                          self.img_timestamp = self.cache_o.get_index_timestamp()
↓ open down ↓ 178 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX