Started to rework the cookies dialog of the new web browser.

Sun, 10 Jul 2016 19:41:24 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 10 Jul 2016 19:41:24 +0200
changeset 5029
1ce5e98ebc43
parent 5028
f7ea46dd1b7e
child 5030
b728bb00886e

Started to rework the cookies dialog of the new web browser.

WebBrowser/CookieJar/CookiesDialog.py file | annotate | diff | comparison | revisions
WebBrowser/CookieJar/CookiesDialog.ui file | annotate | diff | comparison | revisions
--- a/WebBrowser/CookieJar/CookiesDialog.py	Sun Jul 10 16:40:17 2016 +0200
+++ b/WebBrowser/CookieJar/CookiesDialog.py	Sun Jul 10 19:41:24 2016 +0200
@@ -12,17 +12,22 @@
 from PyQt5.QtCore import pyqtSlot, Qt, QDateTime, QByteArray, \
     QSortFilterProxyModel
 from PyQt5.QtGui import QFont, QFontMetrics
-from PyQt5.QtWidgets import QDialog
+from PyQt5.QtWidgets import QDialog, QTreeWidgetItem
 
-from .CookieModel import CookieModel
-
+##from .CookieModel import CookieModel
+##
 from .Ui_CookiesDialog import Ui_CookiesDialog
 
 
+# TODO: Change dialog to use a QTreeWidget and show cookie data on bottom of dialog
+# TODO: Remove CookieModel, CookieDetailsDialog and related files
 class CookiesDialog(QDialog, Ui_CookiesDialog):
     """
     Class implementing a dialog to show all cookies.
     """
+    DomainRole = Qt.UserRole + 1
+    CookieRole = Qt.UserRole + 2
+    
     def __init__(self, cookieJar, parent=None):
         """
         Constructor
@@ -37,108 +42,232 @@
         
         self.__cookieJar = cookieJar
         
-        self.removeButton.clicked.connect(self.cookiesTable.removeSelected)
-        self.removeAllButton.clicked.connect(self.cookiesTable.removeAll)
+        self.__domainDict = {}
+##        self.__itemDict = {}        # TODO: Maybe get rid of this
+        
+        for cookie in self.__cookieJar.cookies():
+            self.__addCookie(cookie)
+    
+    def __cookieDomain(self, cookie):
+        """
+        Private method to extract the cookie domain.
         
