1049 dlg = AddBookmarkDialog() |
1060 dlg = AddBookmarkDialog() |
1050 dlg.setUrl(bytes(self.url().toEncoded()).decode()) |
1061 dlg.setUrl(bytes(self.url().toEncoded()).decode()) |
1051 dlg.setTitle(self.title()) |
1062 dlg.setTitle(self.title()) |
1052 dlg.exec_() |
1063 dlg.exec_() |
1053 |
1064 |
|
1065 def dragEnterEvent(self, evt): |
|
1066 """ |
|
1067 Protected method called by a drag enter event. |
|
1068 |
|
1069 @param evt reference to the drag enter event (QDragEnterEvent) |
|
1070 """ |
|
1071 evt.acceptProposedAction() |
|
1072 |
|
1073 def dragMoveEvent(self, evt): |
|
1074 """ |
|
1075 Protected method called by a drag move event. |
|
1076 |
|
1077 @param evt reference to the drag move event (QDragMoveEvent) |
|
1078 """ |
|
1079 evt.ignore() |
|
1080 if evt.source() != self: |
|
1081 if len(evt.mimeData().urls()) > 0: |
|
1082 evt.acceptProposedAction() |
|
1083 else: |
|
1084 url = QUrl(evt.mimeData().text()) |
|
1085 if url.isValid(): |
|
1086 evt.acceptProposedAction() |
|
1087 |
|
1088 if not evt.isAccepted(): |
|
1089 QWebView.dragMoveEvent(self, evt) |
|
1090 |
|
1091 def dropEvent(self, evt): |
|
1092 """ |
|
1093 Protected method called by a drop event. |
|
1094 |
|
1095 @param evt reference to the drop event (QDropEvent) |
|
1096 """ |
|
1097 QWebView.dropEvent(self, evt) |
|
1098 if not evt.isAccepted() and \ |
|
1099 evt.source() != self and \ |
|
1100 evt.possibleActions() & Qt.CopyAction: |
|
1101 url = QUrl() |
|
1102 if len(evt.mimeData().urls()) > 0: |
|
1103 url = evt.mimeData().urls()[0] |
|
1104 if not url.isValid(): |
|
1105 url = QUrl(evt.mimeData().text()) |
|
1106 if url.isValid(): |
|
1107 self.setSource(url) |
|
1108 evt.acceptProposedAction() |
|
1109 |
|
1110 def mousePressEvent(self, evt): |
|
1111 """ |
|
1112 Protected method called by a mouse press event. |
|
1113 |
|
1114 @param evt reference to the mouse event (QMouseEvent) |
|
1115 """ |
|
1116 self.mw.setEventMouseButtons(evt.buttons()) |
|
1117 self.mw.setEventKeyboardModifiers(evt.modifiers()) |
|
1118 |
|
1119 if evt.button() == Qt.XButton1: |
|
1120 self.pageAction(QWebPage.Back).trigger() |
|
1121 elif evt.button() == Qt.XButton2: |
|
1122 self.pageAction(QWebPage.Forward).trigger() |
|
1123 else: |
|
1124 QWebView.mousePressEvent(self, evt) |
|
1125 |
|
1126 def mouseReleaseEvent(self, evt): |
|
1127 """ |
|
1128 Protected method called by a mouse release event. |
|
1129 |
|
1130 @param evt reference to the mouse event (QMouseEvent) |
|
1131 """ |
|
1132 accepted = evt.isAccepted() |
|
1133 self.__page.event(evt) |
|
1134 if not evt.isAccepted() and \ |
|
1135 self.mw.eventMouseButtons() & Qt.MidButton: |
|
1136 url = QUrl(QApplication.clipboard().text(QClipboard.Selection)) |
|
1137 if not url.isEmpty() and \ |
|
1138 url.isValid() and \ |
|
1139 url.scheme() != "": |
|
1140 self.mw.setEventMouseButtons(Qt.NoButton) |
|
1141 self.mw.setEventKeyboardModifiers(Qt.NoModifier) |
|
1142 self.setSource(url) |
|
1143 evt.setAccepted(accepted) |
|
1144 |
1054 def keyPressEvent(self, evt): |
1145 def keyPressEvent(self, evt): |
1055 """ |
1146 """ |
1056 Protected method called by a key press. |
1147 Protected method called by a key press. |
1057 |
1148 |
1058 This method is overridden from QTextBrowser. |
1149 @param evt reference to the key event (QKeyEvent) |
1059 |
1150 """ |
1060 @param evt the key event (QKeyEvent) |
1151 if hasattr(QtWebKit, 'QWebElement'): |
1061 """ |
1152 if self.__enableAccessKeys: |
|
1153 self.__accessKeysPressed = ( |
|
1154 evt.modifiers() == Qt.ControlModifier and \ |
|
1155 evt.key() == Qt.Key_Control) |
|
1156 if not self.__accessKeysPressed: |
|
1157 if self.__checkForAccessKey(evt): |
|
1158 self.__hideAccessKeys() |
|
1159 evt.accept() |
|
1160 return |
|
1161 self.__hideAccessKeys() |
|
1162 else: |
|
1163 QTimer.singleShot(300, self.__accessKeyShortcut) |
|
1164 |
1062 self.ctrlPressed = (evt.key() == Qt.Key_Control) |
1165 self.ctrlPressed = (evt.key() == Qt.Key_Control) |
1063 QWebView.keyPressEvent(self, evt) |
1166 QWebView.keyPressEvent(self, evt) |
1064 |
1167 |
1065 def keyReleaseEvent(self, evt): |
1168 def keyReleaseEvent(self, evt): |
1066 """ |
1169 """ |
1067 Protected method called by a key release. |
1170 Protected method called by a key release. |
1068 |
1171 |
1069 This method is overridden from QTextBrowser. |
1172 @param evt reference to the key event (QKeyEvent) |
1070 |
1173 """ |
1071 @param evt the key event (QKeyEvent) |
1174 if hasattr(QtWebKit, 'QWebElement'): |
1072 """ |
1175 if self.__enableAccessKeys: |
|
1176 self.__accessKeysPressed = evt.key() == Qt.Key_Control |
|
1177 |
1073 self.ctrlPressed = False |
1178 self.ctrlPressed = False |
1074 QWebView.keyReleaseEvent(self, evt) |
1179 QWebView.keyReleaseEvent(self, evt) |
|
1180 |
|
1181 def focusOutEvent(self, evt): |
|
1182 """ |
|
1183 Protected method called by a focus out event. |
|
1184 |
|
1185 @param evt reference to the focus event (QFocusEvent) |
|
1186 """ |
|
1187 if hasattr(QtWebKit, 'QWebElement'): |
|
1188 if self.__accessKeysPressed: |
|
1189 self.__hideAccessKeys() |
|
1190 self.__accessKeysPressed = False |
|
1191 |
|
1192 QWebView.focusOutEvent(self, evt) |
1075 |
1193 |
1076 def clearHistory(self): |
1194 def clearHistory(self): |
1077 """ |
1195 """ |
1078 Public slot to clear the history. |
1196 Public slot to clear the history. |
1079 """ |
1197 """ |
1294 size /= 1024 * 1024 |
1412 size /= 1024 * 1024 |
1295 unit = self.trUtf8("MB") |
1413 unit = self.trUtf8("MB") |
1296 return "{0:.1f} {1}".format(size, unit) |
1414 return "{0:.1f} {1}".format(size, unit) |
1297 |
1415 |
1298 ############################################################################ |
1416 ############################################################################ |
|
1417 ## Access key related methods below |
|
1418 ############################################################################ |
|
1419 |
|
1420 def __accessKeyShortcut(self): |
|
1421 """ |
|
1422 Private slot to switch the display of access keys. |
|
1423 """ |
|
1424 if not self.hasFocus() or \ |
|
1425 not self.__accessKeysPressed or \ |
|
1426 not self.__enableAccessKeys: |
|
1427 return |
|
1428 |
|
1429 if self.__accessKeyLabels: |
|
1430 self.__hideAccessKeys() |
|
1431 else: |
|
1432 self.__showAccessKeys() |
|
1433 |
|
1434 self.__accessKeysPressed = False |
|
1435 |
|
1436 def __checkForAccessKey(self, evt): |
|
1437 """ |
|
1438 Private method to check the existence of an access key and activate the |
|
1439 corresponding link. |
|
1440 |
|
1441 @param evt reference to the key event (QKeyEvent) |
|
1442 @return flag indicating, if the event was handled (boolean) |
|
1443 """ |
|
1444 if not self.__accessKeyLabels: |
|
1445 return False |
|
1446 |
|
1447 text = evt.text() |
|
1448 if not text: |
|
1449 return False |
|
1450 |
|
1451 key = text[0].upper() |
|
1452 handled = False |
|
1453 if key in self.__accessKeyNodes: |
|
1454 element = self.__accessKeyNodes[key] |
|
1455 p = element.geometry().center() |
|
1456 frame = element.webFrame() |
|
1457 p -= frame.scrollPosition() |
|
1458 frame = frame.parentFrame() |
|
1459 while frame and frame != self.page().mainFrame(): |
|
1460 p -= frame.scrollPosition() |
|
1461 frame = frame.parentFrame() |
|
1462 pevent = QMouseEvent(QEvent.MouseButtonPress, p, Qt.LeftButton, |
|
1463 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) |
|
1464 qApp.sendEvent(self, pevent) |
|
1465 revent = QMouseEvent(QEvent.MouseButtonRelease, p, Qt.LeftButton, |
|
1466 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) |
|
1467 qApp.sendEvent(self, revent) |
|
1468 handled = True |
|
1469 |
|
1470 return handled |
|
1471 |
|
1472 def __hideAccessKeys(self): |
|
1473 """ |
|
1474 Private slot to hide the access key labels. |
|
1475 """ |
|
1476 if self.__accessKeyLabels: |
|
1477 for label in self.__accessKeyLabels: |
|
1478 label.hide() |
|
1479 label.deleteLater() |
|
1480 self.__accessKeyLabels = [] |
|
1481 self.__accessKeyNodes = {} |
|
1482 self.update() |
|
1483 |
|
1484 def __showAccessKeys(self): |
|
1485 """ |
|
1486 Private method to show the access key labels. |
|
1487 """ |
|
1488 supportedElements = [ |
|
1489 "input", "a", "area", "button", "label", "legend", "textarea", |
|
1490 ] |
|
1491 unusedKeys = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" \ |
|
1492 " 0 1 2 3 4 5 6 7 8 9".split() |
|
1493 |
|
1494 viewport = QRect(self.__page.mainFrame().scrollPosition(), |
|
1495 self.__page.viewportSize()) |
|
1496 # Priority first goes to elements with accesskey attributes |
|
1497 alreadyLabeled = [] |
|
1498 for elementType in supportedElements: |
|
1499 result = self.page().mainFrame().findAllElements(elementType).toList() |
|
1500 for element in result: |
|
1501 geometry = element.geometry() |
|
1502 if geometry.size().isEmpty() or \ |
|
1503 not viewport.contains(geometry.topLeft()): |
|
1504 continue |
|
1505 |
|
1506 accessKeyAttribute = element.attribute("accesskey").upper() |
|
1507 if not accessKeyAttribute: |
|
1508 continue |
|
1509 |
|
1510 accessKey = "" |
|
1511 i = 0 |
|
1512 while i < len(accessKeyAttribute): |
|
1513 if accessKeyAttribute[i] in unusedKeys: |
|
1514 accessKey = accessKeyAttribute[i] |
|
1515 break |
|
1516 i += 2 |
|
1517 if accessKey == "": |
|
1518 continue |
|
1519 unusedKeys.remove(accessKey) |
|
1520 self.__makeAccessLabel(accessKey, element) |
|
1521 alreadyLabeled.append(element) |
|
1522 |
|
1523 # Pick an access key first from the letters in the text and then from the |
|
1524 # list of unused access keys |
|
1525 for elementType in supportedElements: |
|
1526 result = self.page().mainFrame().findAllElements(elementType).toList() |
|
1527 for element in result: |
|
1528 geometry = element.geometry() |
|
1529 if not unusedKeys or \ |
|
1530 element in alreadyLabeled or \ |
|
1531 geometry.size().isEmpty() or \ |
|
1532 not viewport.contains(geometry.topLeft()): |
|
1533 continue |
|
1534 |
|
1535 accessKey = "" |
|
1536 text = element.toPlainText().upper() |
|
1537 for c in text: |
|
1538 if c in unusedKeys: |
|
1539 accessKey = c |
|
1540 break |
|
1541 if accessKey == "": |
|
1542 accessKey = unusedKeys[0] |
|
1543 unusedKeys.remove(accessKey) |
|
1544 self.__makeAccessLabel(accessKey, element) |
|
1545 |
|
1546 def __makeAccessLabel(self, accessKey, element): |
|
1547 """ |
|
1548 Private method to generate the access label for an element. |
|
1549 |
|
1550 @param accessKey access key to generate the label for (str) |
|
1551 @param element reference to the web element to create the label for |
|
1552 (QWebElement) |
|
1553 """ |
|
1554 label = QLabel(self) |
|
1555 label.setText("<qt><b>{0}</b></qt>".format(accessKey)) |
|
1556 |
|
1557 p = QToolTip.palette() |
|
1558 color = QColor(Qt.yellow).lighter(150) |
|
1559 color.setAlpha(175) |
|
1560 p.setColor(QPalette.Window, color) |
|
1561 label.setPalette(p) |
|
1562 label.setAutoFillBackground(True) |
|
1563 label.setFrameStyle(QFrame.Box | QFrame.Plain) |
|
1564 point = element.geometry().center() |
|
1565 point -= self.__page.mainFrame().scrollPosition() |
|
1566 label.move(point) |
|
1567 label.show() |
|
1568 point.setX(point.x() - label.width() // 2) |
|
1569 label.move(point) |
|
1570 self.__accessKeyLabels.append(label) |
|
1571 self.__accessKeyNodes[accessKey] = element |
|
1572 |
|
1573 ############################################################################ |
1299 ## Miscellaneous methods below |
1574 ## Miscellaneous methods below |
1300 ############################################################################ |
1575 ############################################################################ |
1301 |
1576 |
1302 def createWindow(self, windowType): |
1577 def createWindow(self, windowType): |
1303 """ |
1578 """ |