40 Special2 = 13 |
41 Special2 = 13 |
41 Special3 = 14 |
42 Special3 = 14 |
42 Special4 = 15 |
43 Special4 = 15 |
43 Max = 16 |
44 Max = 16 |
44 Invalid = 256 |
45 Invalid = 256 |
45 |
46 |
46 def __init__(self, parent=None): |
47 def __init__(self, parent=None): |
47 """ |
48 """ |
48 Constructor |
49 Constructor |
49 |
50 |
50 @param parent reference to the parent object (QObject) |
51 @param parent reference to the parent object (QObject) |
51 """ |
52 """ |
52 super().__init__(parent) |
53 super().__init__(parent) |
53 |
54 |
54 self.__loaded = False |
55 self.__loaded = False |
55 self.__allInfo = {} |
56 self.__allInfo = {} |
56 self.__infoMatches = {} |
57 self.__infoMatches = {} |
57 self.__translations = {} |
58 self.__translations = {} |
58 |
59 |
59 self.__view = None |
60 self.__view = None |
60 self.__clickedPos = QPoint() |
61 self.__clickedPos = QPoint() |
61 |
62 |
62 def __loadSettings(self): |
63 def __loadSettings(self): |
63 """ |
64 """ |
64 Private method to load the settings. |
65 Private method to load the settings. |
65 """ |
66 """ |
66 self.__allInfo[self.FullName] = Preferences.getWebBrowser( |
67 self.__allInfo[self.FullName] = Preferences.getWebBrowser("PimFullName") |
67 "PimFullName") |
68 self.__allInfo[self.LastName] = Preferences.getWebBrowser("PimLastName") |
68 self.__allInfo[self.LastName] = Preferences.getWebBrowser( |
69 self.__allInfo[self.FirstName] = Preferences.getWebBrowser("PimFirstName") |
69 "PimLastName") |
|
70 self.__allInfo[self.FirstName] = Preferences.getWebBrowser( |
|
71 "PimFirstName") |
|
72 self.__allInfo[self.Email] = Preferences.getWebBrowser("PimEmail") |
70 self.__allInfo[self.Email] = Preferences.getWebBrowser("PimEmail") |
73 self.__allInfo[self.Mobile] = Preferences.getWebBrowser("PimMobile") |
71 self.__allInfo[self.Mobile] = Preferences.getWebBrowser("PimMobile") |
74 self.__allInfo[self.Phone] = Preferences.getWebBrowser("PimPhone") |
72 self.__allInfo[self.Phone] = Preferences.getWebBrowser("PimPhone") |
75 self.__allInfo[self.Address] = Preferences.getWebBrowser("PimAddress") |
73 self.__allInfo[self.Address] = Preferences.getWebBrowser("PimAddress") |
76 self.__allInfo[self.City] = Preferences.getWebBrowser("PimCity") |
74 self.__allInfo[self.City] = Preferences.getWebBrowser("PimCity") |
77 self.__allInfo[self.Zip] = Preferences.getWebBrowser("PimZip") |
75 self.__allInfo[self.Zip] = Preferences.getWebBrowser("PimZip") |
78 self.__allInfo[self.State] = Preferences.getWebBrowser("PimState") |
76 self.__allInfo[self.State] = Preferences.getWebBrowser("PimState") |
79 self.__allInfo[self.Country] = Preferences.getWebBrowser("PimCountry") |
77 self.__allInfo[self.Country] = Preferences.getWebBrowser("PimCountry") |
80 self.__allInfo[self.HomePage] = Preferences.getWebBrowser( |
78 self.__allInfo[self.HomePage] = Preferences.getWebBrowser("PimHomePage") |
81 "PimHomePage") |
79 self.__allInfo[self.Special1] = Preferences.getWebBrowser("PimSpecial1") |
82 self.__allInfo[self.Special1] = Preferences.getWebBrowser( |
80 self.__allInfo[self.Special2] = Preferences.getWebBrowser("PimSpecial2") |
83 "PimSpecial1") |
81 self.__allInfo[self.Special3] = Preferences.getWebBrowser("PimSpecial3") |
84 self.__allInfo[self.Special2] = Preferences.getWebBrowser( |
82 self.__allInfo[self.Special4] = Preferences.getWebBrowser("PimSpecial4") |
85 "PimSpecial2") |
83 |
86 self.__allInfo[self.Special3] = Preferences.getWebBrowser( |
|
87 "PimSpecial3") |
|
88 self.__allInfo[self.Special4] = Preferences.getWebBrowser( |
|
89 "PimSpecial4") |
|
90 |
|
91 self.__translations[self.FullName] = self.tr("Full Name") |
84 self.__translations[self.FullName] = self.tr("Full Name") |
92 self.__translations[self.LastName] = self.tr("Last Name") |
85 self.__translations[self.LastName] = self.tr("Last Name") |
93 self.__translations[self.FirstName] = self.tr("First Name") |
86 self.__translations[self.FirstName] = self.tr("First Name") |
94 self.__translations[self.Email] = self.tr("E-mail") |
87 self.__translations[self.Email] = self.tr("E-mail") |
95 self.__translations[self.Mobile] = self.tr("Mobile") |
88 self.__translations[self.Mobile] = self.tr("Mobile") |
102 self.__translations[self.HomePage] = self.tr("Home Page") |
95 self.__translations[self.HomePage] = self.tr("Home Page") |
103 self.__translations[self.Special1] = self.tr("Custom 1") |
96 self.__translations[self.Special1] = self.tr("Custom 1") |
104 self.__translations[self.Special2] = self.tr("Custom 2") |
97 self.__translations[self.Special2] = self.tr("Custom 2") |
105 self.__translations[self.Special3] = self.tr("Custom 3") |
98 self.__translations[self.Special3] = self.tr("Custom 3") |
106 self.__translations[self.Special4] = self.tr("Custom 4") |
99 self.__translations[self.Special4] = self.tr("Custom 4") |
107 |
100 |
108 self.__infoMatches[self.FullName] = ["fullname", "realname"] |
101 self.__infoMatches[self.FullName] = ["fullname", "realname"] |
109 self.__infoMatches[self.LastName] = ["lastname", "surname"] |
102 self.__infoMatches[self.LastName] = ["lastname", "surname"] |
110 self.__infoMatches[self.FirstName] = ["firstname", "name"] |
103 self.__infoMatches[self.FirstName] = ["firstname", "name"] |
111 self.__infoMatches[self.Email] = ["email", "e-mail", "mail"] |
104 self.__infoMatches[self.Email] = ["email", "e-mail", "mail"] |
112 self.__infoMatches[self.Mobile] = ["mobile", "mobilephone"] |
105 self.__infoMatches[self.Mobile] = ["mobile", "mobilephone"] |
115 self.__infoMatches[self.City] = ["city"] |
108 self.__infoMatches[self.City] = ["city"] |
116 self.__infoMatches[self.Zip] = ["zip"] |
109 self.__infoMatches[self.Zip] = ["zip"] |
117 self.__infoMatches[self.State] = ["state", "region"] |
110 self.__infoMatches[self.State] = ["state", "region"] |
118 self.__infoMatches[self.Country] = ["country"] |
111 self.__infoMatches[self.Country] = ["country"] |
119 self.__infoMatches[self.HomePage] = ["homepage", "www"] |
112 self.__infoMatches[self.HomePage] = ["homepage", "www"] |
120 |
113 |
121 self.__loaded = True |
114 self.__loaded = True |
122 |
115 |
123 def showConfigurationDialog(self): |
116 def showConfigurationDialog(self): |
124 """ |
117 """ |
125 Public method to show the configuration dialog. |
118 Public method to show the configuration dialog. |
126 """ |
119 """ |
127 from .PersonalDataDialog import PersonalDataDialog |
120 from .PersonalDataDialog import PersonalDataDialog |
|
121 |
128 dlg = PersonalDataDialog() |
122 dlg = PersonalDataDialog() |
129 if dlg.exec() == QDialog.DialogCode.Accepted: |
123 if dlg.exec() == QDialog.DialogCode.Accepted: |
130 dlg.storeData() |
124 dlg.storeData() |
131 self.__loadSettings() |
125 self.__loadSettings() |
132 |
126 |
133 def createSubMenu(self, menu, view, hitTestResult): |
127 def createSubMenu(self, menu, view, hitTestResult): |
134 """ |
128 """ |
135 Public method to create the personal information sub-menu. |
129 Public method to create the personal information sub-menu. |
136 |
130 |
137 @param menu reference to the main menu (QMenu) |
131 @param menu reference to the main menu (QMenu) |
138 @param view reference to the view (HelpBrowser) |
132 @param view reference to the view (HelpBrowser) |
139 @param hitTestResult reference to the hit test result |
133 @param hitTestResult reference to the hit test result |
140 (WebHitTestResult) |
134 (WebHitTestResult) |
141 """ |
135 """ |
142 self.__view = view |
136 self.__view = view |
143 self.__clickedPos = hitTestResult.pos() |
137 self.__clickedPos = hitTestResult.pos() |
144 |
138 |
145 if not hitTestResult.isContentEditable(): |
139 if not hitTestResult.isContentEditable(): |
146 return |
140 return |
147 |
141 |
148 if not self.__loaded: |
142 if not self.__loaded: |
149 self.__loadSettings() |
143 self.__loadSettings() |
150 |
144 |
151 submenu = QMenu(self.tr("Insert Personal Information"), menu) |
145 submenu = QMenu(self.tr("Insert Personal Information"), menu) |
152 submenu.setIcon(UI.PixmapCache.getIcon("pim")) |
146 submenu.setIcon(UI.PixmapCache.getIcon("pim")) |
153 |
147 |
154 for key, info in sorted(self.__allInfo.items()): |
148 for key, info in sorted(self.__allInfo.items()): |
155 if info: |
149 if info: |
156 act = submenu.addAction(self.__translations[key]) |
150 act = submenu.addAction(self.__translations[key]) |
157 act.setData(info) |
151 act.setData(info) |
158 act.triggered.connect( |
152 act.triggered.connect(functools.partial(self.__insertData, act)) |
159 functools.partial(self.__insertData, act)) |
153 |
160 |
|
161 submenu.addSeparator() |
154 submenu.addSeparator() |
162 submenu.addAction(self.tr("Edit Personal Information"), |
155 submenu.addAction( |
163 self.showConfigurationDialog) |
156 self.tr("Edit Personal Information"), self.showConfigurationDialog |
164 |
157 ) |
|
158 |
165 menu.addMenu(submenu) |
159 menu.addMenu(submenu) |
166 menu.addSeparator() |
160 menu.addSeparator() |
167 |
161 |
168 def __insertData(self, act): |
162 def __insertData(self, act): |
169 """ |
163 """ |
170 Private slot to insert the selected personal information. |
164 Private slot to insert the selected personal information. |
171 |
165 |
172 @param act reference to the action that triggered |
166 @param act reference to the action that triggered |
173 @type QAction |
167 @type QAction |
174 """ |
168 """ |
175 if self.__view is None or self.__clickedPos.isNull(): |
169 if self.__view is None or self.__clickedPos.isNull(): |
176 return |
170 return |
177 |
171 |
178 info = act.data() |
172 info = act.data() |
179 info = info.replace('"', '\\"') |
173 info = info.replace('"', '\\"') |
180 |
174 |
181 source = """ |
175 source = """ |
182 var e = document.elementFromPoint({0}, {1}); |
176 var e = document.elementFromPoint({0}, {1}); |
183 if (e) {{ |
177 if (e) {{ |
184 var v = e.value.substring(0, e.selectionStart); |
178 var v = e.value.substring(0, e.selectionStart); |
185 v += "{2}" + e.value.substring(e.selectionEnd); |
179 v += "{2}" + e.value.substring(e.selectionEnd); |
186 e.value = v; |
180 e.value = v; |
187 }}""".format(self.__clickedPos.x(), self.__clickedPos.y(), info) |
181 }}""".format( |
|
182 self.__clickedPos.x(), self.__clickedPos.y(), info |
|
183 ) |
188 self.__view.page().runJavaScript(source, WebBrowserPage.SafeJsWorld) |
184 self.__view.page().runJavaScript(source, WebBrowserPage.SafeJsWorld) |
189 |
185 |
190 def viewKeyPressEvent(self, view, evt): |
186 def viewKeyPressEvent(self, view, evt): |
191 """ |
187 """ |
192 Protected method to handle key press events we are interested in. |
188 Protected method to handle key press events we are interested in. |
193 |
189 |
194 @param view reference to the view (HelpBrowser) |
190 @param view reference to the view (HelpBrowser) |
195 @param evt reference to the key event (QKeyEvent) |
191 @param evt reference to the key event (QKeyEvent) |
196 @return flag indicating handling of the event (boolean) |
192 @return flag indicating handling of the event (boolean) |
197 """ |
193 """ |
198 if view is None: |
194 if view is None: |
199 return False |
195 return False |
200 |
196 |
201 isEnter = evt.key() in [Qt.Key.Key_Return, Qt.Key.Key_Enter] |
197 isEnter = evt.key() in [Qt.Key.Key_Return, Qt.Key.Key_Enter] |
202 isControlModifier = ( |
198 isControlModifier = evt.modifiers() & Qt.KeyboardModifier.ControlModifier |
203 evt.modifiers() & Qt.KeyboardModifier.ControlModifier |
|
204 ) |
|
205 if not isEnter or not isControlModifier: |
199 if not isEnter or not isControlModifier: |
206 return False |
200 return False |
207 |
201 |
208 if not self.__loaded: |
202 if not self.__loaded: |
209 self.__loadSettings() |
203 self.__loadSettings() |
210 |
204 |
211 source = """ |
205 source = """ |
212 var inputs = document.getElementsByTagName('input'); |
206 var inputs = document.getElementsByTagName('input'); |
213 var table = {0}; |
207 var table = {0}; |
214 for (var i = 0; i < inputs.length; ++i) {{ |
208 for (var i = 0; i < inputs.length; ++i) {{ |
215 var input = inputs[i]; |
209 var input = inputs[i]; |
221 if (key == input.name || input.name.indexOf(key) != -1) {{ |
215 if (key == input.name || input.name.indexOf(key) != -1) {{ |
222 input.value = table[key]; |
216 input.value = table[key]; |
223 break; |
217 break; |
224 }} |
218 }} |
225 }} |
219 }} |
226 }}""".format(self.__matchingJsTable()) |
220 }}""".format( |
|
221 self.__matchingJsTable() |
|
222 ) |
227 view.page().runJavaScript(source, WebBrowserPage.SafeJsWorld) |
223 view.page().runJavaScript(source, WebBrowserPage.SafeJsWorld) |
228 |
224 |
229 return True |
225 return True |
230 |
226 |
231 def connectPage(self, page): |
227 def connectPage(self, page): |
232 """ |
228 """ |
233 Public method to allow the personal information manager to connect to |
229 Public method to allow the personal information manager to connect to |
234 the page. |
230 the page. |
235 |
231 |
236 @param page reference to the web page |
232 @param page reference to the web page |
237 @type WebBrowserPage |
233 @type WebBrowserPage |
238 """ |
234 """ |
239 page.loadFinished.connect(lambda ok: self.__pageLoadFinished(ok, page)) |
235 page.loadFinished.connect(lambda ok: self.__pageLoadFinished(ok, page)) |
240 |
236 |
241 def __pageLoadFinished(self, ok, page): |
237 def __pageLoadFinished(self, ok, page): |
242 """ |
238 """ |
243 Private slot to handle the completion of a page load. |
239 Private slot to handle the completion of a page load. |
244 |
240 |
245 @param ok flag indicating a successful load |
241 @param ok flag indicating a successful load |
246 @type bool |
242 @type bool |
247 @param page reference to the web page object |
243 @param page reference to the web page object |
248 @type WebBrowserPage |
244 @type WebBrowserPage |
249 """ |
245 """ |
250 if page is None or not ok: |
246 if page is None or not ok: |
251 return |
247 return |
252 |
248 |
253 if not self.__loaded: |
249 if not self.__loaded: |
254 self.__loadSettings() |
250 self.__loadSettings() |
255 |
251 |
256 source = """ |
252 source = """ |
257 var inputs = document.getElementsByTagName('input'); |
253 var inputs = document.getElementsByTagName('input'); |
258 var table = {0}; |
254 var table = {0}; |
259 for (var i = 0; i < inputs.length; ++i) {{ |
255 for (var i = 0; i < inputs.length; ++i) {{ |
260 var input = inputs[i]; |
256 var input = inputs[i]; |