├── .gitattributes ├── .gitignore ├── Extensions ├── About.py ├── BaseScintilla.py ├── BottomWidgets │ ├── Assistant.py │ ├── BookmarkWidget.py │ ├── FindInFiles.py │ ├── Messages.py │ ├── Profiler.py │ ├── RunWidget.py │ ├── TasksWidget.py │ └── __init__.py ├── BusyWidget.py ├── CodeEditor.py ├── CodeSnapshot.py ├── Diff.py ├── EditorSplitter.py ├── EditorTabWidget.py ├── EditorWindow │ ├── BuildStatusWidget.py │ ├── EditorWindow.py │ ├── VerticalSplitter.py │ └── __init__.py ├── ExternalLauncher.py ├── Favourites.py ├── FileExplorer.py ├── Global.py ├── GotoLineWidget.py ├── Library │ ├── AdvancedSearch.py │ ├── Library.py │ ├── LibraryAddDialog.py │ └── __init__.py ├── MiniMap.py ├── Notification.py ├── Outline │ ├── Outline.py │ ├── Python │ │ ├── __init__.py │ │ └── pyclbr.py │ └── __init__.py ├── PathLineEdit.py ├── Projects │ ├── NewProjectDialog.py │ ├── ProjectManager │ │ ├── Build.py │ │ ├── ConfigureProject.py │ │ ├── ProjectManager.py │ │ ├── ProjectView │ │ │ ├── ProgressWidget.py │ │ │ ├── ProjectView.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── Projects.py │ └── __init__.py ├── Refactor │ ├── Refactor.py │ ├── UsageDialog.py │ └── __init__.py ├── SearchWidget.py ├── Settings │ ├── ColorScheme │ │ ├── ColorChooser.py │ │ ├── ColorScheme.py │ │ ├── Lexers │ │ │ ├── CssLexer.py │ │ │ ├── HtmlLexer.py │ │ │ ├── PythonLexer.py │ │ │ ├── XmlLexer.py │ │ │ └── __init__.py │ │ ├── StyleEditor.py │ │ ├── StyleLexer.py │ │ └── __init__.py │ ├── GeneralSettings.py │ ├── Keymap.py │ ├── ModuleCompletion.py │ ├── SettingsWidget.py │ ├── SnippetsManager.py │ └── __init__.py ├── StackSwitcher.py ├── Start.py ├── StyleSheet.py ├── TextEditor.py ├── TextSnapshot.py ├── UseData.py ├── ViewSwitcher.py ├── Workspace.py ├── WritePad.py ├── ZoomWidget.py └── __init__.py ├── LICENSE ├── Pcode.py ├── README.md ├── Resources ├── LICENSE ├── PcodeProjects.zip ├── build │ └── 32bit │ │ ├── bases │ │ ├── Console.exe │ │ ├── ConsoleKeepPath.exe │ │ ├── Win32GUI.exe │ │ └── Win32Service.exe │ │ └── initscripts │ │ ├── Console.py │ │ ├── ConsoleKeepPath.py │ │ ├── ConsoleSetLibPath.py │ │ ├── SharedLib.py │ │ └── SharedLibSource.py ├── default_config.py ├── images │ ├── Arrow2-down.png │ ├── Arrow2-up.png │ ├── Clear Green Button.png │ ├── Dashboard.png │ ├── Fullscreen.png │ ├── Stop.png │ ├── Thumbs.db │ ├── Web.png │ ├── _0013_Printer.png │ ├── about.png │ ├── add.png │ ├── alerts │ │ ├── Thumbs.db │ │ ├── _0035_Flashlight.png │ │ ├── construction.png │ │ ├── toast_critical.png │ │ └── toast_warning.png │ ├── archive.png │ ├── arrow-045.png │ ├── asterisk-yellow.png │ ├── attibutes.png │ ├── block.png │ ├── block__.png │ ├── bold.png │ ├── bookmarked_url.png │ ├── border-horizontal.png │ ├── border-inside.png │ ├── border-vertical.png │ ├── border.png │ ├── box-document.png │ ├── box.png │ ├── brainstorming.png │ ├── build.png │ ├── cards_binds.png │ ├── cascade.png │ ├── chat.png │ ├── chat_selected.png │ ├── class.png │ ├── clear.png │ ├── collapse.png │ ├── comment-code.png │ ├── compass.png │ ├── compose.png │ ├── config.png │ ├── consulting.png │ ├── copy.png │ ├── crate.png │ ├── cross.png │ ├── cross_.png │ ├── cushion.png │ ├── cut.png │ ├── database.png │ ├── decrease_indent.png │ ├── disabled.png │ ├── disks-black.png │ ├── document_.png │ ├── down.png │ ├── edit-color.png │ ├── edit-lowercase.png │ ├── edit-number.png │ ├── edit-replace.png │ ├── edit-uppercase.png │ ├── edit.png │ ├── edit2.png │ ├── envelope.png │ ├── erase.png │ ├── err_mark.png │ ├── exit.png │ ├── expand.png │ ├── extender-down.png │ ├── extender-up.png │ ├── fileSaveAll.png │ ├── filter-disable.png │ ├── findDown.png │ ├── findUp.png │ ├── find_in_files.png │ ├── finished-work.png │ ├── flag-green.png │ ├── flag.png │ ├── foaf.png │ ├── fold.png │ ├── folder-horizontal.png │ ├── folder.png │ ├── folder_closed.png │ ├── folder_open.png │ ├── function.png │ ├── gear.png │ ├── graphic-design.png │ ├── guide.png │ ├── haiku-wide.png │ ├── hire-me.png │ ├── history.png │ ├── home.png │ ├── icon.png │ ├── in.png │ ├── inbox--minus.png │ ├── inbox--plus.png │ ├── inbox.png │ ├── increase_indent.png │ ├── issue.png │ ├── italic.png │ ├── led.png │ ├── library.png │ ├── lightbulb.png │ ├── lightning.png │ ├── links.png │ ├── links_selected.png │ ├── location.png │ ├── locked_script.png │ ├── login.png │ ├── mail_check.png │ ├── mail_pinned.png │ ├── mail_thread.png │ ├── map_marker.png │ ├── mark.png │ ├── messages │ │ ├── Thumbs.db │ │ ├── blue.png │ │ ├── orange.png │ │ └── red.png │ ├── milestone.png │ ├── minus.png │ ├── new-item.png │ ├── new.png │ ├── notes.png │ ├── notes_selected.png │ ├── open_file.png │ ├── orange.png │ ├── out.png │ ├── page.png │ ├── paste.png │ ├── pencil.png │ ├── plus.png │ ├── product.png │ ├── project.png │ ├── properties.png │ ├── redo.png │ ├── remove.png │ ├── rerun.png │ ├── run.png │ ├── save_.png │ ├── scope.png │ ├── script.png │ ├── script_grey.png │ ├── search.png │ ├── security │ │ ├── Thumbs.db │ │ ├── allowed.png │ │ ├── attention.png │ │ ├── clean.png │ │ ├── danger.png │ │ ├── denied.png │ │ ├── requesting.png │ │ ├── turbo.png │ │ ├── turbo_inactive.png │ │ └── warning.png │ ├── security_disabled.png │ ├── settings.png │ ├── shell.png │ ├── speech_bubble.png │ ├── splash.png │ ├── star.png │ ├── tag.png │ ├── templates.png │ ├── text_select.png │ ├── tile.png │ ├── tree.png │ ├── ui-button-navigation.png │ ├── ui-menu-blue.png │ ├── ui-scroll-pane-blog.png │ ├── ui-text-field.png │ ├── undo.png │ ├── up.png │ ├── windows.png │ ├── wooden-box.png │ ├── zone-medium.png │ └── zoom.png ├── style │ └── images │ │ ├── Arrow Left.png │ │ ├── Arrow Right.png │ │ ├── Thumbs.db │ │ ├── close-hover.png │ │ ├── close-pressed.png │ │ ├── close1.png │ │ ├── close_black.png │ │ ├── closed.png │ │ ├── document-tree.png │ │ ├── downarrow.png │ │ ├── group_open.png │ │ ├── leftarrow.png │ │ ├── panel-top-selected.png │ │ ├── rightarrow.png │ │ ├── tear.png │ │ ├── uparrow.png │ │ └── vignette.png └── venv │ └── scripts │ ├── nt │ ├── Activate.ps1 │ ├── Deactivate.ps1 │ ├── activate.bat │ ├── deactivate.bat │ └── pydoc.py │ └── posix │ ├── activate │ └── pydoc ├── Xtra ├── __init__.py ├── autopep8.py └── pep8.py ├── __init__.py ├── cx_Freeze ├── __init__.py ├── common.py ├── dist.py ├── finder.py ├── freezer.py ├── hooks.py ├── macdist.py ├── main.py ├── setupwriter.py └── windist.py ├── docs └── screens │ ├── 1.png │ ├── 2.png │ └── 3.png ├── pyflakes ├── __init__.py ├── __main__.py ├── api.py ├── checker.py ├── messages.py ├── reporter.py ├── scripts │ ├── __init__.py │ └── pyflakes.py └── test │ ├── __init__.py │ ├── harness.py │ ├── test_api.py │ ├── test_doctests.py │ ├── test_imports.py │ ├── test_other.py │ ├── test_return_with_arguments_inside_generator.py │ └── test_undefined_names.py ├── rope ├── __init__.py ├── base │ ├── __init__.py │ ├── arguments.py │ ├── ast.py │ ├── astutils.py │ ├── builtins.py │ ├── change.py │ ├── codeanalyze.py │ ├── default_config.py │ ├── evaluate.py │ ├── exceptions.py │ ├── fscommands.py │ ├── history.py │ ├── libutils.py │ ├── oi │ │ ├── __init__.py │ │ ├── doa.py │ │ ├── memorydb.py │ │ ├── objectdb.py │ │ ├── objectinfo.py │ │ ├── runmod.py │ │ ├── soa.py │ │ ├── soi.py │ │ └── transform.py │ ├── prefs.py │ ├── project.py │ ├── pycore.py │ ├── pynames.py │ ├── pynamesdef.py │ ├── pyobjects.py │ ├── pyobjectsdef.py │ ├── pyscopes.py │ ├── resourceobserver.py │ ├── resources.py │ ├── simplify.py │ ├── stdmods.py │ ├── taskhandle.py │ ├── utils.py │ └── worder.py ├── contrib │ ├── __init__.py │ ├── autoimport.py │ ├── changestack.py │ ├── codeassist.py │ ├── finderrors.py │ ├── findit.py │ ├── fixmodnames.py │ ├── fixsyntax.py │ └── generate.py └── refactor │ ├── __init__.py │ ├── change_signature.py │ ├── encapsulate_field.py │ ├── extract.py │ ├── functionutils.py │ ├── importutils │ ├── __init__.py │ ├── actions.py │ ├── importinfo.py │ └── module_imports.py │ ├── inline.py │ ├── introduce_factory.py │ ├── introduce_parameter.py │ ├── localtofield.py │ ├── method_object.py │ ├── move.py │ ├── multiproject.py │ ├── occurrences.py │ ├── patchedast.py │ ├── rename.py │ ├── restructure.py │ ├── similarfinder.py │ ├── sourceutils.py │ ├── suites.py │ ├── topackage.py │ ├── usefunction.py │ └── wildcards.py ├── settings.ini └── venv └── __init__.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | eggs 11 | parts 12 | bin 13 | var 14 | sdist 15 | develop-eggs 16 | .installed.cfg 17 | lib 18 | lib64 19 | __pycache__ 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject -------------------------------------------------------------------------------- /Extensions/About.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PyQt4 import QtGui, QtCore 4 | 5 | from Xtra import autopep8 6 | from Xtra import pep8 7 | import pyflakes 8 | import rope 9 | import cx_Freeze 10 | 11 | 12 | class About(QtGui.QDialog): 13 | 14 | def __init__(self, parent=None): 15 | QtGui.QDialog.__init__(self, parent, 16 | QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint) 17 | 18 | self.setWindowTitle("About") 19 | 20 | mainLayout = QtGui.QVBoxLayout() 21 | mainLayout.setMargin(0) 22 | self.setLayout(mainLayout) 23 | 24 | self.setFixedSize(500, 270) 25 | 26 | form = QtGui.QFormLayout() 27 | form.setMargin(10) 28 | form.addRow("Version", QtGui.QLabel("0.1.5")) 29 | form.addRow("Author", QtGui.QLabel("Amoatey Harrison")) 30 | form.addRow("Email", QtGui.QLabel("fortharris@gmail.com")) 31 | 32 | mainLayout.addLayout(form) 33 | 34 | hbox = QtGui.QHBoxLayout() 35 | hbox.setContentsMargins(5, 0, 5, 0) 36 | mainLayout.addLayout(hbox) 37 | 38 | self.label = QtGui.QLabel("External Libraries:") 39 | hbox.addWidget(self.label) 40 | 41 | hbox.addStretch(1) 42 | 43 | licenseButton = QtGui.QPushButton("License") 44 | licenseButton.setCheckable(True) 45 | licenseButton.clicked.connect(self.showLicense) 46 | hbox.addWidget(licenseButton) 47 | 48 | self.view = QtGui.QStackedWidget() 49 | mainLayout.addWidget(self.view) 50 | 51 | table = QtGui.QTreeWidget() 52 | table.setMinimumHeight(150) 53 | table.setIndentation(0) 54 | table.setHeaderLabels(["Name", "Version", "Author"]) 55 | table.setColumnWidth(0, 150) 56 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 57 | ["Rope", rope.VERSION, "Ali Gholami Rudi"])) 58 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 59 | ["PyFlakes", pyflakes.__version__, "Florent Xicluna"])) 60 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 61 | ["Pep8", pep8.__version__, "Florent Xicluna"])) 62 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 63 | ["PyQt4", "4.11.4", "Riverbank Computing Limited"])) 64 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 65 | ["AutoPep8", autopep8.__version__, "Hideo Hattori"])) 66 | table.addTopLevelItem(QtGui.QTreeWidgetItem( 67 | ["CxFreeze", cx_Freeze.version, "Anthony Tuininga"])) 68 | self.view.addWidget(table) 69 | 70 | self.licenseEdit = QtGui.QTextEdit() 71 | file = open(os.path.join("Resources", "LICENSE"), "r") 72 | self.licenseEdit.setText(file.read()) 73 | file.close() 74 | 75 | self.view.addWidget(self.licenseEdit) 76 | 77 | self.hide() 78 | 79 | def showLicense(self, checked): 80 | if checked: 81 | self.view.setCurrentIndex(1) 82 | self.label.hide() 83 | else: 84 | self.view.setCurrentIndex(0) 85 | self.label.show() 86 | -------------------------------------------------------------------------------- /Extensions/BottomWidgets/BookmarkWidget.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | 4 | class BookmarkWidget(QtGui.QTreeWidget): 5 | 6 | def __init__(self, editorTabWidget, bottomStackSwitcher, parent=None): 7 | QtGui.QTreeWidget.__init__(self, parent) 8 | 9 | self.markersLineList = [] 10 | self.editorTabWidget = editorTabWidget 11 | self.bottomStackSwitcher = bottomStackSwitcher 12 | 13 | self.setColumnCount(3) 14 | self.setHeaderLabels(["#", "Line", "Text"]) 15 | self.itemPressed.connect(self.locateItem) 16 | 17 | self.setColumnWidth(0, 50) 18 | self.setColumnWidth(1, 80) 19 | 20 | self.loadTimer = QtCore.QTimer() 21 | self.loadTimer.setSingleShot(True) 22 | self.loadTimer.timeout.connect(self.load) 23 | 24 | self.editorTabWidget.currentEditorTextChanged.connect( 25 | self.startLoadTimer) 26 | self.editorTabWidget.bookmarksChanged.connect(self.loadTimer.start) 27 | 28 | def startLoadTimer(self): 29 | self.loadTimer.start(1000) 30 | 31 | def load(self): 32 | markerLines = [] 33 | editor = self.editorTabWidget.getEditor() 34 | bookmarks = editor.getBookmarks() 35 | for line in bookmarks: 36 | markerLines.append((line, editor.text(line).strip())) 37 | if markerLines != self.markersLineList: 38 | self.markersLineList = markerLines 39 | self.clear() 40 | m = 1 41 | for i in markerLines: 42 | item = QtGui.QTreeWidgetItem() 43 | item.setText(0, str(m)) 44 | item.setText(1, str(i[0] + 1)) 45 | item.setToolTip(2, i[1]) 46 | item.setText(2, i[1]) 47 | self.addTopLevelItem(item) 48 | 49 | m += 1 50 | self.bottomStackSwitcher.setCount(self, str(len(markerLines))) 51 | 52 | def locateItem(self, item): 53 | lineNum = int(item.data(1, 0)) - 1 54 | self.editorTabWidget.showLine(lineNum) 55 | -------------------------------------------------------------------------------- /Extensions/BottomWidgets/Messages.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtGui, QtCore 3 | 4 | 5 | class MessagesWidget(QtGui.QTreeWidget): 6 | 7 | def __init__(self, bottomStackSwitcher, vSplitter, parent=None): 8 | QtGui.QTreeWidget.__init__(self, parent) 9 | 10 | self.bottomStackSwitcher = bottomStackSwitcher 11 | self.vSplitter = vSplitter 12 | 13 | self.setHeaderLabels(["Message", "Time"]) 14 | self.setColumnWidth(0, 400) 15 | self.setColumnWidth(1, 40) 16 | 17 | def addMessage(self, messType, title, messageList): 18 | parentItem = QtGui.QTreeWidgetItem(self) 19 | if messType == 0: 20 | parentItem.setIcon(0, QtGui.QIcon( 21 | os.path.join("Resources", "images", "security", "attention"))) 22 | elif messType == 1: 23 | parentItem.setIcon(0, QtGui.QIcon( 24 | os.path.join("Resources", "images", "security", "warning"))) 25 | elif messType == 2: 26 | parentItem.setIcon(0, QtGui.QIcon( 27 | os.path.join("Resources", "images", "security", "danger"))) 28 | parentItem.setText(0, title) 29 | parentItem.setText(1, QtCore.QDateTime().currentDateTime().toString()) 30 | for i in messageList: 31 | item = QtGui.QTreeWidgetItem(parentItem) 32 | item.setFirstColumnSpanned(True) 33 | item.setText(0, i) 34 | parentItem.addChild(item) 35 | parentItem.setExpanded(True) 36 | self.scrollToItem(parentItem, 1) 37 | 38 | self.vSplitter.showMessageAvailable() 39 | self.bottomStackSwitcher.setCount(self, str(self.topLevelItemCount())) 40 | self.bottomStackSwitcher.setCurrentWidget(self) 41 | -------------------------------------------------------------------------------- /Extensions/BottomWidgets/TasksWidget.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | from PyQt4 import QtCore, QtGui 4 | 5 | 6 | class TaskFinderThread(QtCore.QThread): 7 | 8 | TASKS_PATTERN = r"(^|#)[ ]*(TODO|FIXME|XXX|HINT|TIP)( |:)([^#]*)" 9 | newTasks = QtCore.pyqtSignal(list) 10 | results = [] 11 | 12 | def run(self): 13 | # TODO: this is a test for the following function 14 | """ 15 | Find tasks in source code (TODO, FIXME, XXX, ...) 16 | """ 17 | results = [] 18 | for line, text in enumerate(self.source.splitlines()): 19 | for todo in re.findall(self.TASKS_PATTERN, text): 20 | results.append((todo[1], line + 1, todo[ 21 | -1].strip().capitalize())) 22 | if results != self.results: 23 | self.results = [] 24 | self.results.extend(results) 25 | self.newTasks.emit(results) 26 | 27 | def findTasks(self, source): 28 | self.source = source 29 | 30 | self.start() 31 | 32 | 33 | class Tasks(QtGui.QTreeWidget): 34 | 35 | def __init__(self, editorTabWidget, bottomStackSwitcher, parent=None): 36 | QtGui.QTreeWidget.__init__(self, parent) 37 | 38 | self.setColumnCount(4) 39 | self.setHeaderLabels(["#", "Type", "Line", "Task"]) 40 | self.setAutoScroll(True) 41 | 42 | self.setColumnWidth(0, 60) 43 | self.setColumnWidth(1, 80) 44 | self.setColumnWidth(2, 80) 45 | self.itemPressed.connect(self.taskPressed) 46 | 47 | self.editorTabWidget = editorTabWidget 48 | self.bottomStackSwitcher = bottomStackSwitcher 49 | self.taskFinder = TaskFinderThread() 50 | 51 | self.taskFinderTimer = QtCore.QTimer() 52 | self.taskFinderTimer.setSingleShot(True) 53 | self.taskFinderTimer.timeout.connect(self.findTasks) 54 | 55 | self.editorTabWidget.currentEditorTextChanged.connect(self.startTimer) 56 | self.editorTabWidget.currentChanged.connect(self.startTimer) 57 | self.taskFinder.newTasks.connect(self.updateTasks) 58 | 59 | self.setStyleSheet(""" 60 | QTreeView { 61 | show-decoration-selected: 1; /* make the selection span the entire width of the view */ 62 | border: none; 63 | } 64 | """) 65 | 66 | def startTimer(self): 67 | self.taskFinderTimer.start(1000) 68 | 69 | def updateTasks(self, results): 70 | self.clear() 71 | self.bottomStackSwitcher.setCount(self, str(len(results))) 72 | for i in results: 73 | item = QtGui.QTreeWidgetItem() 74 | item.setIcon(0, QtGui.QIcon( 75 | os.path.join("Resources", "images", "Clear Green Button"))) 76 | item.setText(1, i[0]) 77 | item.setText(2, str(i[1])) 78 | item.setText(3, i[2]) 79 | self.addTopLevelItem(item) 80 | 81 | def taskPressed(self, item): 82 | lineno = int(item.text(2)) - 1 83 | self.editorTabWidget.showLine(lineno) 84 | 85 | def findTasks(self): 86 | self.taskFinder.findTasks(self.editorTabWidget.getSource()) 87 | -------------------------------------------------------------------------------- /Extensions/BottomWidgets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/BottomWidgets/__init__.py -------------------------------------------------------------------------------- /Extensions/CodeSnapshot.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PyQt4 import QtGui 4 | 5 | from Extensions.BaseScintilla import BaseScintilla 6 | from Extensions import StyleSheet 7 | 8 | 9 | class CodeSnapshot(BaseScintilla): 10 | 11 | def __init__(self, useData, colorScheme, parent=None): 12 | BaseScintilla.__init__(self, parent) 13 | 14 | self.colorScheme = colorScheme 15 | self.DATA = {"fileType": "python"} 16 | 17 | self.setObjectName("editor") 18 | self.enableMarkOccurrence(useData) 19 | 20 | self.createContextMenu() 21 | 22 | self.colorScheme.styleEditor(self) 23 | self.setMarginLineNumbers(0, True) 24 | 25 | def updateLexer(self, lexer): 26 | self.setLexer(lexer) 27 | 28 | def contextMenuEvent(self, event): 29 | state = self.hasSelectedText() 30 | self.copyAct.setEnabled(state) 31 | 32 | self.contextMenu.exec_(event.globalPos()) 33 | 34 | def createContextMenu(self): 35 | self.copyAct = QtGui.QAction( 36 | "Copy", self, 37 | statusTip="Copy selected text", triggered=self.copy) 38 | 39 | self.selectAllAct = QtGui.QAction("Select All", self, 40 | statusTip="Select All", 41 | triggered=self.selectAllText) 42 | 43 | self.selectToMatchingBraceAct = \ 44 | QtGui.QAction( 45 | QtGui.QIcon(os.path.join("Resources", "images", "compose")), 46 | "Select to Matching Brace", self, 47 | statusTip="Select to Matching Brace", 48 | triggered=self.selectToMatchingBrace) 49 | 50 | self.contextMenu = QtGui.QMenu() 51 | self.contextMenu.addSeparator() 52 | self.contextMenu.addAction(self.copyAct) 53 | self.contextMenu.addAction(self.selectAllAct) 54 | self.contextMenu.addAction(self.selectToMatchingBraceAct) 55 | 56 | def selectAllText(self): 57 | self.selectAll() 58 | -------------------------------------------------------------------------------- /Extensions/EditorSplitter.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui, QtCore 2 | 3 | from Extensions.MiniMap import MiniMap 4 | 5 | 6 | 7 | class EditorSplitter(QtGui.QWidget): 8 | 9 | def __init__(self, editor, editor2, DATA, editorTabWidget, parent): 10 | QtGui.QWidget.__init__(self, parent) 11 | 12 | self.editorTabWidget = editorTabWidget 13 | self.DATA = DATA 14 | self.parent = parent 15 | 16 | self.editor = editor 17 | self.editor2 = editor2 18 | 19 | mainLayout = QtGui.QHBoxLayout() 20 | mainLayout.setMargin(0) 21 | mainLayout.setSpacing(0) 22 | self.setLayout(mainLayout) 23 | 24 | self.splitter = QtGui.QSplitter() 25 | mainLayout.addWidget(self.splitter) 26 | 27 | self.splitter.addWidget(self.editor) 28 | self.splitter.addWidget(self.editor2) 29 | editor2.hide() 30 | 31 | self.splitter.setCollapsible(0, False) 32 | self.splitter.setCollapsible(1, False) 33 | 34 | self.editor.modificationChanged.connect(self.textModified) 35 | self.editor2.modificationChanged.connect(self.textModified) 36 | 37 | #self.minimap = MiniMap(self.editor, self) 38 | #mainLayout.addWidget(self.minimap) 39 | 40 | def getEditor(self, index=None): 41 | if index is None: 42 | index = 0 43 | return self.splitter.widget(index) 44 | 45 | def getFocusedEditor(self): 46 | f = self.splitter.focusWidget() 47 | if f is None: 48 | return self.getEditor() 49 | return f 50 | 51 | def textModified(self, modified): 52 | index = self.editorTabWidget.indexOf(self.parent) 53 | self.editorTabWidget.updateTabName(index) 54 | -------------------------------------------------------------------------------- /Extensions/EditorWindow/BuildStatusWidget.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | 4 | class BuildStatusWidget(QtGui.QWidget): 5 | 6 | cancel = QtCore.pyqtSignal() 7 | 8 | def __init__(self, app, useData, parent=None): 9 | QtGui.QDialog.__init__(self, parent) 10 | 11 | self.useData = useData 12 | self.app = app 13 | 14 | mainLayout = QtGui.QHBoxLayout() 15 | mainLayout.setMargin(0) 16 | self.setLayout(mainLayout) 17 | 18 | mainLayout.addWidget(QtGui.QLabel("Build Started...")) 19 | 20 | self.progressBar = QtGui.QProgressBar() 21 | self.progressBar.setMaximumHeight(10) 22 | self.progressBar.setMinimumWidth(100) 23 | self.progressBar.setStyleSheet(""" 24 | QProgressBar { 25 | border: none; 26 | background: transparent; 27 | border-top: 1px solid #6570EA; 28 | border-radius: 0px; 29 | } 30 | 31 | QProgressBar::chunk { 32 | background-color: #65B0EA; 33 | width: 15px; 34 | } 35 | """) 36 | mainLayout.addWidget(self.progressBar) 37 | 38 | self.hide() 39 | 40 | def showBusy(self, busy): 41 | if busy: 42 | self.show() 43 | self.progressBar.setRange(0, 0) 44 | else: 45 | self.hide() 46 | self.progressBar.setRange(0, 1) 47 | if self.useData.SETTINGS['SoundsEnabled'] == "True": 48 | self.app.beep() 49 | -------------------------------------------------------------------------------- /Extensions/EditorWindow/VerticalSplitter.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui 2 | 3 | 4 | class VerticalSplitter(QtGui.QSplitter): 5 | 6 | def __init__(self, parent=None): 7 | QtGui.QSplitter.__init__(self, parent) 8 | 9 | self.setObjectName("vSplitter") 10 | self.setOrientation(2) 11 | 12 | self.bottomTabCollapsed = False 13 | self.splitterMoved.connect(self.updateStatus) 14 | 15 | def updateStatus(self): 16 | bottomTabSize = self.sizes()[1] 17 | self.bottomTabCollapsed = (bottomTabSize == 0) 18 | if self.bottomTabCollapsed: 19 | self.showNormal() 20 | 21 | def showMessageAvailable(self): 22 | if not self.bottomTabCollapsed: 23 | return 24 | self.setStyleSheet(""" 25 | 26 | QSplitter#vSplitter::handle { 27 | background: none; 28 | } 29 | 30 | QSplitter#vSplitter::handle:horizontal { 31 | width: 5px; 32 | } 33 | 34 | QSplitter#vSplitter::handle:vertical { 35 | background: #1281CB; 36 | } 37 | 38 | QSplitter#vSplitter::handle:pressed { 39 | background: gray; 40 | } 41 | 42 | """) 43 | 44 | def showRunning(self): 45 | if not self.bottomTabCollapsed: 46 | return 47 | self.setStyleSheet(""" 48 | 49 | QSplitter#vSplitter::handle { 50 | background: none; 51 | } 52 | 53 | QSplitter#vSplitter::handle:horizontal { 54 | width: 5px; 55 | } 56 | 57 | QSplitter#vSplitter::handle:vertical { 58 | background: #4EC24E; 59 | } 60 | 61 | QSplitter#vSplitter::handle:pressed { 62 | background: gray; 63 | } 64 | 65 | """) 66 | 67 | def showError(self): 68 | if not self.bottomTabCollapsed: 69 | return 70 | self.setStyleSheet(""" 71 | 72 | QSplitter#vSplitter::handle { 73 | background: none; 74 | } 75 | 76 | QSplitter#vSplitter::handle:horizontal { 77 | width: 5px; 78 | } 79 | 80 | QSplitter#vSplitter::handle:vertical { 81 | background: #FD6500; 82 | } 83 | 84 | QSplitter#vSplitter::handle:pressed { 85 | background: gray; 86 | } 87 | 88 | """) 89 | 90 | def showNormal(self): 91 | self.setStyleSheet(""" 92 | 93 | QSplitter#vSplitter::handle { 94 | background: none; 95 | } 96 | 97 | QSplitter#vSplitter::handle:vertical { 98 | background: lightgray; 99 | } 100 | 101 | QSplitter#vSplitter::handle:pressed { 102 | background: gray; 103 | } 104 | 105 | """) 106 | -------------------------------------------------------------------------------- /Extensions/EditorWindow/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/EditorWindow/__init__.py -------------------------------------------------------------------------------- /Extensions/Global.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | from PyQt4 import QtGui, QtCore 4 | 5 | 6 | def getDefaultFont(): 7 | # Platform specific fonts 8 | if sys.platform == 'win32': 9 | font = 'Lucida Console' 10 | font_size = 9 11 | elif sys.platform == 'darwin': 12 | font = 'Monaco' 13 | font_size = 10 14 | else: 15 | font = 'Bitstream Vera Sans Mono' 16 | font_size = 10 17 | 18 | return QtGui.QFont(font, font_size) 19 | 20 | 21 | def iconFromPath(path): 22 | fileInfo = QtCore.QFileInfo(path) 23 | iconProvider = QtGui.QFileIconProvider() 24 | icon = iconProvider.icon(fileInfo) 25 | 26 | return icon 27 | -------------------------------------------------------------------------------- /Extensions/GotoLineWidget.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PyQt4 import QtGui 4 | 5 | 6 | class GotoLineWidget(QtGui.QLabel): 7 | 8 | def __init__(self, editorTabWidget, parent=None): 9 | QtGui.QLabel.__init__(self, parent=None) 10 | 11 | self.editorTabWidget = editorTabWidget 12 | 13 | self.setMinimumHeight(35) 14 | self.setMaximumHeight(35) 15 | self.setMinimumWidth(200) 16 | self.setMaximumWidth(200) 17 | 18 | self.gotoLineAct = \ 19 | QtGui.QAction( 20 | QtGui.QIcon(os.path.join("Resources", "images", "mail_check")), 21 | "Goto Line", self, statusTip="Goto Line", 22 | triggered=self.gotoLine) 23 | 24 | mainLayout = QtGui.QHBoxLayout() 25 | mainLayout.setMargin(3) 26 | mainLayout.setSpacing(2) 27 | self.setLayout(mainLayout) 28 | 29 | self.hideButton = QtGui.QToolButton() 30 | self.hideButton.setAutoRaise(True) 31 | self.hideButton.setIcon( 32 | QtGui.QIcon(os.path.join("Resources", "images", "exit"))) 33 | self.hideButton.clicked.connect(self.hide) 34 | mainLayout.addWidget(self.hideButton) 35 | 36 | self.lineNumberLine = QtGui.QSpinBox() 37 | self.lineNumberLine.setMinimumHeight(25) 38 | self.lineNumberLine.setMinimum(1) 39 | self.lineNumberLine.setMaximum(100000000) 40 | self.lineNumberLine.valueChanged.connect(self.gotoLine) 41 | mainLayout.addWidget(self.lineNumberLine) 42 | 43 | self.goButton = QtGui.QToolButton() 44 | self.goButton.setAutoRaise(True) 45 | self.goButton.setDefaultAction(self.gotoLineAct) 46 | mainLayout.addWidget(self.goButton) 47 | 48 | mainLayout.setStretch(1, 1) 49 | 50 | self.setStyleSheet(""" 51 | QLabel { 52 | background: rgba(138, 201, 255, 200); 53 | border-radius: 0px; 54 | } 55 | """) 56 | 57 | def gotoLine(self, lineno): 58 | if lineno is False: 59 | lineno = self.lineNumberLine.value() 60 | self.editorTabWidget.focusedEditor().showLine(lineno - 1) 61 | -------------------------------------------------------------------------------- /Extensions/Library/LibraryAddDialog.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtCore, QtGui 3 | 4 | 5 | class LibraryAddDialog(QtGui.QDialog): 6 | 7 | def __init__(self, editorTabWidget, parent): 8 | QtGui.QDialog.__init__(self, parent, QtCore.Qt.Window | 9 | QtCore.Qt.WindowCloseButtonHint) 10 | 11 | self.setWindowTitle("Library Add") 12 | self.setFixedSize(400, 120) 13 | 14 | self.editorTabWidget = editorTabWidget 15 | self.library = parent 16 | 17 | head = os.path.splitext(self.editorTabWidget.getTabName())[0] 18 | 19 | mainLayout = QtGui.QVBoxLayout() 20 | 21 | mainLayout.addWidget(QtGui.QLabel("Name in library:")) 22 | 23 | self.nameLine = QtGui.QLineEdit() 24 | self.nameLine.setText(head) 25 | self.nameLine.selectAll() 26 | self.nameLine.textChanged.connect(self.textChanged) 27 | mainLayout.addWidget(self.nameLine) 28 | 29 | hbox = QtGui.QHBoxLayout() 30 | mainLayout.addLayout(hbox) 31 | 32 | self.entireModuleButton = QtGui.QRadioButton("Entire Module") 33 | self.entireModuleButton.setChecked(True) 34 | hbox.addWidget(self.entireModuleButton) 35 | 36 | self.selectionButton = QtGui.QRadioButton("Selection Only") 37 | if self.editorTabWidget.focusedEditor().selectedText().strip() == '': 38 | self.selectionButton.setDisabled(True) 39 | hbox.addWidget(self.selectionButton) 40 | 41 | hbox.addStretch(1) 42 | 43 | self.showDetailsButton = QtGui.QToolButton() 44 | self.showDetailsButton.setAutoRaise(True) 45 | self.showDetailsButton.setToolButtonStyle(2) 46 | self.showDetailsButton.setText("Comments") 47 | self.showDetailsButton.setIcon(QtGui.QIcon( 48 | os.path.join("Resources", "images", "extender-down"))) 49 | self.showDetailsButton.clicked.connect(self.showComments) 50 | hbox.addWidget(self.showDetailsButton) 51 | 52 | self.moreWidget = QtGui.QWidget() 53 | vbox = QtGui.QVBoxLayout() 54 | vbox.setMargin(0) 55 | 56 | self.commentEntry = QtGui.QPlainTextEdit() 57 | vbox.addWidget(self.commentEntry) 58 | 59 | self.moreWidget.setLayout(vbox) 60 | mainLayout.addWidget(self.moreWidget) 61 | 62 | self.moreWidget.hide() 63 | 64 | hbox = QtGui.QHBoxLayout() 65 | 66 | hbox.addStretch(1) 67 | 68 | self.okButton = QtGui.QPushButton("OK") 69 | self.okButton.clicked.connect(self.accept) 70 | hbox.addWidget(self.okButton) 71 | 72 | cancelButton = QtGui.QPushButton("Cancel") 73 | cancelButton.clicked.connect(self.close) 74 | hbox.addWidget(cancelButton) 75 | 76 | mainLayout.addLayout(hbox) 77 | self.setLayout(mainLayout) 78 | 79 | self.accepted = False 80 | 81 | self.exec_() 82 | 83 | def showComments(self): 84 | if self.moreWidget.isVisible(): 85 | self.moreWidget.hide() 86 | self.setFixedSize(400, 120) 87 | self.showDetailsButton.setIcon(QtGui.QIcon( 88 | os.path.join("Resources", "images", "extender-down"))) 89 | else: 90 | self.moreWidget.show() 91 | self.setFixedSize(400, 300) 92 | self.showDetailsButton.setIcon(QtGui.QIcon( 93 | os.path.join("Resources", "images", "extender-up"))) 94 | 95 | def textChanged(self): 96 | if self.nameLine.text().strip() == '': 97 | self.okButton.setDisabled(True) 98 | else: 99 | self.okButton.setDisabled(False) 100 | 101 | def accept(self): 102 | self.accepted = True 103 | 104 | file_name = self.nameLine.text().strip() 105 | self.name = os.path.splitext(file_name)[0] 106 | 107 | self.close() 108 | -------------------------------------------------------------------------------- /Extensions/Library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Library/__init__.py -------------------------------------------------------------------------------- /Extensions/Notification.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui, QtCore 2 | 3 | 4 | class Notification(QtGui.QLabel): 5 | 6 | def __init__(self, parent=None): 7 | QtGui.QLabel.__init__(self, parent) 8 | 9 | self.setMinimumHeight(25) 10 | self.setMargin(5) 11 | 12 | self.easingCurve = QtCore.QEasingCurve.OutCubic 13 | 14 | self.showAnimation = QtCore.QPropertyAnimation(self, 'maximumWidth') 15 | self.showAnimation.setDuration(200) 16 | self.showAnimation.setEasingCurve(self.easingCurve) 17 | 18 | self.setStyleSheet("""background: #1A1A1A; 19 | color: white; 20 | border: 1px solid #72A4CE; 21 | border-radius: 0px; 22 | border-left: 5px solid #72A4CE; 23 | """) 24 | 25 | def mousePressEvent(self, event): 26 | self.hide() 27 | 28 | def showMessage(self, mess): 29 | self.hide() 30 | self.setText(mess) 31 | self.adjustSize() 32 | 33 | max_width = self.geometry().width() 34 | self.showAnimation.setEndValue(max_width + 10) 35 | self.setMaximumWidth(0) 36 | self.show() 37 | self.showAnimation.start() 38 | 39 | 40 | -------------------------------------------------------------------------------- /Extensions/Outline/Python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Outline/Python/__init__.py -------------------------------------------------------------------------------- /Extensions/Outline/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Outline/__init__.py -------------------------------------------------------------------------------- /Extensions/PathLineEdit.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtCore, QtGui 3 | 4 | 5 | class PathLineEdit(QtGui.QLineEdit): 6 | 7 | def __init__(self, parent=None): 8 | super(PathLineEdit, self).__init__(parent) 9 | 10 | self.setTextMargins(0, 0, 42, 0) 11 | 12 | hbox = QtGui.QHBoxLayout() 13 | self.setLayout(hbox) 14 | hbox.setMargin(0) 15 | hbox.setSpacing(0) 16 | hbox.addStretch(1) 17 | 18 | self.fileButton = QtGui.QToolButton() 19 | self.fileButton.setToolTip("Insert File Path") 20 | self.fileButton.setAutoRaise(True) 21 | self.fileButton.setIcon(QtGui.QIcon(os.path.join("Resources", "images", "page"))) 22 | self.fileButton.clicked.connect(self.insertFilePath) 23 | hbox.addWidget(self.fileButton) 24 | 25 | self.dirButton = QtGui.QToolButton() 26 | self.dirButton.setToolTip("Insert Directory Path") 27 | self.dirButton.setAutoRaise(True) 28 | self.dirButton.setIcon(QtGui.QIcon(os.path.join("Resources", "images", "folder_closed"))) 29 | self.dirButton.clicked.connect(self.insertDirPath) 30 | hbox.addWidget(self.dirButton) 31 | 32 | def insertDirPath(self): 33 | directory = QtGui.QFileDialog.getExistingDirectory( 34 | self, QtCore.QDir.homePath()) 35 | if directory: 36 | self.setText(os.path.normpath(directory)) 37 | 38 | def insertFilePath(self): 39 | fileName = QtGui.QFileDialog.getOpenFileName(self, 40 | "File", QtCore.QDir.homePath(), 41 | "All Files (*)") 42 | if fileName: 43 | self.setText(os.path.normpath(fileName)) 44 | -------------------------------------------------------------------------------- /Extensions/Projects/ProjectManager/ProjectManager.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | from PyQt4 import QtCore, QtGui 4 | 5 | from Extensions.Projects.ProjectManager.ProjectView.ProjectView import ProjectView 6 | from Extensions.Projects.ProjectManager.Build import Build 7 | 8 | 9 | class ExportThread(QtCore.QThread): 10 | 11 | def run(self): 12 | self.error = None 13 | try: 14 | shutil.make_archive(self.fileName, "zip", self.path) 15 | except Exception as err: 16 | self.error = str(err) 17 | 18 | def export(self, fileName, path): 19 | self.fileName = fileName 20 | self.path = path 21 | 22 | self.start() 23 | 24 | 25 | class ProjectManager(QtGui.QWidget): 26 | 27 | def __init__( 28 | self, editorTabWidget, messagesWidget, projectPathDict, projectSettings, 29 | useData, app, 30 | busyWidget, buildStatusWidget, parent): 31 | QtGui.QWidget.__init__(self, parent) 32 | 33 | self.busyWidget = busyWidget 34 | self.editorTabWidget = editorTabWidget 35 | 36 | self.useData = useData 37 | self.projects = parent 38 | self.projects = parent 39 | 40 | self.configDialog = editorTabWidget.configDialog 41 | 42 | if projectPathDict["type"] == "Desktop Application": 43 | self.build = Build( 44 | buildStatusWidget, messagesWidget, projectPathDict, projectSettings, useData, 45 | self.configDialog.buildConfig, editorTabWidget, self) 46 | 47 | self.exportThread = ExportThread() 48 | self.exportThread.finished.connect(self.finishExport) 49 | 50 | self.projectView = ProjectView( 51 | self.editorTabWidget, projectPathDict["sourcedir"], app, projectSettings) 52 | 53 | def buildProject(self): 54 | if self.editorTabWidget.errorsInProject(): 55 | reply = QtGui.QMessageBox.warning(self, "Build", 56 | "There are errors in your project. Build anyway?", 57 | QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) 58 | if reply == QtGui.QMessageBox.Yes: 59 | self.build.build() 60 | else: 61 | return 62 | else: 63 | self.build.build() 64 | 65 | def configureProject(self): 66 | self.configDialog.exec_() 67 | 68 | def openBuild(self): 69 | self.build.openDir() 70 | 71 | def exportProject(self): 72 | curren_window = self.projects.projectWindowStack.currentWidget() 73 | name = curren_window.projectPathDict["name"] 74 | path = curren_window.projectPathDict["root"] 75 | 76 | options = QtGui.QFileDialog.Options() 77 | savepath = os.path.join(self.useData.getLastOpenedDir(), name) 78 | savepath = os.path.normpath(savepath) 79 | fileName = QtGui.QFileDialog.getSaveFileName(self, 80 | "Export", savepath, 81 | "All files (*)", options) 82 | if fileName: 83 | self.useData.saveLastOpenedDir(os.path.split(fileName)[0]) 84 | 85 | self.exportThread.export(fileName, path) 86 | self.busyWidget.showBusy(True, "Exporting project... please wait!") 87 | 88 | def finishExport(self): 89 | self.busyWidget.showBusy(False) 90 | if self.exportThread.error is not None: 91 | message = QtGui.QMessageBox.warning( 92 | self, "Export Failed", self.exportThread.error) 93 | -------------------------------------------------------------------------------- /Extensions/Projects/ProjectManager/ProjectView/ProgressWidget.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PyQt4 import QtCore, QtGui 4 | 5 | 6 | class ProgressWidget(QtGui.QLabel): 7 | 8 | updateProgress = QtCore.pyqtSignal(int) 9 | 10 | def __init__(self, parent=None): 11 | QtGui.QLabel.__init__(self, parent) 12 | 13 | self.setMinimumHeight(25) 14 | self.setObjectName("mainLabel") 15 | 16 | mainLayout = QtGui.QVBoxLayout() 17 | mainLayout.setSpacing(0) 18 | mainLayout.setMargin(2) 19 | self.setLayout(mainLayout) 20 | 21 | self.progressBar = QtGui.QProgressBar() 22 | self.progressBar.setTextVisible(False) 23 | self.progressBar.setRange(0, 100) 24 | self.updateProgress.connect(self.updateValue) 25 | mainLayout.addWidget(self.progressBar) 26 | 27 | 28 | hbox = QtGui.QHBoxLayout() 29 | hbox.setMargin(2) 30 | hbox.setSpacing(0) 31 | self.progressBar.setLayout(hbox) 32 | 33 | hbox.addWidget(QtGui.QLabel("Copying: ")) 34 | 35 | self.captionLabel = QtGui.QLabel() 36 | self.captionLabel.setStyleSheet(""" 37 | QLabel { 38 | color: #003366; 39 | } 40 | """) 41 | hbox.addWidget(self.captionLabel) 42 | 43 | hbox.addStretch(1) 44 | 45 | self.cancelButton = QtGui.QToolButton() 46 | self.cancelButton.setIcon( 47 | QtGui.QIcon(os.path.join("Resources", "images", "cross"))) 48 | hbox.addWidget(self.cancelButton) 49 | 50 | self.setStyleSheet(""" 51 | QLabel#mainLabel { 52 | background: #ffffff; 53 | border: none; 54 | } 55 | 56 | QProgressBar { 57 | border: None; 58 | text-align: center; 59 | padding: 0px; 60 | border-radius: 0px; 61 | background-color: Transparent; 62 | } 63 | 64 | QProgressBar::chunk { 65 | color: black; 66 | border-radius: 0px; 67 | background-color: #EDEDED; 68 | } 69 | 70 | """) 71 | 72 | def reset(self): 73 | self.progressBar.setValue(0) 74 | 75 | def updateCurrentJob(self, job): 76 | self.captionLabel.setText(job) 77 | 78 | def updateValue(self, newValue): 79 | self.progressBar.setValue(newValue) 80 | 81 | def showBusy(self, show, mess=None): 82 | if show: 83 | self.captionLabel.setText(mess) 84 | self.cancelButton.show() 85 | self.show() 86 | else: 87 | self.hide() 88 | self.reset() 89 | -------------------------------------------------------------------------------- /Extensions/Projects/ProjectManager/ProjectView/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Projects/ProjectManager/ProjectView/__init__.py -------------------------------------------------------------------------------- /Extensions/Projects/ProjectManager/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Projects/ProjectManager/__init__.py -------------------------------------------------------------------------------- /Extensions/Projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Projects/__init__.py -------------------------------------------------------------------------------- /Extensions/Refactor/UsageDialog.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtCore, QtGui 3 | 4 | 5 | class UsageDialog(QtGui.QDialog): 6 | 7 | def __init__(self, editorTabWidget, title, itemsList, parent=None): 8 | QtGui.QDialog.__init__(self, parent, QtCore.Qt.Window | 9 | QtCore.Qt.WindowCloseButtonHint) 10 | 11 | self.setWindowTitle(title) 12 | self.resize(600, 300) 13 | 14 | self.editorTabWidget = editorTabWidget 15 | 16 | mainLayout = QtGui.QVBoxLayout() 17 | mainLayout.setMargin(0) 18 | self.setLayout(mainLayout) 19 | 20 | self.view = QtGui.QTreeWidget() 21 | self.view.setHeaderLabels(["#"]) 22 | self.view.setColumnWidth(0, 300) 23 | self.view.setSortingEnabled(True) 24 | self.view.sortByColumn(0, QtCore.Qt.AscendingOrder) 25 | self.view.itemActivated.connect(self.showLine) 26 | mainLayout.addWidget(self.view) 27 | 28 | for item in itemsList: 29 | self.view.addTopLevelItem(item) 30 | 31 | self.exec_() 32 | 33 | def showLine(self, item): 34 | if item.parent() is None: 35 | return 36 | path = item.parent().text(0) 37 | fullPath = os.path.join( 38 | self.editorTabWidget.projectPathDict["sourcedir"], path) 39 | self.editorTabWidget.loadfile(fullPath) 40 | line = int(item.text(0)) - 1 41 | self.editorTabWidget.showLine(line) 42 | -------------------------------------------------------------------------------- /Extensions/Refactor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Refactor/__init__.py -------------------------------------------------------------------------------- /Extensions/Settings/ColorScheme/ColorChooser.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | 4 | class ColorChooser(QtGui.QWidget): 5 | 6 | colorChanged = QtCore.pyqtSignal(str) 7 | 8 | def __init__(self, parent=None): 9 | QtGui.QWidget.__init__(self, parent) 10 | 11 | hbox = QtGui.QHBoxLayout() 12 | hbox.setMargin(0) 13 | self.setLayout(hbox) 14 | 15 | self.colorHexLine = QtGui.QLineEdit() 16 | self.colorHexLine.textChanged.connect(self.updateColor) 17 | hbox.addWidget(self.colorHexLine) 18 | 19 | self.colorButton = QtGui.QPushButton() 20 | self.colorButton.clicked.connect(self.chooseColor) 21 | hbox.addWidget(self.colorButton) 22 | 23 | def updateColor(self): 24 | self.styleButton() 25 | self.colorChanged.emit(self.colorHexLine.text()) 26 | 27 | def setColor(self, color): 28 | self.colorHexLine.setText(color) 29 | 30 | def chooseColor(self): 31 | color = self.colorHexLine.text() 32 | color = QtGui.QColorDialog.getColor(QtGui.QColor(color), self) 33 | if not color.isValid(): 34 | return 35 | self.colorHexLine.setText(color.name()) 36 | 37 | def styleButton(self): 38 | colorHex = self.colorHexLine.text() 39 | color = QtGui.QColor(colorHex) 40 | if color.isValid(): 41 | self.colorButton.setAutoFillBackground(True) 42 | style = ("""background: {0}; 43 | min-width: 70; 44 | max-height: 30; 45 | border: 1px solid lightgrey; 46 | border-radius: 0px;""".format(colorHex)) 47 | self.colorButton.setStyleSheet(style) 48 | -------------------------------------------------------------------------------- /Extensions/Settings/ColorScheme/Lexers/PythonLexer.py: -------------------------------------------------------------------------------- 1 | import keyword 2 | import sys 3 | 4 | from PyQt4 import QtGui 5 | from PyQt4.Qsci import QsciLexerPython 6 | 7 | # Platform specific fonts 8 | if sys.platform == 'win32': 9 | defaultFont = 'Consolas' 10 | elif sys.platform == 'darwin': 11 | defaultFont = 'Monaco' 12 | else: 13 | defaultFont = 'Bitstream Vera Sans Mono' 14 | 15 | 16 | 17 | 18 | 19 | 20 | propertyID = { 21 | 'Default': 0, 22 | 'Comment': 1, 23 | 'Number': 2, 24 | 'DoubleQuotedString': 3, 25 | 'SingleQuotedString': 4, 26 | 'Keyword': 5, 27 | 'TripleSingleQuotedString': 6, 28 | 'TripleDoubleQuotedString': 7, 29 | 'ClassName': 8, 30 | 'FunctionMethodName': 9, 31 | 'Operator': 10, 32 | 'Identifier': 11, 33 | 'CommentBlock': 12, 34 | 'UnclosedString': 13, 35 | 'HighlightedIdentifier': 14, 36 | 'Decorator': 15, 37 | } 38 | 39 | 40 | def styleDescriptions(): 41 | return propertyID.keys() 42 | 43 | 44 | def defaultStyle(): 45 | defaultStyle = { 46 | 'UnclosedString': [defaultFont, '#000000', 10, False, False, '#00fd00'], 47 | 'Decorator': [defaultFont, '#00cc00', 10, False, False, '#ffffff'], 48 | 'Default': [defaultFont, '#000000', 10, False, False, '#ffffff'], 49 | 'HighlightedIdentifier': [defaultFont, '#900090', 10, False, False, '#ffffff'], 50 | 'CommentBlock': [defaultFont, '#0000ff', 10, False, False, '#ffffff'], 51 | 'FunctionMethodName': [defaultFont, '#0000ff', 10, False, False, '#ffffff'], 52 | 'DoubleQuotedString': [defaultFont, '#00aa00', 10, False, False, '#ffffff'], 53 | 'Operator': [defaultFont, '#000000', 10, False, False, '#ffffff'], 54 | 'TripleSingleQuotedString': [defaultFont, '#00aa00', 10, False, False, '#ffffff'], 55 | 'Number': [defaultFont, '#000000', 10, False, False, '#ffffff'], 56 | 'Keyword': [defaultFont, '#0000ff', 10, False, False, '#ffffff'], 57 | 'Identifier': [defaultFont, '#000000', 10, False, False, '#ffffff'], 58 | 'ClassName': [defaultFont, '#0000ff', 10, False, False, '#ffffff'], 59 | 'SingleQuotedString': [defaultFont, '#00aa00', 10, False, False, '#ffffff'], 60 | 'TripleDoubleQuotedString': [defaultFont, '#00aa00', 10, False, False, '#ffffff'], 61 | 'Comment': [defaultFont, '#0000ff', 10, False, False, '#ffffff']} 62 | 63 | return defaultStyle 64 | 65 | 66 | class PythonLexer(QsciLexerPython): 67 | 68 | def __init__(self, style, paper): 69 | QsciLexerPython.__init__(self) 70 | 71 | self.lexerPaper = paper 72 | 73 | for key, attrib in style.items(): 74 | value = propertyID[key] 75 | self.setColor(QtGui.QColor(attrib[1]), value) 76 | self.setEolFill(True, value) 77 | self.setPaper(QtGui.QColor(attrib[5]), value) 78 | if self.lexerPaper[0] == "Plain": 79 | self.setPaper(QtGui.QColor(attrib[5]), value) 80 | else: 81 | self.setPaper(QtGui.QColor(self.lexerPaper[1]), value) 82 | 83 | font = QtGui.QFont(attrib[0], attrib[2]) 84 | font.setBold(attrib[3]) 85 | font.setItalic(attrib[4]) 86 | self.setFont(font, value) 87 | 88 | if self.lexerPaper[0] == "Plain": 89 | self.setDefaultPaper(QtGui.QColor("#ffffff")) 90 | else: 91 | self.setDefaultPaper(QtGui.QColor(self.lexerPaper[1])) 92 | 93 | def keywords(self, set): 94 | # 1 to 9 sets 95 | if set == 1: 96 | k = keyword.kwlist 97 | s = k[0] 98 | for i in k[1:]: 99 | s += ' ' + i 100 | return s 101 | elif set == 2: 102 | s = '' 103 | for i in dir(__builtins__): 104 | s += ' ' + i 105 | return s 106 | -------------------------------------------------------------------------------- /Extensions/Settings/ColorScheme/Lexers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Settings/ColorScheme/Lexers/__init__.py -------------------------------------------------------------------------------- /Extensions/Settings/ColorScheme/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Settings/ColorScheme/__init__.py -------------------------------------------------------------------------------- /Extensions/Settings/ModuleCompletion.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | 4 | class ModuleCompletion(QtGui.QTreeWidget): 5 | 6 | def __init__(self, useData, parent=None): 7 | QtGui.QTreeWidget.__init__(self, parent) 8 | 9 | self.useData = useData 10 | 11 | self.setHeaderLabel("Modules") 12 | for i, v in self.useData.libraryDict.items(): 13 | item = QtGui.QTreeWidgetItem(self) 14 | item.setCheckState(0, False) 15 | item.setText(0, i) 16 | item.setCheckState(0, 2) 17 | 18 | for sub in v[0]: 19 | subItem = QtGui.QTreeWidgetItem(item) 20 | subItem.setText(0, sub) 21 | 22 | self.createActions() 23 | 24 | def createActions(self): 25 | self.addItemAct = QtGui.QAction( 26 | "Add Library", self, statusTip="Add Library", triggered=self.addLibrary) 27 | 28 | self.removeItemAct = \ 29 | QtGui.QAction( 30 | "Remove Library", self, statusTip="Remove Library", triggered=self.removeLibrary) 31 | 32 | self.addModuleAct = \ 33 | QtGui.QAction( 34 | "Add Module", self, statusTip="Add Module", triggered=self.addModule) 35 | 36 | self.removeModuleAct = \ 37 | QtGui.QAction( 38 | "Remove Module", self, statusTip="Remove Module", triggered=self.removeModule) 39 | 40 | self.contextMenu = QtGui.QMenu() 41 | self.contextMenu.addAction(self.addItemAct) 42 | self.contextMenu.addAction(self.removeItemAct) 43 | self.contextMenu.addSeparator() 44 | self.contextMenu.addAction(self.addModuleAct) 45 | self.contextMenu.addAction(self.removeModuleAct) 46 | 47 | def contextMenuEvent(self, event): 48 | selected = self.selectedItems() 49 | self.selectedItem = selected[0] 50 | self.selectedParent = self.selectedItem.parent() 51 | 52 | self.contextMenu.exec_(event.globalPos()) 53 | 54 | def addLibrary(self): 55 | return 56 | if self.selectedParent is None: 57 | parent = self.selectedItem 58 | else: 59 | parent = self.selectedParent 60 | newItem = QtGui.QTreeWidgetItem() 61 | newItem.setFlags(QtCore.Qt.ItemIsEditable | 62 | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) 63 | parent.insertChild(self.cu, newItem) 64 | self.editItem(newItem) 65 | 66 | def removeLibrary(self): 67 | if self.selectedParent != None: 68 | itemText = self.selectedItem.text(0) 69 | parentText = self.selectedParent.text(0) 70 | self.useData.libraryDict[parentText][0].remove(itemText) 71 | self.setItemHidden(self.selectedItem, True) 72 | 73 | def addModule(self): 74 | return 75 | if self.selectedParent is None: 76 | parent = self.selectedItem 77 | else: 78 | parent = self.selectedParent 79 | newItem = QtGui.QTreeWidgetItem() 80 | newItem.setFlags(QtCore.Qt.ItemIsEditable | 81 | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) 82 | parent.insertChild(self.cu, newItem) 83 | self.editItem(newItem) 84 | 85 | def removeModule(self): 86 | if self.selectedParent != None: 87 | itemText = self.selectedItem.text(0) 88 | parentText = self.selectedParent.text(0) 89 | self.useData.libraryDict[parentText][0].remove(itemText) 90 | self.setItemHidden(self.selectedItem, True) -------------------------------------------------------------------------------- /Extensions/Settings/SettingsWidget.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | from Extensions.Settings.ColorScheme.ColorScheme import ColorScheme 4 | from Extensions.Settings.Keymap import Keymap 5 | from Extensions.Settings.SnippetsManager import SnippetsManager 6 | from Extensions.Settings.GeneralSettings import GeneralSettings 7 | from Extensions.Settings.ModuleCompletion import ModuleCompletion 8 | 9 | 10 | class SettingsWidget(QtGui.QDialog): 11 | 12 | def __init__(self, useData, mainApp, projectWindowStack, libraryViewer, parent=None): 13 | QtGui.QDialog.__init__(self, parent, QtCore.Qt.Window | 14 | QtCore.Qt.WindowCloseButtonHint) 15 | 16 | self.setWindowTitle("Settings") 17 | 18 | self.useData = useData 19 | self.libraryViewer = libraryViewer 20 | self.projectWindowStack = projectWindowStack 21 | 22 | mainLayout = QtGui.QVBoxLayout() 23 | mainLayout.setMargin(0) 24 | self.setLayout(mainLayout) 25 | 26 | self.settingsTab = QtGui.QTabWidget() 27 | self.settingsTab.setObjectName("settingsTab") 28 | mainLayout.addWidget(self.settingsTab) 29 | 30 | self.generalSettings = GeneralSettings(useData, mainApp, projectWindowStack) 31 | self.settingsTab.addTab(self.generalSettings, "General") 32 | 33 | self.snippetEditor = SnippetsManager( 34 | self.useData.appPathDict["snippetsdir"], self) 35 | self.settingsTab.addTab(self.snippetEditor, "Snippets") 36 | 37 | self.keymapWidget = Keymap(self.useData, projectWindowStack, self) 38 | self.settingsTab.addTab(self.keymapWidget, "Shortcuts") 39 | 40 | self.colorScheme = ColorScheme(self.useData, projectWindowStack, 41 | libraryViewer) 42 | self.settingsTab.addTab(self.colorScheme, "Color Scheme") 43 | 44 | self.libraries = ModuleCompletion(self.useData) 45 | self.settingsTab.addTab(self.libraries, "Module Completion") 46 | -------------------------------------------------------------------------------- /Extensions/Settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/Settings/__init__.py -------------------------------------------------------------------------------- /Extensions/StackSwitcher.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtGui, QtCore 2 | 3 | 4 | class StackSwitcher(QtGui.QWidget): 5 | 6 | changed = QtCore.pyqtSignal(str) 7 | 8 | def __init__(self, stack, parent=None): 9 | QtGui.QDialog.__init__(self, parent) 10 | 11 | self.stack = stack 12 | self.lastIndex = 0 13 | 14 | self.mainLayout = QtGui.QHBoxLayout() 15 | self.mainLayout.setMargin(0) 16 | self.mainLayout.setSpacing(0) 17 | self.setLayout(self.mainLayout) 18 | 19 | self.buttonGroup = QtGui.QButtonGroup() 20 | self.buttonGroup.setExclusive(True) 21 | self.buttonGroup.buttonPressed.connect(self.setIndex) 22 | 23 | def addButton(self, name=None, icon=None, toolTip=None): 24 | button = QtGui.QPushButton() 25 | if name is not None: 26 | button.setText(name) 27 | if toolTip is not None: 28 | button.setToolTip(toolTip) 29 | button.setCheckable(True) 30 | if icon is not None: 31 | button.setIcon(icon) 32 | self.buttonGroup.addButton(button) 33 | self.buttonGroup.setId(button, self.lastIndex) 34 | self.mainLayout.addWidget(button) 35 | 36 | self.lastIndex += 1 37 | 38 | def setIndex(self, button): 39 | index = self.buttonGroup.id(button) 40 | self.stack.setCurrentIndex(index) 41 | self.changed.emit(button.text()) 42 | 43 | def setCount(self, widget, text): 44 | index = self.stack.indexOf(widget) 45 | self.buttonGroup.button(index).setText(text) 46 | 47 | def setCurrentWidget(self, widget): 48 | index = self.stack.indexOf(widget) 49 | button = self.buttonGroup.button(index) 50 | button.setChecked(True) 51 | self.stack.setCurrentWidget(widget) 52 | 53 | self.changed.emit(button.text()) 54 | 55 | def setDefault(self): 56 | """ 57 | Shows the active button after initialization 58 | """ 59 | button = self.buttonGroup.button(0) 60 | button.setChecked(True) 61 | self.changed.emit(button.text()) 62 | -------------------------------------------------------------------------------- /Extensions/TextSnapshot.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PyQt4 import QtGui 4 | 5 | from Extensions.BaseScintilla import BaseScintilla 6 | from Extensions import Global 7 | from Extensions import StyleSheet 8 | 9 | 10 | class TextSnapshot(BaseScintilla): 11 | 12 | def __init__(self, useData, colorScheme, fileType, parent=None): 13 | BaseScintilla.__init__(self, parent) 14 | 15 | self.setFont(Global.getDefaultFont()) 16 | self.setMarginLineNumbers(0, True) 17 | self.createContextMenu() 18 | 19 | self.DATA = {"fileType": fileType} 20 | self.setObjectName("editor") 21 | self.enableMarkOccurrence(useData) 22 | 23 | self.colorScheme = colorScheme 24 | self.colorScheme.styleEditor(self) 25 | 26 | def updateLexer(self, lexer): 27 | self.setLexer(lexer) 28 | 29 | def createContextMenu(self): 30 | self.copyAct = QtGui.QAction( 31 | "Copy", self, shortcut=QtGui.QKeySequence.Copy, 32 | statusTip="Copy selected text", triggered=self.copy) 33 | 34 | self.selectAllAct = QtGui.QAction("Select All", self, 35 | shortcut=QtGui.QKeySequence.SelectAll, 36 | statusTip="Select All", 37 | triggered=self.selectAllText) 38 | 39 | self.selectToMatchingBraceAct = \ 40 | QtGui.QAction(QtGui.QIcon(os.path.join("Resources", "images", "text_select")), 41 | "Select to Matching Brace", self, 42 | statusTip="Select to Matching Brace", 43 | triggered=self.selectToMatchingBrace) 44 | 45 | self.contextMenu = QtGui.QMenu() 46 | self.contextMenu.addAction(self.copyAct) 47 | self.contextMenu.addAction(self.selectAllAct) 48 | self.contextMenu.addAction(self.selectToMatchingBraceAct) 49 | 50 | def contextMenuEvent(self, event): 51 | state = self.hasSelectedText() 52 | 53 | self.copyAct.setEnabled(state) 54 | self.contextMenu.exec_(event.globalPos()) 55 | 56 | def selectAllText(self): 57 | self.selectAll() 58 | -------------------------------------------------------------------------------- /Extensions/ViewSwitcher.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtGui 3 | 4 | from Extensions import StyleSheet 5 | 6 | 7 | class ViewSwitcher(QtGui.QLabel): 8 | 9 | def __init__(self, parent=None): 10 | QtGui.QLabel.__init__(self, parent) 11 | 12 | self.setMinimumHeight(35) 13 | self.setMaximumHeight(35) 14 | self.setMinimumWidth(175) 15 | self.setMaximumWidth(175) 16 | 17 | self.lastIndex = 0 18 | 19 | self.mainLayout = QtGui.QHBoxLayout() 20 | self.mainLayout.setMargin(0) 21 | self.mainLayout.setSpacing(0) 22 | self.setLayout(self.mainLayout) 23 | 24 | self.editorTabWidget = parent 25 | self.editorTabWidget.currentChanged.connect(self.setCurrentView) 26 | 27 | self.buttonGroup = QtGui.QButtonGroup() 28 | self.buttonGroup.setExclusive(True) 29 | self.buttonGroup.buttonPressed.connect(self.viewChanged) 30 | 31 | self.hideButton = QtGui.QToolButton() 32 | self.hideButton.setAutoRaise(True) 33 | self.hideButton.setIcon( 34 | QtGui.QIcon(os.path.join("Resources", "images", "exit"))) 35 | self.hideButton.clicked.connect(self.hide) 36 | self.mainLayout.addWidget(self.hideButton) 37 | 38 | self.setStyleSheet(StyleSheet.viewSwitcherStyle) 39 | 40 | self.addButton(QtGui.QIcon( 41 | os.path.join("Resources", "images", "notes_selected")), "Editor") 42 | self.addButton(QtGui.QIcon( 43 | os.path.join("Resources", "images", "notes")), "Snapshot") 44 | self.addButton(QtGui.QIcon( 45 | os.path.join("Resources", "images", "links_selected")), "Unified Diff") 46 | self.addButton(QtGui.QIcon( 47 | os.path.join("Resources", "images", "links")), "Context Diff") 48 | 49 | def setCurrentView(self): 50 | index = self.editorTabWidget.currentWidget().currentIndex() 51 | self.setIndex(None, index) 52 | 53 | def viewChanged(self, button): 54 | index = self.buttonGroup.id(button) 55 | self.setIndex(button, index) 56 | 57 | if index == 2: 58 | self.editorTabWidget.getUnifiedDiff().generateUnifiedDiff() 59 | elif index == 3: 60 | self.editorTabWidget.getContextDiff().generateContextDiff() 61 | 62 | def addButton(self, icon, toolTip): 63 | button = QtGui.QToolButton() 64 | button.setToolTip(toolTip) 65 | button.setCheckable(True) 66 | button.setIcon(icon) 67 | self.buttonGroup.addButton(button) 68 | self.buttonGroup.setId(button, self.lastIndex) 69 | self.mainLayout.addWidget(button) 70 | 71 | self.lastIndex += 1 72 | 73 | def setIndex(self, button, index=None): 74 | button = self.buttonGroup.button(index) 75 | button.setChecked(True) 76 | subStack = self.editorTabWidget.currentWidget() 77 | subStack.setCurrentIndex(index) 78 | 79 | def setDefault(self): 80 | """ 81 | Shows the active button after initialization 82 | """ 83 | button = self.buttonGroup.button(0) 84 | button.setChecked(True) 85 | self.changed.emit(button.text()) 86 | -------------------------------------------------------------------------------- /Extensions/WritePad.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | 3 | 4 | class WritePad(QtGui.QMainWindow): 5 | 6 | def __init__(self, path, name, parent=None): 7 | QtGui.QMainWindow.__init__(self, parent) 8 | 9 | self.setWindowTitle(name + " - Notes") 10 | self.resize(600, 300) 11 | screen = QtGui.QDesktopWidget().screenGeometry() 12 | size = self.geometry() 13 | self.move((screen.width() - size.width()) / 2, 14 | (screen.height() - size.height()) / 2) 15 | 16 | self.path = path 17 | self.setObjectName("writePad") 18 | 19 | self.noteSaveTimer = QtCore.QTimer() 20 | self.noteSaveTimer.setSingleShot(True) 21 | self.noteSaveTimer.timeout.connect(self.saveNotes) 22 | 23 | self.writePad = QtGui.QPlainTextEdit() 24 | self.writePad.setLineWrapMode(QtGui.QPlainTextEdit.NoWrap) 25 | self.writePad.setFont(QtGui.QFont("Ms Reference Sans Serif", 10.9)) 26 | self.setCentralWidget(self.writePad) 27 | 28 | # load notes 29 | try: 30 | file = open(self.path, "r") 31 | self.writePad.setPlainText(file.read()) 32 | file.close() 33 | except: 34 | file = open(path, "w") 35 | file.close() 36 | 37 | self.writePad.textChanged.connect(self.startSaveTimer) 38 | 39 | def startSaveTimer(self): 40 | self.noteSaveTimer.start(1000) 41 | 42 | def saveNotes(self): 43 | file = open(self.path, "w") 44 | file.write(self.writePad.toPlainText()) 45 | file.close() 46 | -------------------------------------------------------------------------------- /Extensions/ZoomWidget.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PyQt4 import QtCore, QtGui 3 | 4 | 5 | class ZoomWidget(QtGui.QLabel): 6 | 7 | def __init__(self, useData, editor, parent=None): 8 | QtGui.QLabel.__init__(self, parent=None) 9 | 10 | self.useData = useData 11 | self.editor = editor 12 | self.prevValue = 0 13 | 14 | self.setMinimumHeight(130) 15 | self.setMaximumHeight(130) 16 | self.setMinimumWidth(38) 17 | self.setMaximumWidth(38) 18 | 19 | mainLayout = QtGui.QVBoxLayout() 20 | mainLayout.setMargin(1) 21 | mainLayout.setSpacing(0) 22 | self.setLayout(mainLayout) 23 | 24 | self.increaseButton = QtGui.QToolButton() 25 | self.increaseButton.setMaximumWidth(36) 26 | self.increaseButton.setText('+') 27 | self.increaseButton.setMaximumHeight(36) 28 | self.increaseButton.clicked.connect(self.zoomIn) 29 | mainLayout.addWidget(self.increaseButton) 30 | 31 | self.zoomBox = QtGui.QSpinBox() 32 | self.zoomBox.setMinimum(0) 33 | self.zoomBox.setReadOnly(True) 34 | self.zoomBox.setAlignment(QtCore.Qt.AlignHCenter) 35 | self.zoomBox.setButtonSymbols(2) 36 | self.zoomBox.setMaximum(100) 37 | self.zoomBox.setSingleStep(10) 38 | self.zoomBox.setSuffix("%") 39 | self.zoomBox.valueChanged.connect(self.changePosition) 40 | mainLayout.addWidget(self.zoomBox) 41 | 42 | self.decreaseButton = QtGui.QToolButton() 43 | self.decreaseButton.setMaximumWidth(36) 44 | self.decreaseButton.setText('-') 45 | self.decreaseButton.setMaximumHeight(36) 46 | self.decreaseButton.clicked.connect(self.zoomOut) 47 | mainLayout.addWidget(self.decreaseButton) 48 | 49 | self.hideButton = QtGui.QToolButton() 50 | self.hideButton.setMaximumWidth(36) 51 | self.hideButton.setMaximumHeight(36) 52 | self.hideButton.setAutoRaise(True) 53 | self.hideButton.setIcon( 54 | QtGui.QIcon(os.path.join("Resources", "images", "exit"))) 55 | self.hideButton.clicked.connect(self.hide) 56 | mainLayout.addWidget(self.hideButton) 57 | 58 | self.hide() 59 | 60 | self.setStyleSheet(""" 61 | QLabel { 62 | background: rgba(138, 201, 255, 200); 63 | border-radius: 0px; 64 | } 65 | 66 | """) 67 | 68 | def changePosition(self, value): 69 | if self.prevValue > value: 70 | self.editor.zoomOut() 71 | elif self.prevValue < value: 72 | self.editor.zoomIn() 73 | else: 74 | self.editor.zoomOut() 75 | self.prevValue = value 76 | 77 | def zoomIn(self): 78 | self.zoomBox.setValue(self.zoomBox.value() + 10) 79 | 80 | def zoomOut(self): 81 | self.zoomBox.setValue(self.zoomBox.value() - 10) 82 | -------------------------------------------------------------------------------- /Extensions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Extensions/__init__.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pcode 2 | ===== 3 | 4 | ## Python 3 IDE 5 | 6 | Pcode seeks to simplify the process of development in python by means of: 7 | 8 | 1. A simple and intuitive UI ( Zero clutter ) 9 | 1. Utilization of very powerful open source libraries 10 | 1. Implementation of carefully chosen features 11 | 1. Support for other file formats that commonly accompany python development 12 | 13 | ### Features: 14 | 1. Builds source code into executable 15 | 1. Refactoring 16 | 1. Project Management 17 | 1. Go-to-Definition 18 | 1. Snippets 19 | 1. Support for syntax coloring for XML, HTML and CSS 20 | 1. Error Analysis 21 | 1. Pep8 checker and fixer 22 | 1. Auto-completion 23 | 1. Outline Explorer 24 | 1. Profiler 25 | 1. Find-in-Files/Replace 26 | 1. Code Library 27 | 1. Split Editor ( Horizontal and Vertical ) 28 | 1. Etc. 29 | 30 | ### Download 31 | Click on [Release](https://github.com/fortharris/Pcode/releases) to view available downloads. 32 | 33 | ### Dependencies: 34 | 1. Python 3 ( for running programs ) 35 | 1. PyQt4 ( if you are running from source ) 36 | 37 | Then perhaps: 38 | * Pywin32 for windows ( for stamping executables if you are running from source ) 39 | 40 | ### License: 41 | * GPL v3 42 | 43 | ### Latest version: 0.1.5 44 | 45 | Mailing List: [pcode-ide@googlegroups.com](https://groups.google.com/forum/#!forum/pcode-ide) 46 | 47 | ### Screenshots 48 | ![Alt text](/docs/screens/1.png "1") 49 | ![Alt text](/docs/screens/2.png "2") 50 | ![Alt text](/docs/screens/3.png "3") 51 | -------------------------------------------------------------------------------- /Resources/PcodeProjects.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/PcodeProjects.zip -------------------------------------------------------------------------------- /Resources/build/32bit/bases/Console.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/build/32bit/bases/Console.exe -------------------------------------------------------------------------------- /Resources/build/32bit/bases/ConsoleKeepPath.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/build/32bit/bases/ConsoleKeepPath.exe -------------------------------------------------------------------------------- /Resources/build/32bit/bases/Win32GUI.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/build/32bit/bases/Win32GUI.exe -------------------------------------------------------------------------------- /Resources/build/32bit/bases/Win32Service.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/build/32bit/bases/Win32Service.exe -------------------------------------------------------------------------------- /Resources/build/32bit/initscripts/Console.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # Console.py 3 | # Initialization script for cx_Freeze which manipulates the path so that the 4 | # directory in which the executable is found is searched for extensions but 5 | # no other directory is searched. It also sets the attribute sys.frozen so that 6 | # the Win32 extensions behave as expected. 7 | #------------------------------------------------------------------------------ 8 | 9 | import os 10 | import sys 11 | import zipimport 12 | 13 | sys.frozen = True 14 | sys.path = sys.path[:4] 15 | 16 | os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl") 17 | os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk") 18 | 19 | m = __import__("__main__") 20 | importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME) 21 | if INITSCRIPT_ZIP_FILE_NAME != SHARED_ZIP_FILE_NAME: 22 | moduleName = m.__name__ 23 | else: 24 | name, ext = os.path.splitext(os.path.basename(os.path.normcase(FILE_NAME))) 25 | moduleName = "%s__main__" % name 26 | code = importer.get_code(moduleName) 27 | exec(code, m.__dict__) 28 | 29 | versionInfo = sys.version_info[:3] 30 | if versionInfo >= (2, 5, 0) and versionInfo <= (2, 6, 4): 31 | module = sys.modules.get("threading") 32 | if module is not None: 33 | module._shutdown() 34 | 35 | -------------------------------------------------------------------------------- /Resources/build/32bit/initscripts/ConsoleKeepPath.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # ConsoleKeepPath.py 3 | # Initialization script for cx_Freeze which leaves the path alone and does 4 | # not set the sys.frozen attribute. 5 | #------------------------------------------------------------------------------ 6 | 7 | import sys 8 | import zipimport 9 | 10 | m = __import__("__main__") 11 | importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME) 12 | code = importer.get_code(m.__name__) 13 | exec(code, m.__dict__) 14 | 15 | versionInfo = sys.version_info[:3] 16 | if versionInfo >= (2, 5, 0) and versionInfo <= (2, 6, 4): 17 | module = sys.modules.get("threading") 18 | if module is not None: 19 | module._shutdown() 20 | 21 | -------------------------------------------------------------------------------- /Resources/build/32bit/initscripts/ConsoleSetLibPath.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # ConsoleSetLibPath.py 3 | # Initialization script for cx_Freeze which manipulates the path so that the 4 | # directory in which the executable is found is searched for extensions but 5 | # no other directory is searched. The environment variable LD_LIBRARY_PATH is 6 | # manipulated first, however, to ensure that shared libraries found in the 7 | # target directory are found. This requires a restart of the executable because 8 | # the environment variable LD_LIBRARY_PATH is only checked at startup. 9 | #------------------------------------------------------------------------------ 10 | 11 | import os 12 | import sys 13 | import zipimport 14 | 15 | paths = os.environ.get("LD_LIBRARY_PATH", "").split(os.pathsep) 16 | 17 | if DIR_NAME not in paths: 18 | paths.insert(0, DIR_NAME) 19 | os.environ["LD_LIBRARY_PATH"] = os.pathsep.join(paths) 20 | os.execv(sys.executable, sys.argv) 21 | 22 | sys.frozen = True 23 | sys.path = sys.path[:4] 24 | 25 | os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl") 26 | os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk") 27 | 28 | m = __import__("__main__") 29 | importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME) 30 | 31 | if INITSCRIPT_ZIP_FILE_NAME != SHARED_ZIP_FILE_NAME: 32 | moduleName = m.__name__ 33 | else: 34 | name, ext = os.path.splitext(os.path.basename(os.path.normcase(FILE_NAME))) 35 | moduleName = "%s__main__" % name 36 | 37 | code = importer.get_code(moduleName) 38 | exec(code, m.__dict__) 39 | 40 | versionInfo = sys.version_info[:3] 41 | 42 | if versionInfo >= (2, 5, 0) and versionInfo <= (2, 6, 4): 43 | module = sys.modules.get("threading") 44 | if module is not None: 45 | module._shutdown() 46 | 47 | -------------------------------------------------------------------------------- /Resources/build/32bit/initscripts/SharedLib.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # SharedLib.py 3 | # Initialization script for cx_Freeze which behaves similarly to the one for 4 | # console based applications but must handle the case where Python has already 5 | # been initialized and another DLL of this kind has been loaded. As such it 6 | # does not block the path unless sys.frozen is not already set. 7 | #------------------------------------------------------------------------------ 8 | 9 | import encodings 10 | import os 11 | import sys 12 | import warnings 13 | 14 | if not hasattr(sys, "frozen"): 15 | sys.frozen = True 16 | sys.path = sys.path[:4] 17 | 18 | os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl") 19 | os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk") 20 | 21 | -------------------------------------------------------------------------------- /Resources/build/32bit/initscripts/SharedLibSource.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # SharedLibSource.py 3 | # Initialization script for cx_Freeze which imports the site module (as per 4 | # normal processing of a Python script) and then searches for a file with the 5 | # same name as the shared library but with the extension .pth. The entries in 6 | # this file are used to modify the path to use for subsequent imports. 7 | #------------------------------------------------------------------------------ 8 | 9 | import os 10 | import sys 11 | import warnings 12 | 13 | # the site module must be imported for normal behavior to take place; it is 14 | # done dynamically so that cx_Freeze will not add all modules referenced by 15 | # the site module to the frozen executable 16 | __import__("site") 17 | 18 | # now locate the pth file to modify the path appropriately 19 | baseName, ext = os.path.splitext(FILE_NAME) 20 | pathFileName = baseName + ".pth" 21 | sys.path = [s.strip() for s in file(pathFileName).read().splitlines()] + \ 22 | sys.path 23 | 24 | -------------------------------------------------------------------------------- /Resources/default_config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | 3 | 4 | def set_prefs(prefs): 5 | """This function is called before opening the project""" 6 | 7 | # Specify which files and folders to ignore in the project. 8 | # Changes to ignored resources are not added to the history and 9 | # VCSs. Also they are not returned in `Project.get_files()`. 10 | # Note that ``?`` and ``*`` match all characters but slashes. 11 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 12 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 13 | # '.svn': matches 'pkg/.svn' and all of its children 14 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 15 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 16 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', 17 | '.hg', '.svn', '_svn', '.git', 18 | '__pycache__'] 19 | 20 | # Specifies which files should be considered python files. It is 21 | # useful when you have scripts inside your project. Only files 22 | # ending with ``.py`` are considered to be python files by 23 | # default. 24 | #prefs['python_files'] = ['*.py'] 25 | 26 | # Custom source folders: By default rope searches the project 27 | # for finding source folders (folders that should be searched 28 | # for finding modules). You can add paths to that list. Note 29 | # that rope guesses project source folders correctly most of the 30 | # time; use this if you have any problems. 31 | # The folders should be relative to project root and use '/' for 32 | # separating folders regardless of the platform rope is running on. 33 | # 'src/my_source_folder' for instance. 34 | #prefs.add('source_folders', 'src') 35 | 36 | # You can extend python path for looking up modules 37 | #prefs.add('python_path', '~/python/') 38 | 39 | # Should rope save object information or not. 40 | prefs['save_objectdb'] = True 41 | prefs['compress_objectdb'] = False 42 | 43 | # If `True`, rope analyzes each module when it is being saved. 44 | prefs['automatic_soa'] = True 45 | # The depth of calls to follow in static object analysis 46 | prefs['soa_followed_calls'] = 0 47 | 48 | # If `False` when running modules or unit tests "dynamic object 49 | # analysis" is turned off. This makes them much faster. 50 | prefs['perform_doa'] = True 51 | 52 | # Rope can check the validity of its object DB when running. 53 | prefs['validate_objectdb'] = True 54 | 55 | # How many undos to hold? 56 | prefs['max_history_items'] = 32 57 | 58 | # Shows whether to save history across sessions. 59 | prefs['save_history'] = True 60 | prefs['compress_history'] = False 61 | 62 | # Set the number spaces used for indenting. According to 63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 64 | # unit-tests use 4 spaces it is more reliable, too. 65 | prefs['indent_size'] = 4 66 | 67 | # Builtin and c-extension modules that are allowed to be imported 68 | # and inspected by rope. 69 | prefs['extension_modules'] = [] 70 | 71 | # Add all standard c-extensions to extension_modules list. 72 | prefs['import_dynload_stdmods'] = True 73 | 74 | # If `True` modules with syntax errors are considered to be empty. 75 | # The default value is `False`; When `False` syntax errors raise 76 | # `rope.base.exceptions.ModuleSyntaxError` exception. 77 | prefs['ignore_syntax_errors'] = False 78 | 79 | # If `True`, rope ignores unresolvable imports. Otherwise, they 80 | # appear in the importing namespace. 81 | prefs['ignore_bad_imports'] = False 82 | 83 | 84 | def project_opened(project): 85 | """This function is called after opening the project""" 86 | # Do whatever you like here! 87 | -------------------------------------------------------------------------------- /Resources/images/Arrow2-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Arrow2-down.png -------------------------------------------------------------------------------- /Resources/images/Arrow2-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Arrow2-up.png -------------------------------------------------------------------------------- /Resources/images/Clear Green Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Clear Green Button.png -------------------------------------------------------------------------------- /Resources/images/Dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Dashboard.png -------------------------------------------------------------------------------- /Resources/images/Fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Fullscreen.png -------------------------------------------------------------------------------- /Resources/images/Stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Stop.png -------------------------------------------------------------------------------- /Resources/images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Thumbs.db -------------------------------------------------------------------------------- /Resources/images/Web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/Web.png -------------------------------------------------------------------------------- /Resources/images/_0013_Printer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/_0013_Printer.png -------------------------------------------------------------------------------- /Resources/images/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/about.png -------------------------------------------------------------------------------- /Resources/images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/add.png -------------------------------------------------------------------------------- /Resources/images/alerts/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/alerts/Thumbs.db -------------------------------------------------------------------------------- /Resources/images/alerts/_0035_Flashlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/alerts/_0035_Flashlight.png -------------------------------------------------------------------------------- /Resources/images/alerts/construction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/alerts/construction.png -------------------------------------------------------------------------------- /Resources/images/alerts/toast_critical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/alerts/toast_critical.png -------------------------------------------------------------------------------- /Resources/images/alerts/toast_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/alerts/toast_warning.png -------------------------------------------------------------------------------- /Resources/images/archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/archive.png -------------------------------------------------------------------------------- /Resources/images/arrow-045.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/arrow-045.png -------------------------------------------------------------------------------- /Resources/images/asterisk-yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/asterisk-yellow.png -------------------------------------------------------------------------------- /Resources/images/attibutes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/attibutes.png -------------------------------------------------------------------------------- /Resources/images/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/block.png -------------------------------------------------------------------------------- /Resources/images/block__.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/block__.png -------------------------------------------------------------------------------- /Resources/images/bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/bold.png -------------------------------------------------------------------------------- /Resources/images/bookmarked_url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/bookmarked_url.png -------------------------------------------------------------------------------- /Resources/images/border-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/border-horizontal.png -------------------------------------------------------------------------------- /Resources/images/border-inside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/border-inside.png -------------------------------------------------------------------------------- /Resources/images/border-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/border-vertical.png -------------------------------------------------------------------------------- /Resources/images/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/border.png -------------------------------------------------------------------------------- /Resources/images/box-document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/box-document.png -------------------------------------------------------------------------------- /Resources/images/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/box.png -------------------------------------------------------------------------------- /Resources/images/brainstorming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/brainstorming.png -------------------------------------------------------------------------------- /Resources/images/build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/build.png -------------------------------------------------------------------------------- /Resources/images/cards_binds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cards_binds.png -------------------------------------------------------------------------------- /Resources/images/cascade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cascade.png -------------------------------------------------------------------------------- /Resources/images/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/chat.png -------------------------------------------------------------------------------- /Resources/images/chat_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/chat_selected.png -------------------------------------------------------------------------------- /Resources/images/class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/class.png -------------------------------------------------------------------------------- /Resources/images/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/clear.png -------------------------------------------------------------------------------- /Resources/images/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/collapse.png -------------------------------------------------------------------------------- /Resources/images/comment-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/comment-code.png -------------------------------------------------------------------------------- /Resources/images/compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/compass.png -------------------------------------------------------------------------------- /Resources/images/compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/compose.png -------------------------------------------------------------------------------- /Resources/images/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/config.png -------------------------------------------------------------------------------- /Resources/images/consulting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/consulting.png -------------------------------------------------------------------------------- /Resources/images/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/copy.png -------------------------------------------------------------------------------- /Resources/images/crate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/crate.png -------------------------------------------------------------------------------- /Resources/images/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cross.png -------------------------------------------------------------------------------- /Resources/images/cross_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cross_.png -------------------------------------------------------------------------------- /Resources/images/cushion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cushion.png -------------------------------------------------------------------------------- /Resources/images/cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/cut.png -------------------------------------------------------------------------------- /Resources/images/database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/database.png -------------------------------------------------------------------------------- /Resources/images/decrease_indent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/decrease_indent.png -------------------------------------------------------------------------------- /Resources/images/disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/disabled.png -------------------------------------------------------------------------------- /Resources/images/disks-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/disks-black.png -------------------------------------------------------------------------------- /Resources/images/document_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/document_.png -------------------------------------------------------------------------------- /Resources/images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/down.png -------------------------------------------------------------------------------- /Resources/images/edit-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit-color.png -------------------------------------------------------------------------------- /Resources/images/edit-lowercase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit-lowercase.png -------------------------------------------------------------------------------- /Resources/images/edit-number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit-number.png -------------------------------------------------------------------------------- /Resources/images/edit-replace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit-replace.png -------------------------------------------------------------------------------- /Resources/images/edit-uppercase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit-uppercase.png -------------------------------------------------------------------------------- /Resources/images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit.png -------------------------------------------------------------------------------- /Resources/images/edit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/edit2.png -------------------------------------------------------------------------------- /Resources/images/envelope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/envelope.png -------------------------------------------------------------------------------- /Resources/images/erase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/erase.png -------------------------------------------------------------------------------- /Resources/images/err_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/err_mark.png -------------------------------------------------------------------------------- /Resources/images/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/exit.png -------------------------------------------------------------------------------- /Resources/images/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/expand.png -------------------------------------------------------------------------------- /Resources/images/extender-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/extender-down.png -------------------------------------------------------------------------------- /Resources/images/extender-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/extender-up.png -------------------------------------------------------------------------------- /Resources/images/fileSaveAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/fileSaveAll.png -------------------------------------------------------------------------------- /Resources/images/filter-disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/filter-disable.png -------------------------------------------------------------------------------- /Resources/images/findDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/findDown.png -------------------------------------------------------------------------------- /Resources/images/findUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/findUp.png -------------------------------------------------------------------------------- /Resources/images/find_in_files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/find_in_files.png -------------------------------------------------------------------------------- /Resources/images/finished-work.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/finished-work.png -------------------------------------------------------------------------------- /Resources/images/flag-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/flag-green.png -------------------------------------------------------------------------------- /Resources/images/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/flag.png -------------------------------------------------------------------------------- /Resources/images/foaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/foaf.png -------------------------------------------------------------------------------- /Resources/images/fold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/fold.png -------------------------------------------------------------------------------- /Resources/images/folder-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/folder-horizontal.png -------------------------------------------------------------------------------- /Resources/images/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/folder.png -------------------------------------------------------------------------------- /Resources/images/folder_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/folder_closed.png -------------------------------------------------------------------------------- /Resources/images/folder_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/folder_open.png -------------------------------------------------------------------------------- /Resources/images/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/function.png -------------------------------------------------------------------------------- /Resources/images/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/gear.png -------------------------------------------------------------------------------- /Resources/images/graphic-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/graphic-design.png -------------------------------------------------------------------------------- /Resources/images/guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/guide.png -------------------------------------------------------------------------------- /Resources/images/haiku-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/haiku-wide.png -------------------------------------------------------------------------------- /Resources/images/hire-me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/hire-me.png -------------------------------------------------------------------------------- /Resources/images/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/history.png -------------------------------------------------------------------------------- /Resources/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/home.png -------------------------------------------------------------------------------- /Resources/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/icon.png -------------------------------------------------------------------------------- /Resources/images/in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/in.png -------------------------------------------------------------------------------- /Resources/images/inbox--minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/inbox--minus.png -------------------------------------------------------------------------------- /Resources/images/inbox--plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/inbox--plus.png -------------------------------------------------------------------------------- /Resources/images/inbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/inbox.png -------------------------------------------------------------------------------- /Resources/images/increase_indent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/increase_indent.png -------------------------------------------------------------------------------- /Resources/images/issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/issue.png -------------------------------------------------------------------------------- /Resources/images/italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/italic.png -------------------------------------------------------------------------------- /Resources/images/led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/led.png -------------------------------------------------------------------------------- /Resources/images/library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/library.png -------------------------------------------------------------------------------- /Resources/images/lightbulb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/lightbulb.png -------------------------------------------------------------------------------- /Resources/images/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/lightning.png -------------------------------------------------------------------------------- /Resources/images/links.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/links.png -------------------------------------------------------------------------------- /Resources/images/links_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/links_selected.png -------------------------------------------------------------------------------- /Resources/images/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/location.png -------------------------------------------------------------------------------- /Resources/images/locked_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/locked_script.png -------------------------------------------------------------------------------- /Resources/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/login.png -------------------------------------------------------------------------------- /Resources/images/mail_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/mail_check.png -------------------------------------------------------------------------------- /Resources/images/mail_pinned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/mail_pinned.png -------------------------------------------------------------------------------- /Resources/images/mail_thread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/mail_thread.png -------------------------------------------------------------------------------- /Resources/images/map_marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/map_marker.png -------------------------------------------------------------------------------- /Resources/images/mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/mark.png -------------------------------------------------------------------------------- /Resources/images/messages/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/messages/Thumbs.db -------------------------------------------------------------------------------- /Resources/images/messages/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/messages/blue.png -------------------------------------------------------------------------------- /Resources/images/messages/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/messages/orange.png -------------------------------------------------------------------------------- /Resources/images/messages/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/messages/red.png -------------------------------------------------------------------------------- /Resources/images/milestone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/milestone.png -------------------------------------------------------------------------------- /Resources/images/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/minus.png -------------------------------------------------------------------------------- /Resources/images/new-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/new-item.png -------------------------------------------------------------------------------- /Resources/images/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/new.png -------------------------------------------------------------------------------- /Resources/images/notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/notes.png -------------------------------------------------------------------------------- /Resources/images/notes_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/notes_selected.png -------------------------------------------------------------------------------- /Resources/images/open_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/open_file.png -------------------------------------------------------------------------------- /Resources/images/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/orange.png -------------------------------------------------------------------------------- /Resources/images/out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/out.png -------------------------------------------------------------------------------- /Resources/images/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/page.png -------------------------------------------------------------------------------- /Resources/images/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/paste.png -------------------------------------------------------------------------------- /Resources/images/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/pencil.png -------------------------------------------------------------------------------- /Resources/images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/plus.png -------------------------------------------------------------------------------- /Resources/images/product.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/product.png -------------------------------------------------------------------------------- /Resources/images/project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/project.png -------------------------------------------------------------------------------- /Resources/images/properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/properties.png -------------------------------------------------------------------------------- /Resources/images/redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/redo.png -------------------------------------------------------------------------------- /Resources/images/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/remove.png -------------------------------------------------------------------------------- /Resources/images/rerun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/rerun.png -------------------------------------------------------------------------------- /Resources/images/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/run.png -------------------------------------------------------------------------------- /Resources/images/save_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/save_.png -------------------------------------------------------------------------------- /Resources/images/scope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/scope.png -------------------------------------------------------------------------------- /Resources/images/script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/script.png -------------------------------------------------------------------------------- /Resources/images/script_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/script_grey.png -------------------------------------------------------------------------------- /Resources/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/search.png -------------------------------------------------------------------------------- /Resources/images/security/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/Thumbs.db -------------------------------------------------------------------------------- /Resources/images/security/allowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/allowed.png -------------------------------------------------------------------------------- /Resources/images/security/attention.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/attention.png -------------------------------------------------------------------------------- /Resources/images/security/clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/clean.png -------------------------------------------------------------------------------- /Resources/images/security/danger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/danger.png -------------------------------------------------------------------------------- /Resources/images/security/denied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/denied.png -------------------------------------------------------------------------------- /Resources/images/security/requesting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/requesting.png -------------------------------------------------------------------------------- /Resources/images/security/turbo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/turbo.png -------------------------------------------------------------------------------- /Resources/images/security/turbo_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/turbo_inactive.png -------------------------------------------------------------------------------- /Resources/images/security/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security/warning.png -------------------------------------------------------------------------------- /Resources/images/security_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/security_disabled.png -------------------------------------------------------------------------------- /Resources/images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/settings.png -------------------------------------------------------------------------------- /Resources/images/shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/shell.png -------------------------------------------------------------------------------- /Resources/images/speech_bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/speech_bubble.png -------------------------------------------------------------------------------- /Resources/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/splash.png -------------------------------------------------------------------------------- /Resources/images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/star.png -------------------------------------------------------------------------------- /Resources/images/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/tag.png -------------------------------------------------------------------------------- /Resources/images/templates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/templates.png -------------------------------------------------------------------------------- /Resources/images/text_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/text_select.png -------------------------------------------------------------------------------- /Resources/images/tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/tile.png -------------------------------------------------------------------------------- /Resources/images/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/tree.png -------------------------------------------------------------------------------- /Resources/images/ui-button-navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/ui-button-navigation.png -------------------------------------------------------------------------------- /Resources/images/ui-menu-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/ui-menu-blue.png -------------------------------------------------------------------------------- /Resources/images/ui-scroll-pane-blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/ui-scroll-pane-blog.png -------------------------------------------------------------------------------- /Resources/images/ui-text-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/ui-text-field.png -------------------------------------------------------------------------------- /Resources/images/undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/undo.png -------------------------------------------------------------------------------- /Resources/images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/up.png -------------------------------------------------------------------------------- /Resources/images/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/windows.png -------------------------------------------------------------------------------- /Resources/images/wooden-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/wooden-box.png -------------------------------------------------------------------------------- /Resources/images/zone-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/zone-medium.png -------------------------------------------------------------------------------- /Resources/images/zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/images/zoom.png -------------------------------------------------------------------------------- /Resources/style/images/Arrow Left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/Arrow Left.png -------------------------------------------------------------------------------- /Resources/style/images/Arrow Right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/Arrow Right.png -------------------------------------------------------------------------------- /Resources/style/images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/Thumbs.db -------------------------------------------------------------------------------- /Resources/style/images/close-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/close-hover.png -------------------------------------------------------------------------------- /Resources/style/images/close-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/close-pressed.png -------------------------------------------------------------------------------- /Resources/style/images/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/close1.png -------------------------------------------------------------------------------- /Resources/style/images/close_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/close_black.png -------------------------------------------------------------------------------- /Resources/style/images/closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/closed.png -------------------------------------------------------------------------------- /Resources/style/images/document-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/document-tree.png -------------------------------------------------------------------------------- /Resources/style/images/downarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/downarrow.png -------------------------------------------------------------------------------- /Resources/style/images/group_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/group_open.png -------------------------------------------------------------------------------- /Resources/style/images/leftarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/leftarrow.png -------------------------------------------------------------------------------- /Resources/style/images/panel-top-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/panel-top-selected.png -------------------------------------------------------------------------------- /Resources/style/images/rightarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/rightarrow.png -------------------------------------------------------------------------------- /Resources/style/images/tear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/tear.png -------------------------------------------------------------------------------- /Resources/style/images/uparrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/uparrow.png -------------------------------------------------------------------------------- /Resources/style/images/vignette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/Resources/style/images/vignette.png -------------------------------------------------------------------------------- /Resources/venv/scripts/nt/Activate.ps1: -------------------------------------------------------------------------------- 1 | $env:VIRTUAL_ENV="__VENV_DIR__" 2 | 3 | # Revert to original values 4 | if (Test-Path function:_OLD_VIRTUAL_PROMPT) { 5 | copy-item function:_OLD_VIRTUAL_PROMPT function:prompt 6 | remove-item function:_OLD_VIRTUAL_PROMPT 7 | } 8 | 9 | if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { 10 | copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME 11 | remove-item env:_OLD_VIRTUAL_PYTHONHOME 12 | } 13 | 14 | if (Test-Path env:_OLD_VIRTUAL_PATH) { 15 | copy-item env:_OLD_VIRTUAL_PATH env:PATH 16 | remove-item env:_OLD_VIRTUAL_PATH 17 | } 18 | 19 | # Set the prompt to include the env name 20 | copy-item function:prompt function:_OLD_VIRTUAL_PROMPT 21 | function prompt { 22 | Write-Host -NoNewline -ForegroundColor Green '[__VENV_NAME__]' 23 | _OLD_VIRTUAL_PROMPT 24 | } 25 | 26 | # Clear PYTHONHOME 27 | if (Test-Path env:PYTHONHOME) { 28 | copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME 29 | remove-item env:PYTHONHOME 30 | } 31 | 32 | # Add the venv to the PATH 33 | copy-item env:PATH env:_OLD_VIRTUAL_PATH 34 | $env:PATH = "$env:VIRTUAL_ENV\__VENV_BIN_NAME__;$env:PATH" 35 | -------------------------------------------------------------------------------- /Resources/venv/scripts/nt/Deactivate.ps1: -------------------------------------------------------------------------------- 1 | # Revert to original values 2 | if (Test-Path function:_OLD_VIRTUAL_PROMPT) { 3 | copy-item function:_OLD_VIRTUAL_PROMPT function:prompt 4 | remove-item function:_OLD_VIRTUAL_PROMPT 5 | } 6 | 7 | if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { 8 | copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME 9 | remove-item env:_OLD_VIRTUAL_PYTHONHOME 10 | } 11 | 12 | if (Test-Path env:_OLD_VIRTUAL_PATH) { 13 | copy-item env:_OLD_VIRTUAL_PATH env:PATH 14 | remove-item env:_OLD_VIRTUAL_PATH 15 | } 16 | 17 | if (Test-Path env:VIRTUAL_ENV) { 18 | remove-item env:VIRTUAL_ENV 19 | } 20 | -------------------------------------------------------------------------------- /Resources/venv/scripts/nt/activate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set VIRTUAL_ENV=__VENV_DIR__ 3 | 4 | if not defined PROMPT ( 5 | set PROMPT=$P$G 6 | ) 7 | 8 | if defined _OLD_VIRTUAL_PROMPT ( 9 | set PROMPT=%_OLD_VIRTUAL_PROMPT% 10 | ) 11 | 12 | if defined _OLD_VIRTUAL_PYTHONHOME ( 13 | set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% 14 | ) 15 | 16 | set _OLD_VIRTUAL_PROMPT=%PROMPT% 17 | set PROMPT=__VENV_NAME__%PROMPT% 18 | 19 | if defined PYTHONHOME ( 20 | set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% 21 | set PYTHONHOME= 22 | ) 23 | 24 | if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%; goto SKIPPATH 25 | 26 | set _OLD_VIRTUAL_PATH=%PATH% 27 | 28 | :SKIPPATH 29 | set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH% 30 | 31 | :END 32 | -------------------------------------------------------------------------------- /Resources/venv/scripts/nt/deactivate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if defined _OLD_VIRTUAL_PROMPT ( 4 | set PROMPT=%_OLD_VIRTUAL_PROMPT% 5 | ) 6 | set _OLD_VIRTUAL_PROMPT= 7 | 8 | if defined _OLD_VIRTUAL_PYTHONHOME ( 9 | set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% 10 | set _OLD_VIRTUAL_PYTHONHOME= 11 | ) 12 | 13 | if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% 14 | 15 | set _OLD_VIRTUAL_PATH= 16 | 17 | :END 18 | -------------------------------------------------------------------------------- /Resources/venv/scripts/nt/pydoc.py: -------------------------------------------------------------------------------- 1 | #!__VENV_PYTHON__ 2 | if __name__ == '__main__': 3 | import sys, pydoc 4 | sys.exit(pydoc.cli()) 5 | -------------------------------------------------------------------------------- /Resources/venv/scripts/posix/activate: -------------------------------------------------------------------------------- 1 | # This file must be used with "source bin/activate" *from bash* 2 | # you cannot run it directly 3 | 4 | deactivate () { 5 | # reset old environment variables 6 | if [ -n "$_OLD_VIRTUAL_PATH" ] ; then 7 | PATH="$_OLD_VIRTUAL_PATH" 8 | export PATH 9 | unset _OLD_VIRTUAL_PATH 10 | fi 11 | if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then 12 | PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" 13 | export PYTHONHOME 14 | unset _OLD_VIRTUAL_PYTHONHOME 15 | fi 16 | 17 | # This should detect bash and zsh, which have a hash command that must 18 | # be called to get it to forget past commands. Without forgetting 19 | # past commands the $PATH changes we made may not be respected 20 | if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then 21 | hash -r 22 | fi 23 | 24 | if [ -n "$_OLD_VIRTUAL_PS1" ] ; then 25 | PS1="$_OLD_VIRTUAL_PS1" 26 | export PS1 27 | unset _OLD_VIRTUAL_PS1 28 | fi 29 | 30 | unset VIRTUAL_ENV 31 | if [ ! "$1" = "nondestructive" ] ; then 32 | # Self destruct! 33 | unset -f deactivate 34 | fi 35 | } 36 | 37 | # unset irrelavent variables 38 | deactivate nondestructive 39 | 40 | VIRTUAL_ENV="__VENV_DIR__" 41 | export VIRTUAL_ENV 42 | 43 | _OLD_VIRTUAL_PATH="$PATH" 44 | PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH" 45 | export PATH 46 | 47 | # unset PYTHONHOME if set 48 | # this will fail if PYTHONHOME is set to the empty string (which is bad anyway) 49 | # could use `if (set -u; : $PYTHONHOME) ;` in bash 50 | if [ -n "$PYTHONHOME" ] ; then 51 | _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" 52 | unset PYTHONHOME 53 | fi 54 | 55 | if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then 56 | _OLD_VIRTUAL_PS1="$PS1" 57 | if [ "x__VENV_NAME__" != x ] ; then 58 | PS1="__VENV_NAME__$PS1" 59 | else 60 | if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then 61 | # special case for Aspen magic directories 62 | # see http://www.zetadev.com/software/aspen/ 63 | PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" 64 | else 65 | PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" 66 | fi 67 | fi 68 | export PS1 69 | fi 70 | 71 | # This should detect bash and zsh, which have a hash command that must 72 | # be called to get it to forget past commands. Without forgetting 73 | # past commands the $PATH changes we made may not be respected 74 | if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then 75 | hash -r 76 | fi 77 | -------------------------------------------------------------------------------- /Resources/venv/scripts/posix/pydoc: -------------------------------------------------------------------------------- 1 | #!__VENV_PYTHON__ 2 | if __name__ == '__main__': 3 | import sys, pydoc 4 | sys.exit(pydoc.cli()) 5 | 6 | -------------------------------------------------------------------------------- /Xtra/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/__init__.py -------------------------------------------------------------------------------- /cx_Freeze/__init__.py: -------------------------------------------------------------------------------- 1 | version = "4.3.4" 2 | 3 | import sys 4 | from cx_Freeze.dist import * 5 | if sys.platform == "win32" and sys.version_info[:2] >= (2, 5): 6 | from cx_Freeze.windist import * 7 | elif sys.platform == "darwin": 8 | from cx_Freeze.macdist import * 9 | from cx_Freeze.finder import * 10 | from cx_Freeze.freezer import * 11 | from cx_Freeze.main import * 12 | 13 | del dist 14 | del finder 15 | del freezer 16 | 17 | -------------------------------------------------------------------------------- /cx_Freeze/common.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains utility functions shared between cx_Freeze modules. 3 | """ 4 | 5 | 6 | def normalize_to_list(value): 7 | """ 8 | Takes the different formats of options containing multiple values and 9 | returns the value as a list object. 10 | """ 11 | if value is None: 12 | normalizedValue = [] 13 | elif isinstance(value, str): 14 | normalizedValue = value.split(',') 15 | else: 16 | normalizedValue = list(value) 17 | 18 | return normalizedValue 19 | -------------------------------------------------------------------------------- /cx_Freeze/setupwriter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import subprocess 4 | 5 | if sys.version_info[0] < 3: 6 | input = raw_input 7 | 8 | class SetupWriter(object): 9 | bases = { 10 | "C" : "Console", 11 | "G" : "Win32GUI", 12 | "S" : "Win32Service" 13 | } 14 | 15 | @property 16 | def base(self): 17 | return self.bases[self.baseCode] 18 | 19 | @property 20 | def defaultExecutableName(self): 21 | name, ext = os.path.splitext(self.script) 22 | return name 23 | 24 | def __init__(self): 25 | self.name = self.description = self.script = "" 26 | self.executableName = self.defaultExecutableName 27 | self.setupFileName = "setup.py" 28 | self.version = "1.0" 29 | self.baseCode = "C" 30 | 31 | def GetBooleanValue(self, label, default = False): 32 | defaultResponse = default and "y" or "n" 33 | while True: 34 | response = self.GetValue(label, defaultResponse, 35 | separator = "? ").lower() 36 | if response in ("y", "n", "yes", "no"): 37 | break 38 | return response in ("y", "yes") 39 | 40 | def GetValue(self, label, default = "", separator = ": "): 41 | if default: 42 | label += " [%s]" % default 43 | return input(label + separator).strip() or default 44 | 45 | def PopulateFromCommandLine(self): 46 | self.name = self.GetValue("Project name", self.name) 47 | self.version = self.GetValue("Version", self.version) 48 | self.description = self.GetValue("Description", self.description) 49 | self.script = self.GetValue("Python file to make executable from", 50 | self.script) 51 | self.executableName = self.GetValue("Executable file name", 52 | self.defaultExecutableName) 53 | basesPrompt = "(C)onsole application, (G)UI application, or (S)ervice" 54 | while True: 55 | self.baseCode = self.GetValue(basesPrompt, "C") 56 | if self.baseCode in self.bases: 57 | break 58 | while True: 59 | self.setupFileName = self.GetValue("Save setup script to", 60 | self.setupFileName) 61 | if not os.path.exists(self.setupFileName): 62 | break 63 | if self.GetBooleanValue("Overwrite %s" % self.setupFileName): 64 | break 65 | 66 | def Write(self): 67 | output = open(self.setupFileName, "w") 68 | w = lambda s: output.write(s + "\n") 69 | 70 | w("from cx_Freeze import setup, Executable") 71 | w("") 72 | 73 | w("# Dependencies are automatically detected, but it might need") 74 | w("# fine tuning.") 75 | w("buildOptions = dict(packages = [], excludes = [])") 76 | w("") 77 | 78 | if self.base.startswith('Win32'): 79 | w("import sys") 80 | w("base = %r if sys.platform=='win32' else None" % self.base) 81 | else: 82 | w("base = %r" % self.base) 83 | w("") 84 | 85 | w("executables = [") 86 | if self.executableName != self.defaultExecutableName: 87 | w(" Executable(%r, base=base, targetName = %r)" % \ 88 | (self.script, self.executableName)) 89 | else: 90 | w(" Executable(%r, base=base)" % self.script) 91 | w("]") 92 | w("") 93 | 94 | w(("setup(name=%r,\n" 95 | " version = %r,\n" 96 | " description = %r,\n" 97 | " options = dict(build_exe = buildOptions),\n" 98 | " executables = executables)") % \ 99 | (self.name, self.version, self.description)) 100 | 101 | def main(): 102 | writer = SetupWriter() 103 | writer.PopulateFromCommandLine() 104 | writer.Write() 105 | print("") 106 | print("Setup script written to %s; run it as:" % writer.setupFileName) 107 | print(" python %s build" % writer.setupFileName) 108 | if writer.GetBooleanValue("Run this now"): 109 | subprocess.call(["python", writer.setupFileName, "build"]) 110 | 111 | -------------------------------------------------------------------------------- /docs/screens/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/docs/screens/1.png -------------------------------------------------------------------------------- /docs/screens/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/docs/screens/2.png -------------------------------------------------------------------------------- /docs/screens/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/docs/screens/3.png -------------------------------------------------------------------------------- /pyflakes/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.9.2' 2 | -------------------------------------------------------------------------------- /pyflakes/__main__.py: -------------------------------------------------------------------------------- 1 | from pyflakes.api import main 2 | 3 | # python -m pyflakes (with Python >= 2.7) 4 | if __name__ == '__main__': 5 | main(prog='pyflakes') 6 | -------------------------------------------------------------------------------- /pyflakes/messages.py: -------------------------------------------------------------------------------- 1 | """ 2 | Provide the class Message and its subclasses. 3 | """ 4 | 5 | 6 | class Message(object): 7 | message = '' 8 | message_args = () 9 | 10 | def __init__(self, filename, loc): 11 | self.filename = filename 12 | self.lineno = loc.lineno 13 | self.col = getattr(loc, 'col_offset', 0) 14 | 15 | def __str__(self): 16 | return '%s:%s: %s' % (self.filename, self.lineno, 17 | self.message % self.message_args) 18 | 19 | 20 | class UnusedImport(Message): 21 | message = '%r imported but unused' 22 | 23 | def __init__(self, filename, loc, name): 24 | Message.__init__(self, filename, loc) 25 | self.message_args = (name,) 26 | 27 | 28 | class RedefinedWhileUnused(Message): 29 | message = 'redefinition of unused %r from line %r' 30 | 31 | def __init__(self, filename, loc, name, orig_loc): 32 | Message.__init__(self, filename, loc) 33 | self.message_args = (name, orig_loc.lineno) 34 | 35 | 36 | class RedefinedInListComp(Message): 37 | message = 'list comprehension redefines %r from line %r' 38 | 39 | def __init__(self, filename, loc, name, orig_loc): 40 | Message.__init__(self, filename, loc) 41 | self.message_args = (name, orig_loc.lineno) 42 | 43 | 44 | class ImportShadowedByLoopVar(Message): 45 | message = 'import %r from line %r shadowed by loop variable' 46 | 47 | def __init__(self, filename, loc, name, orig_loc): 48 | Message.__init__(self, filename, loc) 49 | self.message_args = (name, orig_loc.lineno) 50 | 51 | 52 | class ImportStarUsed(Message): 53 | message = "'from %s import *' used; unable to detect undefined names" 54 | 55 | def __init__(self, filename, loc, modname): 56 | Message.__init__(self, filename, loc) 57 | self.message_args = (modname,) 58 | 59 | 60 | class UndefinedName(Message): 61 | message = 'undefined name %r' 62 | 63 | def __init__(self, filename, loc, name): 64 | Message.__init__(self, filename, loc) 65 | self.message_args = (name,) 66 | 67 | 68 | class DoctestSyntaxError(Message): 69 | message = 'syntax error in doctest' 70 | 71 | def __init__(self, filename, loc, position=None): 72 | Message.__init__(self, filename, loc) 73 | if position: 74 | (self.lineno, self.col) = position 75 | self.message_args = () 76 | 77 | 78 | class UndefinedExport(Message): 79 | message = 'undefined name %r in __all__' 80 | 81 | def __init__(self, filename, loc, name): 82 | Message.__init__(self, filename, loc) 83 | self.message_args = (name,) 84 | 85 | 86 | class UndefinedLocal(Message): 87 | message = ('local variable %r (defined in enclosing scope on line %r) ' 88 | 'referenced before assignment') 89 | 90 | def __init__(self, filename, loc, name, orig_loc): 91 | Message.__init__(self, filename, loc) 92 | self.message_args = (name, orig_loc.lineno) 93 | 94 | 95 | class DuplicateArgument(Message): 96 | message = 'duplicate argument %r in function definition' 97 | 98 | def __init__(self, filename, loc, name): 99 | Message.__init__(self, filename, loc) 100 | self.message_args = (name,) 101 | 102 | 103 | class LateFutureImport(Message): 104 | message = 'future import(s) %r after other statements' 105 | 106 | def __init__(self, filename, loc, names): 107 | Message.__init__(self, filename, loc) 108 | self.message_args = (names,) 109 | 110 | 111 | class UnusedVariable(Message): 112 | """ 113 | Indicates that a variable has been explicity assigned to but not actually 114 | used. 115 | """ 116 | message = 'local variable %r is assigned to but never used' 117 | 118 | def __init__(self, filename, loc, names): 119 | Message.__init__(self, filename, loc) 120 | self.message_args = (names,) 121 | 122 | 123 | class ReturnWithArgsInsideGenerator(Message): 124 | """ 125 | Indicates a return statement with arguments inside a generator. 126 | """ 127 | message = '\'return\' with argument inside generator' 128 | 129 | 130 | class ReturnOutsideFunction(Message): 131 | """ 132 | Indicates a return statement outside of a function/method. 133 | """ 134 | message = '\'return\' outside function' 135 | -------------------------------------------------------------------------------- /pyflakes/reporter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Provide the Reporter class. 3 | """ 4 | 5 | import re 6 | import sys 7 | 8 | 9 | class Reporter(object): 10 | """ 11 | Formats the results of pyflakes checks to users. 12 | """ 13 | 14 | def __init__(self, warningStream, errorStream): 15 | """ 16 | Construct a L{Reporter}. 17 | 18 | @param warningStream: A file-like object where warnings will be 19 | written to. The stream's C{write} method must accept unicode. 20 | C{sys.stdout} is a good value. 21 | @param errorStream: A file-like object where error output will be 22 | written to. The stream's C{write} method must accept unicode. 23 | C{sys.stderr} is a good value. 24 | """ 25 | self._stdout = warningStream 26 | self._stderr = errorStream 27 | 28 | def unexpectedError(self, filename, msg): 29 | """ 30 | An unexpected error occurred trying to process C{filename}. 31 | 32 | @param filename: The path to a file that we could not process. 33 | @ptype filename: C{unicode} 34 | @param msg: A message explaining the problem. 35 | @ptype msg: C{unicode} 36 | """ 37 | self._stderr.write("%s: %s\n" % (filename, msg)) 38 | 39 | def syntaxError(self, filename, msg, lineno, offset, text): 40 | """ 41 | There was a syntax errror in C{filename}. 42 | 43 | @param filename: The path to the file with the syntax error. 44 | @ptype filename: C{unicode} 45 | @param msg: An explanation of the syntax error. 46 | @ptype msg: C{unicode} 47 | @param lineno: The line number where the syntax error occurred. 48 | @ptype lineno: C{int} 49 | @param offset: The column on which the syntax error occurred, or None. 50 | @ptype offset: C{int} 51 | @param text: The source code containing the syntax error. 52 | @ptype text: C{unicode} 53 | """ 54 | line = text.splitlines()[-1] 55 | if offset is not None: 56 | offset = offset - (len(text) - len(line)) 57 | self._stderr.write('%s:%d:%d: %s\n' % 58 | (filename, lineno, offset + 1, msg)) 59 | else: 60 | self._stderr.write('%s:%d: %s\n' % (filename, lineno, msg)) 61 | self._stderr.write(line) 62 | self._stderr.write('\n') 63 | if offset is not None: 64 | self._stderr.write(re.sub(r'\S', ' ', line[:offset]) + 65 | "^\n") 66 | 67 | def flake(self, message): 68 | """ 69 | pyflakes found something wrong with the code. 70 | 71 | @param: A L{pyflakes.messages.Message}. 72 | """ 73 | self._stdout.write(str(message)) 74 | self._stdout.write('\n') 75 | 76 | 77 | def _makeDefaultReporter(): 78 | """ 79 | Make a reporter that can be used when no reporter is specified. 80 | """ 81 | return Reporter(sys.stdout, sys.stderr) 82 | -------------------------------------------------------------------------------- /pyflakes/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/pyflakes/scripts/__init__.py -------------------------------------------------------------------------------- /pyflakes/scripts/pyflakes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Implementation of the command-line I{pyflakes} tool. 3 | """ 4 | from __future__ import absolute_import 5 | 6 | # For backward compatibility 7 | __all__ = ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main'] 8 | from pyflakes.api import check, checkPath, checkRecursive, iterSourceCode, main 9 | -------------------------------------------------------------------------------- /pyflakes/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortharris/Pcode/147962d160a834c219e12cb456abc130826468e4/pyflakes/test/__init__.py -------------------------------------------------------------------------------- /pyflakes/test/harness.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import textwrap 4 | import unittest 5 | 6 | from pyflakes import checker 7 | 8 | __all__ = ['TestCase', 'skip', 'skipIf'] 9 | 10 | if sys.version_info < (2, 7): 11 | skip = lambda why: (lambda func: 'skip') # not callable 12 | skipIf = lambda cond, why: (skip(why) if cond else lambda func: func) 13 | else: 14 | skip = unittest.skip 15 | skipIf = unittest.skipIf 16 | PyCF_ONLY_AST = 1024 17 | 18 | 19 | class TestCase(unittest.TestCase): 20 | 21 | withDoctest = False 22 | 23 | def flakes(self, input, *expectedOutputs, **kw): 24 | tree = compile(textwrap.dedent(input), "", "exec", PyCF_ONLY_AST) 25 | w = checker.Checker(tree, withDoctest=self.withDoctest, **kw) 26 | outputs = [type(o) for o in w.messages] 27 | expectedOutputs = list(expectedOutputs) 28 | outputs.sort(key=lambda t: t.__name__) 29 | expectedOutputs.sort(key=lambda t: t.__name__) 30 | self.assertEqual(outputs, expectedOutputs, '''\ 31 | for input: 32 | %s 33 | expected outputs: 34 | %r 35 | but got: 36 | %s''' % (input, expectedOutputs, '\n'.join([str(o) for o in w.messages]))) 37 | return w 38 | 39 | if sys.version_info < (2, 7): 40 | 41 | def assertIs(self, expr1, expr2, msg=None): 42 | if expr1 is not expr2: 43 | self.fail(msg or '%r is not %r' % (expr1, expr2)) 44 | -------------------------------------------------------------------------------- /pyflakes/test/test_return_with_arguments_inside_generator.py: -------------------------------------------------------------------------------- 1 | 2 | from sys import version_info 3 | 4 | from pyflakes import messages as m 5 | from pyflakes.test.harness import TestCase, skipIf 6 | 7 | 8 | class Test(TestCase): 9 | @skipIf(version_info >= (3, 3), 'new in Python 3.3') 10 | def test_return(self): 11 | self.flakes(''' 12 | class a: 13 | def b(): 14 | for x in a.c: 15 | if x: 16 | yield x 17 | return a 18 | ''', m.ReturnWithArgsInsideGenerator) 19 | 20 | @skipIf(version_info >= (3, 3), 'new in Python 3.3') 21 | def test_returnNone(self): 22 | self.flakes(''' 23 | def a(): 24 | yield 12 25 | return None 26 | ''', m.ReturnWithArgsInsideGenerator) 27 | 28 | @skipIf(version_info >= (3, 3), 'new in Python 3.3') 29 | def test_returnYieldExpression(self): 30 | self.flakes(''' 31 | def a(): 32 | b = yield a 33 | return b 34 | ''', m.ReturnWithArgsInsideGenerator) 35 | -------------------------------------------------------------------------------- /rope/__init__.py: -------------------------------------------------------------------------------- 1 | """rope, a python refactoring library""" 2 | 3 | INFO = __doc__ 4 | VERSION = '0.9.4-1' 5 | COPYRIGHT = """\ 6 | Copyright (C) 2006-2010 Ali Gholami Rudi 7 | Copyright (C) 2009-2010 Anton Gritsay 8 | Copyright (C) 2011 Dmitriy Zhukov 9 | 10 | This program is free software; you can redistribute it and/or modify it 11 | under the terms of GNU General Public License as published by the 12 | Free Software Foundation; either version 2 of the license, or (at your 13 | opinion) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details.""" 19 | -------------------------------------------------------------------------------- /rope/base/__init__.py: -------------------------------------------------------------------------------- 1 | """Base rope package 2 | 3 | This package contains rope core modules that are used by other modules 4 | and packages. 5 | 6 | """ 7 | 8 | __all__ = ['project', 'libutils', 'exceptions'] 9 | -------------------------------------------------------------------------------- /rope/base/arguments.py: -------------------------------------------------------------------------------- 1 | import rope.base.evaluate 2 | from rope.base import ast 3 | 4 | 5 | class Arguments(object): 6 | """A class for evaluating parameters passed to a function 7 | 8 | You can use the `create_arguments` factory. It handles implicit 9 | first arguments. 10 | 11 | """ 12 | 13 | def __init__(self, args, scope): 14 | self.args = args 15 | self.scope = scope 16 | self.instance = None 17 | 18 | def get_arguments(self, parameters): 19 | result = [] 20 | for pyname in self.get_pynames(parameters): 21 | if pyname is None: 22 | result.append(None) 23 | else: 24 | result.append(pyname.get_object()) 25 | return result 26 | 27 | def get_pynames(self, parameters): 28 | result = [None] * max(len(parameters), len(self.args)) 29 | for index, arg in enumerate(self.args): 30 | if isinstance(arg, ast.keyword) and arg.arg in parameters: 31 | result[parameters.index(arg.arg)] = self._evaluate(arg.value) 32 | else: 33 | result[index] = self._evaluate(arg) 34 | return result 35 | 36 | def get_instance_pyname(self): 37 | if self.args: 38 | return self._evaluate(self.args[0]) 39 | 40 | def _evaluate(self, ast_node): 41 | return rope.base.evaluate.eval_node(self.scope, ast_node) 42 | 43 | 44 | def create_arguments(primary, pyfunction, call_node, scope): 45 | """A factory for creating `Arguments`""" 46 | args = list(call_node.args) 47 | args.extend(call_node.keywords) 48 | called = call_node.func 49 | # XXX: Handle constructors 50 | if _is_method_call(primary, pyfunction) and \ 51 | isinstance(called, ast.Attribute): 52 | args.insert(0, called.value) 53 | return Arguments(args, scope) 54 | 55 | 56 | class ObjectArguments(object): 57 | 58 | def __init__(self, pynames): 59 | self.pynames = pynames 60 | 61 | def get_arguments(self, parameters): 62 | result = [] 63 | for pyname in self.pynames: 64 | if pyname is None: 65 | result.append(None) 66 | else: 67 | result.append(pyname.get_object()) 68 | return result 69 | 70 | def get_pynames(self, parameters): 71 | return self.pynames 72 | 73 | def get_instance_pyname(self): 74 | return self.pynames[0] 75 | class MixedArguments(object): 76 | 77 | def __init__(self, pyname, arguments, scope): 78 | """`argumens` is an instance of `Arguments`""" 79 | self.pyname = pyname 80 | self.args = arguments 81 | 82 | def get_pynames(self, parameters): 83 | return [self.pyname] + self.args.get_pynames(parameters[1:]) 84 | 85 | def get_arguments(self, parameters): 86 | result = [] 87 | for pyname in self.get_pynames(parameters): 88 | if pyname is None: 89 | result.append(None) 90 | else: 91 | result.append(pyname.get_object()) 92 | return result 93 | 94 | def get_instance_pyname(self): 95 | return self.pyname 96 | 97 | 98 | def _is_method_call(primary, pyfunction): 99 | if primary is None: 100 | return False 101 | pyobject = primary.get_object() 102 | if isinstance(pyobject.get_type(), rope.base.pyobjects.PyClass) and \ 103 | isinstance(pyfunction, rope.base.pyobjects.PyFunction) and \ 104 | isinstance(pyfunction.parent, rope.base.pyobjects.PyClass): 105 | return True 106 | if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass) and \ 107 | isinstance(pyfunction, rope.base.builtins.BuiltinFunction): 108 | return True 109 | return False 110 | -------------------------------------------------------------------------------- /rope/base/ast.py: -------------------------------------------------------------------------------- 1 | import _ast 2 | from _ast import * 3 | 4 | from rope.base import fscommands 5 | 6 | 7 | def parse(source, filename=''): 8 | # NOTE: the raw string should be given to `compile` function 9 | if isinstance(source, str): 10 | source = fscommands.unicode_to_file_data(source) 11 | source = source.decode() 12 | if '\r' in source: 13 | source = source.replace('\r\n', '\n').replace('\r', '\n') 14 | if not source.endswith('\n'): 15 | source += '\n' 16 | try: 17 | return compile(source.encode(), filename, 'exec', _ast.PyCF_ONLY_AST) 18 | except (TypeError, ValueError) as e: 19 | error = SyntaxError() 20 | error.lineno = 1 21 | error.filename = filename 22 | error.msg = str(e) 23 | raise error 24 | 25 | 26 | def walk(node, walker): 27 | """Walk the syntax tree""" 28 | method_name = '_' + node.__class__.__name__ 29 | method = getattr(walker, method_name, None) 30 | if method is not None: 31 | return method(node) 32 | for child in get_child_nodes(node): 33 | walk(child, walker) 34 | 35 | 36 | def get_child_nodes(node): 37 | if isinstance(node, _ast.Module): 38 | return node.body 39 | result = [] 40 | if node._fields is not None: 41 | for name in node._fields: 42 | child = getattr(node, name) 43 | if isinstance(child, list): 44 | for entry in child: 45 | if isinstance(entry, _ast.AST): 46 | result.append(entry) 47 | if isinstance(child, _ast.AST): 48 | result.append(child) 49 | return result 50 | 51 | 52 | def call_for_nodes(node, callback, recursive=False): 53 | """If callback returns `True` the child nodes are skipped""" 54 | result = callback(node) 55 | if recursive and not result: 56 | for child in get_child_nodes(node): 57 | call_for_nodes(child, callback, recursive) 58 | 59 | 60 | def get_children(node): 61 | result = [] 62 | if node._fields is not None: 63 | for name in node._fields: 64 | if name in ['lineno', 'col_offset']: 65 | continue 66 | child = getattr(node, name) 67 | result.append(child) 68 | return result 69 | -------------------------------------------------------------------------------- /rope/base/astutils.py: -------------------------------------------------------------------------------- 1 | from rope.base import ast 2 | 3 | 4 | def get_name_levels(node): 5 | """Return a list of ``(name, level)`` tuples for assigned names 6 | 7 | The `level` is `None` for simple assignments and is a list of 8 | numbers for tuple assignments for example in:: 9 | 10 | a, (b, c) = x 11 | 12 | The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for 13 | `c` is ``[1, 1]``. 14 | 15 | """ 16 | visitor = _NodeNameCollector() 17 | ast.walk(node, visitor) 18 | return visitor.names 19 | 20 | 21 | class _NodeNameCollector(object): 22 | 23 | def __init__(self, levels=None): 24 | self.names = [] 25 | self.levels = levels 26 | self.index = 0 27 | 28 | def _add_node(self, node): 29 | new_levels = [] 30 | if self.levels is not None: 31 | new_levels = list(self.levels) 32 | new_levels.append(self.index) 33 | self.index += 1 34 | self._added(node, new_levels) 35 | 36 | def _added(self, node, levels): 37 | if hasattr(node, 'id'): 38 | self.names.append((node.id, levels)) 39 | 40 | def _Name(self, node): 41 | self._add_node(node) 42 | 43 | def _Tuple(self, node): 44 | new_levels = [] 45 | if self.levels is not None: 46 | new_levels = list(self.levels) 47 | new_levels.append(self.index) 48 | self.index += 1 49 | visitor = _NodeNameCollector(new_levels) 50 | for child in ast.get_child_nodes(node): 51 | ast.walk(child, visitor) 52 | self.names.extend(visitor.names) 53 | 54 | def _Subscript(self, node): 55 | self._add_node(node) 56 | 57 | def _Attribute(self, node): 58 | self._add_node(node) 59 | 60 | def _Slice(self, node): 61 | self._add_node(node) 62 | -------------------------------------------------------------------------------- /rope/base/default_config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | 3 | 4 | def set_prefs(prefs): 5 | """This function is called before opening the project""" 6 | 7 | # Specify which files and folders to ignore in the project. 8 | # Changes to ignored resources are not added to the history and 9 | # VCSs. Also they are not returned in `Project.get_files()`. 10 | # Note that ``?`` and ``*`` match all characters but slashes. 11 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 12 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 13 | # '.svn': matches 'pkg/.svn' and all of its children 14 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 15 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 16 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', 17 | '.hg', '.svn', '_svn', '.git', 18 | '__pycache__'] 19 | 20 | # Specifies which files should be considered python files. It is 21 | # useful when you have scripts inside your project. Only files 22 | # ending with ``.py`` are considered to be python files by 23 | # default. 24 | #prefs['python_files'] = ['*.py'] 25 | 26 | # Custom source folders: By default rope searches the project 27 | # for finding source folders (folders that should be searched 28 | # for finding modules). You can add paths to that list. Note 29 | # that rope guesses project source folders correctly most of the 30 | # time; use this if you have any problems. 31 | # The folders should be relative to project root and use '/' for 32 | # separating folders regardless of the platform rope is running on. 33 | # 'src/my_source_folder' for instance. 34 | #prefs.add('source_folders', 'src') 35 | 36 | # You can extend python path for looking up modules 37 | #prefs.add('python_path', '~/python/') 38 | 39 | # Should rope save object information or not. 40 | prefs['save_objectdb'] = True 41 | prefs['compress_objectdb'] = False 42 | 43 | # If `True`, rope analyzes each module when it is being saved. 44 | prefs['automatic_soa'] = True 45 | # The depth of calls to follow in static object analysis 46 | prefs['soa_followed_calls'] = 0 47 | 48 | # If `False` when running modules or unit tests "dynamic object 49 | # analysis" is turned off. This makes them much faster. 50 | prefs['perform_doa'] = True 51 | 52 | # Rope can check the validity of its object DB when running. 53 | prefs['validate_objectdb'] = True 54 | 55 | # How many undos to hold? 56 | prefs['max_history_items'] = 32 57 | 58 | # Shows whether to save history across sessions. 59 | prefs['save_history'] = True 60 | prefs['compress_history'] = False 61 | 62 | # Set the number spaces used for indenting. According to 63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 64 | # unit-tests use 4 spaces it is more reliable, too. 65 | prefs['indent_size'] = 4 66 | 67 | # Builtin and c-extension modules that are allowed to be imported 68 | # and inspected by rope. 69 | prefs['extension_modules'] = [] 70 | 71 | # Add all standard c-extensions to extension_modules list. 72 | prefs['import_dynload_stdmods'] = True 73 | 74 | # If `True` modules with syntax errors are considered to be empty. 75 | # The default value is `False`; When `False` syntax errors raise 76 | # `rope.base.exceptions.ModuleSyntaxError` exception. 77 | prefs['ignore_syntax_errors'] = False 78 | 79 | # If `True`, rope ignores unresolvable imports. Otherwise, they 80 | # appear in the importing namespace. 81 | prefs['ignore_bad_imports'] = False 82 | 83 | 84 | def project_opened(project): 85 | """This function is called after opening the project""" 86 | # Do whatever you like here! 87 | -------------------------------------------------------------------------------- /rope/base/exceptions.py: -------------------------------------------------------------------------------- 1 | class RopeError(Exception): 2 | """Base exception for rope""" 3 | 4 | 5 | class ResourceNotFoundError(RopeError): 6 | """Resource not found exception""" 7 | 8 | 9 | class RefactoringError(RopeError): 10 | """Errors for performing a refactoring""" 11 | 12 | 13 | class InterruptedTaskError(RopeError): 14 | """The task has been interrupted""" 15 | 16 | 17 | class HistoryError(RopeError): 18 | """Errors for history undo/redo operations""" 19 | 20 | 21 | class ModuleNotFoundError(RopeError): 22 | """Module not found exception""" 23 | 24 | 25 | class AttributeNotFoundError(RopeError): 26 | """Attribute not found exception""" 27 | 28 | 29 | class NameNotFoundError(RopeError): 30 | """Name not found exception""" 31 | 32 | 33 | class BadIdentifierError(RopeError): 34 | """The name cannot be resolved""" 35 | 36 | 37 | class ModuleSyntaxError(RopeError): 38 | """Module has syntax errors 39 | 40 | The `filename` and `lineno` fields indicate where the error has 41 | occurred. 42 | 43 | """ 44 | 45 | def __init__(self, filename, lineno, message): 46 | self.filename = filename 47 | self.lineno = lineno 48 | self.message_ = message 49 | super(ModuleSyntaxError, self).__init__( 50 | 'Syntax error in file <%s> line <%s>: %s' % 51 | (filename, lineno, message)) 52 | 53 | 54 | class ModuleDecodeError(RopeError): 55 | """Cannot decode module""" 56 | 57 | def __init__(self, filename, message): 58 | self.filename = filename 59 | self.message_ = message 60 | super(ModuleDecodeError, self).__init__( 61 | 'Cannot decode file <%s>: %s' % (filename, message)) 62 | -------------------------------------------------------------------------------- /rope/base/libutils.py: -------------------------------------------------------------------------------- 1 | """A few useful functions for using rope as a library""" 2 | import os.path 3 | 4 | import rope.base.project 5 | import rope.base.pycore 6 | from rope.base import taskhandle 7 | 8 | 9 | def path_to_resource(project, path, type=None): 10 | """Get the resource at path 11 | 12 | You only need to specify `type` if `path` does not exist. It can 13 | be either 'file' or 'folder'. If the type is `None` it is assumed 14 | that the resource already exists. 15 | 16 | Note that this function uses `Project.get_resource()`, 17 | `Project.get_file()`, and `Project.get_folder()` methods. 18 | 19 | """ 20 | project_path = relative(project.address, path) 21 | if project_path is None: 22 | project_path = rope.base.project._realpath(path) 23 | project = rope.base.project.get_no_project() 24 | if type is None: 25 | return project.get_resource(project_path) 26 | if type == 'file': 27 | return project.get_file(project_path) 28 | if type == 'folder': 29 | return project.get_folder(project_path) 30 | return None 31 | 32 | def relative(root, path): 33 | root = rope.base.project._realpath(root).replace(os.path.sep, '/') 34 | path = rope.base.project._realpath(path).replace(os.path.sep, '/') 35 | if path == root: 36 | return '' 37 | if path.startswith(root + '/'): 38 | return path[len(root) + 1:] 39 | 40 | def report_change(project, path, old_content): 41 | """Report that the contents of file at `path` was changed 42 | 43 | The new contents of file is retrieved by reading the file. 44 | 45 | """ 46 | resource = path_to_resource(project, path) 47 | if resource is None: 48 | return 49 | for observer in list(project.observers): 50 | observer.resource_changed(resource) 51 | if project.pycore.automatic_soa: 52 | rope.base.pycore.perform_soa_on_changed_scopes(project, resource, 53 | old_content) 54 | 55 | def analyze_modules(project, task_handle=taskhandle.NullTaskHandle()): 56 | """Perform static object analysis on all python files in the project 57 | 58 | Note that this might be really time consuming. 59 | """ 60 | resources = project.pycore.get_python_files() 61 | job_set = task_handle.create_jobset('Analyzing Modules', len(resources)) 62 | for resource in resources: 63 | job_set.started_job(resource.path) 64 | project.pycore.analyze_module(resource) 65 | job_set.finished_job() 66 | -------------------------------------------------------------------------------- /rope/base/oi/__init__.py: -------------------------------------------------------------------------------- 1 | """Rope object analysis and inference package 2 | 3 | Rope makes some simplifying assumptions about a python program. It 4 | assumes that a program only performs assignments and function calls. 5 | Tracking assignments is simple and `PyName` objects handle that. The 6 | main problem is function calls. Rope uses these two approaches for 7 | obtaining call information: 8 | 9 | * Static object analysis: `rope.base.pycore.PyCore.analyze_module()` 10 | 11 | It can analyze modules to obtain information about functions. This 12 | is done by analyzing function calls in a module or scope. Currently 13 | SOA analyzes the scopes that are changed while saving or when the 14 | user asks to analyze a module. That is mainly because static 15 | analysis is time-consuming. 16 | 17 | * Dynamic object analysis: `rope.base.pycore.PyCore.run_module()` 18 | 19 | When you run a module or your testsuite, when DOA is enabled, it 20 | collects information about parameters passed to and objects returned 21 | from functions. The main problem with this approach is that it is 22 | quite slow; Not when looking up the information but when collecting 23 | them. 24 | 25 | An instance of `rope.base.oi.objectinfo.ObjectInfoManager` can be used 26 | for accessing these information. It saves the data in a 27 | `rope.base.oi.objectdb.ObjectDB` internally. 28 | 29 | Now if our objectdb does not know anything about a function and we 30 | need the value returned by it, static object inference, SOI, comes 31 | into play. It analyzes function body and tries to infer the object 32 | that is returned from it (we usually need the returned value for the 33 | given parameter objects). 34 | 35 | Rope might collect and store information for other `PyName`\s, too. 36 | For instance rope stores the object builtin containers hold. 37 | 38 | """ 39 | -------------------------------------------------------------------------------- /rope/base/oi/memorydb.py: -------------------------------------------------------------------------------- 1 | from rope.base.oi import objectdb 2 | 3 | 4 | class MemoryDB(objectdb.FileDict): 5 | 6 | def __init__(self, project, persist=None): 7 | self.project = project 8 | self._persist = persist 9 | self.files = self 10 | self._load_files() 11 | self.project.data_files.add_write_hook(self.write) 12 | 13 | def _load_files(self): 14 | self._files = {} 15 | if self.persist: 16 | result = self.project.data_files.read_data( 17 | 'objectdb', compress=self.compress, import_=True) 18 | if result is not None: 19 | self._files = result 20 | 21 | def keys(self): 22 | return list(self._files.keys()) 23 | 24 | def __contains__(self, key): 25 | return key in self._files 26 | 27 | def __getitem__(self, key): 28 | return FileInfo(self._files[key]) 29 | 30 | def create(self, path): 31 | self._files[path] = {} 32 | 33 | def rename(self, file, newfile): 34 | if file not in self._files: 35 | return 36 | self._files[newfile] = self._files[file] 37 | del self[file] 38 | 39 | def __delitem__(self, file): 40 | del self._files[file] 41 | 42 | def write(self): 43 | if self.persist: 44 | self.project.data_files.write_data('objectdb', self._files, 45 | self.compress) 46 | 47 | @property 48 | def compress(self): 49 | return self.project.prefs.get('compress_objectdb', False) 50 | 51 | @property 52 | def persist(self): 53 | if self._persist is not None: 54 | return self._persist 55 | else: 56 | return self.project.prefs.get('save_objectdb', False) 57 | 58 | 59 | class FileInfo(objectdb.FileInfo): 60 | 61 | def __init__(self, scopes): 62 | self.scopes = scopes 63 | 64 | def create_scope(self, key): 65 | self.scopes[key] = ScopeInfo() 66 | 67 | def keys(self): 68 | return list(self.scopes.keys()) 69 | 70 | def __contains__(self, key): 71 | return key in self.scopes 72 | 73 | def __getitem__(self, key): 74 | return self.scopes[key] 75 | 76 | def __delitem__(self, key): 77 | del self.scopes[key] 78 | 79 | 80 | class ScopeInfo(objectdb.ScopeInfo): 81 | 82 | def __init__(self): 83 | self.call_info = {} 84 | self.per_name = {} 85 | 86 | def get_per_name(self, name): 87 | return self.per_name.get(name, None) 88 | 89 | def save_per_name(self, name, value): 90 | self.per_name[name] = value 91 | 92 | def get_returned(self, parameters): 93 | return self.call_info.get(parameters, None) 94 | 95 | def get_call_infos(self): 96 | for args, returned in self.call_info.items(): 97 | yield objectdb.CallInfo(args, returned) 98 | 99 | def add_call(self, parameters, returned): 100 | self.call_info[parameters] = returned 101 | 102 | def __getstate__(self): 103 | return (self.call_info, self.per_name) 104 | 105 | def __setstate__(self, data): 106 | self.call_info, self.per_name = data 107 | -------------------------------------------------------------------------------- /rope/base/prefs.py: -------------------------------------------------------------------------------- 1 | class Prefs(object): 2 | 3 | def __init__(self): 4 | self.prefs = {} 5 | self.callbacks = {} 6 | 7 | def set(self, key, value): 8 | """Set the value of `key` preference to `value`.""" 9 | if key in self.callbacks: 10 | self.callbacks[key](value) 11 | else: 12 | self.prefs[key] = value 13 | 14 | def add(self, key, value): 15 | """Add an entry to a list preference 16 | 17 | Add `value` to the list of entries for the `key` preference. 18 | 19 | """ 20 | if not key in self.prefs: 21 | self.prefs[key] = [] 22 | self.prefs[key].append(value) 23 | 24 | def get(self, key, default=None): 25 | """Get the value of the key preference""" 26 | return self.prefs.get(key, default) 27 | 28 | def add_callback(self, key, callback): 29 | """Add `key` preference with `callback` function 30 | 31 | Whenever `key` is set the callback is called with the 32 | given `value` as parameter. 33 | 34 | """ 35 | self.callbacks[key] = callback 36 | 37 | def __setitem__(self, key, value): 38 | self.set(key, value) 39 | 40 | def __getitem__(self, key): 41 | return self.get(key) 42 | -------------------------------------------------------------------------------- /rope/base/pynamesdef.py: -------------------------------------------------------------------------------- 1 | import rope.base.oi.soi 2 | from rope.base import pynames 3 | from rope.base.pynames import * 4 | 5 | 6 | class AssignedName(pynames.AssignedName): 7 | 8 | def __init__(self, lineno=None, module=None, pyobject=None): 9 | self.lineno = lineno 10 | self.module = module 11 | self.assignments = [] 12 | self.pyobject = _Inferred(self._get_inferred, 13 | pynames._get_concluded_data(module)) 14 | self.pyobject.set(pyobject) 15 | 16 | @utils.prevent_recursion(lambda: None) 17 | def _get_inferred(self): 18 | if self.module is not None: 19 | return rope.base.oi.soi.infer_assigned_object(self) 20 | 21 | def get_object(self): 22 | return self.pyobject.get() 23 | 24 | def get_definition_location(self): 25 | """Returns a (module, lineno) tuple""" 26 | if self.lineno is None and self.assignments: 27 | self.lineno = self.assignments[0].get_lineno() 28 | return (self.module, self.lineno) 29 | 30 | def invalidate(self): 31 | """Forget the `PyObject` this `PyName` holds""" 32 | self.pyobject.set(None) 33 | 34 | 35 | class ParameterName(pynames.ParameterName): 36 | 37 | def __init__(self, pyfunction, index): 38 | self.pyfunction = pyfunction 39 | self.index = index 40 | 41 | def get_object(self): 42 | result = self.pyfunction.get_parameter(self.index) 43 | if result is None: 44 | result = rope.base.pyobjects.get_unknown() 45 | return result 46 | 47 | def get_objects(self): 48 | """Returns the list of objects passed as this parameter""" 49 | return rope.base.oi.soi.get_passed_objects( 50 | self.pyfunction, self.index) 51 | 52 | def get_definition_location(self): 53 | return (self.pyfunction.get_module(), self.pyfunction.get_ast().lineno) 54 | 55 | _Inferred = pynames._Inferred 56 | -------------------------------------------------------------------------------- /rope/base/simplify.py: -------------------------------------------------------------------------------- 1 | """A module to ease code analysis 2 | 3 | This module is here to help source code analysis. 4 | """ 5 | import re 6 | 7 | from rope.base import codeanalyze, utils 8 | 9 | 10 | @utils.cached(7) 11 | def real_code(source): 12 | """Simplify `source` for analysis 13 | 14 | It replaces: 15 | 16 | * comments with spaces 17 | * strs with a new str filled with spaces 18 | * implicit and explicit continuations with spaces 19 | * tabs and semicolons with spaces 20 | 21 | The resulting code is a lot easier to analyze if we are interested 22 | only in offsets. 23 | """ 24 | collector = codeanalyze.ChangeCollector(source) 25 | for start, end in ignored_regions(source): 26 | if source[start] == '#': 27 | replacement = ' ' * (end - start) 28 | else: 29 | replacement = '"%s"' % (' ' * (end - start - 2)) 30 | collector.add_change(start, end, replacement) 31 | source = collector.get_changed() or source 32 | collector = codeanalyze.ChangeCollector(source) 33 | parens = 0 34 | for match in _parens.finditer(source): 35 | i = match.start() 36 | c = match.group() 37 | if c in '({[': 38 | parens += 1 39 | if c in ')}]': 40 | parens -= 1 41 | if c == '\n' and parens > 0: 42 | collector.add_change(i, i + 1, ' ') 43 | source = collector.get_changed() or source 44 | return source.replace('\\\n', ' ').replace('\t', ' ').replace(';', '\n') 45 | 46 | 47 | @utils.cached(7) 48 | def ignored_regions(source): 49 | """Return ignored regions like strings and comments in `source` """ 50 | return [(match.start(), match.end()) for match in _str.finditer(source)] 51 | 52 | 53 | _str = re.compile('%s|%s' % (codeanalyze.get_comment_pattern(), 54 | codeanalyze.get_string_pattern())) 55 | _parens = re.compile(r'[\({\[\]}\)\n]') 56 | -------------------------------------------------------------------------------- /rope/base/stdmods.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from rope.base import utils 5 | 6 | 7 | def _stdlib_path(): 8 | import inspect 9 | return os.path.dirname(inspect.getsourcefile(inspect)) 10 | 11 | @utils.cached(1) 12 | def standard_modules(): 13 | return python_modules() | dynload_modules() 14 | 15 | @utils.cached(1) 16 | def python_modules(): 17 | result = set() 18 | lib_path = _stdlib_path() 19 | if os.path.exists(lib_path): 20 | for name in os.listdir(lib_path): 21 | path = os.path.join(lib_path, name) 22 | if os.path.isdir(path): 23 | if '-' not in name: 24 | result.add(name) 25 | else: 26 | if name.endswith('.py'): 27 | result.add(name[:-3]) 28 | return result 29 | 30 | @utils.cached(1) 31 | def dynload_modules(): 32 | result = set(sys.builtin_module_names) 33 | dynload_path = os.path.join(_stdlib_path(), 'lib-dynload') 34 | if os.path.exists(dynload_path): 35 | for name in os.listdir(dynload_path): 36 | path = os.path.join(dynload_path, name) 37 | if os.path.isfile(path): 38 | if name.endswith('.so') or name.endswith('.dll'): 39 | if "cpython" in name: 40 | result.add(os.path.splitext(os.path.splitext(name)[0])[0]) 41 | else: 42 | result.add(os.path.splitext(name)[0]) 43 | return result 44 | -------------------------------------------------------------------------------- /rope/base/taskhandle.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from rope.base import exceptions 4 | 5 | 6 | class TaskHandle(object): 7 | 8 | def __init__(self, name='Task', interrupts=True): 9 | """Construct a TaskHandle 10 | 11 | If `interrupts` is `False` the task won't be interrupted by 12 | calling `TaskHandle.stop()`. 13 | 14 | """ 15 | self.name = name 16 | self.interrupts = interrupts 17 | self.stopped = False 18 | self.job_sets = [] 19 | self.observers = [] 20 | 21 | def stop(self): 22 | """Interrupts the refactoring""" 23 | if self.interrupts: 24 | self.stopped = True 25 | self._inform_observers() 26 | 27 | def current_jobset(self): 28 | """Return the current `JobSet`""" 29 | if self.job_sets: 30 | return self.job_sets[-1] 31 | 32 | def add_observer(self, observer): 33 | """Register an observer for this task handle 34 | 35 | The observer is notified whenever the task is stopped or 36 | a job gets finished. 37 | 38 | """ 39 | self.observers.append(observer) 40 | 41 | def is_stopped(self): 42 | return self.stopped 43 | 44 | def get_jobsets(self): 45 | return self.job_sets 46 | 47 | def create_jobset(self, name='JobSet', count=None): 48 | result = JobSet(self, name=name, count=count) 49 | self.job_sets.append(result) 50 | self._inform_observers() 51 | return result 52 | 53 | def _inform_observers(self): 54 | for observer in list(self.observers): 55 | observer() 56 | 57 | 58 | class JobSet(object): 59 | 60 | def __init__(self, handle, name, count): 61 | self.handle = handle 62 | self.name = name 63 | self.count = count 64 | self.done = 0 65 | self.job_name = None 66 | 67 | def started_job(self, name): 68 | self.check_status() 69 | self.job_name = name 70 | self.handle._inform_observers() 71 | 72 | def finished_job(self): 73 | self.check_status() 74 | self.done += 1 75 | self.handle._inform_observers() 76 | self.job_name = None 77 | 78 | def check_status(self): 79 | if self.handle.is_stopped(): 80 | raise exceptions.InterruptedTaskError() 81 | 82 | def get_active_job_name(self): 83 | return self.job_name 84 | 85 | def get_percent_done(self): 86 | if self.count is not None and self.count > 0: 87 | percent = self.done * 100 // self.count 88 | return min(percent, 100) 89 | 90 | def get_name(self): 91 | return self.name 92 | 93 | 94 | class NullTaskHandle(object): 95 | 96 | def __init__(self): 97 | pass 98 | 99 | def is_stopped(self): 100 | return False 101 | 102 | def stop(self): 103 | pass 104 | 105 | def create_jobset(self, *args, **kwds): 106 | return NullJobSet() 107 | 108 | def get_jobsets(self): 109 | return [] 110 | 111 | def add_observer(self, observer): 112 | pass 113 | 114 | 115 | class NullJobSet(object): 116 | 117 | def started_job(self, name): 118 | pass 119 | 120 | def finished_job(self): 121 | pass 122 | 123 | def check_status(self): 124 | pass 125 | 126 | def get_active_job_name(self): 127 | pass 128 | 129 | def get_percent_done(self): 130 | pass 131 | 132 | def get_name(self): 133 | pass 134 | -------------------------------------------------------------------------------- /rope/base/utils.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | 4 | def saveit(func): 5 | """A decorator that caches the return value of a function""" 6 | 7 | name = '_' + func.__name__ 8 | def _wrapper(self, *args, **kwds): 9 | if not hasattr(self, name): 10 | setattr(self, name, func(self, *args, **kwds)) 11 | return getattr(self, name) 12 | return _wrapper 13 | 14 | cacheit = saveit 15 | 16 | def prevent_recursion(default): 17 | """A decorator that returns the return value of `default` in recursions""" 18 | def decorator(func): 19 | name = '_calling_%s_' % func.__name__ 20 | def newfunc(self, *args, **kwds): 21 | if getattr(self, name, False): 22 | return default() 23 | setattr(self, name, True) 24 | try: 25 | return func(self, *args, **kwds) 26 | finally: 27 | setattr(self, name, False) 28 | return newfunc 29 | return decorator 30 | 31 | 32 | def ignore_exception(exception_class): 33 | """A decorator that ignores `exception_class` exceptions""" 34 | def _decorator(func): 35 | def newfunc(*args, **kwds): 36 | try: 37 | return func(*args, **kwds) 38 | except exception_class: 39 | pass 40 | return newfunc 41 | return _decorator 42 | 43 | 44 | def deprecated(message=None): 45 | """A decorator for deprecated functions""" 46 | def _decorator(func, message=message): 47 | if message is None: 48 | message = '%s is deprecated' % func.__name__ 49 | def newfunc(*args, **kwds): 50 | warnings.warn(message, DeprecationWarning, stacklevel=2) 51 | return func(*args, **kwds) 52 | return newfunc 53 | return _decorator 54 | 55 | 56 | def cached(count): 57 | """A caching decorator based on parameter objects""" 58 | def decorator(func): 59 | return _Cached(func, count) 60 | return decorator 61 | 62 | class _Cached(object): 63 | 64 | def __init__(self, func, count): 65 | self.func = func 66 | self.cache = [] 67 | self.count = count 68 | 69 | def __call__(self, *args, **kwds): 70 | key = (args, kwds) 71 | for cached_key, cached_result in self.cache: 72 | if cached_key == key: 73 | return cached_result 74 | result = self.func(*args, **kwds) 75 | self.cache.append((key, result)) 76 | if len(self.cache) > self.count: 77 | del self.cache[0] 78 | return result 79 | -------------------------------------------------------------------------------- /rope/contrib/__init__.py: -------------------------------------------------------------------------------- 1 | """rope IDE tools package 2 | 3 | This package contains modules that can be used in IDEs 4 | but do not depend on the UI. So these modules will be used 5 | by `rope.ui` modules. 6 | 7 | """ 8 | -------------------------------------------------------------------------------- /rope/contrib/changestack.py: -------------------------------------------------------------------------------- 1 | """For performing many refactorings as a single command 2 | 3 | `changestack` module can be used to perform many refactorings on top 4 | of each other as one bigger command. It can be used like:: 5 | 6 | stack = ChangeStack(project, 'my big command') 7 | 8 | #.. 9 | stack.push(refactoring1.get_changes()) 10 | #.. 11 | stack.push(refactoring2.get_changes()) 12 | #.. 13 | stack.push(refactoringX.get_changes()) 14 | 15 | stack.pop_all() 16 | changes = stack.merged() 17 | 18 | Now `changes` can be previewed or performed as before. 19 | """ 20 | 21 | from rope.base import change 22 | 23 | 24 | class ChangeStack(object): 25 | 26 | def __init__(self, project, description='merged changes'): 27 | self.project = project 28 | self.description = description 29 | self.stack = [] 30 | 31 | def push(self, changes): 32 | self.stack.append(changes) 33 | self.project.do(changes) 34 | 35 | def pop_all(self): 36 | for i in range(len(self.stack)): 37 | self.project.history.undo(drop=True) 38 | 39 | def merged(self): 40 | result = change.ChangeSet(self.description) 41 | for changes in self.stack: 42 | for c in self._basic_changes(changes): 43 | result.add_change(c) 44 | return result 45 | 46 | def _basic_changes(self, changes): 47 | if isinstance(changes, change.ChangeSet): 48 | for child in changes.changes: 49 | for atom in self._basic_changes(child): 50 | yield atom 51 | else: 52 | yield changes 53 | -------------------------------------------------------------------------------- /rope/contrib/finderrors.py: -------------------------------------------------------------------------------- 1 | """Finding bad name and attribute accesses 2 | 3 | `find_errors` function can be used to find possible bad name and 4 | attribute accesses. As an example:: 5 | 6 | errors = find_errors(project, project.get_resource('mod.py')) 7 | for error in errors: 8 | print '%s: %s' % (error.lineno, error.error) 9 | 10 | prints possible errors for ``mod.py`` file. 11 | 12 | TODO: 13 | 14 | * use task handles 15 | * reporting names at most once 16 | * attributes of extension modules that don't appear in 17 | extension_modules project config can be ignored 18 | * not calling `PyScope.get_inner_scope_for_line()` if it is a 19 | bottleneck; needs profiling 20 | * not reporting occurrences where rope cannot infer the object 21 | * rope saves multiple objects for some of the names in its objectdb 22 | use all of them not to give false positives 23 | * ... ;-) 24 | 25 | """ 26 | from rope.base import ast, evaluate, pyobjects 27 | 28 | 29 | def find_errors(project, resource): 30 | """Find possible bad name and attribute accesses 31 | 32 | It returns a list of `Error`\s. 33 | """ 34 | pymodule = project.pycore.resource_to_pyobject(resource) 35 | finder = _BadAccessFinder(pymodule) 36 | ast.walk(pymodule.get_ast(), finder) 37 | return finder.errors 38 | 39 | 40 | class _BadAccessFinder(object): 41 | 42 | def __init__(self, pymodule): 43 | self.pymodule = pymodule 44 | self.scope = pymodule.get_scope() 45 | self.errors = [] 46 | 47 | def _Name(self, node): 48 | if isinstance(node.ctx, (ast.Store, ast.Param)): 49 | return 50 | scope = self.scope.get_inner_scope_for_line(node.lineno) 51 | pyname = scope.lookup(node.id) 52 | if pyname is None: 53 | self._add_error(node, 'Unresolved variable') 54 | elif self._is_defined_after(scope, pyname, node.lineno): 55 | self._add_error(node, 'Defined later') 56 | 57 | def _Attribute(self, node): 58 | if not isinstance(node.ctx, ast.Store): 59 | scope = self.scope.get_inner_scope_for_line(node.lineno) 60 | pyname = evaluate.eval_node(scope, node.value) 61 | if pyname is not None and \ 62 | pyname.get_object() != pyobjects.get_unknown(): 63 | if node.attr not in pyname.get_object(): 64 | self._add_error(node, 'Unresolved attribute') 65 | ast.walk(node.value, self) 66 | 67 | def _add_error(self, node, msg): 68 | if isinstance(node, ast.Attribute): 69 | name = node.attr 70 | else: 71 | name = node.id 72 | if name != 'None': 73 | error = Error(node.lineno, msg + ' ' + name) 74 | self.errors.append(error) 75 | 76 | def _is_defined_after(self, scope, pyname, lineno): 77 | location = pyname.get_definition_location() 78 | if location is not None and location[1] is not None: 79 | if location[0] == self.pymodule and \ 80 | lineno <= location[1] <= scope.get_end(): 81 | return True 82 | 83 | 84 | class Error(object): 85 | 86 | def __init__(self, lineno, error): 87 | self.lineno = lineno 88 | self.error = error 89 | 90 | def __str__(self): 91 | return '%s: %s' % (self.lineno, self.error) 92 | -------------------------------------------------------------------------------- /rope/contrib/fixmodnames.py: -------------------------------------------------------------------------------- 1 | """Fix the name of modules 2 | 3 | This module is useful when you want to rename many of the modules in 4 | your project. That can happen specially when you want to change their 5 | naming style. 6 | 7 | For instance:: 8 | 9 | fixer = FixModuleNames(project) 10 | changes = fixer.get_changes(fixer=str.lower) 11 | project.do(changes) 12 | 13 | Here it renames all modules and packages to use lower-cased chars. 14 | You can tell it to use any other style by using the ``fixer`` 15 | argument. 16 | 17 | """ 18 | from rope.base import change, taskhandle 19 | from rope.contrib import changestack 20 | from rope.refactor import rename 21 | 22 | 23 | class FixModuleNames(object): 24 | 25 | def __init__(self, project): 26 | self.project = project 27 | 28 | def get_changes(self, fixer=str.lower, 29 | task_handle=taskhandle.NullTaskHandle()): 30 | """Fix module names 31 | 32 | `fixer` is a function that takes and returns a `str`. Given 33 | the name of a module, it should return the fixed name. 34 | 35 | """ 36 | stack = changestack.ChangeStack(self.project, 'Fixing module names') 37 | jobset = task_handle.create_jobset('Fixing module names', 38 | self._count_fixes(fixer) + 1) 39 | try: 40 | while True: 41 | for resource in self._tobe_fixed(fixer): 42 | jobset.started_job(resource.path) 43 | renamer = rename.Rename(self.project, resource) 44 | changes = renamer.get_changes(fixer(self._name(resource))) 45 | stack.push(changes) 46 | jobset.finished_job() 47 | break 48 | else: 49 | break 50 | finally: 51 | jobset.started_job('Reverting to original state') 52 | stack.pop_all() 53 | jobset.finished_job() 54 | return stack.merged() 55 | 56 | def _count_fixes(self, fixer): 57 | return len(list(self._tobe_fixed(fixer))) 58 | 59 | def _tobe_fixed(self, fixer): 60 | for resource in self.project.pycore.get_python_files(): 61 | modname = self._name(resource) 62 | if modname != fixer(modname): 63 | yield resource 64 | 65 | def _name(self, resource): 66 | modname = resource.name.rsplit('.', 1)[0] 67 | if modname == '__init__': 68 | modname = resource.parent.name 69 | return modname 70 | -------------------------------------------------------------------------------- /rope/refactor/__init__.py: -------------------------------------------------------------------------------- 1 | """rope refactor package 2 | 3 | This package contains modules that perform python refactorings. 4 | Refactoring classes perform refactorings in 4 steps: 5 | 6 | 1. Collect some data for performing the refactoring and use them 7 | to construct a refactoring class. Like:: 8 | 9 | renamer = Rename(project, resource, offset) 10 | 11 | 2. Some refactorings give you useful information about the 12 | refactoring after their construction. Like:: 13 | 14 | print(renamer.get_old_name()) 15 | 16 | 3. Give the refactoring class more information about how to 17 | perform the refactoring and get the changes this refactoring is 18 | going to make. This is done by calling `get_changes` method of the 19 | refactoring class. Like:: 20 | 21 | changes = renamer.get_changes(new_name) 22 | 23 | 4. You can commit the changes. Like:: 24 | 25 | project.do(changes) 26 | 27 | These steps are like the steps IDEs usually do for performing a 28 | refactoring. These are the things an IDE does in each step: 29 | 30 | 1. Construct a refactoring object by giving it information like 31 | resource, offset and ... . Some of the refactoring problems (like 32 | performing rename refactoring on language keywords) can be reported 33 | here. 34 | 2. Print some information about the refactoring and ask the user 35 | about the information that are necessary for completing the 36 | refactoring (like new name). 37 | 3. Call the `get_changes` by passing it information asked from 38 | the user (if necessary) and get and preview the changes returned by 39 | it. 40 | 4. perform the refactoring. 41 | 42 | From ``0.5m5`` release the `get_changes()` method of some time- 43 | consuming refactorings take an optional `rope.base.taskhandle. 44 | TaskHandle` parameter. You can use this object for stopping or 45 | monitoring the progress of refactorings. 46 | 47 | """ 48 | from rope.refactor.importutils import ImportOrganizer 49 | from rope.refactor.topackage import ModuleToPackage 50 | 51 | 52 | __all__ = ['rename', 'move', 'inline', 'extract', 'restructure', 'topackage', 53 | 'importutils', 'usefunction', 'change_signature', 54 | 'encapsulate_field', 'introduce_factory', 'introduce_parameter', 55 | 'localtofield', 'method_object', 'multiproject'] 56 | -------------------------------------------------------------------------------- /rope/refactor/introduce_parameter.py: -------------------------------------------------------------------------------- 1 | import rope.base.change 2 | from rope.base import exceptions, evaluate, worder, codeanalyze 3 | from rope.refactor import functionutils, sourceutils, occurrences 4 | 5 | 6 | class IntroduceParameter(object): 7 | """Introduce parameter refactoring 8 | 9 | This refactoring adds a new parameter to a function and replaces 10 | references to an expression in it with the new parameter. 11 | 12 | The parameter finding part is different from finding similar 13 | pieces in extract refactorings. In this refactoring parameters 14 | are found based on the object they reference to. For instance 15 | in:: 16 | 17 | class A(object): 18 | var = None 19 | 20 | class B(object): 21 | a = A() 22 | 23 | b = B() 24 | a = b.a 25 | 26 | def f(a): 27 | x = b.a.var + a.var 28 | 29 | using this refactoring on ``a.var`` with ``p`` as the new 30 | parameter name, will result in:: 31 | 32 | def f(p=a.var): 33 | x = p + p 34 | 35 | """ 36 | 37 | def __init__(self, project, resource, offset): 38 | self.pycore = project.pycore 39 | self.resource = resource 40 | self.offset = offset 41 | self.pymodule = self.pycore.resource_to_pyobject(self.resource) 42 | scope = self.pymodule.get_scope().get_inner_scope_for_offset(offset) 43 | if scope.get_kind() != 'Function': 44 | raise exceptions.RefactoringError( 45 | 'Introduce parameter should be performed inside functions') 46 | self.pyfunction = scope.pyobject 47 | self.name, self.pyname = self._get_name_and_pyname() 48 | if self.pyname is None: 49 | raise exceptions.RefactoringError( 50 | 'Cannot find the definition of <%s>' % self.name) 51 | 52 | def _get_primary(self): 53 | word_finder = worder.Worder(self.resource.read()) 54 | return word_finder.get_primary_at(self.offset) 55 | 56 | def _get_name_and_pyname(self): 57 | return (worder.get_name_at(self.resource, self.offset), 58 | evaluate.eval_location(self.pymodule, self.offset)) 59 | 60 | def get_changes(self, new_parameter): 61 | definition_info = functionutils.DefinitionInfo.read(self.pyfunction) 62 | definition_info.args_with_defaults.append((new_parameter, 63 | self._get_primary())) 64 | collector = codeanalyze.ChangeCollector(self.resource.read()) 65 | header_start, header_end = self._get_header_offsets() 66 | body_start, body_end = sourceutils.get_body_region(self.pyfunction) 67 | collector.add_change(header_start, header_end, 68 | definition_info.to_string()) 69 | self._change_function_occurances(collector, body_start, 70 | body_end, new_parameter) 71 | changes = rope.base.change.ChangeSet('Introduce parameter <%s>' % 72 | new_parameter) 73 | change = rope.base.change.ChangeContents(self.resource, 74 | collector.get_changed()) 75 | changes.add_change(change) 76 | return changes 77 | 78 | def _get_header_offsets(self): 79 | lines = self.pymodule.lines 80 | start_line = self.pyfunction.get_scope().get_start() 81 | end_line = self.pymodule.logical_lines.\ 82 | logical_line_in(start_line)[1] 83 | start = lines.get_line_start(start_line) 84 | end = lines.get_line_end(end_line) 85 | start = self.pymodule.source_code.find('def', start) + 4 86 | end = self.pymodule.source_code.rfind(':', start, end) 87 | return start, end 88 | 89 | def _change_function_occurances(self, collector, function_start, 90 | function_end, new_name): 91 | finder = occurrences.create_finder(self.pycore, self.name, self.pyname) 92 | for occurrence in finder.find_occurrences(resource=self.resource): 93 | start, end = occurrence.get_primary_range() 94 | if function_start <= start < function_end: 95 | collector.add_change(start, end, new_name) 96 | -------------------------------------------------------------------------------- /rope/refactor/localtofield.py: -------------------------------------------------------------------------------- 1 | from rope.base import pynames, evaluate, exceptions, worder 2 | from rope.refactor.rename import Rename 3 | 4 | 5 | class LocalToField(object): 6 | 7 | def __init__(self, project, resource, offset): 8 | self.project = project 9 | self.pycore = project.pycore 10 | self.resource = resource 11 | self.offset = offset 12 | 13 | def get_changes(self): 14 | name = worder.get_name_at(self.resource, self.offset) 15 | this_pymodule = self.pycore.resource_to_pyobject(self.resource) 16 | pyname = evaluate.eval_location(this_pymodule, self.offset) 17 | if not self._is_a_method_local(pyname): 18 | raise exceptions.RefactoringError( 19 | 'Convert local variable to field should be performed on \n' 20 | 'a local variable of a method.') 21 | 22 | pymodule, lineno = pyname.get_definition_location() 23 | function_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) 24 | # Not checking redefinition 25 | #self._check_redefinition(name, function_scope) 26 | 27 | new_name = self._get_field_name(function_scope.pyobject, name) 28 | changes = Rename(self.project, self.resource, self.offset).\ 29 | get_changes(new_name, resources=[self.resource]) 30 | return changes 31 | 32 | def _check_redefinition(self, name, function_scope): 33 | class_scope = function_scope.parent 34 | if name in class_scope.pyobject: 35 | raise exceptions.RefactoringError( 36 | 'The field %s already exists' % name) 37 | 38 | def _get_field_name(self, pyfunction, name): 39 | self_name = pyfunction.get_param_names()[0] 40 | new_name = self_name + '.' + name 41 | return new_name 42 | 43 | def _is_a_method_local(self, pyname): 44 | pymodule, lineno = pyname.get_definition_location() 45 | holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) 46 | parent = holding_scope.parent 47 | return isinstance(pyname, pynames.AssignedName) and \ 48 | pyname in list(holding_scope.get_names().values()) and \ 49 | holding_scope.get_kind() == 'Function' and \ 50 | parent is not None and parent.get_kind() == 'Class' 51 | -------------------------------------------------------------------------------- /rope/refactor/method_object.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from rope.base import pyobjects, exceptions, change, evaluate, codeanalyze 4 | from rope.refactor import sourceutils, occurrences, rename 5 | 6 | 7 | class MethodObject(object): 8 | 9 | def __init__(self, project, resource, offset): 10 | self.pycore = project.pycore 11 | this_pymodule = self.pycore.resource_to_pyobject(resource) 12 | pyname = evaluate.eval_location(this_pymodule, offset) 13 | if pyname is None or not isinstance(pyname.get_object(), 14 | pyobjects.PyFunction): 15 | raise exceptions.RefactoringError( 16 | 'Replace method with method object refactoring should be ' 17 | 'performed on a function.') 18 | self.pyfunction = pyname.get_object() 19 | self.pymodule = self.pyfunction.get_module() 20 | self.resource = self.pymodule.get_resource() 21 | 22 | def get_new_class(self, name): 23 | body = sourceutils.fix_indentation( 24 | self._get_body(), sourceutils.get_indent(self.pycore) * 2) 25 | return 'class %s(object):\n\n%s%sdef __call__(self):\n%s' % \ 26 | (name, self._get_init(), 27 | ' ' * sourceutils.get_indent(self.pycore), body) 28 | 29 | def get_changes(self, classname=None, new_class_name=None): 30 | if new_class_name is not None: 31 | warnings.warn( 32 | 'new_class_name parameter is deprecated; use classname', 33 | DeprecationWarning, stacklevel=2) 34 | classname = new_class_name 35 | collector = codeanalyze.ChangeCollector(self.pymodule.source_code) 36 | start, end = sourceutils.get_body_region(self.pyfunction) 37 | indents = sourceutils.get_indents( 38 | self.pymodule.lines, self.pyfunction.get_scope().get_start()) + \ 39 | sourceutils.get_indent(self.pycore) 40 | new_contents = ' ' * indents + 'return %s(%s)()\n' % \ 41 | (classname, ', '.join(self._get_parameter_names())) 42 | collector.add_change(start, end, new_contents) 43 | insertion = self._get_class_insertion_point() 44 | collector.add_change(insertion, insertion, 45 | '\n\n' + self.get_new_class(classname)) 46 | changes = change.ChangeSet('Replace method with method object refactoring') 47 | changes.add_change(change.ChangeContents(self.resource, 48 | collector.get_changed())) 49 | return changes 50 | 51 | def _get_class_insertion_point(self): 52 | current = self.pyfunction 53 | while current.parent != self.pymodule: 54 | current = current.parent 55 | end = self.pymodule.lines.get_line_end(current.get_scope().get_end()) 56 | return min(end + 1, len(self.pymodule.source_code)) 57 | 58 | def _get_body(self): 59 | body = sourceutils.get_body(self.pyfunction) 60 | for param in self._get_parameter_names(): 61 | body = param + ' = None\n' + body 62 | pymod = self.pycore.get_string_module(body, self.resource) 63 | pyname = pymod[param] 64 | finder = occurrences.create_finder(self.pycore, param, pyname) 65 | result = rename.rename_in_module(finder, 'self.' + param, 66 | pymodule=pymod) 67 | body = result[result.index('\n') + 1:] 68 | return body 69 | 70 | def _get_init(self): 71 | params = self._get_parameter_names() 72 | indents = ' ' * sourceutils.get_indent(self.pycore) 73 | if not params: 74 | return '' 75 | header = indents + 'def __init__(self' 76 | body = '' 77 | for arg in params: 78 | new_name = arg 79 | if arg == 'self': 80 | new_name = 'host' 81 | header += ', %s' % new_name 82 | body += indents * 2 + 'self.%s = %s\n' % (arg, new_name) 83 | header += '):' 84 | return '%s\n%s\n' % (header, body) 85 | 86 | def _get_parameter_names(self): 87 | return self.pyfunction.get_param_names() 88 | -------------------------------------------------------------------------------- /rope/refactor/multiproject.py: -------------------------------------------------------------------------------- 1 | """This module can be used for performing cross-project refactorings 2 | 3 | See the "cross-project refactorings" section of ``docs/library.txt`` 4 | file. 5 | 6 | """ 7 | 8 | from rope.base import resources, project, libutils 9 | 10 | 11 | class MultiProjectRefactoring(object): 12 | 13 | def __init__(self, refactoring, projects, addpath=True): 14 | """Create a multiproject proxy for the main refactoring 15 | 16 | `projects` are other project. 17 | 18 | """ 19 | self.refactoring = refactoring 20 | self.projects = projects 21 | self.addpath = addpath 22 | 23 | def __call__(self, project, *args, **kwds): 24 | """Create the refactoring""" 25 | return _MultiRefactoring(self.refactoring, self.projects, 26 | self.addpath, project, *args, **kwds) 27 | 28 | 29 | class _MultiRefactoring(object): 30 | 31 | def __init__(self, refactoring, other_projects, addpath, 32 | project, *args, **kwds): 33 | self.refactoring = refactoring 34 | self.projects = [project] + other_projects 35 | for other_project in other_projects: 36 | for folder in self.project.pycore.get_source_folders(): 37 | other_project.get_prefs().add('python_path', folder.real_path) 38 | self.refactorings = [] 39 | for other in self.projects: 40 | args, kwds = self._resources_for_args(other, args, kwds) 41 | self.refactorings.append( 42 | self.refactoring(other, *args, **kwds)) 43 | 44 | def get_all_changes(self, *args, **kwds): 45 | """Get a project to changes dict""" 46 | result = [] 47 | for project, refactoring in zip(self.projects, self.refactorings): 48 | args, kwds = self._resources_for_args(project, args, kwds) 49 | result.append((project, refactoring.get_changes(*args, **kwds))) 50 | return result 51 | 52 | def __getattr__(self, name): 53 | return getattr(self.main_refactoring, name) 54 | 55 | def _resources_for_args(self, project, args, kwds): 56 | newargs = [self._change_project_resource(project, arg) for arg in args] 57 | newkwds = dict((name, self._change_project_resource(project, value)) 58 | for name, value in kwds.items()) 59 | return newargs, newkwds 60 | 61 | def _change_project_resource(self, project, obj): 62 | if isinstance(obj, resources.Resource) and \ 63 | obj.project != project: 64 | return libutils.path_to_resource(project, obj.real_path) 65 | return obj 66 | 67 | @property 68 | def project(self): 69 | return self.projects[0] 70 | 71 | @property 72 | def main_refactoring(self): 73 | return self.refactorings[0] 74 | 75 | 76 | def perform(project_changes): 77 | for project, changes in project_changes: 78 | project.do(changes) 79 | -------------------------------------------------------------------------------- /rope/refactor/sourceutils.py: -------------------------------------------------------------------------------- 1 | from rope.base import ast, codeanalyze 2 | 3 | 4 | def get_indents(lines, lineno): 5 | return codeanalyze.count_line_indents(lines.get_line(lineno)) 6 | 7 | 8 | def find_minimum_indents(source_code): 9 | result = 80 10 | lines = source_code.split('\n') 11 | for line in lines: 12 | if line.strip() == '': 13 | continue 14 | result = min(result, codeanalyze.count_line_indents(line)) 15 | return result 16 | 17 | 18 | def indent_lines(source_code, amount): 19 | if amount == 0: 20 | return source_code 21 | lines = source_code.splitlines(True) 22 | result = [] 23 | for l in lines: 24 | if l.strip() == '': 25 | result.append('\n') 26 | continue 27 | if amount < 0: 28 | indents = codeanalyze.count_line_indents(l) 29 | result.append(max(0, indents + amount) * ' ' + l.lstrip()) 30 | else: 31 | result.append(' ' * amount + l) 32 | return ''.join(result) 33 | 34 | 35 | def fix_indentation(code, new_indents): 36 | """Change the indentation of `code` to `new_indents`""" 37 | min_indents = find_minimum_indents(code) 38 | return indent_lines(code, new_indents - min_indents) 39 | 40 | 41 | def add_methods(pymodule, class_scope, methods_sources): 42 | source_code = pymodule.source_code 43 | lines = pymodule.lines 44 | insertion_line = class_scope.get_end() 45 | if class_scope.get_scopes(): 46 | insertion_line = class_scope.get_scopes()[-1].get_end() 47 | insertion_offset = lines.get_line_end(insertion_line) 48 | methods = '\n\n' + '\n\n'.join(methods_sources) 49 | indented_methods = fix_indentation( 50 | methods, get_indents(lines, class_scope.get_start()) + 51 | get_indent(pymodule.pycore)) 52 | result = [] 53 | result.append(source_code[:insertion_offset]) 54 | result.append(indented_methods) 55 | result.append(source_code[insertion_offset:]) 56 | return ''.join(result) 57 | 58 | 59 | def get_body(pyfunction): 60 | """Return unindented function body""" 61 | scope = pyfunction.get_scope() 62 | pymodule = pyfunction.get_module() 63 | start, end = get_body_region(pyfunction) 64 | return fix_indentation(pymodule.source_code[start:end], 0) 65 | 66 | 67 | def get_body_region(defined): 68 | """Return the start and end offsets of function body""" 69 | scope = defined.get_scope() 70 | pymodule = defined.get_module() 71 | lines = pymodule.lines 72 | node = defined.get_ast() 73 | start_line = node.lineno 74 | if defined.get_doc() is None: 75 | start_line = node.body[0].lineno 76 | elif len(node.body) > 1: 77 | start_line = node.body[1].lineno 78 | start = lines.get_line_start(start_line) 79 | scope_start = pymodule.logical_lines.logical_line_in(scope.start) 80 | if scope_start[1] >= start_line: 81 | # a one-liner! 82 | # XXX: what if colon appears in a string 83 | start = pymodule.source_code.index(':', start) + 1 84 | while pymodule.source_code[start].isspace(): 85 | start += 1 86 | end = min(lines.get_line_end(scope.end) + 1, len(pymodule.source_code)) 87 | return start, end 88 | 89 | 90 | def get_indent(pycore): 91 | project = pycore.project 92 | return project.prefs.get('indent_size', 4) 93 | -------------------------------------------------------------------------------- /rope/refactor/topackage.py: -------------------------------------------------------------------------------- 1 | import rope.refactor.importutils 2 | from rope.base.change import ChangeSet, ChangeContents, MoveResource, CreateFolder 3 | 4 | 5 | class ModuleToPackage(object): 6 | 7 | def __init__(self, project, resource): 8 | self.project = project 9 | self.pycore = project.pycore 10 | self.resource = resource 11 | 12 | def get_changes(self): 13 | changes = ChangeSet('Transform <%s> module to package' % 14 | self.resource.path) 15 | new_content = self._transform_relatives_to_absolute(self.resource) 16 | if new_content is not None: 17 | changes.add_change(ChangeContents(self.resource, new_content)) 18 | parent = self.resource.parent 19 | name = self.resource.name[:-3] 20 | changes.add_change(CreateFolder(parent, name)) 21 | parent_path = parent.path + '/' 22 | if not parent.path: 23 | parent_path = '' 24 | new_path = parent_path + '%s/__init__.py' % name 25 | if self.resource.project == self.project: 26 | changes.add_change(MoveResource(self.resource, new_path)) 27 | return changes 28 | 29 | def _transform_relatives_to_absolute(self, resource): 30 | pymodule = self.pycore.resource_to_pyobject(resource) 31 | import_tools = rope.refactor.importutils.ImportTools(self.pycore) 32 | return import_tools.relatives_to_absolutes(pymodule) 33 | -------------------------------------------------------------------------------- /settings.ini: -------------------------------------------------------------------------------- 1 | workspace=None 2 | firstRun=True 3 | running=False 4 | --------------------------------------------------------------------------------