7 Module implementing the browser model. |
7 Module implementing the browser model. |
8 """ |
8 """ |
9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 import sys |
|
13 import os |
12 import os |
14 import fnmatch |
13 import fnmatch |
|
14 import json |
15 |
15 |
16 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, \ |
16 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, \ |
17 QFileSystemWatcher, Qt |
17 QFileSystemWatcher, Qt, QProcess |
18 from PyQt4.QtGui import QImageReader, QApplication, QFont |
18 from PyQt4.QtGui import QImageReader, QApplication, QFont |
19 |
19 |
20 import UI.PixmapCache |
20 import UI.PixmapCache |
21 import Preferences |
21 import Preferences |
22 import Utilities |
22 import Utilities |
48 |
48 |
49 self.progDir = None |
49 self.progDir = None |
50 self.watchedItems = {} |
50 self.watchedItems = {} |
51 self.watcher = QFileSystemWatcher(self) |
51 self.watcher = QFileSystemWatcher(self) |
52 self.watcher.directoryChanged.connect(self.directoryChanged) |
52 self.watcher.directoryChanged.connect(self.directoryChanged) |
|
53 |
|
54 self.__sysPathInterpreter = "" |
|
55 self.__sysPathItem = None |
53 |
56 |
54 if not nopopulate: |
57 if not nopopulate: |
55 rootData = QApplication.translate("BrowserModel", "Name") |
58 rootData = QApplication.translate("BrowserModel", "Name") |
56 self.rootItem = BrowserItem(None, rootData) |
59 self.rootItem = BrowserItem(None, rootData) |
57 |
60 |
350 |
353 |
351 def __populateModel(self): |
354 def __populateModel(self): |
352 """ |
355 """ |
353 Private method to populate the browser model. |
356 Private method to populate the browser model. |
354 """ |
357 """ |
355 self._addItem(BrowserSysPathItem(self.rootItem), self.rootItem) |
|
356 |
|
357 self.toplevelDirs = [] |
358 self.toplevelDirs = [] |
358 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs') |
359 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs') |
359 if tdp: |
360 if tdp: |
360 self.toplevelDirs = tdp |
361 self.toplevelDirs = tdp |
361 else: |
362 else: |
366 d.absoluteFilePath())) |
367 d.absoluteFilePath())) |
367 |
368 |
368 for d in self.toplevelDirs: |
369 for d in self.toplevelDirs: |
369 itm = BrowserDirectoryItem(self.rootItem, d) |
370 itm = BrowserDirectoryItem(self.rootItem, d) |
370 self._addItem(itm, self.rootItem) |
371 self._addItem(itm, self.rootItem) |
|
372 |
|
373 def interpreterChanged(self, interpreter): |
|
374 """ |
|
375 Public method to handle a change of the debug client's interpreter. |
|
376 |
|
377 @param interpreter interpreter of the debug client (string) |
|
378 """ |
|
379 if interpreter and "python" in interpreter.lower(): |
|
380 if interpreter.endswith("w.exe"): |
|
381 interpreter = interpreter.replace("w.exe", ".exe") |
|
382 if self.__sysPathInterpreter != interpreter: |
|
383 self.__sysPathInterpreter = interpreter |
|
384 # step 1: remove sys.path entry |
|
385 if self.__sysPathItem is not None: |
|
386 self.beginRemoveRows( |
|
387 QModelIndex(), self.__sysPathItem.row(), |
|
388 self.__sysPathItem.row()) |
|
389 self.rootItem.removeChild(self.__sysPathItem) |
|
390 self.endRemoveRows() |
|
391 self.__sysPathItem = None |
|
392 |
|
393 if self.__sysPathInterpreter: |
|
394 # step 2: add a new one |
|
395 self.__sysPathItem = BrowserSysPathItem(self.rootItem) |
|
396 self.addItem(self.__sysPathItem) |
|
397 else: |
|
398 # remove sys.path entry |
|
399 if self.__sysPathItem is not None: |
|
400 self.beginRemoveRows( |
|
401 QModelIndex(), self.__sysPathItem.row(), |
|
402 self.__sysPathItem.row()) |
|
403 self.rootItem.removeChild(self.__sysPathItem) |
|
404 self.endRemoveRows() |
|
405 self.__sysPathItem = None |
|
406 self.__sysPathInterpreter = "" |
371 |
407 |
372 def programChange(self, dirname): |
408 def programChange(self, dirname): |
373 """ |
409 """ |
374 Public method to change the entry for the directory of file being |
410 Public method to change the entry for the directory of file being |
375 debugged. |
411 debugged. |
522 Public method to populate a sys.path item's subtree. |
558 Public method to populate a sys.path item's subtree. |
523 |
559 |
524 @param parentItem reference to the sys.path item to be populated |
560 @param parentItem reference to the sys.path item to be populated |
525 @param repopulate flag indicating a repopulation (boolean) |
561 @param repopulate flag indicating a repopulation (boolean) |
526 """ |
562 """ |
527 if len(sys.path) > 0: |
563 if self.__sysPathInterpreter: |
528 if repopulate: |
564 script = "import sys, json; print(json.dumps(sys.path))" |
529 self.beginInsertRows( |
565 proc = QProcess() |
530 self.createIndex(parentItem.row(), 0, parentItem), |
566 proc.start(self.__sysPathInterpreter, ["-c", script]) |
531 0, len(sys.path) - 1) |
567 finished = proc.waitForFinished(3000) |
532 for p in sys.path: |
568 if finished: |
533 if p == '': |
569 procOutput = str(proc.readAllStandardOutput(), |
534 p = os.getcwd() |
570 Preferences.getSystem("IOEncoding"), |
535 |
571 'replace') |
536 node = BrowserDirectoryItem(parentItem, p) |
572 syspath = [p for p in json.loads(procOutput) if p] |
537 self._addItem(node, parentItem) |
573 if len(syspath) > 0: |
538 if repopulate: |
574 if repopulate: |
539 self.endInsertRows() |
575 self.beginInsertRows( |
|
576 self.createIndex(parentItem.row(), 0, parentItem), |
|
577 0, len(syspath) - 1) |
|
578 for p in syspath: |
|
579 if os.path.isdir(p): |
|
580 node = BrowserDirectoryItem(parentItem, p) |
|
581 else: |
|
582 node = BrowserFileItem(parentItem, p) |
|
583 self._addItem(node, parentItem) |
|
584 if repopulate: |
|
585 self.endInsertRows() |
|
586 else: |
|
587 proc.kill() |
540 |
588 |
541 def populateFileItem(self, parentItem, repopulate=False): |
589 def populateFileItem(self, parentItem, repopulate=False): |
542 """ |
590 """ |
543 Public method to populate a file item's subtree. |
591 Public method to populate a file item's subtree. |
544 |
592 |
584 dict["@@Globals@@"].globals, |
632 dict["@@Globals@@"].globals, |
585 QApplication.translate("BrowserModel", "Globals")) |
633 QApplication.translate("BrowserModel", "Globals")) |
586 self._addItem(node, parentItem) |
634 self._addItem(node, parentItem) |
587 if repopulate: |
635 if repopulate: |
588 self.endInsertRows() |
636 self.endInsertRows() |
|
637 parentItem._populated = True |
589 |
638 |
590 def populateClassItem(self, parentItem, repopulate=False): |
639 def populateClassItem(self, parentItem, repopulate=False): |
591 """ |
640 """ |
592 Public method to populate a class item's subtree. |
641 Public method to populate a class item's subtree. |
593 |
642 |