Sun, 10 Jul 2016 19:41:24 +0200
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>&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 &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&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><no cookie selected></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><no cookie selected></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><no cookie selected></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><no cookie selected></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><no cookie selected></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><no cookie selected></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>&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 &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&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>