1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
23 from InterfaceQT import utilIcons
27 ##fonctions utilitaires
28 def normabspath(path):
30 Function returning a normalized, absolute path.
32 @param path file path (string)
33 @return absolute, normalized path (string)
35 return os.path.abspath(path)
40 Function to compare two paths.
42 @param f1 first path for the compare (string)
43 @param f2 second path for the compare (string)
44 @return flag indicating whether the two paths represent the
47 if f1 is None or f2 is None:
50 if normcasepath(f1) == normcasepath(f2):
55 def normcasepath(path):
57 Function returning a path, that is normalized with respect to its case and references.
59 @param path file path (string)
60 @return case normalized path (string)
62 return os.path.normcase(os.path.normpath(path))
69 Base class inherited by all specific viewmanager classes.
71 It defines the interface to be implemented by specific
72 viewmanager classes and all common methods.
74 @signal lastEditorClosed emitted after the last editor window was closed
75 @signal editorOpened(string) emitted after an editor window was opened
76 @signal editorSaved(string) emitted after an editor window was saved
77 @signal checkActions(editor) emitted when some actions should be checked
79 @signal cursorChanged(editor) emitted after the cursor position of the active
81 @signal breakpointToggled(editor) emitted when a breakpoint is toggled.
82 @signal bookmarkToggled(editor) emitted when a bookmark is toggled.
84 def __init__(self, ui ):
88 @param ui reference to the main user interface
89 @param dbs reference to the debug server object
91 # initialize the instance variables
96 self.currentEditor = None
97 self.untitledCount = 0
98 self.srHistory = {"search" : QStringList(), "replace" : QStringList()}
99 self.editorsCheckFocusIn = 1
100 self.recent = QStringList()
103 # initialize the central store for api information (used by
104 # autocompletion and calltips)
106 self.initFileFilters()
109 def initFileFilters(self):
111 Private method to initialize the lists of supported filename filters.
113 self.fileFiltersString = self.trUtf8(\
114 'Python Files (*.py);;'
115 'Aster Files (*.com*);;'
116 'Pyrex Files (*.pyx);;'
117 'Quixote Template Files (*.ptl);;'
118 'IDL Files (*.idl);;'
119 'C Files (*.h *.c);;'
120 'C++ Files (*.h *.hpp *.hh *.cxx *.cpp *.cc);;'
122 'HTML Files (*.html *.htm *.asp *.shtml *.css);;'
123 'PHP Files (*.php *.php3 *.php4 *.php5 *.phtml);;'
124 'XML Files (*.xml *.xsl *.xslt *.dtd);;'
125 'Java Files (*.java);;'
126 'JavaScript Files (*.js);;'
127 'SQL Files (*.sql);;'
128 'Docbook Files (*.docbook);;'
129 'Perl Files (*.pl *.pm *.ph);;'
130 'Shell Files (*.sh);;'
131 'Aster Files (*.com*);;'
134 fileFilters = QStringList.split(';;', self.fileFiltersString)
137 for fileFilter in fileFilters:
138 extensions = QStringList.split('*', fileFilter)
139 for extension in extensions[1:]:
140 extension = unicode(extension).strip().replace(')', '')
142 self.ext2Filter[extension] = unicode(fileFilter)
146 #####################################################################
147 ## methods above need to be implemented by a subclass
148 #####################################################################
152 public method to signal if splitting of the view is available.
154 @return flag indicating splitting of the view is available.
160 Public method used to split the current view.
164 def removeSplit(self):
166 Public method used to remove the current split view.
168 @return Flag indicating successful deletion
172 def setSplitOrientation(self, orientation):
174 Public method used to set the orientation of the split view.
176 @param orientation orientation of the split
177 (QSplitter.Horizontal or QSplitter.Vertical)
181 def eventFilter(self, object, event):
183 Private method called to filter an event.
185 @param object object, that generated the event (QObject)
186 @param event the event, that was generated by object (QEvent)
187 @return flag indicating if event was filtered out
191 def focusInEvent(self, event):
193 Public method called when the viewmanager receives focus.
195 @param event the event object (QFocusEvent)
197 self.editorActGrp.setEnabled(1)
199 def focusOutEvent(self, event):
201 Public method called when the viewmanager loses focus.
203 @param event the event object (QFocusEvent)
205 self.editorActGrp.setEnabled(0)
208 def initEditMenu(self):
210 Public method to create the Edit menu
212 @return the generated menu
214 menu = QPopupMenu(self.ui)
215 menu.insertTearOffHandle()
216 self.undoAct.addTo(menu)
217 self.redoAct.addTo(menu)
218 self.revertAct.addTo(menu)
219 menu.insertSeparator()
220 self.cutAct.addTo(menu)
221 self.copyAct.addTo(menu)
222 self.pasteAct.addTo(menu)
223 self.deleteAct.addTo(menu)
224 menu.insertSeparator()
225 self.indentAct.addTo(menu)
226 self.unindentAct.addTo(menu)
227 menu.insertSeparator()
228 self.commentAct.addTo(menu)
229 self.uncommentAct.addTo(menu)
230 self.streamCommentAct.addTo(menu)
231 self.boxCommentAct.addTo(menu)
232 menu.insertSeparator()
233 self.autoCompleteAct.addTo(menu)
234 self.autoCompleteFromDocAct.addTo(menu)
235 self.autoCompleteFromAPIsAct.addTo(menu)
236 menu.insertSeparator()
237 self.searchAct.addTo(menu)
238 self.searchAgainAct.addTo(menu)
239 self.replaceAct.addTo(menu)
240 menu.insertSeparator()
241 self.searchFilesAct.addTo(menu)
242 menu.insertSeparator()
243 self.gotoAct.addTo(menu)
244 self.gotoBraceAct.addTo(menu)
245 menu.insertSeparator()
246 self.selectBraceAct.addTo(menu)
247 self.selectAllAct.addTo(menu)
248 self.deselectAllAct.addTo(menu)
249 menu.insertSeparator()
250 self.shortenEmptyAct.addTo(menu)
251 self.convertEOLAct.addTo(menu)
255 def initEditToolbar(self):
257 Public method to create the Edit toolbar
259 @return the generated toolbar
261 tb = QToolBar(self.ui)
262 self.undoAct.addTo(tb)
263 self.redoAct.addTo(tb)
265 self.cutAct.addTo(tb)
266 self.copyAct.addTo(tb)
267 self.pasteAct.addTo(tb)
268 self.deleteAct.addTo(tb)
270 self.indentAct.addTo(tb)
271 self.unindentAct.addTo(tb)
273 self.commentAct.addTo(tb)
274 self.uncommentAct.addTo(tb)
278 ##################################################################
279 ## Initialize the search related actions, search menu and toolbar
280 ##################################################################
282 def initSearchActions(self):
284 Private method defining the user interface actions for the search commands.
286 self.searchActGrp = QActionGroup(self)
288 self.searchAct = QAction(self.trUtf8('Search'),
289 QIconSet(utilIcons.getPixmap("find.png")),
290 self.trUtf8('&Search...'),
291 QKeySequence(self.trUtf8("CTRL+F","Search|Search")),
293 self.searchAct.setStatusTip(self.trUtf8('Search for a text'))
294 self.searchAct.setWhatsThis(self.trUtf8(
296 """<p>Search for some text in the current editor. A"""
297 """ dialog is shown to enter the searchtext and options"""
298 """ for the search.</p>"""
300 self.connect(self.searchAct,SIGNAL('activated()'),self.handleSearch)
301 self.searchActions.append(self.searchAct)
303 self.searchAgainAct = QAction(self.trUtf8('Search again'),
304 QIconSet(utilIcons.getPixmap("findNext.png")),
305 self.trUtf8('Search &again'),
306 Qt.Key_F3,self.searchActGrp)
307 self.searchAgainAct.setStatusTip(self.trUtf8('Search again for text'))
308 self.searchAgainAct.setWhatsThis(self.trUtf8(
309 """<b>Search again</b>"""
310 """<p>Search again for some text in the current editor."""
311 """ The previously entered searchtext and options are reused.</p>"""
313 self.connect(self.searchAgainAct,SIGNAL('activated()'),self.searchDlg.handleFindNext)
314 self.searchActions.append(self.searchAgainAct)
316 self.replaceAct = QAction(self.trUtf8('Replace'),
317 self.trUtf8('&Replace...'),
318 QKeySequence(self.trUtf8("CTRL+R","Search|Replace")),
320 self.replaceAct.setStatusTip(self.trUtf8('Replace some text'))
321 self.replaceAct.setWhatsThis(self.trUtf8(
323 """<p>Search for some text in the current editor and replace it. A"""
324 """ dialog is shown to enter the searchtext, the replacement text"""
325 """ and options for the search and replace.</p>"""
327 self.connect(self.replaceAct,SIGNAL('activated()'),self.handleReplace)
328 self.searchActions.append(self.replaceAct)
330 self.gotoAct = QAction(self.trUtf8('Goto Line'),
331 QIconSet(utilIcons.getPixmap("goto.png")),
332 self.trUtf8('&Goto Line...'),
333 QKeySequence(self.trUtf8("CTRL+G","Search|Goto Line")),
335 self.gotoAct.setStatusTip(self.trUtf8('Goto Line'))
336 self.gotoAct.setWhatsThis(self.trUtf8(
337 """<b>Goto Line</b>"""
338 """<p>Go to a specific line of text in the current editor."""
339 """ A dialog is shown to enter the linenumber.</p>"""
341 self.connect(self.gotoAct,SIGNAL('activated()'),self.handleGoto)
342 self.searchActions.append(self.gotoAct)
344 self.gotoBraceAct = QAction(self.trUtf8('Goto Brace'),
345 QIconSet(utilIcons.getPixmap("gotoBrace.png")),
346 self.trUtf8('Goto &Brace'),
347 QKeySequence(self.trUtf8("CTRL+L","Search|Goto Brace")),
349 self.gotoBraceAct.setStatusTip(self.trUtf8('Goto Brace'))
350 self.gotoBraceAct.setWhatsThis(self.trUtf8(
351 """<b>Goto Brace</b>"""
352 """<p>Go to the matching brace in the current editor.</p>"""
354 self.connect(self.gotoBraceAct,SIGNAL('activated()'),self.handleGotoBrace)
355 self.searchActions.append(self.gotoBraceAct)
357 self.searchActGrp.setEnabled(0)
359 self.searchFilesAct = QAction(self.trUtf8('Search in Files'),
360 QIconSet(utilIcons.getPixmap("projectFind.png")),
361 self.trUtf8('Search in &Files...'),
362 QKeySequence(self.trUtf8("SHIFT+CTRL+F","Search|Search Files")),
364 self.searchFilesAct.setStatusTip(self.trUtf8('Search for a text in files'))
365 self.searchFilesAct.setWhatsThis(self.trUtf8(
366 """<b>Search in Files</b>"""
367 """<p>Search for some text in the files of a directory tree"""
368 """ or the project. A dialog is shown to enter the searchtext"""
369 """ and options for the search and to display the result.</p>"""
371 self.connect(self.searchFilesAct,SIGNAL('activated()'),self.handleSearchFiles)
372 self.searchActions.append(self.searchFilesAct)
375 ##################################################################
376 ## Initialize the view related actions, view menu and toolbar
377 ##################################################################
379 def initViewActions(self):
381 Protected method defining the user interface actions for the view commands.
383 self.viewActGrp = QActionGroup(self)
384 self.viewFoldActGrp = QActionGroup(self)
386 self.zoomInAct = QAction(self.trUtf8('Zoom in'),
387 QIconSet(utilIcons.getPixmap("zoomIn.png")),
388 self.trUtf8('Zoom &in'),
389 Qt.CTRL+Qt.Key_Plus, self.viewActGrp)
390 self.zoomInAct.setStatusTip(self.trUtf8('Zoom in on the text'))
391 self.zoomInAct.setWhatsThis(self.trUtf8(
393 """<p>Zoom in on the text. This makes the text bigger.</p>"""
395 self.connect(self.zoomInAct,SIGNAL('activated()'),self.handleZoomIn)
396 self.viewActions.append(self.zoomInAct)
398 self.zoomOutAct = QAction(self.trUtf8('Zoom out'),
399 QIconSet(utilIcons.getPixmap("zoomOut.png")),
400 self.trUtf8('Zoom &out'),
401 Qt.CTRL+Qt.Key_Minus, self.viewActGrp)
402 self.zoomOutAct.setStatusTip(self.trUtf8('Zoom out on the text'))
403 self.zoomOutAct.setWhatsThis(self.trUtf8(
404 """<b>Zoom out</b>"""
405 """<p>Zoom out on the text. This makes the text smaller.</p>"""
407 self.connect(self.zoomOutAct,SIGNAL('activated()'),self.handleZoomOut)
408 self.viewActions.append(self.zoomOutAct)
410 self.zoomToAct = QAction(self.trUtf8('Zoom'),
411 QIconSet(utilIcons.getPixmap("zoomTo.png")),
412 self.trUtf8('&Zoom'),
414 self.zoomToAct.setStatusTip(self.trUtf8('Zoom the text'))
415 self.zoomToAct.setWhatsThis(self.trUtf8(
417 """<p>Zoom the text. This opens a dialog where the"""
418 """ desired size can be entered.</p>"""
420 self.connect(self.zoomToAct,SIGNAL('activated()'),self.handleZoom)
421 self.viewActions.append(self.zoomToAct)
423 self.toggleAllAct = QAction(self.trUtf8('Toggle all folds'),
424 self.trUtf8('Toggle &all folds'),
425 0, self.viewFoldActGrp)
426 self.toggleAllAct.setStatusTip(self.trUtf8('Toggle all folds'))
427 self.toggleAllAct.setWhatsThis(self.trUtf8(
428 """<b>Toggle all folds</b>"""
429 """<p>Toggle all folds of the current editor.</p>"""
431 self.connect(self.toggleAllAct,SIGNAL('activated()'),self.handleToggleAll)
432 self.viewActions.append(self.toggleAllAct)
434 self.toggleCurrentAct = QAction(self.trUtf8('Toggle current fold'),
435 self.trUtf8('Toggle ¤t fold'),
436 0, self.viewFoldActGrp)
437 self.toggleCurrentAct.setStatusTip(self.trUtf8('Toggle current fold'))
438 self.toggleCurrentAct.setWhatsThis(self.trUtf8(
439 """<b>Toggle current fold</b>"""
440 """<p>Toggle the folds of the current line of the current editor.</p>"""
442 self.connect(self.toggleCurrentAct,SIGNAL('activated()'),self.handleToggleCurrent)
443 self.viewActions.append(self.toggleCurrentAct)
445 self.unhighlightAct = QAction(self.trUtf8('Remove all highlights'),
446 QIconSet(utilIcons.getPixmap("unhighlight.png")),
447 self.trUtf8('Remove all highlights'),
449 self.unhighlightAct.setStatusTip(self.trUtf8('Remove all highlights'))
450 self.unhighlightAct.setWhatsThis(self.trUtf8(
451 """<b>Remove all highlights</b>"""
452 """<p>Remove the highlights of all editors.</p>"""
454 self.connect(self.unhighlightAct,SIGNAL('activated()'),self.unhighlight)
455 self.viewActions.append(self.unhighlightAct)
457 self.splitViewAct = QAction(self.trUtf8('Split view'),
458 QIconSet(utilIcons.getPixmap("splitVertical.png")),
459 self.trUtf8('&Split view'),
461 self.splitViewAct.setStatusTip(self.trUtf8('Add a split to the view'))
462 self.splitViewAct.setWhatsThis(self.trUtf8(
463 """<b>Split view</b>"""
464 """<p>Add a split to the view.</p>"""
466 self.connect(self.splitViewAct,SIGNAL('activated()'),self.handleSplitView)
467 self.viewActions.append(self.splitViewAct)
469 self.splitOrientationAct = QAction(self.trUtf8('Arrange horizontally'),
470 self.trUtf8('Arrange &horizontally'),
472 self.splitOrientationAct.setStatusTip(self.trUtf8('Arrange the splitted views horizontally'))
473 self.splitOrientationAct.setWhatsThis(self.trUtf8(
474 """<b>Arrange horizontally</b>"""
475 """<p>Arrange the splitted views horizontally.</p>"""
477 self.splitOrientationAct.setOn(0)
478 self.connect(self.splitOrientationAct,SIGNAL('activated()'),self.handleSplitOrientation)
479 self.viewActions.append(self.splitOrientationAct)
481 self.splitRemoveAct = QAction(self.trUtf8('Remove split'),
482 QIconSet(utilIcons.getPixmap("remsplitVertical.png")),
483 self.trUtf8('&Remove split'),
485 self.splitRemoveAct.setStatusTip(self.trUtf8('Remove the current split'))
486 self.splitRemoveAct.setWhatsThis(self.trUtf8(
487 """<b>Remove split</b>"""
488 """<p>Remove the current split.</p>"""
490 self.connect(self.splitRemoveAct,SIGNAL('activated()'),self.removeSplit)
491 self.viewActions.append(self.splitRemoveAct)
493 self.viewActGrp.setEnabled(0)
494 self.viewFoldActGrp.setEnabled(0)
495 self.unhighlightAct.setEnabled(0)
496 self.splitViewAct.setEnabled(0)
497 self.splitOrientationAct.setEnabled(0)
498 self.splitRemoveAct.setEnabled(0)
500 def initViewMenu(self):
502 Public method to create the View menu
504 @return the generated menu
506 menu = QPopupMenu(self.ui)
507 menu.insertTearOffHandle()
508 self.viewActGrp.addTo(menu)
509 menu.insertSeparator()
510 self.viewFoldActGrp.addTo(menu)
511 menu.insertSeparator()
512 self.unhighlightAct.addTo(menu)
514 menu.insertSeparator()
515 self.splitViewAct.addTo(menu)
516 self.splitOrientationAct.addTo(menu)
517 self.splitRemoveAct.addTo(menu)
520 def initViewToolbar(self):
522 Public method to create the View toolbar
524 @return the generated toolbar
526 tb = QToolBar(self.ui)
527 self.viewActGrp.addTo(tb)
529 self.unhighlightAct.addTo(tb)
532 self.splitViewAct.addTo(tb)
533 self.splitRemoveAct.addTo(tb)
537 ##################################################################
538 ## Initialize the macro related actions and macro menu
539 ##################################################################
541 def initMacroActions(self):
543 Private method defining the user interface actions for the macro commands.
545 self.macroActGrp = QActionGroup(self)
547 self.macroStartRecAct = QAction(self.trUtf8('Start Macro Recording'),
548 self.trUtf8('S&tart Macro Recording'),
550 self.macroStartRecAct.setStatusTip(self.trUtf8('Start Macro Recording'))
551 self.macroStartRecAct.setWhatsThis(self.trUtf8(
552 """<b>Start Macro Recording</b>"""
553 """<p>Start recording editor commands into a new macro.</p>"""
555 self.connect(self.macroStartRecAct,SIGNAL('activated()'),self.handleMacroStartRecording)
556 self.macroActions.append(self.macroStartRecAct)
558 self.macroStopRecAct = QAction(self.trUtf8('Stop Macro Recording'),
559 self.trUtf8('Sto&p Macro Recording'),
561 self.macroStopRecAct.setStatusTip(self.trUtf8('Stop Macro Recording'))
562 self.macroStopRecAct.setWhatsThis(self.trUtf8(
563 """<b>Stop Macro Recording</b>"""
564 """<p>Stop recording editor commands into a new macro.</p>"""
566 self.connect(self.macroStopRecAct,SIGNAL('activated()'),self.handleMacroStopRecording)
567 self.macroActions.append(self.macroStopRecAct)
569 self.macroRunAct = QAction(self.trUtf8('Run Macro'),
570 self.trUtf8('&Run Macro'),
572 self.macroRunAct.setStatusTip(self.trUtf8('Run Macro'))
573 self.macroRunAct.setWhatsThis(self.trUtf8(
574 """<b>Run Macro</b>"""
575 """<p>Run a previously recorded editor macro.</p>"""
577 self.connect(self.macroRunAct,SIGNAL('activated()'),self.handleMacroRun)
578 self.macroActions.append(self.macroRunAct)
580 self.macroDeleteAct = QAction(self.trUtf8('Delete Macro'),
581 self.trUtf8('&Delete Macro'),
583 self.macroDeleteAct.setStatusTip(self.trUtf8('Delete Macro'))
584 self.macroDeleteAct.setWhatsThis(self.trUtf8(
585 """<b>Delete Macro</b>"""
586 """<p>Delete a previously recorded editor macro.</p>"""
588 self.connect(self.macroDeleteAct,SIGNAL('activated()'),self.handleMacroDelete)
589 self.macroActions.append(self.macroDeleteAct)
591 self.macroLoadAct = QAction(self.trUtf8('Load Macro'),
592 self.trUtf8('&Load Macro'),
594 self.macroLoadAct.setStatusTip(self.trUtf8('Load Macro'))
595 self.macroLoadAct.setWhatsThis(self.trUtf8(
596 """<b>Load Macro</b>"""
597 """<p>Load an editor macro from a file.</p>"""
599 self.connect(self.macroLoadAct,SIGNAL('activated()'),self.handleMacroLoad)
600 self.macroActions.append(self.macroLoadAct)
602 self.macroSaveAct = QAction(self.trUtf8('Save Macro'),
603 self.trUtf8('&Save Macro'),
605 self.macroSaveAct.setStatusTip(self.trUtf8('Save Macro'))
606 self.macroSaveAct.setWhatsThis(self.trUtf8(
607 """<b>Save Macro</b>"""
608 """<p>Save a previously recorded editor macro to a file.</p>"""
610 self.connect(self.macroSaveAct,SIGNAL('activated()'),self.handleMacroSave)
611 self.macroActions.append(self.macroSaveAct)
613 self.macroActGrp.setEnabled(0)
615 def initMacroMenu(self):
617 Public method to create the Macro menu
619 @return the generated menu
621 menu = QPopupMenu(self.ui)
622 menu.insertTearOffHandle()
623 self.macroActGrp.addTo(menu)
627 def checkDirty(self, editor):
629 Private method to check dirty status and open a message window.
631 @param editor editor window to check
632 @return flag indicating successful reset of the dirty flag (boolean)
635 if (editor.modified) and (editor in self.doubles.keys()) :
636 res = QMessageBox.warning(
638 self.trUtf8("Fichier Duplique"),
639 self.trUtf8("Le fichier ne sera pas sauvegarde."),
640 self.trUtf8("&Quitter"),
641 self.trUtf8("&Annuler"))
642 if res == 0 : return 1
645 fn = editor.getFileName()
647 fn = self.trUtf8('Noname')
648 res = QMessageBox.warning(self.parent(),
649 self.trUtf8("Fichier Modifie"),
650 self.trUtf8("Le fichier <b>%1</b> n a pas ete sauvegarde.")
652 self.trUtf8("&Sauvegarder"), self.trUtf8("&Quitter "),
653 self.trUtf8("&Annuler"), 0, 2)
655 (ok, newName) = editor.saveFile()
657 self.setEditorName(editor, newName)
663 def checkAllDirty(self):
665 Public method to check the dirty status of all editors.
667 @return flag indicating successful reset of all dirty flags (boolean)
669 for editor in self.editors:
670 if not self.checkDirty(editor):
675 def closeEditor(self, editor):
677 Private method to close an editor window.
679 @param editor editor window to be closed
680 @return flag indicating success (boolean)
682 # save file if necessary
683 if not self.checkDirty(editor):
687 self.removeView(editor)
688 self.editors.remove(editor)
689 if not len(self.editors):
690 self.handleLastEditorClosed()
691 self.emit(PYSIGNAL('lastEditorClosed'), ()) #CS_pbruno connecter signal avec l'appli
694 def handleClose(self):
696 Public method to close the current window.
698 @return flag indicating success (boolean)
700 aw = self.activeWindow()
704 res = self.closeEditor(aw)
705 if res and aw == self.currentEditor:
706 self.currentEditor = None
710 def handleNewView(self):
712 Public method to close the current window.
714 @return flag indicating success (boolean)
716 aw = self.activeWindow()
723 def handleCloseAll(self):
725 Private method to close all editor windows via file menu.
727 savedEditors = self.editors[:]
729 for editor in savedEditors:
730 retour=retour*self.closeEditor(editor)
733 def handleCloseWindow(self, fn):
735 Public method to close an arbitrary source editor.
737 @param fn filename of editor to be closed
738 @return flag indicating success (boolean)
740 for editor in self.editors:
741 if samepath(fn, editor.getFileName()):
746 res = self.closeEditor(editor)
747 if res and editor == self.currentEditor:
748 self.currentEditor = None
752 def handleExit(self):
754 Public method to handle the debugged program terminating.
756 if self.currentEditor is not None:
757 self.currentEditor.highlight()
758 self.currentEditor = None
762 def handlePythonFile(self,pyfn,lineno=None):
764 Public method to handle the user selecting a file for display.
766 @param pyfn name of file to be opened
767 @param lineno line number to place the cursor at
770 self.displayPythonFile(pyfn,lineno)
775 def displayJDC(self,jdc,fn=None):
777 Public slot to display a file in an editor.
779 @param fn name of file to be opened
780 @param lineno line number to place the cursor at
783 if fn != None : titre=fn.split("/")[-1]
784 newWin, editor = self.getEditor(None, jdc, title = titre )
788 self.handleModificationStatusChanged(editor.modified, editor)
789 self.checkActions(editor)
791 # insert filename into list of recently opened files
792 self.addToRecentList(editor.getFileName())
796 def newEditorView(self, fn, caller):
798 Public method to create a new editor displaying the given document.
800 @param fn filename of this view
801 @param caller reference to the editor calling this method
803 from editor import JDCEditor
804 editor = JDCEditor(fn, None, self, editor=caller)
805 self.editors.append(editor)
806 self.connect(editor, PYSIGNAL('modificationStatusChanged'),
807 self.handleModificationStatusChanged)
808 self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
809 self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
810 self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
811 self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
812 self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
813 self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'),
814 self.handleEditoracAPIsAvailable)
815 self.handleEditorOpened()
816 self.emit(PYSIGNAL('editorOpened'), (fn,))
818 self.connect(caller, PYSIGNAL('editorRenamed'), editor.handleRenamed)
819 self.connect(editor, PYSIGNAL('editorRenamed'), caller.handleRenamed)
821 self.addView(editor, fn)
822 self.handleModificationStatusChanged(editor.modified, editor)
823 self.checkActions(editor)
825 def addToRecentList(self, fn):
827 Public slot to add a filename to the list of recently opened files.
829 @param fn name of the file to be added
831 self.recent.remove(fn)
832 self.recent.prepend(fn)
833 if len(self.recent) > 9:
834 self.recent = self.recent[:9]
836 def toggleWindow(self,w):
838 Private method to toggle a workspace window.
840 @param w editor window to be toggled
847 def setFileLine(self,fn,line,error=0,syntaxError=0):
849 Public method to update the user interface when the current program or line changes.
851 @param fn filename of editor to update (string)
852 @param line line number to highlight (int)
853 @param error flag indicating an error highlight (boolean)
854 @param syntaxError flag indicating a syntax error
856 self.setSbFile(fn,line)
859 newWin, self.currentEditor = self.getEditor(fn)
863 # Change the highlighted line.
864 self.currentEditor.highlight(line,error,syntaxError)
866 self.currentEditor.highlightVisible()
867 self.checkActions(self.currentEditor, 0)
869 def setSbFile(self,fn=None,line=None,pos=None):
871 Private method to set the file info in the status bar.
873 @param fn filename to display (string)
874 @param line line number to display (int)
875 @param pos character position to display (int)
881 if QFileInfo(fn).isWritable():
886 self.sbWritable.setText(writ)
887 self.sbFile.setText(self.trUtf8('File: %1').arg(fn,-50))
892 self.sbLine.setText(self.trUtf8('Line: %1').arg(line,5))
897 self.sbPos.setText(self.trUtf8('Pos: %1').arg(pos, 5))
899 def unhighlight(self, current=0):
901 Public method to switch off all highlights.
903 @param current flag indicating only the current editor should be unhighlighted
907 if self.currentEditor is not None:
908 self.currentEditor.highlight()
910 for editor in self.editors:
913 def getOpenFilenames(self):
915 Public method returning a list of the filenames of all editors.
917 @return list of all opened filenames (list of strings)
920 for editor in self.editors:
921 fn = editor.getFileName()
927 def getEditor(self, fn, jdc = None, title = None, units = None):
929 Private method to return the editor displaying the given file.
931 If there is no editor with the given file, a new editor window is
934 @param fn filename to look for
935 @param isPythonFile flag indicating that this is a Python file
936 even if it doesn't have the .py extension (boolean)
937 @return tuple of two values giving a flag indicating a new window creation and
938 a reference to the editor displaying this file
942 for editor in self.editors:
943 if samepath(fn, editor.getFileName()):
944 abort = QMessageBox.warning(self,
945 self.trUtf8("Fichier"),
946 self.trUtf8("Le fichier <b>%1</b> est deja ouvert.Voulez-vous l ouvrir tel qu'il etait lors du dernier enregistrement") .arg(fn),
947 self.trUtf8("&Duplication"),
948 self.trUtf8("&Annuler"), None, 1)
953 from editor import JDCEditor
954 editor = JDCEditor(fn, jdc, self,units=units)
956 self.doubles[editor]=double
957 #self.doubles[double]=editor
958 if editor.jdc: # le fichier est bien un jdc
959 self.editors.append(editor)
960 self.connect(editor, PYSIGNAL('modificationStatusChanged'),
961 self.handleModificationStatusChanged)
962 self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
963 self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
964 self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
965 self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
966 self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
967 self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'),
968 self.handleEditoracAPIsAvailable)
969 self.handleEditorOpened()
970 self.emit(PYSIGNAL('editorOpened'), (fn,))
976 self.addView(editor, fn , title)
978 self.showView(editor, fn)
980 return (newWin, editor)
983 def getOpenEditor(self, fn):
985 Public method to return the editor displaying the given file.
987 @param fn filename to look for
988 @return a reference to the editor displaying this file or None, if
991 for editor in self.editors:
992 if samepath(fn, editor.getFileName()):
997 def getActiveName(self):
999 Public method to retrieve the filename of the active window.
1001 @return filename of active window (string)
1003 aw = self.activeWindow()
1005 return aw.getFileName()
1009 def saveEditor(self, fn):
1011 Public method to save a named editor file.
1013 @param fn filename of editor to be saved (string)
1014 @return flag indicating success (boolean)
1016 for editor in self.editors:
1017 if samepath(fn, editor.getFileName()):
1022 if not editor.modified:
1025 ok, dummy = editor.saveFile()
1028 def saveCurrentEditor(self):
1030 Public slot to save the contents of the current editor.
1032 aw = self.activeWindow()
1033 if aw in self.doubles.keys() :
1034 QMessageBox.warning(
1036 self.trUtf8("Fichier Duplique"),
1037 self.trUtf8("Le fichier ne sera pas sauvegarde."),
1038 self.trUtf8("&Annuler"))
1041 ok, newName = aw.saveFile()
1043 self.setEditorName(aw, newName)
1047 def saveAsCurrentEditor(self):
1049 Public slot to save the contents of the current editor to a new file.
1051 aw = self.activeWindow()
1053 ok, newName = aw.saveFileAs()
1055 self.setEditorName(aw, newName)
1059 def saveAllEditors(self):
1061 Public slot to save the contents of all editors.
1063 for editor in self.editors:
1064 ok, newName = editor.saveFile()
1066 self.setEditorName(editor, newName)
1068 # restart autosave timer
1069 if self.autosaveInterval > 0:
1070 self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
1072 def saveCurrentEditorToProject(self):
1074 Public slot to save the contents of the current editor to the current project.
1076 pro = self.ui.getProject()
1078 aw = self.activeWindow()
1080 ok, newName = aw.saveFileAs(path)
1082 self.setEditorName(aw, newName)
1083 pro.appendFile(newName)
1087 def newIncludeEditor(self) :
1088 self.newEditor(include=1)
1090 def newEditor(self,include=0):
1092 Public slot to generate a new empty editor.
1094 from editor import JDCEditor
1095 editor = JDCEditor(None,None,self,include=include)
1097 self.editors.append(editor)
1098 self.connect(editor, PYSIGNAL('modificationStatusChanged'),
1099 self.handleModificationStatusChanged)
1100 self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
1101 self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
1102 self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
1103 self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
1104 self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
1105 self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'),
1106 self.handleEditoracAPIsAvailable)
1107 self.addView(editor, None)
1108 self.handleEditorOpened()
1109 self.checkActions(editor)
1110 self.emit(PYSIGNAL('editorOpened'), (None,))
1112 def printCurrentEditor(self):
1114 Public slot to print the contents of the current editor.
1116 aw = self.activeWindow()
1122 def printCurrentEditorSel(self):
1124 Public slot to print the selection of the current editor.
1126 aw = self.activeWindow()
1132 def handlevisuJdcPy(self):
1133 if self.activeWindow()== None : return
1134 self.activeWindow().viewJdcPy()
1136 def handleViewJdcFichierSource(self):
1137 if self.activeWindow()== None : return
1138 self.activeWindow().viewJdcSource()
1140 def handleViewJdcRapport(self):
1141 if self.activeWindow()== None : return
1142 self.activeWindow().viewJdcRapport()
1144 def handleNewProject(self):
1146 Public slot to handle the NewProject signal.
1148 self.saveToProjectAct.setEnabled(1)
1150 def handleProjectOpened(self):
1152 Public slot to handle the projectOpened signal.
1154 self.saveToProjectAct.setEnabled(1)
1156 def handleProjectClosed(self):
1158 Public slot to handle the projectClosed signal.
1160 self.saveToProjectAct.setEnabled(0)
1162 def handleProjectFileRenamed(self, oldfn, newfn):
1164 Public slot to handle the projectFileRenamed signal.
1166 @param oldfn old filename of the file (string)
1167 @param newfn new filename of the file (string)
1169 editor = self.getOpenEditor(oldfn)
1171 editor.fileRenamed(newfn)
1173 def enableEditorsCheckFocusIn(self, enabled):
1175 Public method to set a flag enabling the editors to perform focus in checks.
1177 @param enabled flag indicating focus in checks should be performed (boolean)
1179 self.editorsCheckFocusIn = enabled
1181 def editorsCheckFocusInEnabled(self):
1183 Public method returning the flag indicating editors should perform focus in checks.
1185 @return flag indicating focus in checks should be performed (boolean)
1187 return self.editorsCheckFocusIn
1189 def handleFindFileName(self):
1191 Private method to handle the search for file action.
1193 self.ui.findFileNameDialog.show()
1194 self.ui.findFileNameDialog.raiseW()
1195 self.ui.findFileNameDialog.setActiveWindow()
1197 ##################################################################
1198 ## Below are the action methods for the edit menu
1199 ##################################################################
1201 def handleEditUndo(self):
1203 Private method to handle the undo action.
1205 self.activeWindow().undo()
1207 def handleEditRedo(self):
1209 Private method to handle the redo action.
1211 self.activeWindow().redo()
1213 def handleEditRevert(self):
1215 Private method to handle the revert action.
1217 self.activeWindow().revertToUnmodified()
1219 def handleEditCut(self):
1221 Private method to handle the cut action.
1223 self.activeWindow().cut()
1225 def handleEditCopy(self):
1227 Private method to handle the copy action.
1229 self.activeWindow().copy()
1231 def handleEditPaste(self):
1233 Private method to handle the paste action.
1235 self.activeWindow().paste()
1237 def handleEditDelete(self):
1239 Private method to handle the delete action.
1241 self.activeWindow().clear()
1243 def handleEditIndent(self):
1245 Private method to handle the indent action.
1247 self.activeWindow().indentLineOrSelection()
1249 def handleEditUnindent(self):
1251 Private method to handle the unindent action.
1253 self.activeWindow().unindentLineOrSelection()
1255 def handleEditComment(self):
1257 Private method to handle the comment action.
1259 self.activeWindow().commentLineOrSelection()
1261 def handleEditUncomment(self):
1263 Private method to handle the uncomment action.
1265 self.activeWindow().uncommentLineOrSelection()
1267 def handleEditStreamComment(self):
1269 Private method to handle the stream comment action.
1271 self.activeWindow().streamCommentLineOrSelection()
1273 def handleEditBoxComment(self):
1275 Private method to handle the box comment action.
1277 self.activeWindow().boxCommentLineOrSelection()
1279 def handleEditSelectBrace(self):
1281 Private method to handle the select to brace action.
1283 self.activeWindow().selectToMatchingBrace()
1285 def handleEditSelectAll(self):
1287 Private method to handle the select all action.
1289 self.activeWindow().selectAll(1)
1291 def handleEditDeselectAll(self):
1293 Private method to handle the select all action.
1295 self.activeWindow().selectAll(0)
1297 def handleConvertEOL(self):
1299 Private method to handle the convert line end characters action.
1301 aw = self.activeWindow()
1302 aw.convertEols(aw.eolMode())
1304 def handleShortenEmptyLines(self):
1306 Private method to handle the shorten empty lines action.
1308 self.activeWindow().handleShortenEmptyLines()
1310 def handleEditAutoComplete(self):
1312 Private method to handle the autocomplete action.
1314 aw = self.activeWindow()
1317 def handleEditAutoCompleteFromDoc(self):
1319 Private method to handle the autocomplete from document action.
1321 aw = self.activeWindow()
1322 aw.autoCompleteFromDocument()
1324 def handleEditAutoCompleteFromAPIs(self):
1326 Private method to handle the autocomplete from APIs action.
1328 aw = self.activeWindow()
1329 aw.autoCompleteFromAPIs()
1331 def handleEditoracAPIsAvailable(self, available):
1333 Private method to handle the availability of API autocompletion signal.
1335 self.autoCompleteFromAPIsAct.setEnabled(available)
1337 ##################################################################
1338 ## Below are the action and utility methods for the search menu
1339 ##################################################################
1341 def getWord(self, text, index):
1343 Private method to get the word at a position.
1345 @param text text to look at (string or QString)
1346 @param index position to look at (int)
1347 @return the word at that position
1349 re = QRegExp('[^\w_]')
1350 start = text.findRev(re, index) + 1
1351 end = text.find(re, index)
1353 word = text.mid(start, end-start)
1358 def textForFind(self):
1360 Private method to determine the selection or the current word for the next find operation.
1362 @return selection or current word (QString)
1364 aw = self.activeWindow()
1368 if aw.hasSelectedText():
1369 text = aw.selectedText()
1370 if text.contains('\r') or text.contains('\n'):
1371 # the selection contains at least a newline, it is
1372 # unlikely to be the expression to search for
1377 # no selected text, determine the word at the current position
1378 line, index = aw.getCursorPosition()
1379 return self.getWord(aw.text(line), index)
1381 def getSRHistory(self, key):
1383 Private method to get the search or replace history list.
1385 @param key list to return (must be 'search' or 'replace')
1386 @return the requested history list (QStringList)
1388 return self.srHistory[key]
1390 def handleSearch(self):
1392 Private method to handle the search action.
1394 self.searchDlg.showFind(self.textForFind())
1396 def handleReplace(self):
1398 Private method to handle the replace action.
1400 self.replaceDlg.showReplace(self.textForFind())
1402 def handleGoto(self):
1404 Private method to handle the goto action.
1406 aw = self.activeWindow()
1407 dlg = GotoDialog(self.ui, None, 1)
1409 if dlg.exec_loop() == QDialog.Accepted:
1410 aw.gotoLine(min(dlg.getLinenumber(), aw.lines()))
1412 def handleGotoBrace(self):
1414 Private method to handle the goto brace action.
1416 self.activeWindow().moveToMatchingBrace()
1418 def handleSearchFiles(self):
1420 Private method to handle the search in files action.
1422 self.ui.findFilesDialog.show(self.textForFind())
1423 self.ui.findFilesDialog.raiseW()
1424 self.ui.findFilesDialog.setActiveWindow()
1426 ##################################################################
1427 ## Below are the action methods for the view menu
1428 ##################################################################
1430 def handleZoomIn(self):
1432 Private method to handle the zoom in action.
1434 self.activeWindow().zoomIn()
1436 def handleZoomOut(self):
1438 Private method to handle the zoom out action.
1440 self.activeWindow().zoomOut()
1442 def handleZoom(self):
1444 Private method to handle the zoom action.
1446 aw = self.activeWindow()
1447 dlg = ZoomDialog(aw.getZoom(), self.ui, None, 1)
1448 if dlg.exec_loop() == QDialog.Accepted:
1449 aw.zoomTo(dlg.getZoomSize())
1451 def handleToggleAll(self):
1453 Private method to handle the toggle all folds action.
1455 self.activeWindow().foldAll()
1457 def handleToggleCurrent(self):
1459 Private method to handle the toggle current fold action.
1461 aw = self.activeWindow()
1462 line, index = aw.getCursorPosition()
1465 def handleSplitView(self):
1467 Private method to handle the split view action.
1471 def handleSplitOrientation(self):
1473 Private method to handle the split orientation action.
1475 if self.splitOrientationAct.isOn():
1476 self.setSplitOrientation(QSplitter.Horizontal)
1477 self.splitViewAct.setIconSet(\
1478 QIconSet(utilIcons.getPixmap("splitHorizontal.png")))
1479 self.splitRemoveAct.setIconSet(\
1480 QIconSet(utilIcons.getPixmap("remsplitHorizontal.png")))
1482 self.setSplitOrientation(QSplitter.Vertical)
1483 self.splitViewAct.setIconSet(\
1484 QIconSet(utilIcons.getPixmap("splitVertical.png")))
1485 self.splitRemoveAct.setIconSet(\
1486 QIconSet(utilIcons.getPixmap("remsplitVertical.png")))
1488 ##################################################################
1489 ## Below are the action methods for the macro menu
1490 ##################################################################
1492 def handleMacroStartRecording(self):
1494 Private method to handle the start macro recording action.
1496 self.activeWindow().handleStartMacroRecording()
1498 def handleMacroStopRecording(self):
1500 Private method to handle the stop macro recording action.
1502 self.activeWindow().handleStopMacroRecording()
1504 def handleMacroRun(self):
1506 Private method to handle the run macro action.
1508 self.activeWindow().handleRunMacro()
1510 def handleMacroDelete(self):
1512 Private method to handle the delete macro action.
1514 self.activeWindow().handleDeleteMacro()
1516 def handleMacroLoad(self):
1518 Private method to handle the load macro action.
1520 self.activeWindow().handleLoadMacro()
1522 def handleMacroSave(self):
1524 Private method to handle the save macro action.
1526 self.activeWindow().handleSaveMacro()
1528 ##################################################################
1529 ## Below are the action methods for the bookmarks menu
1530 ##################################################################
1532 def handleToggleBookmark(self):
1534 Private method to handle the toggle bookmark action.
1536 self.activeWindow().handleToggleBookmark()
1538 def handleNextBookmark(self):
1540 Private method to handle the next bookmark action.
1542 self.activeWindow().handleNextBookmark()
1544 def handlePreviousBookmark(self):
1546 Private method to handle the previous bookmark action.
1548 self.activeWindow().handlePreviousBookmark()
1550 def handleClearAllBookmarks(self):
1552 Private method to handle the clear all bookmarks action.
1554 for editor in self.editors:
1555 editor.handleClearBookmarks()
1557 self.bookmarkNextAct.setEnabled(0)
1558 self.bookmarkPreviousAct.setEnabled(0)
1559 self.bookmarkClearAct.setEnabled(0)
1561 def handleShowBookmarksMenu(self):
1563 Private method to handle the show bookmarks menu signal.
1566 self.bookmarksMenu.clear()
1568 filenames = self.getOpenFilenames()
1570 for filename in filenames:
1571 editor = self.getOpenEditor(filename)
1572 for bookmark in editor.getBookmarks():
1573 if len(filename) > 50:
1577 id = self.bookmarksMenu.insertItem(\
1578 "%s%s : %d" % (dots, filename[-50:], bookmark))
1579 self.bookmarks[id] = (filename, bookmark)
1581 def handleBookmarkSelected(self, id):
1583 Private method to handle the bookmark selected signal.
1585 @param id index of the selected menu entry
1586 This acts as an index into the list of bookmarks
1587 that was created, when the bookmarks menu was built.
1589 self.displayPythonFile(self.bookmarks[id][0], self.bookmarks[id][1])
1591 def handleBookmarkToggled(self, editor):
1593 Private slot to handle the bookmarkToggled signal.
1595 It checks some bookmark actions and reemits the signal.
1597 @param editor editor that sent the signal
1599 if editor.hasBookmarks():
1600 self.bookmarkNextAct.setEnabled(1)
1601 self.bookmarkPreviousAct.setEnabled(1)
1602 self.bookmarkClearAct.setEnabled(1)
1604 self.bookmarkNextAct.setEnabled(0)
1605 self.bookmarkPreviousAct.setEnabled(0)
1606 self.bookmarkClearAct.setEnabled(0)
1607 self.emit(PYSIGNAL('bookmarkToggled'), (editor,))
1609 def handleGotoSyntaxError(self):
1611 Private method to handle the goto syntax error action.
1613 self.activeWindow().handleGotoSyntaxError()
1615 def handleClearAllSyntaxErrors(self):
1617 Private method to handle the clear all syntax errors action.
1619 for editor in self.editors:
1620 editor.handleClearSyntaxError()
1622 def handleSyntaxErrorToggled(self, editor):
1624 Private slot to handle the syntaxerrorToggled signal.
1626 It checks some syntax error actions and reemits the signal.
1628 @param editor editor that sent the signal
1630 if editor.hasSyntaxErrors():
1631 self.syntaxErrorGotoAct.setEnabled(1)
1632 self.syntaxErrorClearAct.setEnabled(1)
1634 self.syntaxErrorGotoAct.setEnabled(0)
1635 self.syntaxErrorClearAct.setEnabled(0)
1636 self.emit(PYSIGNAL('syntaxerrorToggled'), (editor,))
1638 ##################################################################
1639 ## Below are general utility methods
1640 ##################################################################
1642 def handleResetUI(self):
1644 Public slot to handle the resetUI signal.
1646 editor = self.activeWindow()
1650 line, pos = editor.getCursorPosition()
1651 self.setSbFile(editor.getFileName(), line+1, pos)
1653 def closeViewManager(self):
1655 Public method to shutdown the viewmanager.
1657 If it cannot close all editor windows, it aborts the shutdown process.
1659 @return flag indicating success (boolean)
1661 self.handleCloseAll()
1662 if len(self.editors):
1667 def handleLastEditorClosed(self):
1669 Private slot to handle the lastEditorClosed signal.
1674 def handleEditorOpened(self):
1676 Private slot to handle the editorOpened signal.
1678 self.closeActGrp.setEnabled(1)
1679 self.saveActGrp.setEnabled(1)
1680 self.printAct.setEnabled(1)
1681 self.printSelAct.setEnabled(1)
1682 self.editActGrp.setEnabled(1)
1683 self.searchActGrp.setEnabled(1)
1684 self.viewActGrp.setEnabled(1)
1685 self.viewFoldActGrp.setEnabled(1)
1686 self.unhighlightAct.setEnabled(1)
1687 self.splitViewAct.setEnabled(1)
1688 self.splitOrientationAct.setEnabled(1)
1689 self.macroActGrp.setEnabled(1)
1690 self.bookmarkActGrp.setEnabled(1)
1692 # activate the autosave timer
1693 if not self.autosaveTimer.isActive() and \
1694 self.autosaveInterval > 0:
1695 self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
1698 def checkActions(self, editor, setSb=1):
1700 Private slot to check some actions for their enable/disable status and set the statusbar info.
1702 @param editor editor window
1703 @param setSb flag indicating an update of the status bar is wanted (boolean)
1705 if editor is not None:
1706 self.saveAct.setEnabled(editor.modified)
1707 self.revertAct.setEnabled(editor.modified)
1709 lex = editor.getLexer()
1711 self.commentAct.setEnabled(lex.canBlockComment())
1712 self.uncommentAct.setEnabled(lex.canBlockComment())
1713 self.streamCommentAct.setEnabled(lex.canStreamComment())
1714 self.boxCommentAct.setEnabled(lex.canBoxComment())
1716 self.commentAct.setEnabled(0)
1717 self.uncommentAct.setEnabled(0)
1718 self.streamCommentAct.setEnabled(0)
1719 self.boxCommentAct.setEnabled(0)
1721 if editor.hasBookmarks():
1722 self.bookmarkNextAct.setEnabled(1)
1723 self.bookmarkPreviousAct.setEnabled(1)
1724 self.bookmarkClearAct.setEnabled(1)
1726 self.bookmarkNextAct.setEnabled(0)
1727 self.bookmarkPreviousAct.setEnabled(0)
1728 self.bookmarkClearAct.setEnabled(0)
1730 if editor.hasSyntaxErrors():
1731 self.syntaxErrorGotoAct.setEnabled(1)
1732 self.syntaxErrorClearAct.setEnabled(1)
1734 self.syntaxErrorGotoAct.setEnabled(0)
1735 self.syntaxErrorClearAct.setEnabled(0)
1737 if editor.canAutoCompleteFromAPIs():
1738 self.autoCompleteFromAPIsAct.setEnabled(1)
1740 self.autoCompleteFromAPIsAct.setEnabled(0)
1743 line, pos = editor.getCursorPosition()
1744 self.setSbFile(editor.getFileName(), line+1, pos)
1746 self.emit(PYSIGNAL('checkActions'), (editor,))
1748 def handlePreferencesChanged(self):
1750 Public slot to handle the preferencesChanged signal.
1752 This method performs the following actions
1754 <li>reread the colours for the syntax highlighting</li>
1755 <li>reloads the already created API objetcs</li>
1756 <li>starts or stops the autosave timer</li>
1757 <li><b>Note</b>: changes in viewmanager type are activated
1758 on an application restart.</li>
1761 # reload api information
1762 for language, api in self.apis.items():
1764 apifiles = Preferences.getEditorAPI(language)
1767 for apifile in apifiles:
1770 self.apis[language] = None
1772 # reload editor settings
1773 for editor in self.editors:
1774 editor.readSettings()
1776 # reload the autosave timer setting
1777 self.autosaveInterval = Preferences.getEditor("AutosaveInterval")
1778 if len(self.editors):
1779 if self.autosaveTimer.isActive() and \
1780 self.autosaveInterval == 0:
1781 self.autosaveTimer.stop()
1782 elif not self.autosaveTimer.isActive() and \
1783 self.autosaveInterval > 0:
1784 self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
1786 def handleEditorSaved(self, fn):
1788 Public slot to handle the editorSaved signal.
1790 It simply reemits the signal.
1792 @param fn filename of the saved editor
1794 self.emit(PYSIGNAL('editorSaved'), (fn,))
1796 def handleCursorChanged(self, fn, line, pos):
1798 Private slot to handle the cursorChanged signal.
1800 It emits the signal cursorChanged with parameter editor.
1802 @param fn filename (string)
1803 @param line line number of the cursor (int)
1804 @param pos position in line of the cursor (int)
1806 self.setSbFile(fn, line, pos)
1807 self.emit(PYSIGNAL('cursorChanged'), (self.getOpenEditor(fn),))
1809 def handleBreakpointToggled(self, editor):
1811 Private slot to handle the breakpointToggled signal.
1813 It simply reemits the signal.
1815 @param editor editor that sent the signal
1817 self.emit(PYSIGNAL('breakpointToggled'), (editor,))
1820 def getProject(self):
1822 Public method to get a reference to the Project object.
1824 @return Reference to the Project object (Project.Project)
1826 return self.ui.getProject()
1828 def getActions(self, type):
1830 Public method to get a list of all actions.
1832 @param type string denoting the action set to get.
1833 It must be one of "edit", "file", "search",
1835 @return list of all actions (list of QAction)
1838 exec 'actionList = self.%sActions[:]' % type
1844 def editorCommand(self, cmd):
1846 Private method to send an editor command to the active window.
1848 @param cmd the scintilla command to be sent
1850 aw = self.activeWindow()
1852 aw.SendScintilla(cmd)
1854 ##################################################################
1855 ## Below are protected utility methods
1856 ##################################################################
1858 def _getOpenStartDir(self):
1860 Protected method to return the starting directory for a file open dialog.
1862 The appropriate starting directory is calculated
1863 using the following search order, until a match is found:<br />
1864 1: Directory of currently active editor<br />
1865 2: Directory of currently active Project<br />
1868 @return String name of directory to start or None
1870 # if we have an active source, return its path
1871 if self.activeWindow() is not None and \
1872 self.activeWindow().getFileName():
1873 return os.path.dirname(self.activeWindow().getFileName())
1875 # ok, try if there is an active project and return its path
1876 elif self.getProject().isOpen():
1877 return self.getProject().ppath
1881 userDir=os.path.expanduser("~/Eficas_install/")
1887 def _getOpenFileFilter(self):
1889 Protected method to return the active filename filter for a file open dialog.
1891 The appropriate filename filter is determined by file extension of
1892 the currently active editor.
1894 @return name of the filename filter (QString) or None
1896 if self.activeWindow() is not None and \
1897 self.activeWindow().getFileName():
1898 ext = os.path.splitext(self.activeWindow().getFileName())[1]
1900 return QString(self.ext2Filter[ext])
1911 Module implementing a tabbed viewmanager class.
1916 class TabWidget(QTabWidget):
1918 Class implementing a custimized TabWidget.
1920 def __init__(self, parent):
1924 @param parent parent widget (QWidget)
1926 QTabWidget.__init__(self, parent)
1931 self.connect(self, SIGNAL("currentChanged(QWidget *)"), self.handleCurrentChanged)
1933 def handleCurrentChanged(self):
1935 Private slot called by the currentChanged signal.
1937 self.curIndex = self.currentPageIndex()
1939 def addTab(self, editor, title):
1941 Overwritten method to add a new tab.
1943 @param editor the editor object to be added (QScintilla.Editor.Editor)
1944 @param title title for the new tab (string, QString or QTab)
1946 QTabWidget.addTab(self, editor, title)
1948 if not editor in self.editors:
1949 self.editors.append(editor)
1950 self.connect(editor, PYSIGNAL('captionChanged'),
1951 self.handleCaptionChange)
1953 def showPage(self, editor):
1955 Overridden method to show a tab.
1957 @param editor the editor object to be shown (QScintilla.Editor.Editor)
1959 QTabWidget.showPage(self, editor)
1960 self.curIndex = self.indexOf(editor)
1964 Public slot used to show the next tab.
1968 if self.curIndex == self.count():
1971 QTabWidget.showPage(self, self.page(self.curIndex))
1975 Public slot used to show the previous tab.
1979 if self.curIndex == -1:
1980 self.curIndex = self.count() - 1
1982 QTabWidget.showPage(self, self.page(self.curIndex))
1984 def handleCaptionChange(self, cap, editor):
1986 Private method to handle Caption change signals from the editor.
1988 Updates the listview text to reflect the new caption information.
1990 @param cap Caption for the editor
1991 @param editor Editor to update the caption for
1993 fn = editor.getFileName()
1995 txt = os.path.basename(fn)
1996 if editor.isReadOnly():
1997 txt = '%s (ro)' % txt
1998 self.changeTab(editor, txt)
2000 def removePage(self, object):
2002 Overwritten method to remove a page.
2004 @param object object to be removed (QObject)
2006 QTabWidget.removePage(self, object)
2008 self.disconnect( object, PYSIGNAL('captionChanged'),
2009 self.handleCaptionChange )
2010 self.editors.remove(object)
2012 def hasEditor(self, editor):
2014 Public method to check for an editor.
2016 @param editor editor object to check for
2017 @return flag indicating, whether the editor to be checked belongs
2018 to the list of editors managed by this tab widget.
2020 return editor in self.editors
2022 def hasEditors(self):
2024 Public method to test, if any editor is managed.
2026 @return flag indicating editors are managed
2028 return len(self.editors) and 1 or 0
2030 class Tabview(QSplitter, ViewManager):
2032 Class implementing a tabbed viewmanager class embedded in a splitter.
2034 @signal lastEditorClosed emitted after the last editor window was closed
2035 @signal editorOpened emitted after an editor window was opened
2036 @signal editorSaved emitted after an editor window was saved
2038 def __init__(self,parent, ui):
2042 @param parent parent widget (QWidget)
2043 @param ui reference to the main user interface
2044 @param dbs reference to the debug server object
2046 self.tabWidgets = []
2048 QSplitter.__init__(self,parent)
2049 ViewManager.__init__(self, ui)
2050 tw = TabWidget(self)
2051 self.tabWidgets.append(tw)
2052 self.currentTabWidget = tw
2053 self.connect(tw, SIGNAL('currentChanged(QWidget*)'),
2054 self.handleCurrentChanged)
2055 tw.installEventFilter(self)
2056 tw.tabBar().installEventFilter(self)
2057 self.setOrientation(QSplitter.Vertical)
2059 def initViewActions(self):
2061 Protected method defining the user interface actions for the view commands.
2063 ViewManager.initViewActions(self)
2065 self.nextTabAct = QAction(self.trUtf8('Show next tab'),
2066 self.trUtf8('Show next tab'),
2067 QKeySequence(self.trUtf8('Ctrl+Alt+Tab')), self)
2068 self.connect(self.nextTabAct, SIGNAL('activated()'), self.nextTab)
2069 self.viewActions.append(self.nextTabAct)
2071 self.prevTabAct = QAction(self.trUtf8('Show previous tab'),
2072 self.trUtf8('Show previous tab'),
2073 QKeySequence(self.trUtf8('Shift+Ctrl+Alt+Tab')), self)
2074 self.connect(self.prevTabAct, SIGNAL('activated()'), self.prevTab)
2075 self.viewActions.append(self.prevTabAct)
2079 Private slot used to show the next tab of the current tabwidget.
2081 self.currentTabWidget.nextTab()
2085 Private slot used to show the previous tab of the current tabwidget.
2087 self.currentTabWidget.prevTab()
2089 def canCascade(self):
2091 Public method to signal if cascading of managed windows is available.
2093 @return flag indicating cascading of windows is available
2099 Public method to signal if tiling of managed windows is available.
2101 @return flag indicating tiling of windows is available
2107 public method to signal if splitting of the view is available.
2109 @return flag indicating splitting of the view is available.
2115 Public method to tile the managed windows.
2121 Public method to cascade the managed windows.
2125 def removeAllViews(self):
2127 Private method to remove all views (i.e. windows)
2129 for win in self.editors:
2130 self.removeView(win)
2132 def removeView(self, win):
2134 Private method to remove a view (i.e. window)
2136 @param win editor window to be removed
2138 for tw in self.tabWidgets:
2139 if tw.hasEditor(win):
2144 # if this was the last editor in this view, switch to the next, that
2145 # still has open editors
2146 for i in range(self.tabWidgets.index(tw), -1, -1) + \
2147 range(self.tabWidgets.index(tw) + 1, len(self.tabWidgets)):
2148 if self.tabWidgets[i].hasEditors():
2149 self.currentTabWidget = self.tabWidgets[i]
2150 self.activeWindow().setFocus()
2153 def addView(self, win, fn=None, title=None):
2155 Private method to add a view (i.e. window)
2157 @param win editor window to be added
2158 @param fn filename of this editor
2163 self.untitledCount += 1
2164 self.currentTabWidget.addTab(win, self.trUtf8("Untitled %1").arg(self.untitledCount))
2166 self.currentTabWidget.addTab(win, title)
2168 txt = os.path.basename(fn)
2169 if not QFileInfo(fn).isWritable():
2170 txt = '%s (ro)' % txt
2171 self.currentTabWidget.addTab(win, txt)
2172 self.currentTabWidget.setTabToolTip(win, os.path.dirname(fn))
2173 self.currentTabWidget.showPage(win)
2176 def showView(self, win, fn=None):
2178 Private method to show a view (i.e. window)
2180 @param win editor window to be shown
2181 @param fn filename of this editor
2184 for tw in self.tabWidgets:
2185 if tw.hasEditor(win):
2187 self.currentTabWidget = tw
2191 def activeWindow(self):
2193 Private method to return the active (i.e. current) window.
2195 @return reference to the active editor
2197 return self.currentTabWidget.currentPage()
2199 def handleShowWindowMenu(self, windowMenu):
2201 Private method to set up the viewmanager part of the Window menu.
2203 @param windowMenu reference to the window menu
2207 def initWindowActions(self):
2209 Define the user interface actions for window handling.
2213 def setEditorName(self, editor, newName):
2215 Change the displayed name of the editor.
2217 @param editor editor window to be changed
2218 @param newName new name to be shown (string or QString)
2220 self.currentTabWidget.changeTab(editor,
2221 os.path.basename(unicode(newName)))
2222 self.currentTabWidget.setTabToolTip(editor,
2223 os.path.dirname(unicode(newName)))
2225 def handleModificationStatusChanged(self, m, editor):
2227 Private slot to handle the modificationStatusChanged signal.
2229 @param m flag indicating the modification status (boolean)
2230 @param editor editor window changed
2232 for tw in self.tabWidgets:
2233 if tw.hasEditor(editor):
2236 tw.setTabIconSet(editor,
2237 QIconSet(utilIcons.getPixmap("fileModified.png")))
2238 elif editor.hasSyntaxErrors():
2239 tw.setTabIconSet(editor,
2240 QIconSet(utilIcons.getPixmap("syntaxError.png")))
2242 tw.setTabIconSet(editor,
2243 QIconSet(utilIcons.getPixmap("empty.png")))
2244 self.checkActions(editor)
2246 def handleSyntaxErrorToggled(self, editor):
2248 Private slot to handle the syntaxerrorToggled signal.
2250 @param editor editor that sent the signal
2252 for tw in self.tabWidgets:
2253 if tw.hasEditor(editor):
2255 if editor.hasSyntaxErrors():
2256 tw.setTabIconSet(editor,
2257 QIconSet(utilIcons.getPixmap("syntaxError.png")))
2259 tw.setTabIconSet(editor,
2260 QIconSet(utilIcons.getPixmap("empty.png")))
2262 ViewManager.handleSyntaxErrorToggled(self, editor)
2266 Public method used to split the current view.
2268 tw = TabWidget(self)
2270 self.tabWidgets.append(tw)
2271 self.currentTabWidget = self.tabWidgets[-1]
2272 self.connect(tw, SIGNAL('currentChanged(QWidget*)'),
2273 self.handleCurrentChanged)
2274 tw.installEventFilter(self)
2275 tw.tabBar().installEventFilter(self)
2276 self.setSizes([int(100/len(self.tabWidgets))] * len(self.tabWidgets))
2277 self.splitRemoveAct.setEnabled(1)
2279 def removeSplit(self):
2281 Public method used to remove the current split view.
2283 @return flag indicating successfull removal
2285 if len(self.tabWidgets) > 1:
2286 tw = self.currentTabWidget
2288 savedEditors = tw.editors[:]
2289 for editor in savedEditors:
2290 res &= self.closeEditor(editor)
2292 i = self.tabWidgets.index(tw)
2293 if i == len(self.tabWidgets)-1:
2295 self.tabWidgets.remove(tw)
2297 self.currentTabWidget = self.tabWidgets[i]
2298 if len(self.tabWidgets) == 1:
2299 self.splitRemoveAct.setEnabled(0)
2304 def setSplitOrientation(self, orientation):
2306 Public method used to set the orientation of the split view.
2308 @param orientation orientation of the split
2309 (QSplitter.Horizontal or QSplitter.Vertical)
2311 self.setOrientation(orientation)
2313 def handleCurrentChanged(self, editor):
2315 Private slot to handle the currentChanged signal.
2317 @param editor selected editor window
2319 self.checkActions(editor)
2322 def eventFilter(self, watched, event):
2324 Method called to filter the event queue.
2326 @param watched the QObject being watched
2327 @param event the event that occurred
2330 if event.type() == QEvent.MouseButtonPress and \
2331 not event.button() == Qt.RightButton:
2332 if isinstance(watched, QTabWidget):
2333 self.currentTabWidget = watched
2334 elif isinstance(watched, QTabBar):
2335 self.currentTabWidget = watched.parent()
2336 elif isinstance(watched, QScintilla.Editor.Editor):
2337 for tw in self.tabWidgets:
2338 if tw.hasEditor(watched):
2339 self.currentTabWidget = tw
2342 aw = self.activeWindow()
2344 self.checkActions(aw)
2350 class MyTabview(Tabview):
2352 Base class inherited by all specific viewmanager classes.
2354 It defines the interface to be implemented by specific
2355 viewmanager classes and all common methods.
2357 @signal lastEditorClosed emitted after the last editor window was closed
2358 @signal editorOpened(string) emitted after an editor window was opened
2359 @signal editorSaved(string) emitted after an editor window was saved
2360 @signal checkActions(editor) emitted when some actions should be checked
2362 @signal cursorChanged(editor) emitted after the cursor position of the active
2364 @signal breakpointToggled(editor) emitted when a breakpoint is toggled.
2365 @signal bookmarkToggled(editor) emitted when a bookmark is toggled.
2367 def __init__(self, parent, ui):
2368 Tabview.__init__(self, parent, ui)
2370 self.code =self.appli.code
2371 self.salome=self.appli.salome
2374 def initRecent(self) :
2375 rep=self.appli.CONFIGURATION.rep_user
2376 monFichier=rep+"/listefichiers_"+self.code
2380 while ( index < 9) :
2383 l=(ligne.split("\n"))[0]
2384 self.recent.append(l)
2391 def SauveRecents(self) :
2392 rep=self.appli.CONFIGURATION.rep_user
2393 monFichier=rep+"/listefichiers_"+self.code
2395 f=open(monFichier,'w')
2396 if len(self.recent) == 0 : return
2398 while ( index < len(self.recent)):
2399 ligne=str(self.recent[index])+"\n"
2410 def checkActions(self, editor, setSb=1):
2412 Private slot to check some actions for their enable/disable status and set the statusbar info.
2414 @param editor editor window
2415 @param setSb flag indicating an update of the status bar is wanted (boolean)
2417 self.emit(PYSIGNAL('checkActions'), (editor,))
2420 def addToRecentList(self, fn):
2422 Public slot to add a filename to the list of recently opened files.
2424 @param fn name of the file to be added
2426 self.recent.remove(fn)
2427 self.recent.prepend(fn)
2428 if len(self.recent) > 9:
2429 self.recent = self.recent[:9]
2431 def handleOpen(self,fn=None,patron=0,units=None):
2433 Public slot to open a Python JDC file.
2435 @param prog name of file to be opened (string or QString)
2436 patron booleen pour indiquer si le fichier doit etre
2437 ajoute a la liste des fichiers ouverts recemment
2439 # Get the file name if one wasn't specified.
2442 fn = QFileDialog.getOpenFileName(self._getOpenStartDir(),
2443 self.trUtf8('JDC Files (*.comm);;''All Files (*)'), self.ui)
2448 fn = normabspath(unicode(fn))
2450 newWin, editor = self.getEditor(fn,units=units)
2453 self.handleModificationStatusChanged(editor.modified, editor)
2454 self.checkActions(editor)
2456 # insert filename into list of recently opened files
2457 if patron == 0 : self.addToRecentList(fn)
2460 ##################################################################
2461 ## Below are protected utility methods
2462 #################################################################
2464 def _getOpenStartDir(self):
2466 Protected method to return the starting directory for a file open dialog.
2468 The appropriate starting directory is calculated
2469 using the following search order, until a match is found:<br />
2470 1: Directory of currently active editor<br />
2471 2: Directory of currently active Project<br />
2474 @return String name of directory to start or None
2476 # if we have an active source, return its path
2477 if self.activeWindow() is not None and \
2478 self.activeWindow().getFileName():
2479 return os.path.dirname(self.activeWindow().getFileName())
2483 # None will cause open dialog to start with cwd
2485 userDir=self.appli.CONFIGURATION.savedir
2488 userDir=os.path.expanduser("~")
2494 def handleEditorOpened(self):
2496 Private slot to handle the editorOpened signal.
2500 def handleModificationStatusChanged(self, m, editor):
2502 Private slot to handle the modificationStatusChanged signal.
2504 @param m flag indicating the modification status (boolean)
2505 @param editor editor window changed
2507 for tw in self.tabWidgets:
2508 if tw.hasEditor(editor):
2511 #tw.setTabIconSet(editor,
2512 # QIconSet(utilIcons.getPixmap("fileModified.png")))
2514 elif editor.hasSyntaxErrors():
2515 tw.setTabIconSet(editor,
2516 QIconSet(utilIcons.getPixmap("syntaxError.png")))
2518 tw.setTabIconSet(editor,
2519 QIconSet(utilIcons.getPixmap("empty.png")))
2520 self.checkActions(editor)
2525 if __name__=='__main__':
2528 if hasattr(prefs,'encoding'):
2529 # Hack pour changer le codage par defaut des strings
2532 sys.setdefaultencoding(prefs.encoding)
2533 del sys.setdefaultencoding
2536 #CS_pbruno note: fait implicitement des trucs ces imports (grr)
2538 from Editeur import import_code
2539 from Editeur import session
2541 # Analyse des arguments de la ligne de commande
2542 options=session.parse(sys.argv)
2544 app = QApplication(sys.argv)
2546 mw = MyTabview(None,None)
2547 app.setMainWidget(mw)
2548 app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
2550 mw.getEditor('azAster.comm')
2551 mw.getEditor('azAster2.comm')
2552 res = app.exec_loop()