-        self.cookiesTable.verticalHeader().hide()
-        model = CookieModel(cookieJar, self)
-        self.__proxyModel = QSortFilterProxyModel(self)
-        self.__proxyModel.setSourceModel(model)
-        self.searchEdit.textChanged.connect(
-            self.__proxyModel.setFilterFixedString)
-        self.cookiesTable.setModel(self.__proxyModel)
-        self.cookiesTable.doubleClicked.connect(self.__showCookieDetails)
-        self.cookiesTable.selectionModel().selectionChanged.connect(
-            self.__tableSelectionChanged)
-        self.cookiesTable.model().modelReset.connect(self.__tableModelReset)
+        @param cookie cookie to get the domain from
+        @type QNetworkCookie
+        @return domain of the cookie
+        @rtype str
+        """
+        domain = cookie.domain()
+        if domain.startswith("."):
+            domain = domain[1:]
+        return domain
+    
+    def __addCookie(self, cookie):
+        """
+        Private method to add a cookie to the tree.
+        
+        @param cookie reference to the cookie
+        @type QNetworkCookie
+        """
+        domain = self.__cookieDomain(cookie)
+        if domain in self.__domainDict:
+            itm = QTreeWidgetItem(self.__domainDict[domain])
+        else:
+            newParent = QTreeWidgetItem(self.cookiesTree)
+            newParent.setText(0, domain)
+            newParent.setData(0, self.DomainRole, cookie.domain())
+            self.__domainDict[domain] = newParent
+            
+            itm = QTreeWidgetItem(newParent)
+        
+        itm.setText(0, cookie.domain())
+        itm.setText(1, bytes(cookie.name()).decode())
+        itm.setData(0, self.CookieRole, cookie)
+        
+##        self.__itemDict[itm] = cookie
         
-        fm = QFontMetrics(QFont())
-        height = fm.height() + fm.height() // 3
-        self.cookiesTable.verticalHeader().setDefaultSectionSize(height)
-        self.cookiesTable.verticalHeader().setMinimumSectionSize(-1)
-        for section in range(model.columnCount()):
-            header = self.cookiesTable.horizontalHeader()\
-                .sectionSizeHint(section)
-            if section == 0:
-                header = fm.width("averagebiglonghost.averagedomain.info")
-            elif section == 1:
-                header = fm.width("_session_id")
-            elif section == 4:
-                header = fm.width(
-                    QDateTime.currentDateTime().toString(Qt.LocalDate))
-            buffer = fm.width("mm")
-            header += buffer
-            self.cookiesTable.horizontalHeader().resizeSection(section, header)
-        self.cookiesTable.horizontalHeader().setStretchLastSection(True)
-        self.cookiesTable.model().sort(
-            self.cookiesTable.horizontalHeader().sortIndicatorSection(),
-            Qt.AscendingOrder)
-        
-        self.__detailsDialog = None
-    
-    def __showCookieDetails(self, index):
-        """
-        Private slot to show a dialog with the cookie details.
-        
-        @param index index of the entry to show (QModelIndex)
-        """
-        if not index.isValid():
-            return
-        
-        cookiesTable = self.sender()
-        if cookiesTable is None:
-            return
-        
-        model = cookiesTable.model()
-        row = index.row()
-        
-        domain = model.data(model.index(row, 0))
-        name = model.data(model.index(row, 1))
-        path = model.data(model.index(row, 2))
-        secure = model.data(model.index(row, 3))
-        expires = model.data(model.index(row, 4)).toString("yyyy-MM-dd hh:mm")
-        data = model.data(model.index(row, 5))
-        if data is None:
-            value = ""
-        else:
-            value = bytes(QByteArray.fromPercentEncoding(data)).decode()
-        
-        if self.__detailsDialog is None:
-            from .CookieDetailsDialog import CookieDetailsDialog
-            self.__detailsDialog = CookieDetailsDialog(self)
-        self.__detailsDialog.setData(domain, name, path, secure, expires,
-                                     value)
-        self.__detailsDialog.show()
+##        self.removeButton.clicked.connect(self.cookiesTable.removeSelected)
+##        self.removeAllButton.clicked.connect(self.cookiesTable.removeAll)
+##        
+##        self.cookiesTable.verticalHeader().hide()
+##        model = CookieModel(cookieJar, self)
+##        self.__proxyModel = QSortFilterProxyModel(self)
+##        self.__proxyModel.setSourceModel(model)
+##        self.searchEdit.textChanged.connect(
+##            self.__proxyModel.setFilterFixedString)
+##        self.cookiesTable.setModel(self.__proxyModel)
+##        self.cookiesTable.doubleClicked.connect(self.__showCookieDetails)
+##        self.cookiesTable.selectionModel().selectionChanged.connect(
+##            self.__tableSelectionChanged)
+##        self.cookiesTable.model().modelReset.connect(self.__tableModelReset)
+##        
+##        fm = QFontMetrics(QFont())
+##        height = fm.height() + fm.height() // 3
+##        self.cookiesTable.verticalHeader().setDefaultSectionSize(height)
+##        self.cookiesTable.verticalHeader().setMinimumSectionSize(-1)
+##        for section in range(model.columnCount()):
+##            header = self.cookiesTable.horizontalHeader()\
+##                .sectionSizeHint(section)
+##            if section == 0:
+##                header = fm.width("averagebiglonghost.averagedomain.info")
+##            elif section == 1:
+##                header = fm.width("_session_id")
+##            elif section == 4:
+##                header = fm.width(
+##                    QDateTime.currentDateTime().toString(Qt.LocalDate))
+##            buffer = fm.width("mm")
+##            header += buffer
+##            self.cookiesTable.horizontalHeader().resizeSection(section, header)
+##        self.cookiesTable.horizontalHeader().setStretchLastSection(True)
+##        self.cookiesTable.model().sort(
+##            self.cookiesTable.horizontalHeader().sortIndicatorSection(),
+##            Qt.AscendingOrder)
+##        
+##        self.__detailsDialog = None
+##    
+##    def __showCookieDetails(self, index):
+##        """
+##        Private slot to show a dialog with the cookie details.
+##        
+##        @param index index of the entry to show (QModelIndex)
+##        """
+##        if not index.isValid():
+##            return
+##        
+##        cookiesTable = self.sender()
+##        if cookiesTable is None:
+##            return
+##        
+##        model = cookiesTable.model()
+##        row = index.row()
+##        
+##        domain = model.data(model.index(row, 0))
+##        name = model.data(model.index(row, 1))
+##        path = model.data(model.index(row, 2))
+##        secure = model.data(model.index(row, 3))
+##        expires = model.data(model.index(row, 4)).toString("yyyy-MM-dd hh:mm")
+##        data = model.data(model.index(row, 5))
+##        if data is None:
+##            value = ""
+##        else:
+##            value = bytes(QByteArray.fromPercentEncoding(data)).decode()
+##        
+##        if self.__detailsDialog is None:
+##            from .CookieDetailsDialog import CookieDetailsDialog
+##            self.__detailsDialog = CookieDetailsDialog(self)
+##        self.__detailsDialog.setData(domain, name, path, secure, expires,
+##                                     value)
+##        self.__detailsDialog.show()
     
     @pyqtSlot()
     def on_addButton_clicked(self):
         """
         Private slot to add a new exception.
         """
