Tools/TRPreviewer.py

branch
Py2 comp.
changeset 3484
645c12de6b0c
parent 3178
f25fc1364c88
parent 3345
071afe8be2a1
child 3591
2f2a4a76dd22
equal deleted inserted replaced
3456:96232974dcdb 3484:645c12de6b0c
53 53
54 self.setStyle(Preferences.getUI("Style"), 54 self.setStyle(Preferences.getUI("Style"),
55 Preferences.getUI("StyleSheet")) 55 Preferences.getUI("StyleSheet"))
56 56
57 self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint())) 57 self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint()))
58 self.setAttribute(Qt.WA_DeleteOnClose)
59 self.statusBar() 58 self.statusBar()
60 59
61 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) 60 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
62 self.setWindowTitle(self.trUtf8("Translations Previewer")) 61 self.setWindowTitle(self.tr("Translations Previewer"))
63 62
64 self.cw = QWidget(self) 63 self.cw = QWidget(self)
65 self.cw.setObjectName("qt_central_widget") 64 self.cw.setObjectName("qt_central_widget")
66 65
67 self.TRPreviewerLayout = QVBoxLayout(self.cw) 66 self.TRPreviewerLayout = QVBoxLayout(self.cw)
73 self.languageLayout.setContentsMargins(0, 0, 0, 0) 72 self.languageLayout.setContentsMargins(0, 0, 0, 0)
74 self.languageLayout.setSpacing(6) 73 self.languageLayout.setSpacing(6)
75 self.languageLayout.setObjectName("languageLayout") 74 self.languageLayout.setObjectName("languageLayout")
76 75
77 self.languageLabel = QLabel( 76 self.languageLabel = QLabel(
78 self.trUtf8("Select language file"), self.cw) 77 self.tr("Select language file"), self.cw)
79 self.languageLabel.setObjectName("languageLabel") 78 self.languageLabel.setObjectName("languageLabel")
80 self.languageLayout.addWidget(self.languageLabel) 79 self.languageLayout.addWidget(self.languageLabel)
81 80
82 self.languageCombo = QComboBox(self.cw) 81 self.languageCombo = QComboBox(self.cw)
83 self.languageCombo.setObjectName("languageCombo") 82 self.languageCombo.setObjectName("languageCombo")
84 self.languageCombo.setEditable(False) 83 self.languageCombo.setEditable(False)
85 self.languageCombo.setToolTip(self.trUtf8("Select language file")) 84 self.languageCombo.setToolTip(self.tr("Select language file"))
86 self.languageCombo.setSizePolicy( 85 self.languageCombo.setSizePolicy(
87 QSizePolicy.Expanding, QSizePolicy.Preferred) 86 QSizePolicy.Expanding, QSizePolicy.Preferred)
88 self.languageLayout.addWidget(self.languageCombo) 87 self.languageLayout.addWidget(self.languageCombo)
89 88
90 languageSpacer = QSpacerItem( 89 languageSpacer = QSpacerItem(
157 """ 156 """
158 Private method to define the user interface actions. 157 Private method to define the user interface actions.
159 """ 158 """
160 self.openUIAct = QAction( 159 self.openUIAct = QAction(
161 UI.PixmapCache.getIcon("openUI.png"), 160 UI.PixmapCache.getIcon("openUI.png"),
162 self.trUtf8('&Open UI Files...'), self) 161 self.tr('&Open UI Files...'), self)
163 self.openUIAct.setStatusTip(self.trUtf8('Open UI files for display')) 162 self.openUIAct.setStatusTip(self.tr('Open UI files for display'))
164 self.openUIAct.setWhatsThis(self.trUtf8( 163 self.openUIAct.setWhatsThis(self.tr(
165 """<b>Open UI Files</b>""" 164 """<b>Open UI Files</b>"""
166 """<p>This opens some UI files for display.</p>""" 165 """<p>This opens some UI files for display.</p>"""
167 )) 166 ))
168 self.openUIAct.triggered[()].connect(self.__openWidget) 167 self.openUIAct.triggered.connect(self.__openWidget)
169 168
170 self.openQMAct = QAction( 169 self.openQMAct = QAction(
171 UI.PixmapCache.getIcon("openQM.png"), 170 UI.PixmapCache.getIcon("openQM.png"),
172 self.trUtf8('Open &Translation Files...'), self) 171 self.tr('Open &Translation Files...'), self)
173 self.openQMAct.setStatusTip(self.trUtf8( 172 self.openQMAct.setStatusTip(self.tr(
174 'Open Translation files for display')) 173 'Open Translation files for display'))
175 self.openQMAct.setWhatsThis(self.trUtf8( 174 self.openQMAct.setWhatsThis(self.tr(
176 """<b>Open Translation Files</b>""" 175 """<b>Open Translation Files</b>"""
177 """<p>This opens some translation files for display.</p>""" 176 """<p>This opens some translation files for display.</p>"""
178 )) 177 ))
179 self.openQMAct.triggered[()].connect(self.__openTranslation) 178 self.openQMAct.triggered.connect(self.__openTranslation)
180 179
181 self.reloadAct = QAction( 180 self.reloadAct = QAction(
182 UI.PixmapCache.getIcon("reload.png"), 181 UI.PixmapCache.getIcon("reload.png"),
183 self.trUtf8('&Reload Translations'), self) 182 self.tr('&Reload Translations'), self)
184 self.reloadAct.setStatusTip(self.trUtf8( 183 self.reloadAct.setStatusTip(self.tr(
185 'Reload the loaded translations')) 184 'Reload the loaded translations'))
186 self.reloadAct.setWhatsThis(self.trUtf8( 185 self.reloadAct.setWhatsThis(self.tr(
187 """<b>Reload Translations</b>""" 186 """<b>Reload Translations</b>"""
188 """<p>This reloads the translations for the loaded""" 187 """<p>This reloads the translations for the loaded"""
189 """ languages.</p>""" 188 """ languages.</p>"""
190 )) 189 ))
191 self.reloadAct.triggered[()].connect(self.translations.reload) 190 self.reloadAct.triggered.connect(self.translations.reload)
192 191
193 self.exitAct = QAction( 192 self.exitAct = QAction(
194 UI.PixmapCache.getIcon("exit.png"), self.trUtf8('&Quit'), self) 193 UI.PixmapCache.getIcon("exit.png"), self.tr('&Quit'), self)
195 self.exitAct.setShortcut(QKeySequence( 194 self.exitAct.setShortcut(QKeySequence(
196 self.trUtf8("Ctrl+Q", "File|Quit"))) 195 self.tr("Ctrl+Q", "File|Quit")))
197 self.exitAct.setStatusTip(self.trUtf8('Quit the application')) 196 self.exitAct.setStatusTip(self.tr('Quit the application'))
198 self.exitAct.setWhatsThis(self.trUtf8( 197 self.exitAct.setWhatsThis(self.tr(
199 """<b>Quit</b>""" 198 """<b>Quit</b>"""
200 """<p>Quit the application.</p>""" 199 """<p>Quit the application.</p>"""
201 )) 200 ))
202 self.exitAct.triggered[()].connect(qApp.closeAllWindows) 201 self.exitAct.triggered.connect(qApp.closeAllWindows)
203 202
204 self.whatsThisAct = QAction( 203 self.whatsThisAct = QAction(
205 UI.PixmapCache.getIcon("whatsThis.png"), 204 UI.PixmapCache.getIcon("whatsThis.png"),
206 self.trUtf8('&What\'s This?'), self) 205 self.tr('&What\'s This?'), self)
207 self.whatsThisAct.setShortcut(QKeySequence(self.trUtf8("Shift+F1"))) 206 self.whatsThisAct.setShortcut(QKeySequence(self.tr("Shift+F1")))
208 self.whatsThisAct.setStatusTip(self.trUtf8('Context sensitive help')) 207 self.whatsThisAct.setStatusTip(self.tr('Context sensitive help'))
209 self.whatsThisAct.setWhatsThis(self.trUtf8( 208 self.whatsThisAct.setWhatsThis(self.tr(
210 """<b>Display context sensitive help</b>""" 209 """<b>Display context sensitive help</b>"""
211 """<p>In What's This? mode, the mouse cursor shows an arrow""" 210 """<p>In What's This? mode, the mouse cursor shows an arrow"""
212 """ with a question mark, and you can click on the interface""" 211 """ with a question mark, and you can click on the interface"""
213 """ elements to get a short description of what they do and""" 212 """ elements to get a short description of what they do and"""
214 """ how to use them. In dialogs, this feature can be accessed""" 213 """ how to use them. In dialogs, this feature can be accessed"""
215 """ using the context help button in the titlebar.</p>""" 214 """ using the context help button in the titlebar.</p>"""
216 )) 215 ))
217 self.whatsThisAct.triggered[()].connect(self.__whatsThis) 216 self.whatsThisAct.triggered.connect(self.__whatsThis)
218 217
219 self.aboutAct = QAction(self.trUtf8('&About'), self) 218 self.aboutAct = QAction(self.tr('&About'), self)
220 self.aboutAct.setStatusTip(self.trUtf8( 219 self.aboutAct.setStatusTip(self.tr(
221 'Display information about this software')) 220 'Display information about this software'))
222 self.aboutAct.setWhatsThis(self.trUtf8( 221 self.aboutAct.setWhatsThis(self.tr(
223 """<b>About</b>""" 222 """<b>About</b>"""
224 """<p>Display some information about this software.</p>""" 223 """<p>Display some information about this software.</p>"""
225 )) 224 ))
226 self.aboutAct.triggered[()].connect(self.__about) 225 self.aboutAct.triggered.connect(self.__about)
227 226
228 self.aboutQtAct = QAction(self.trUtf8('About &Qt'), self) 227 self.aboutQtAct = QAction(self.tr('About &Qt'), self)
229 self.aboutQtAct.setStatusTip( 228 self.aboutQtAct.setStatusTip(
230 self.trUtf8('Display information about the Qt toolkit')) 229 self.tr('Display information about the Qt toolkit'))
231 self.aboutQtAct.setWhatsThis(self.trUtf8( 230 self.aboutQtAct.setWhatsThis(self.tr(
232 """<b>About Qt</b>""" 231 """<b>About Qt</b>"""
233 """<p>Display some information about the Qt toolkit.</p>""" 232 """<p>Display some information about the Qt toolkit.</p>"""
234 )) 233 ))
235 self.aboutQtAct.triggered[()].connect(self.__aboutQt) 234 self.aboutQtAct.triggered.connect(self.__aboutQt)
236 235
237 self.tileAct = QAction(self.trUtf8('&Tile'), self) 236 self.tileAct = QAction(self.tr('&Tile'), self)
238 self.tileAct.setStatusTip(self.trUtf8('Tile the windows')) 237 self.tileAct.setStatusTip(self.tr('Tile the windows'))
239 self.tileAct.setWhatsThis(self.trUtf8( 238 self.tileAct.setWhatsThis(self.tr(
240 """<b>Tile the windows</b>""" 239 """<b>Tile the windows</b>"""
241 """<p>Rearrange and resize the windows so that they are""" 240 """<p>Rearrange and resize the windows so that they are"""
242 """ tiled.</p>""" 241 """ tiled.</p>"""
243 )) 242 ))
244 self.tileAct.triggered[()].connect(self.preview.tileSubWindows) 243 self.tileAct.triggered.connect(self.preview.tileSubWindows)
245 244
246 self.cascadeAct = QAction(self.trUtf8('&Cascade'), self) 245 self.cascadeAct = QAction(self.tr('&Cascade'), self)
247 self.cascadeAct.setStatusTip(self.trUtf8('Cascade the windows')) 246 self.cascadeAct.setStatusTip(self.tr('Cascade the windows'))
248 self.cascadeAct.setWhatsThis(self.trUtf8( 247 self.cascadeAct.setWhatsThis(self.tr(
249 """<b>Cascade the windows</b>""" 248 """<b>Cascade the windows</b>"""
250 """<p>Rearrange and resize the windows so that they are""" 249 """<p>Rearrange and resize the windows so that they are"""
251 """ cascaded.</p>""" 250 """ cascaded.</p>"""
252 )) 251 ))
253 self.cascadeAct.triggered[()].connect(self.preview.cascadeSubWindows) 252 self.cascadeAct.triggered.connect(self.preview.cascadeSubWindows)
254 253
255 self.closeAct = QAction( 254 self.closeAct = QAction(
256 UI.PixmapCache.getIcon("close.png"), self.trUtf8('&Close'), self) 255 UI.PixmapCache.getIcon("close.png"), self.tr('&Close'), self)
257 self.closeAct.setShortcut(QKeySequence(self.trUtf8( 256 self.closeAct.setShortcut(QKeySequence(self.tr(
258 "Ctrl+W", "File|Close"))) 257 "Ctrl+W", "File|Close")))
259 self.closeAct.setStatusTip(self.trUtf8('Close the current window')) 258 self.closeAct.setStatusTip(self.tr('Close the current window'))
260 self.closeAct.setWhatsThis(self.trUtf8( 259 self.closeAct.setWhatsThis(self.tr(
261 """<b>Close Window</b>""" 260 """<b>Close Window</b>"""
262 """<p>Close the current window.</p>""" 261 """<p>Close the current window.</p>"""
263 )) 262 ))
264 self.closeAct.triggered[()].connect(self.preview.closeWidget) 263 self.closeAct.triggered.connect(self.preview.closeWidget)
265 264
266 self.closeAllAct = QAction(self.trUtf8('Clos&e All'), self) 265 self.closeAllAct = QAction(self.tr('Clos&e All'), self)
267 self.closeAllAct.setStatusTip(self.trUtf8('Close all windows')) 266 self.closeAllAct.setStatusTip(self.tr('Close all windows'))
268 self.closeAllAct.setWhatsThis(self.trUtf8( 267 self.closeAllAct.setWhatsThis(self.tr(
269 """<b>Close All Windows</b>""" 268 """<b>Close All Windows</b>"""
270 """<p>Close all windows.</p>""" 269 """<p>Close all windows.</p>"""
271 )) 270 ))
272 self.closeAllAct.triggered[()].connect(self.preview.closeAllWidgets) 271 self.closeAllAct.triggered.connect(self.preview.closeAllWidgets)
273 272
274 def __initMenus(self): 273 def __initMenus(self):
275 """ 274 """
276 Private method to create the menus. 275 Private method to create the menus.
277 """ 276 """
278 mb = self.menuBar() 277 mb = self.menuBar()
279 278
280 menu = mb.addMenu(self.trUtf8('&File')) 279 menu = mb.addMenu(self.tr('&File'))
281 menu.setTearOffEnabled(True) 280 menu.setTearOffEnabled(True)
282 menu.addAction(self.openUIAct) 281 menu.addAction(self.openUIAct)
283 menu.addAction(self.openQMAct) 282 menu.addAction(self.openQMAct)
284 menu.addAction(self.reloadAct) 283 menu.addAction(self.reloadAct)
285 menu.addSeparator() 284 menu.addSeparator()
286 menu.addAction(self.closeAct) 285 menu.addAction(self.closeAct)
287 menu.addAction(self.closeAllAct) 286 menu.addAction(self.closeAllAct)
288 menu.addSeparator() 287 menu.addSeparator()
289 menu.addAction(self.exitAct) 288 menu.addAction(self.exitAct)
290 289
291 self.windowMenu = mb.addMenu(self.trUtf8('&Window')) 290 self.windowMenu = mb.addMenu(self.tr('&Window'))
292 self.windowMenu.setTearOffEnabled(True) 291 self.windowMenu.setTearOffEnabled(True)
293 self.windowMenu.aboutToShow.connect(self.__showWindowMenu) 292 self.windowMenu.aboutToShow.connect(self.__showWindowMenu)
294 self.windowMenu.triggered.connect(self.preview.toggleSelectedWidget) 293 self.windowMenu.triggered.connect(self.preview.toggleSelectedWidget)
295 294
296 mb.addSeparator() 295 mb.addSeparator()
297 296
298 menu = mb.addMenu(self.trUtf8('&Help')) 297 menu = mb.addMenu(self.tr('&Help'))
299 menu.setTearOffEnabled(True) 298 menu.setTearOffEnabled(True)
300 menu.addAction(self.aboutAct) 299 menu.addAction(self.aboutAct)
301 menu.addAction(self.aboutQtAct) 300 menu.addAction(self.aboutQtAct)
302 menu.addSeparator() 301 menu.addSeparator()
303 menu.addAction(self.whatsThisAct) 302 menu.addAction(self.whatsThisAct)
304 303
305 def __initToolbars(self): 304 def __initToolbars(self):
306 """ 305 """
307 Private method to create the toolbars. 306 Private method to create the toolbars.
308 """ 307 """
309 filetb = self.addToolBar(self.trUtf8("File")) 308 filetb = self.addToolBar(self.tr("File"))
310 filetb.setIconSize(UI.Config.ToolBarIconSize) 309 filetb.setIconSize(UI.Config.ToolBarIconSize)
311 filetb.addAction(self.openUIAct) 310 filetb.addAction(self.openUIAct)
312 filetb.addAction(self.openQMAct) 311 filetb.addAction(self.openQMAct)
313 filetb.addAction(self.reloadAct) 312 filetb.addAction(self.reloadAct)
314 filetb.addSeparator() 313 filetb.addSeparator()
315 filetb.addAction(self.closeAct) 314 filetb.addAction(self.closeAct)
316 filetb.addSeparator() 315 filetb.addSeparator()
317 filetb.addAction(self.exitAct) 316 filetb.addAction(self.exitAct)
318 317
319 helptb = self.addToolBar(self.trUtf8("Help")) 318 helptb = self.addToolBar(self.tr("Help"))
320 helptb.setIconSize(UI.Config.ToolBarIconSize) 319 helptb.setIconSize(UI.Config.ToolBarIconSize)
321 helptb.addAction(self.whatsThisAct) 320 helptb.addAction(self.whatsThisAct)
322 321
323 def __whatsThis(self): 322 def __whatsThis(self):
324 """ 323 """
350 """ 349 """
351 Private slot to show the about information. 350 Private slot to show the about information.
352 """ 351 """
353 E5MessageBox.about( 352 E5MessageBox.about(
354 self, 353 self,
355 self.trUtf8("TR Previewer"), 354 self.tr("TR Previewer"),
356 self.trUtf8( 355 self.tr(
357 """<h3> About TR Previewer </h3>""" 356 """<h3> About TR Previewer </h3>"""
358 """<p>The TR Previewer loads and displays Qt User-Interface""" 357 """<p>The TR Previewer loads and displays Qt User-Interface"""
359 """ files and translation files and shows dialogs for a""" 358 """ files and translation files and shows dialogs for a"""
360 """ selected language.</p>""" 359 """ selected language.</p>"""
361 ) 360 )
363 362
364 def __aboutQt(self): 363 def __aboutQt(self):
365 """ 364 """
366 Private slot to show info about Qt. 365 Private slot to show info about Qt.
367 """ 366 """
368 E5MessageBox.aboutQt(self, self.trUtf8("TR Previewer")) 367 E5MessageBox.aboutQt(self, self.tr("TR Previewer"))
369 368
370 def __openWidget(self): 369 def __openWidget(self):
371 """ 370 """
372 Private slot to handle the Open Dialog action. 371 Private slot to handle the Open Dialog action.
373 """ 372 """
374 fileNameList = E5FileDialog.getOpenFileNames( 373 fileNameList = E5FileDialog.getOpenFileNames(
375 None, 374 None,
376 self.trUtf8("Select UI files"), 375 self.tr("Select UI files"),
377 "", 376 "",
378 self.trUtf8("Qt User-Interface Files (*.ui)")) 377 self.tr("Qt User-Interface Files (*.ui)"))
379 378
380 for fileName in fileNameList: 379 for fileName in fileNameList:
381 self.preview.loadWidget(fileName) 380 self.preview.loadWidget(fileName)
382 381
383 self.__updateActions() 382 self.__updateActions()
386 """ 385 """
387 Private slot to handle the Open Translation action. 386 Private slot to handle the Open Translation action.
388 """ 387 """
389 fileNameList = E5FileDialog.getOpenFileNames( 388 fileNameList = E5FileDialog.getOpenFileNames(
390 None, 389 None,
391 self.trUtf8("Select translation files"), 390 self.tr("Select translation files"),
392 "", 391 "",
393 self.trUtf8("Qt Translation Files (*.qm)")) 392 self.tr("Qt Translation Files (*.qm)"))
394 393
395 first = True 394 first = True
396 for fileName in fileNameList: 395 for fileName in fileNameList:
397 self.translations.add(fileName, first) 396 self.translations.add(fileName, first)
398 first = False 397 first = False
477 ntr.fileName = fileName 476 ntr.fileName = fileName
478 ntr.name = self.__uniqueName(fileName) 477 ntr.name = self.__uniqueName(fileName)
479 if ntr.name is None: 478 if ntr.name is None:
480 E5MessageBox.warning( 479 E5MessageBox.warning(
481 self.parent(), 480 self.parent(),
482 self.trUtf8("Set Translator"), 481 self.tr("Set Translator"),
483 self.trUtf8( 482 self.tr(
484 """<p>The translation filename <b>{0}</b>""" 483 """<p>The translation filename <b>{0}</b>"""
485 """ is invalid.</p>""").format(fileName)) 484 """ is invalid.</p>""").format(fileName))
486 return 485 return
487 486
488 ntr.translator = self.loadTransFile(fileName) 487 ntr.translator = self.loadTransFile(fileName)
507 if name != noTranslationName: 506 if name != noTranslationName:
508 trans = self.__findName(name) 507 trans = self.__findName(name)
509 if trans is None: 508 if trans is None:
510 E5MessageBox.warning( 509 E5MessageBox.warning(
511 self.parent(), 510 self.parent(),
512 self.trUtf8("Set Translator"), 511 self.tr("Set Translator"),
513 self.trUtf8( 512 self.tr(
514 """<p>The translator <b>{0}</b> is not known.</p>""") 513 """<p>The translator <b>{0}</b> is not known.</p>""")
515 .format(name)) 514 .format(name))
516 return 515 return
517 516
518 nTranslator = trans.translator 517 nTranslator = trans.translator
650 if tr.load(transFileName): 649 if tr.load(transFileName):
651 return tr 650 return tr
652 651
653 E5MessageBox.warning( 652 E5MessageBox.warning(
654 self.parent(), 653 self.parent(),
655 self.trUtf8("Load Translator"), 654 self.tr("Load Translator"),
656 self.trUtf8("""<p>The translation file <b>{0}</b> could""" 655 self.tr("""<p>The translation file <b>{0}</b> could"""
657 """ not be loaded.</p>""").format(transFileName)) 656 """ not be loaded.</p>""").format(transFileName))
658 return None 657 return None
659 658
660 def hasTranslations(self): 659 def hasTranslations(self):
661 """ 660 """
662 Public method to check for loaded translations. 661 Public method to check for loaded translations.
680 """ 679 """
681 super(WidgetView, self).__init__(parent) 680 super(WidgetView, self).__init__(parent)
682 if name: 681 if name:
683 self.setObjectName(name) 682 self.setObjectName(name)
684 self.setWindowTitle(name) 683 self.setWindowTitle(name)
685 self.setAttribute(Qt.WA_DeleteOnClose)
686 684
687 self.__widget = None 685 self.__widget = None
688 self.__uiFileName = uiFileName 686 self.__uiFileName = uiFileName
689 self.__layout = QHBoxLayout(self) 687 self.__layout = QHBoxLayout(self)
690 self.__valid = False 688 self.__valid = False
724 pass 722 pass
725 723
726 if not self.__widget: 724 if not self.__widget:
727 E5MessageBox.warning( 725 E5MessageBox.warning(
728 self, 726 self,
729 self.trUtf8("Load UI File"), 727 self.tr("Load UI File"),
730 self.trUtf8( 728 self.tr(
731 """<p>The file <b>{0}</b> could not be loaded.</p>""") 729 """<p>The file <b>{0}</b> could not be loaded.</p>""")
732 .format(self.__uiFileName)) 730 .format(self.__uiFileName))
733 self.__valid = False 731 self.__valid = False
734 return 732 return
735 733
780 if wview is None: 778 if wview is None:
781 name = os.path.basename(uiFileName) 779 name = os.path.basename(uiFileName)
782 if not name: 780 if not name:
783 E5MessageBox.warning( 781 E5MessageBox.warning(
784 self, 782 self,
785 self.trUtf8("Load UI File"), 783 self.tr("Load UI File"),
786 self.trUtf8( 784 self.tr(
787 """<p>The file <b>{0}</b> could not be loaded.</p>""") 785 """<p>The file <b>{0}</b> could not be loaded.</p>""")
788 .format(uiFileName)) 786 .format(uiFileName))
789 return 787 return
790 788
791 uname = name 789 uname = name

eric ide

mercurial