eric6/Helpviewer/PersonalInformationManager/PersonalInformationManager.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2012 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a personal information manager used to complete form
8 fields.
9 """
10
11 from __future__ import unicode_literals
12
13 from PyQt5.QtCore import Qt, QObject
14 from PyQt5.QtWidgets import QDialog, QMenu
15
16 import Preferences
17 import UI.PixmapCache
18
19
20 class PersonalInformationManager(QObject):
21 """
22 Class implementing the personal information manager used to complete form
23 fields.
24 """
25 FullName = 0
26 LastName = 1
27 FirstName = 2
28 Email = 3
29 Mobile = 4
30 Phone = 5
31 Address = 6
32 City = 7
33 Zip = 8
34 State = 9
35 Country = 10
36 HomePage = 11
37 Special1 = 12
38 Special2 = 13
39 Special3 = 14
40 Special4 = 15
41 Max = 16
42 Invalid = 256
43
44 def __init__(self, parent=None):
45 """
46 Constructor
47
48 @param parent reference to the parent object (QObject)
49 """
50 super(PersonalInformationManager, self).__init__(parent)
51
52 self.__loaded = False
53 self.__allInfo = {}
54 self.__infoMatches = {}
55 self.__translations = {}
56
57 self.__view = None
58 self.__element = None
59
60 def __loadSettings(self):
61 """
62 Private method to load the settings.
63 """
64 self.__allInfo[self.FullName] = Preferences.getHelp("PimFullName")
65 self.__allInfo[self.LastName] = Preferences.getHelp("PimLastName")
66 self.__allInfo[self.FirstName] = Preferences.getHelp("PimFirstName")
67 self.__allInfo[self.Email] = Preferences.getHelp("PimEmail")
68 self.__allInfo[self.Mobile] = Preferences.getHelp("PimMobile")
69 self.__allInfo[self.Phone] = Preferences.getHelp("PimPhone")
70 self.__allInfo[self.Address] = Preferences.getHelp("PimAddress")
71 self.__allInfo[self.City] = Preferences.getHelp("PimCity")
72 self.__allInfo[self.Zip] = Preferences.getHelp("PimZip")
73 self.__allInfo[self.State] = Preferences.getHelp("PimState")
74 self.__allInfo[self.Country] = Preferences.getHelp("PimCountry")
75 self.__allInfo[self.HomePage] = Preferences.getHelp("PimHomePage")
76 self.__allInfo[self.Special1] = Preferences.getHelp("PimSpecial1")
77 self.__allInfo[self.Special2] = Preferences.getHelp("PimSpecial2")
78 self.__allInfo[self.Special3] = Preferences.getHelp("PimSpecial3")
79 self.__allInfo[self.Special4] = Preferences.getHelp("PimSpecial4")
80
81 self.__translations[self.FullName] = self.tr("Full Name")
82 self.__translations[self.LastName] = self.tr("Last Name")
83 self.__translations[self.FirstName] = self.tr("First Name")
84 self.__translations[self.Email] = self.tr("E-mail")
85 self.__translations[self.Mobile] = self.tr("Mobile")
86 self.__translations[self.Phone] = self.tr("Phone")
87 self.__translations[self.Address] = self.tr("Address")
88 self.__translations[self.City] = self.tr("City")
89 self.__translations[self.Zip] = self.tr("ZIP Code")
90 self.__translations[self.State] = self.tr("State/Region")
91 self.__translations[self.Country] = self.tr("Country")
92 self.__translations[self.HomePage] = self.tr("Home Page")
93 self.__translations[self.Special1] = self.tr("Custom 1")
94 self.__translations[self.Special2] = self.tr("Custom 2")
95 self.__translations[self.Special3] = self.tr("Custom 3")
96 self.__translations[self.Special4] = self.tr("Custom 4")
97
98 self.__infoMatches[self.FullName] = ["fullname", "realname"]
99 self.__infoMatches[self.LastName] = ["lastname", "surname"]
100 self.__infoMatches[self.FirstName] = ["firstname", "name"]
101 self.__infoMatches[self.Email] = ["email", "e-mail", "mail"]
102 self.__infoMatches[self.Mobile] = ["mobile", "mobilephone"]
103 self.__infoMatches[self.Phone] = ["phone", "telephone"]
104 self.__infoMatches[self.Address] = ["address"]
105 self.__infoMatches[self.City] = ["city"]
106 self.__infoMatches[self.Zip] = ["zip"]
107 self.__infoMatches[self.State] = ["state", "region"]
108 self.__infoMatches[self.Country] = ["country"]
109 self.__infoMatches[self.HomePage] = ["homepage", "www"]
110
111 self.__loaded = True
112
113 def showConfigurationDialog(self):
114 """
115 Public method to show the configuration dialog.
116 """
117 from .PersonalDataDialog import PersonalDataDialog
118 dlg = PersonalDataDialog()
119 if dlg.exec_() == QDialog.Accepted:
120 dlg.storeData()
121 self.__loadSettings()
122
123 def createSubMenu(self, menu, view, hitTestResult):
124 """
125 Public method to create the personal information sub-menu.
126
127 @param menu reference to the main menu (QMenu)
128 @param view reference to the view (HelpBrowser)
129 @param hitTestResult reference to the hit test result
130 (QWebHitTestResult)
131 """
132 self.__view = view
133 self.__element = hitTestResult.element()
134
135 if not hitTestResult.isContentEditable():
136 return
137
138 if not self.__loaded:
139 self.__loadSettings()
140
141 submenu = QMenu(self.tr("Insert Personal Information"), menu)
142 submenu.setIcon(UI.PixmapCache.getIcon("pim.png"))
143
144 for key, info in sorted(self.__allInfo.items()):
145 if info:
146 act = submenu.addAction(self.__translations[key])
147 act.setData(info)
148 act.triggered.connect(lambda: self.__insertData(act))
149
150 submenu.addSeparator()
151 submenu.addAction(self.tr("Edit Personal Information"),
152 self.showConfigurationDialog)
153
154 menu.addMenu(submenu)
155 menu.addSeparator()
156
157 def __insertData(self, act):
158 """
159 Private slot to insert the selected personal information.
160
161 @param act reference to the action that triggered
162 @type QAction
163 """
164 if not self.__element or self.__element.isNull():
165 return
166
167 info = act.data()
168 info = info.replace('"', '\\"')
169 self.__element.evaluateJavaScript(
170 'var newVal = this.value.substring(0, this.selectionStart) +'
171 ' "{0}" + this.value.substring(this.selectionEnd); this.value ='
172 ' newVal;'.format(info))
173
174 def viewKeyPressEvent(self, view, evt):
175 """
176 Protected method to handle key press events we are interested in.
177
178 @param view reference to the view (HelpBrowser)
179 @param evt reference to the key event (QKeyEvent)
180 @return flag indicating handling of the event (boolean)
181 """
182 if view is None:
183 return False
184
185 isEnter = evt.key() in [Qt.Key_Return, Qt.Key_Enter]
186 if not isEnter or evt.modifiers() != Qt.ControlModifier:
187 return False
188
189 if not self.__loaded:
190 self.__loadSettings()
191
192 document = view.page().mainFrame().documentElement()
193 elements = document.findAll('input[type="text"]')
194
195 for element in elements:
196 name = element.attribute("name")
197 if name == "":
198 continue
199
200 match = self.__nameMatch(name)
201 if match != self.Invalid:
202 element.evaluateJavaScript(
203 'this.value = "{0}"'.format(self.__allInfo[match]))
204
205 return True
206
207 def __nameMatch(self, name):
208 """
209 Private method to find the information entry for the given field.
210
211 @param name name of the form field (string)
212 @return value of the information entry (integer)
213 """
214 for index in range(self.Max):
215 if self.__allInfo[index]:
216 for n in self.__infoMatches[index]:
217 if name == n or n in name:
218 return index
219
220 return self.Invalid
221
222 def connectPage(self, page):
223 """
224 Public method to allow the personal information manager to connect to
225 the page.
226
227 @param page reference to the web page (HelpWebPage)
228 """
229 page.loadFinished.connect(lambda ok: self.__pageLoadFinished(ok, page))
230
231 def __pageLoadFinished(self, ok, page):
232 """
233 Private slot to handle the completion of a page load.
234
235 @param ok flag indicating a successful load
236 @type bool
237 @param page reference to the web page object
238 @type HelpWebPage
239 """
240 if page is None or not ok:
241 return
242
243 if not self.__loaded:
244 self.__loadSettings()
245
246 document = page.mainFrame().documentElement()
247 elements = document.findAll('input[type="text"]')
248
249 for element in elements:
250 name = element.attribute("name")
251 if name == "":
252 continue
253
254 match = self.__nameMatch(name)
255 if match != self.Invalid:
256 element.setStyleProperty(
257 "-webkit-appearance", "none")
258 element.setStyleProperty(
259 "-webkit-box-shadow", "inset 0 0 2px 1px #0000EE")

eric ide

mercurial