-        selection = self.cookiesTable.selectionModel().selectedRows()
-        if len(selection) == 0:
+        # TODO: change this
+##        selection = self.cookiesTable.selectionModel().selectedRows()
+##        if len(selection) == 0:
+##            return
+##        
+##        from .CookiesExceptionsDialog import CookiesExceptionsDialog
+##        
+##        firstSelected = selection[0]
+##        domainSelection = firstSelected.sibling(firstSelected.row(), 0)
+##        domain = self.__proxyModel.data(domainSelection, Qt.DisplayRole)
+##        dlg = CookiesExceptionsDialog(self.__cookieJar, self)
+##        dlg.setDomainName(domain)
+##        dlg.exec_()
+##    
+##    def __tableSelectionChanged(self, selected, deselected):
+##        """
+##        Private slot to handle a change of selected items.
+##        
+##        @param selected selected indexes (QItemSelection)
+##        @param deselected deselected indexes (QItemSelection)
+##        """
+##        self.addButton.setEnabled(len(selected.indexes()) > 0)
+##    
+##    def __tableModelReset(self):
+##        """
+##        Private slot to handle a reset of the cookies table.
+##        """
+##        self.addButton.setEnabled(False)
+    
+    @pyqtSlot()
+    def on_removeButton_clicked(self):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot()
+    def on_removeAllButton_clicked(self):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
+    def on_cookiesTree_currentItemChanged(self, current, previous):
+        """
+        Private slot to handle a change of the current item.
+        
+        @param current reference to the current item
+        @type QTreeWidgetItem
+        @param previous reference to the previous current item
+        @type QTreeWidgetItem
+        """
+        self.addButton.setEnabled(current is not None)
+        self.removeButton.setEnabled(current is not None)
+        
+        if current is None:
             return
         
-        from .CookiesExceptionsDialog import CookiesExceptionsDialog
-        
-        firstSelected = selection[0]
-        domainSelection = firstSelected.sibling(firstSelected.row(), 0)
-        domain = self.__proxyModel.data(domainSelection, Qt.DisplayRole)
-        dlg = CookiesExceptionsDialog(self.__cookieJar, self)
-        dlg.setDomainName(domain)
-        dlg.exec_()
+        if not current.text(1):
+            # it is a cookie domain entry
+            self.domain.setText(self.tr("<no cookie selected>"))
+            self.name.setText(self.tr("<no cookie selected>"))
+            self.path.setText(self.tr("<no cookie selected>"))
+            self.secure.setText(self.tr("<no cookie selected>"))
+            self.expiration.setText(self.tr("<no cookie selected>"))
+            self.value.setText(self.tr("<no cookie selected>"))
+            
+            self.removeButton.setText(self.tr("Remove Cookies"))
+        else:
+            # it is a cookie entry
+            cookie = current.data(0, self.CookieRole)
+            
+            self.domain.setText(cookie.domain())
+            self.name.setText(bytes(cookie.name()).decode())
+            self.path.setText(cookie.path())
+            if cookie.isSecure():
+                self.secure.setText(self.tr("Secure connections only"))
+            else:
+                self.secure.setText(self.tr("All connections"))
+            if cookie.isSessionCookie():
+                self.expiration.setText(self.tr("Session Cookie"))
+            else:
+                self.expiration.setText(
+                    cookie.expirationDate().toString("yyyy-MM-dd HH:mm:ss"))
+            self.value.setText(
+                bytes(QByteArray.fromPercentEncoding(cookie.value())).decode())
+            
+            self.removeButton.setText(self.tr("Remove Cookie"))
     
-    def __tableSelectionChanged(self, selected, deselected):
+    @pyqtSlot(str)
+    def on_searchEdit_textChanged(self, txt):
         """
-        Private slot to handle a change of selected items.
+        Private slot to search and filter the cookie tree.
         
-        @param selected selected indexes (QItemSelection)
-        @param deselected deselected indexes (QItemSelection)
+        @param txt text to search for
+        @type str
         """
-        self.addButton.setEnabled(len(selected.indexes()) > 0)
-    
-    def __tableModelReset(self):
-        """
-        Private slot to handle a reset of the cookies table.
-        """
-        self.addButton.setEnabled(False)
+        if not txt:
+            for row in range(self.cookiesTree.topLevelItemCount()):
+                self.cookiesTree.topLevelItem(row).setHidden(False)
+        else:
+            for row in range(self.cookiesTree.topLevelItemCount()):
+                text = self.cookiesTree.topLevelItem(row).text(0)
+                self.cookiesTree.topLevelItem(row).setHidden(txt not in text)
--- a/WebBrowser/CookieJar/CookiesDialog.ui	Sun Jul 10 16:40:17 2016 +0200
+++ b/WebBrowser/CookieJar/CookiesDialog.ui	Sun Jul 10 19:41:24 2016 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>500</width>
-    <height>350</height>
+    <height>480</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -16,8 +16,8 @@
   <property name="sizeGripEnabled">
    <bool>true</bool>
   </property>
-  <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0" colspan="4">
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <spacer name="horizontalSpacer">
@@ -48,84 +48,248 @@
          <property name="toolTip">
           <string>Enter search term for cookies</string>
          </property>
+         <property name="placeholderText">
+          <string>Search</string>
+         </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </item>
-   <item row="1" column="0" colspan="4">
-    <widget class="E5TableView" name="cookiesTable">
+   <item>
+    <widget class="QTreeWidget" name="cookiesTree">
      <property name="alternatingRowColors">
       <bool>true</bool>
      </property>
-     <property name="selectionBehavior">
-      <enum>QAbstractItemView::SelectRows</enum>
-     </property>
-     <property name="textElideMode">
-      <enum>Qt::ElideMiddle</enum>
-     </property>
-     <property name="showGrid">
-      <bool>false</bool>
-     </property>
      <property name="sortingEnabled">
       <bool>true</bool>
      </property>
-    </widget>
-   </item>
-   <item row="2" column="0">
-    <widget class="QPushButton" name="removeButton">
-     <property name="toolTip">
-      <string>Press to remove the selected entries</string>
-     </property>
-     <property name="text">
-      <string>&amp;Remove</string>
-     </property>
-     <property name="autoDefault">
-      <bool>false</bool>
+     <property name="allColumnsShowFocus">
+      <bool>true</bool>
      </property>
-    </widget>
-   </item>
-   <item row="2" column="1">
-    <widget class="QPushButton" name="removeAllButton">
-     <property name="toolTip">
-      <string>Press to remove all entries</string>
-     </property>
-     <property name="text">
-      <string>Remove &amp;All</string>
-     </property>
-     <property name="autoDefault">
-      <bool>false</bool>
-     </property>
+     <column>
+      <property name="text">
+       <string>Server</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Cookie Name</string>
+      </property>
+     </column>
     </widget>
    </item>
-   <item row="2" column="2">
-    <widget class="QPushButton" name="addButton">
-     <property name="toolTip">
-      <string>Press to open the cookies exceptions dialog to add a new rule</string>
+   <item>
+    <widget class="QFrame" name="frame">
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
      </property>
-     <property name="text">
-      <string>Add R&amp;ule...</string>
-     </property>
-     <property name="autoDefault">
-      <bool>false</bool>
-     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Domain:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="E5SqueezeLabel" name="domain">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Name:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="E5SqueezeLabel" name="name">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Path:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="E5SqueezeLabel" name="path">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>Secure:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="E5SqueezeLabel" name="secure">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>Expiration:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="E5SqueezeLabel" name="expiration">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>Value:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="E5SqueezeLabel" name="value">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>&lt;no cookie selected&gt;</string>
+        </property>
+        <property name="wordWrap">
+         <bool>true</bool>
+        </property>
+        <property name="textInteractionFlags">
+         <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
-   <item row="2" column="3">
-    <spacer name="horizontalSpacer_2">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>208</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QPushButton" name="removeButton">
+       <property name="toolTip">
+        <string>Press to remove the selected entries</string>
+       </property>
+       <property name="text">
+        <string>&amp;Remove</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="removeAllButton">
+       <property name="toolTip">
+        <string>Press to remove all entries</string>
+       </property>
+       <property name="text">
+        <string>Remove &amp;All</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="addButton">
+       <property name="toolTip">
+        <string>Press to open the cookies exceptions dialog to add a new rule</string>
+       </property>
+       <property name="text">
+        <string>Add R&amp;ule...</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>208</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
    </item>
-   <item row="3" column="0" colspan="4">
+   <item>
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
@@ -144,18 +308,17 @@
    <header>E5Gui/E5LineEdit.h</header>
   </customwidget>
   <customwidget>
-   <class>E5TableView</class>
-   <extends>QTableView</extends>
-   <header>E5Gui/E5TableView.h</header>
+   <class>E5SqueezeLabel</class>
+   <extends>QLabel</extends>
+   <header>E5Gui/E5SqueezeLabels.h</header>
   </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>searchEdit</tabstop>
-  <tabstop>cookiesTable</tabstop>
+  <tabstop>cookiesTree</tabstop>
   <tabstop>removeButton</tabstop>
   <tabstop>removeAllButton</tabstop>
   <tabstop>addButton</tabstop>
-  <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources/>
  <connections>

eric ide

mercurial