├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── cadnano2
├── README.md
├── __init__.py
├── cadnano.bat
├── cadnano.py
├── cadnanoqt.py
├── controllers
│ ├── __init__.py
│ ├── documentcontroller.py
│ ├── itemcontrollers
│ │ ├── __init__.py
│ │ ├── activesliceitemcontroller.py
│ │ ├── partitemcontroller.py
│ │ ├── strand
│ │ │ ├── __init__.py
│ │ │ ├── abstractstranditemcontroller.py
│ │ │ ├── endpointitemcontroller.py
│ │ │ ├── stranditemcontroller.py
│ │ │ └── xoveritemcontroller.py
│ │ └── virtualhelixitemcontroller.py
│ ├── mayacontrollers
│ │ ├── __init__.py
│ │ ├── helixManip.py
│ │ ├── mayaObjectManager.py
│ │ ├── mayaSelectionContex.py
│ │ └── removedMsgCmd.py
│ └── viewrootcontroller.py
├── data
│ ├── __init__.py
│ ├── dnasequences.py
│ └── mayadefaultmodules.txt
├── dummyqt
│ ├── QtCore.py
│ ├── QtGui.py
│ └── __init__.py
├── icons
│ ├── add-bases.svg
│ ├── cadnano2-app-icon.ico
│ ├── cadnano2-app-icon.png
│ ├── cadnano2-app-icon_shelf.png
│ ├── cadnano2-document-icon.ico
│ ├── cadnano2-document-icon.png
│ ├── cadnano2-icon_doc-legacy.png
│ ├── cadnano2_installer-bkg.png
│ ├── data-export-staples.png
│ ├── data-new_32.png
│ ├── data-open_32.png
│ ├── data-save_32.png
│ ├── data-svg.png
│ ├── export-staples.png
│ ├── export-staples.svg
│ ├── part-filter-endpoint.png
│ ├── part-filter-handle.png
│ ├── part-filter-part.png
│ ├── part-filter-scaf.png
│ ├── part-filter-stap.png
│ ├── part-filter-strand.png
│ ├── part-filter-xover.png
│ ├── part-new-honeycomb.png
│ ├── part-new-square.png
│ ├── path-addseq.png
│ ├── path-addseq.svg
│ ├── path-autobreak.png
│ ├── path-break_48.png
│ ├── path-edit_32.png
│ ├── path-erase_32.png
│ ├── path-erase_48x48.png
│ ├── path-force-xover.png
│ ├── path-frame.png
│ ├── path-insert.png
│ ├── path-insert_48x48.png
│ ├── path-loop.png
│ ├── path-loop_48.png
│ ├── path-modify.png
│ ├── path-modify.svg
│ ├── path-move.png
│ ├── path-paint_48.png
│ ├── path-pen_48.png
│ ├── path-sequence.png
│ ├── path-skip.png
│ ├── path-skip_48x48.png
│ ├── path-staple.png
│ ├── remove-bases.svg
│ ├── slice-delete-last.png
│ ├── slice-edit.png
│ ├── slice-go-first.png
│ ├── slice-go-last.png
│ ├── slice-move.png
│ ├── slice-renumber.png
│ └── source
│ │ ├── cadnano2-icon.pdf
│ │ ├── part-filter-endpoint.ai
│ │ ├── part-filter-handle.ai
│ │ ├── part-filter-scaf.ai
│ │ ├── part-filter-stap.ai
│ │ ├── part-filter-strand.ai
│ │ ├── part-filter-xover.ai
│ │ ├── part-new-honeycomb.ai
│ │ ├── part-new-square.ai
│ │ ├── path-addseq.ai
│ │ ├── path-break.ai
│ │ ├── path-frame.ai
│ │ ├── path-insert.ai
│ │ ├── path-loop.ai
│ │ ├── path-paint.ai
│ │ ├── path-sequence.ai
│ │ └── path-skip.ai
├── include
│ ├── __init__.py
│ ├── fetchfile.py
│ └── getdependencies.py
├── main.py
├── model
│ ├── __init__.py
│ ├── decorators
│ │ ├── __init__.py
│ │ ├── decorator.py
│ │ ├── insertion.py
│ │ └── modifier.py
│ ├── document.py
│ ├── enum.py
│ ├── io
│ │ ├── __init__.py
│ │ ├── decoder.py
│ │ ├── encoder.py
│ │ ├── legacydecoder.py
│ │ └── legacyencoder.py
│ ├── oligo.py
│ ├── parts
│ │ ├── __init__.py
│ │ ├── honeycombpart.py
│ │ ├── part.py
│ │ └── squarepart.py
│ ├── strand.py
│ ├── strandset.py
│ └── virtualhelix.py
├── osx
│ ├── CNApplicationDelegate.py
│ └── __init__.py
├── plugins
│ ├── autobreak
│ │ ├── Makefile
│ │ ├── __init__.py
│ │ ├── autobreak.py
│ │ ├── autobreakconfig.py
│ │ ├── autobreakconfig.ui
│ │ ├── autobreakconfig_ui.py
│ │ └── staplegraph.py
│ └── test.py
├── spCadNano.py
├── tests
│ ├── __init__.py
│ ├── cadnanoguitestcase.py
│ ├── functionaltestinputs
│ │ ├── Nature09_monolith.csv
│ │ ├── Nature09_monolith.json
│ │ ├── Nature09_squarenut.csv
│ │ ├── Nature09_squarenut.json
│ │ ├── Science09_beachball_v1.csv
│ │ ├── Science09_beachball_v1.json
│ │ ├── Science09_prot120_98_v3.csv
│ │ ├── Science09_prot120_98_v3.json
│ │ ├── __init__.py
│ │ ├── gap_vs_skip.csv
│ │ ├── gap_vs_skip.json
│ │ ├── loop_size_1.csv
│ │ ├── loop_size_1.json
│ │ ├── loops_and_skips.csv
│ │ ├── loops_and_skips.json
│ │ ├── simple42.csv
│ │ ├── simple42legacy.csv
│ │ ├── simple42legacy.json
│ │ ├── skip.csv
│ │ └── skip.json
│ ├── functionaltests.py
│ ├── guitestcase.py
│ ├── modeltests.py
│ ├── runall.py
│ ├── unittests.py
│ └── xmlrunner.py
├── ui
│ ├── Makefile
│ ├── __init__.py
│ ├── dialogs
│ │ ├── __init__.py
│ │ ├── about.ui
│ │ ├── addseq.ui
│ │ ├── dialogicons_rc.py.bak
│ │ ├── images
│ │ │ ├── cadnano2-about.png
│ │ │ ├── part-honeycomb.png
│ │ │ ├── part-square.png
│ │ │ ├── path-addseq.svg
│ │ │ ├── path-edit_32.png
│ │ │ ├── path-force-xover.png
│ │ │ ├── path-paint_48.png
│ │ │ └── source
│ │ │ │ └── cadnano2-about.ai
│ │ ├── latticetype.ui
│ │ ├── preferences.ui
│ │ ├── ui.dialogs.dialogicons.qrc
│ │ ├── ui_about.py
│ │ ├── ui_addseq.py
│ │ ├── ui_latticetype.py
│ │ ├── ui_preferences.py
│ │ ├── ui_warning.py
│ │ └── warning.ui
│ └── mainwindow
│ │ ├── __init__.py
│ │ ├── icons_rc.py
│ │ ├── images
│ │ ├── add-bases.svg
│ │ ├── cadnano2-app-icon.ico
│ │ ├── cadnano2-app-icon.png
│ │ ├── cadnano2-app-icon_shelf.png
│ │ ├── cadnano2-document-icon.ico
│ │ ├── cadnano2-document-icon.png
│ │ ├── cadnano2-icon_doc-legacy.png
│ │ ├── cadnano2_installer-bkg.png
│ │ ├── data-export-staples.png
│ │ ├── data-new_32.png
│ │ ├── data-open_32.png
│ │ ├── data-save_32.png
│ │ ├── data-svg.png
│ │ ├── export-staples.png
│ │ ├── export-staples.svg
│ │ ├── part-filter-endpoint.png
│ │ ├── part-filter-handle.png
│ │ ├── part-filter-part.png
│ │ ├── part-filter-scaf.png
│ │ ├── part-filter-stap.png
│ │ ├── part-filter-strand.png
│ │ ├── part-filter-xover.png
│ │ ├── part-new-honeycomb.png
│ │ ├── part-new-square.png
│ │ ├── path-addseq.png
│ │ ├── path-addseq.svg
│ │ ├── path-autobreak.png
│ │ ├── path-break_48.png
│ │ ├── path-edit_32.png
│ │ ├── path-erase_32.png
│ │ ├── path-erase_48x48.png
│ │ ├── path-force-xover.png
│ │ ├── path-frame.png
│ │ ├── path-insert.png
│ │ ├── path-insert_48x48.png
│ │ ├── path-loop.png
│ │ ├── path-loop_48.png
│ │ ├── path-modify.png
│ │ ├── path-modify.svg
│ │ ├── path-move.png
│ │ ├── path-paint_48.png
│ │ ├── path-pen_48.png
│ │ ├── path-sequence.png
│ │ ├── path-skip.png
│ │ ├── path-skip_48x48.png
│ │ ├── path-staple.png
│ │ ├── remove-bases.svg
│ │ ├── slice-delete-last.png
│ │ ├── slice-edit.png
│ │ ├── slice-go-first.png
│ │ ├── slice-go-last.png
│ │ ├── slice-move.png
│ │ ├── slice-renumber.png
│ │ └── source
│ │ │ ├── cadnano2-icon.pdf
│ │ │ ├── part-filter-endpoint.ai
│ │ │ ├── part-filter-handle.ai
│ │ │ ├── part-filter-scaf.ai
│ │ │ ├── part-filter-stap.ai
│ │ │ ├── part-filter-strand.ai
│ │ │ ├── part-filter-xover.ai
│ │ │ ├── part-new-honeycomb.ai
│ │ │ ├── part-new-square.ai
│ │ │ ├── path-addseq.ai
│ │ │ ├── path-break.ai
│ │ │ ├── path-frame.ai
│ │ │ ├── path-insert.ai
│ │ │ ├── path-loop.ai
│ │ │ ├── path-paint.ai
│ │ │ ├── path-sequence.ai
│ │ │ └── path-skip.ai
│ │ ├── mainwindow.ui
│ │ ├── svgbutton.py
│ │ ├── ui.mainwindow.icons.qrc
│ │ └── ui_mainwindow.py
├── util.py
└── views
│ ├── QGraphicsScene-event-dispatching-overview.txt
│ ├── __init__.py
│ ├── customqgraphicsview.py
│ ├── documentwindow.py
│ ├── pathview
│ ├── __init__.py
│ ├── activesliceitem.py
│ ├── colorpanel.py
│ ├── partitem.py
│ ├── pathrootitem.py
│ ├── pathselection.py
│ ├── prexoveritem.py
│ ├── strand
│ │ ├── __init__.py
│ │ ├── abstractstranditem.py
│ │ ├── decorators
│ │ │ ├── __init__.py
│ │ │ ├── abstractdecoratoritem.py
│ │ │ ├── fluorophoreitem.py
│ │ │ ├── insertionitem.py
│ │ │ ├── skipitem.py
│ │ │ └── stapleextensionitem.py
│ │ ├── endpointitem.py
│ │ ├── stranditem.py
│ │ └── xoveritem.py
│ ├── tools
│ │ ├── __init__.py
│ │ ├── abstractpathtool.py
│ │ ├── addseqtool.py
│ │ ├── breaktool.py
│ │ ├── erasetool.py
│ │ ├── insertiontool.py
│ │ ├── painttool.py
│ │ ├── pathtoolmanager.py
│ │ ├── penciltool.py
│ │ ├── selecttool.py
│ │ └── skiptool.py
│ ├── virtualhelixhandleitem.py
│ └── virtualhelixitem.py
│ ├── preferences.py
│ ├── sliceview
│ ├── __init__.py
│ ├── activesliceitem.py
│ ├── emptyhelixitem.py
│ ├── partitem.py
│ ├── slicerootitem.py
│ ├── tools
│ │ ├── __init__.py
│ │ └── slicetoolmanager.py
│ └── virtualhelixitem.py
│ ├── solidview
│ ├── __init__.py
│ ├── halfcylinderhelixnode.py
│ ├── mayaHotKeys.py
│ ├── mayaUI.py
│ ├── partitem.py
│ ├── predecoratornode.py
│ ├── solidrootitem.py
│ ├── stranditem.py
│ └── virtualhelixitem.py
│ └── styles.py
├── dist
├── cadnano2-2.4.0-py3-none-any.whl
└── cadnano2-2.4.0.tar.gz
└── pyproject.toml
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | __pycache__
3 | *.pyc
4 | *.egg-info
5 | build
6 | dist
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 2.4.0
2 |
3 | * Migrated to PyQt6
4 | * Packaged for PyPI and pip install
5 |
6 | ## 2.0.1
7 |
8 | * Fixed circular scaffold highlighting when opening from an nno file.
9 | * OSX: Reconnected objc bridge so files open via double-click or dock icon drop.
10 | * Fixed bug in display of square-lattice crossover locations.
11 | * Square lattice canvas extension now happens in 32-base steps.
12 | * Updated icon for AddSeq Tool.
13 | * Moved Frame button to the View menu and moved AutoStaple button to the top toolbar.
14 |
15 |
16 | ## 2.0.0
17 |
18 | * Undo/redo.
19 | * Unified interface for square-lattice and honeycomb-lattice parts. The new workflow is to open a document and then click the "Honeycomb" or "Square" button on the top toolbar to create a new part for editing.
20 | * Stored user preferences.
21 | * Scroll to zoom (e.g. via mousewheel). Command+mouse-drag to pan.
22 | * Pencil tool: Left-click to create or destroy staple or scaffold. Right-click to create a forced crossover.
23 | * DNA sequences are displayed live in the interface.
24 | * Export button: creates a staple csv file, replacing the old SeqTool copy-to-clipboard dialog.
25 | * Frame button: zoom-to-fit of path view.
26 | * New file format (.nno extension)
27 | * Loop is renamed to Insert. Its size can be edited in place via its numeric label.
28 | * Multiple helices can be reordered by selecting the helix labels (leftmost orange circle) and dragging the group.
29 | * Delete-Last button removed. To delete a helix, selecting its label and press delete.
30 | * 3D view is removed. See planned features for future replacement.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2011 Wyss Institute at Harvard University and University of California San Francisco
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 | http://www.opensource.org/licenses/mit-license.php
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cadnano2 DNA Origami Design Software
2 |
3 | ## Overview
4 | [Cadnano](http://cadnano.org/) is computer-aided design software for DNA origami nanostructures. The original citation is [here](https://academic.oup.com/nar/article/37/15/5001/2409858).
5 |
6 | ## Installation
7 |
8 | **macOS**
9 | * Install [homebrew](https://brew.sh/)
10 | * Install python3: `brew install python3`
11 | * Create a virtualenv: `python3 -m venv ~/virtualenvs/cn24x`
12 | * Activate virtualenv: `source ~/virtualenvs/cn24x/bin/activate`
13 | * Install via pip: `pip3 install cadnano2`
14 |
15 | **Linux**
16 | * Create a virtual env: `python3 -m venv ~/virtualenvs/cn24x`
17 | * Activate the venv: `source ~/virtualenvs/cn24x/bin/activate`
18 | * Install from PyPI: `pip3 install cadnano2`
19 |
20 | **Windows** (tested for Python 3.10.4)
21 | * Download and install latest [python3](https://www.python.org/downloads/)
22 | * Use "Manage app execution aliases" to disable launching "App Installer" via any python executables.
23 | * Add python app folder to your system path, e.g. `C:\Users\shawn\AppData\Local\Programs\Python\Python310\`
24 | * Add scripts folder to your system path, e.g. `C:\Users\shawn\AppData\Local\Programs\Python\Python310\Scripts\`
25 | * Open command prompt (cmd.exe) and confirm you can run "python" and "pip".
26 | * Install Cadnano via pip: `pip install cadnano2`
27 |
28 | ## Running
29 |
30 | **macOS or Linux**
31 | * Open the Terminal
32 | * (macOS or Linux) Activate virtual env:
33 | - `source ~/virtualenvs/cn24x/bin/activate`
34 | * Run the app: `cadnano2`
35 |
36 | **Windows**
37 | * Open the Command Prompt
38 | * Run the app: `cadnano2`
39 |
40 | **macOS alias**
41 | * Add to `~/.zprofile`: `alias cn2="source ~/virtualenvs/cn24x/bin/activate && cadnano2"`
42 | * Open new Terminal and run: `cn2`
43 |
44 | ## Upgrading
45 | * Open the Terminal
46 | * Activate virtual env: `source ~/virtualenvs/cn24x/bin/activate`
47 | * Upgrade via pip: `pip install --upgrade cadnano2`
48 |
49 |
50 | ## Development
51 |
52 | **Setup a dev environment (Mac or Linux)**
53 |
54 | * Create a virtualenv: `python3 -m venv ~/virtualenvs/cn24dev`
55 | * Activate virtualenv: `source ~/virtualenvs/cn24dev/bin/activate`
56 | * Install build dependencies: `pip install setuptools wheel pyqt6`
57 | * Clone repo: `git clone git@github.com:douglaslab/cadnano2.git`
58 | * Change directory: `cd cadnano2`
59 | * Make desired code edits
60 | * Build and install: `pip install -e .`
61 | * Test: `cadnano2`
62 | * Repeat previous 3 steps as needed
63 |
64 | **Setup a dev environment (Windows)**
65 |
66 | * Install venv: `pip install virtualenv`
67 | * Create a virtualenv: `python -m venv virtualenvs\cn24dev` (e.g. in %homepath%)
68 | * Activate virtualenv: `virtualenvs\cn24dev\Scripts\activate`
69 | * Install build dependencies: `pip install setuptools wheel pyqt6`
70 | * Clone repo: `git clone git@github.com:douglaslab/cadnano2.git`
71 | * Change directory: `cd cadnano2`
72 | * Make desired code edits
73 | * Build and install: `pip install -e .`
74 | * Test: `cadnano2`
75 | * Repeat previous 3 steps as needed
76 |
77 |
78 | **Build new dist and upload to PyPi**
79 |
80 | * `pip install build twine` <- install [build](https://pypi.org/project/build/) and [twine](https://pypi.org/project/twine/)
81 | * `cd /path/to/cadnano2/`
82 | * `python3 -m build` creates dist/cadnano2-x.y.z.tar.gz and cadnano2-x.y.z-py3-none-any.whl
83 | * `python3 -m twine upload dist/cadnano2-x.y.z*`
84 |
85 | ## Version notes
86 |
87 | This version of Cadnano2 is maintained by the [Douglas Lab](http://bionano.ucsf.edu/). It is derived from [cadnano/cadnano2](https://github.com/cadnano/cadnano2).
88 |
89 | If you wish to use the Cadnano Python API for scripting, see [cadnano2.5](https://github.com/douglaslab/cadnano2.5/).
90 |
91 | ## License
92 |
93 | This version of Cadnano2 is available under the MIT License. GUI code that uses PyQt6 is GPLv3 as [required](http://pyqt.sourceforge.net/Docs/PyQt6/introduction.html#license) by Riverbank Computing.
94 |
--------------------------------------------------------------------------------
/cadnano2/README.md:
--------------------------------------------------------------------------------
1 | # Cadnano2 DNA Origami Software (PyQt6 port)
2 |
3 | ## Overview
4 | [Cadnano](http://cadnano.org/) is computer-aided design software for DNA origami nanostructures. The original citation is [here](https://academic.oup.com/nar/article/37/15/5001/2409858).
5 |
6 | This version of Cadnano2 is being maintained by the [Douglas Lab](http://bionano.ucsf.edu/) to preserve the lattice-based design interface for research purposes. This is not a direct fork of [cadnano/cadnano2](https://github.com/cadnano/cadnano2) because that would result in a 200+ MB download when cloning. We have removed the [installer](https://github.com/cadnano/cadnano2/tree/master/installer) directory and git history, which makes this version less than 3 MB to download, or 11 MB uncompressed.
7 |
8 | If you wish to use the newest version of Cadnano that supports Python scripting and non-lattice designs, see [cadnano2.5](https://github.com/cadnano/cadnano2.5/).
9 |
10 | ## License
11 |
12 | This version of Cadnano2 is available under the MIT License.
13 | GUI code that uses PyQt6 or PyQt3D is GPLv3 as [required](http://pyqt.sourceforge.net/Docs/PyQt6/introduction.html#license) by Riverbank Computing.
14 |
--------------------------------------------------------------------------------
/cadnano2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/__init__.py
--------------------------------------------------------------------------------
/cadnano2/cadnano.bat:
--------------------------------------------------------------------------------
1 | start pythonw main.py %1 %2 %3 %4
2 | exit
--------------------------------------------------------------------------------
/cadnano2/cadnano.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os.path
3 | from glob import glob
4 | from code import interact
5 | import cadnano2.util as util
6 |
7 | sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))+"/include")
8 |
9 | global sharedApp
10 | sharedApp = None
11 |
12 |
13 | def ignoreEnv():
14 | return environ.get('CADNANO_IGNORE_ENV_VARS_EXCEPT_FOR_ME', False)
15 |
16 | # The global application object used when cadnano is run as a python module
17 |
18 | class HeadlessCadnano(object):
19 | undoGroup = None
20 | def isInMaya(self):
21 | return False
22 | class prefs():
23 | squareRows = 50
24 | squareCols = 50
25 | def isGui(self):
26 | return False
27 | # end def
28 |
29 | def app(appArgs=None):
30 | global sharedApp
31 | if sharedApp != None:
32 | return sharedApp
33 | return initAppWithoutGui(appArgs)
34 |
35 | def initAppWithoutGui(appArgs=sys.argv):
36 | global sharedApp
37 | sharedApp = HeadlessCadnano()
38 | # loadAllPlugins()
39 | return sharedApp
40 |
41 | def initAppWithGui(appArgs=sys.argv):
42 | util.qtFrameworkList = ['PyQt', 'PySide']
43 | from .cadnanoqt import CadnanoQt
44 | global sharedApp
45 | sharedApp = CadnanoQt(appArgs)
46 | sharedApp.finishInit()
47 | if util.isWindows():
48 | pass
49 | # import ctypes
50 | # myappid = 'harvard.cadnano.cadnano2.2' # arbitrary string
51 | # ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
52 | return sharedApp
53 |
54 | def initAppMaya(appArgs=sys.argv):
55 | import cadnano2.util as util
56 | util.qtFrameworkList = ['PyQt', 'PySide']
57 | from cadnanoqt import CadnanoQt
58 | global sharedApp
59 | sharedApp = CadnanoQt(appArgs)
60 | return sharedApp
61 | # end def
62 |
63 | def path():
64 | return os.path.abspath(os.path.dirname(__file__))
65 |
66 | # maps plugin path (extension stripped) -> plugin module
67 | loadedPlugins = {}
68 |
69 | def unloadedPlugins():
70 | """ Returns a list of plugin paths that have yet to
71 | be loaded but are in the top level of one of the
72 | search directories specified in pluginDirs"""
73 | internalPlugins = os.path.join(path(), 'plugins')
74 | pluginDirs = [internalPlugins]
75 | results = []
76 | for pluginDir in pluginDirs:
77 | if not os.path.isdir(pluginDir):
78 | continue
79 | for dirent in os.listdir(pluginDir):
80 | f = os.path.join(pluginDir, dirent)
81 | isfile = os.path.isfile(f)
82 | hasValidSuffix = dirent.endswith(('.py', '.so'))
83 | if isfile and hasValidSuffix:
84 | results.append(f)
85 | if os.path.isdir(f) and\
86 | os.path.isfile(os.path.join(f, '__init__.py')):
87 | results.append(f)
88 | return [x for x in results if x not in loadedPlugins]
89 |
90 | # Plugins are no longer supported, so needn't import imp
91 |
92 | # def loadPlugin(f):
93 | # path, fname = os.path.split(f)
94 | # name, ext = os.path.splitext(fname)
95 | # pluginKey = os.path.join(path, name)
96 | # try:
97 | # mod = loadedPlugins[pluginKey]
98 | # return mod
99 | # except KeyError:
100 | # pass
101 | # file, filename, data = imp.find_module(name, [path])
102 | # mod = imp.load_module(name, file, filename, data)
103 | # loadedPlugins[pluginKey] = mod
104 | # return mod
105 |
106 | # def loadAllPlugins():
107 | # loadedAPlugin = False
108 | # for p in unloadedPlugins():
109 | # loadPlugin(p)
110 | # loadedAPlugin = True
111 | # return loadedAPlugin
--------------------------------------------------------------------------------
/cadnano2/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/controllers/__init__.py
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/controllers/itemcontrollers/__init__.py
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/activesliceitemcontroller.py:
--------------------------------------------------------------------------------
1 | class ActiveSliceItemController(object):
2 | def __init__(self, activeSliceItem, modelPart):
3 | self._activeSliceItem = activeSliceItem
4 | self._modelPart = modelPart
5 | self.connectSignals()
6 |
7 | def connectSignals(self):
8 | aSI = self._activeSliceItem
9 | mP = self._modelPart
10 |
11 | mP.partActiveSliceResizeSignal.connect(aSI.updateRectSlot)
12 | mP.partActiveSliceIndexSignal.connect(aSI.updateIndexSlot)
13 | mP.partStrandChangedSignal.connect(aSI.strandChangedSlot)
14 | # end def
15 |
16 | def disconnectSignals(self):
17 | aSI = self._activeSliceItem
18 | mP = self._modelPart
19 |
20 | mP.partActiveSliceResizeSignal.disconnect(aSI.updateRectSlot)
21 | mP.partActiveSliceIndexSignal.disconnect(aSI.updateIndexSlot)
22 | mP.partStrandChangedSignal.disconnect(aSI.strandChangedSlot)
23 | # end def
24 | # end class
25 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/partitemcontroller.py:
--------------------------------------------------------------------------------
1 | class PartItemController(object):
2 | def __init__(self, partItem, modelPart):
3 | self._partItem = partItem
4 | self._modelPart = modelPart
5 | self.connectSignals()
6 |
7 | def connectSignals(self):
8 | mP = self._modelPart
9 | pI = self._partItem
10 |
11 | if hasattr(pI, "partHideSlot"):
12 | mP.partHideSignal.connect(pI.partHideSlot)
13 | if hasattr(pI, "partActiveVirtualHelixChangedSlot"):
14 | mP.partActiveVirtualHelixChangedSignal.connect(pI.partActiveVirtualHelixChangedSlot)
15 |
16 | mP.partDimensionsChangedSignal.connect(pI.partDimensionsChangedSlot)
17 | mP.partParentChangedSignal.connect(pI.partParentChangedSlot)
18 | mP.partPreDecoratorSelectedSignal.connect(pI.partPreDecoratorSelectedSlot)
19 | mP.partRemovedSignal.connect(pI.partRemovedSlot)
20 | mP.partStrandChangedSignal.connect(pI.updatePreXoverItemsSlot)
21 | mP.partVirtualHelixAddedSignal.connect(pI.partVirtualHelixAddedSlot)
22 | mP.partVirtualHelixRenumberedSignal.connect(pI.partVirtualHelixRenumberedSlot)
23 | mP.partVirtualHelixResizedSignal.connect(pI.partVirtualHelixResizedSlot)
24 | mP.partVirtualHelicesReorderedSignal.connect(pI.partVirtualHelicesReorderedSlot)
25 | # end def
26 |
27 | def disconnectSignals(self):
28 | mP = self._modelPart
29 | pI = self._partItem
30 |
31 | if hasattr(pI, "partHideSlot"):
32 | mP.partHideSignal.disconnect(pI.partHideSlot)
33 | if hasattr(pI, "partActiveVirtualHelixChangedSlot"):
34 | mP.partActiveVirtualHelixChangedSignal.disconnect(pI.partActiveVirtualHelixChangedSlot)
35 |
36 | mP.partDimensionsChangedSignal.disconnect(pI.partDimensionsChangedSlot)
37 | mP.partParentChangedSignal.disconnect(pI.partParentChangedSlot)
38 | mP.partPreDecoratorSelectedSignal.disconnect(pI.partPreDecoratorSelectedSlot)
39 | mP.partRemovedSignal.disconnect(pI.partRemovedSlot)
40 | mP.partStrandChangedSignal.disconnect(pI.updatePreXoverItemsSlot)
41 | mP.partVirtualHelixAddedSignal.disconnect(pI.partVirtualHelixAddedSlot)
42 | mP.partVirtualHelixRenumberedSignal.disconnect(pI.partVirtualHelixRenumberedSlot)
43 | mP.partVirtualHelixResizedSignal.disconnect(pI.partVirtualHelixResizedSlot)
44 | mP.partVirtualHelicesReorderedSignal.disconnect(pI.partVirtualHelicesReorderedSlot)
45 | # end def
46 | # end class
47 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/strand/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/controllers/itemcontrollers/strand/__init__.py
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/strand/abstractstranditemcontroller.py:
--------------------------------------------------------------------------------
1 | import cadnano2.util as util
2 | # from cadnano2.controllers.itemcontrollers.abstractitemcontroller import AbstractItemController
3 |
4 |
5 | class AbstractStrandItemController(object):
6 | def __init__(self, strandItem, modelStrand):
7 | """
8 | Do not call connectSignals here. subclasses
9 | will install two sets of signals.
10 | """
11 | if self.__class__ == AbstractStrandItemController:
12 | e = "AbstractStrandItemController should be subclassed."
13 | raise NotImplementedError(e)
14 | self._strandItem = strandItem
15 | self._modelStrand = modelStrand
16 | self._modelOligo = modelStrand.oligo()
17 | # end def
18 |
19 | def reconnectOligoSignals(self):
20 | self.disconnectOligoSignals()
21 | self.connectOligoSignals()
22 | # end def
23 |
24 | def connectSignals(self):
25 | """Connects modelStrant signals to strandItem slots."""
26 | mS = self._modelStrand
27 | sI = self._strandItem
28 |
29 | AbstractStrandItemController.connectOligoSignals(self)
30 | mS.strandHasNewOligoSignal.connect(sI.strandHasNewOligoSlot)
31 | mS.strandRemovedSignal.connect(sI.strandRemovedSlot)
32 |
33 | mS.strandInsertionAddedSignal.connect(sI.strandInsertionAddedSlot)
34 | mS.strandInsertionChangedSignal.connect(sI.strandInsertionChangedSlot)
35 | mS.strandInsertionRemovedSignal.connect(sI.strandInsertionRemovedSlot)
36 | mS.strandDecoratorAddedSignal.connect(sI.strandDecoratorAddedSlot)
37 | mS.strandDecoratorChangedSignal.connect(sI.strandDecoratorChangedSlot)
38 | mS.strandDecoratorRemovedSignal.connect(sI.strandDecoratorRemovedSlot)
39 | mS.strandModifierAddedSignal.connect(sI.strandModifierAddedSlot)
40 | mS.strandModifierChangedSignal.connect(sI.strandModifierChangedSlot)
41 | mS.strandModifierRemovedSignal.connect(sI.strandModifierRemovedSlot)
42 |
43 | mS.selectedChangedSignal.connect(sI.selectedChangedSlot)
44 | # end def
45 |
46 | def connectOligoSignals(self):
47 | sI = self._strandItem
48 | mO = self._modelStrand.oligo()
49 | self._modelOligo = mO
50 | mO.oligoAppearanceChangedSignal.connect(sI.oligoAppearanceChangedSlot)
51 | # end def
52 |
53 | def disconnectSignals(self):
54 | mS = self._modelStrand
55 | sI = self._strandItem
56 |
57 | AbstractStrandItemController.disconnectOligoSignals(self)
58 | mS.strandHasNewOligoSignal.disconnect(sI.strandHasNewOligoSlot)
59 | mS.strandRemovedSignal.disconnect(sI.strandRemovedSlot)
60 |
61 | mS.strandInsertionAddedSignal.disconnect(sI.strandInsertionAddedSlot)
62 | mS.strandInsertionChangedSignal.disconnect(sI.strandInsertionChangedSlot)
63 | mS.strandInsertionRemovedSignal.disconnect(sI.strandInsertionRemovedSlot)
64 | mS.strandDecoratorAddedSignal.disconnect(sI.strandDecoratorAddedSlot)
65 | mS.strandDecoratorChangedSignal.disconnect(sI.strandDecoratorChangedSlot)
66 | mS.strandDecoratorRemovedSignal.disconnect(sI.strandDecoratorRemovedSlot)
67 | mS.strandModifierAddedSignal.disconnect(sI.strandModifierAddedSlot)
68 | mS.strandModifierChangedSignal.disconnect(sI.strandModifierChangedSlot)
69 | mS.strandModifierRemovedSignal.disconnect(sI.strandModifierRemovedSlot)
70 |
71 | mS.selectedChangedSignal.disconnect(sI.selectedChangedSlot)
72 | # end def
73 |
74 | def disconnectOligoSignals(self):
75 | sI = self._strandItem
76 | mO = self._modelOligo
77 | mO.oligoAppearanceChangedSignal.disconnect(sI.oligoAppearanceChangedSlot)
78 | # end def
79 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/strand/endpointitemcontroller.py:
--------------------------------------------------------------------------------
1 | from cadnano2.controllers.itemcontrollers.strand.abstractstranditemcontroller \
2 | import AbstractStrandItemController
3 |
4 |
5 | class EndpointItemController(AbstractStrandItemController):
6 | def __init__(self, strandItem, modelOligo, modelStrand):
7 | super(EndpointItemController, self).__init__(strandItem, modelStrand)
8 | self.connectSignals()
9 | # end def
10 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/strand/stranditemcontroller.py:
--------------------------------------------------------------------------------
1 | import cadnano2.util as util
2 | from cadnano2.controllers.itemcontrollers.strand.abstractstranditemcontroller \
3 | import AbstractStrandItemController
4 |
5 |
6 | class StrandItemController(AbstractStrandItemController):
7 | def __init__(self, strandItem, modelStrand):
8 | super(StrandItemController, self).__init__(strandItem, modelStrand)
9 | self.connectSignals()
10 | # end def
11 |
12 | def reconnectOligoSignals(self):
13 | """
14 | use this for whenever a strands oligo changes
15 | """
16 | AbstractStrandItemController.disconnectOligoSignals(self)
17 | self.disconnectOligoSignals()
18 | AbstractStrandItemController.connectOligoSignals(self)
19 | self.connectOligoSignals()
20 | # end def
21 |
22 | def connectSignals(self):
23 | AbstractStrandItemController.connectSignals(self)
24 | mS = self._modelStrand
25 | sI = self._strandItem
26 | mS.strandResizedSignal.connect(sI.strandResizedSlot)
27 | # mS.strandXover5pChangedSignal.connect(sI.strandXover5pChangedSlot)
28 | mS.strandUpdateSignal.connect(sI.strandUpdateSlot)
29 | self.connectOligoSignals()
30 | # end def
31 |
32 | def connectOligoSignals(self):
33 | mO = self._modelStrand.oligo()
34 | self._modelOligo = mO
35 | sI = self._strandItem
36 | mO.oligoSequenceAddedSignal.connect(sI.oligoSequenceAddedSlot)
37 | mO.oligoSequenceClearedSignal.connect(sI.oligoSequenceClearedSlot)
38 | # end def
39 |
40 | def disconnectSignals(self):
41 | AbstractStrandItemController.disconnectSignals(self)
42 | mS = self._modelStrand
43 | sI = self._strandItem
44 | mS.strandResizedSignal.disconnect(sI.strandResizedSlot)
45 | # mS.strandXover5pChangedSignal.disconnect(sI.strandXover5pChangedSlot)
46 | mS.strandUpdateSignal.disconnect(sI.strandUpdateSlot)
47 | self.disconnectOligoSignals()
48 | # end def
49 |
50 | def disconnectOligoSignals(self):
51 | mO = self._modelOligo
52 | sI = self._strandItem
53 | mO.oligoSequenceAddedSignal.disconnect(sI.oligoSequenceAddedSlot)
54 | mO.oligoSequenceClearedSignal.disconnect(sI.oligoSequenceClearedSlot)
55 | # end def
56 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/strand/xoveritemcontroller.py:
--------------------------------------------------------------------------------
1 | import cadnano2.util as util
2 |
3 |
4 | class XoverItemController(object):
5 | def __init__(self, xoverItem, modelStrand5p):
6 | self._xoverItem = xoverItem
7 | self._modelStrand5p = modelStrand5p
8 | self._modelOligo = modelStrand5p.oligo()
9 | self.connectSignals()
10 | # end def
11 |
12 | def reconnectOligoSignals(self):
13 | """
14 | use this for whenever a strands oligo changes
15 | """
16 | self.disconnectSignals()
17 | self.connectSignals()
18 | # end def
19 |
20 | def reconnectSignals(self, strand):
21 | self.disconnectSignals()
22 | self._modelStrand5p = strand
23 | self.connectSignals()
24 | # end def
25 |
26 | def connectSignals(self):
27 | xI = self._xoverItem
28 | s5p = self._modelStrand5p
29 | mO = s5p.oligo()
30 | self._modelOligo = mO
31 |
32 | s5p.strand5pHasSwappedSignal.connect(xI.strandSwapSlot)
33 | s5p.strandHasNewOligoSignal.connect(xI.strandHasNewOligoSlot)
34 | mO.oligoAppearanceChangedSignal.connect(xI.oligoAppearanceChangedSlot)
35 | s5p.strandXover5pRemovedSignal.connect(xI.xover5pRemovedSlot)
36 | # end def
37 |
38 | def disconnectSignals(self):
39 | xI = self._xoverItem
40 | s5p = self._modelStrand5p
41 | mO = self._modelOligo
42 |
43 | s5p.strand5pHasSwappedSignal.disconnect(xI.strandSwapSlot)
44 | s5p.strandHasNewOligoSignal.disconnect(xI.strandHasNewOligoSlot)
45 | mO.oligoAppearanceChangedSignal.disconnect(xI.oligoAppearanceChangedSlot)
46 | s5p.strandXover5pRemovedSignal.connect(xI.xover5pRemovedSlot)
47 | # end def
48 |
--------------------------------------------------------------------------------
/cadnano2/controllers/itemcontrollers/virtualhelixitemcontroller.py:
--------------------------------------------------------------------------------
1 | class VirtualHelixItemController():
2 | def __init__(self, virtualHelixItem, modelVirtualHelix):
3 | self._virtualHelixItem = virtualHelixItem
4 | self._modelVirtualHelix = modelVirtualHelix
5 | self.connectSignals()
6 | # end def
7 |
8 | def connectSignals(self):
9 | vhItem = self._virtualHelixItem
10 | mvh = self._modelVirtualHelix
11 |
12 | mvh.virtualHelixNumberChangedSignal.connect(vhItem.virtualHelixNumberChangedSlot)
13 | mvh.virtualHelixRemovedSignal.connect(vhItem.virtualHelixRemovedSlot)
14 |
15 | for strandSet in mvh.getStrandSets():
16 | strandSet.strandsetStrandAddedSignal.connect(vhItem.strandAddedSlot)
17 | # strandSet.decoratorAddedSignal.connect(vhItem.decoratorAddedSlot)
18 | # end def
19 |
20 | def disconnectSignals(self):
21 | vhItem = self._virtualHelixItem
22 | mvh = self._modelVirtualHelix
23 |
24 | mvh.virtualHelixNumberChangedSignal.disconnect(vhItem.virtualHelixNumberChangedSlot)
25 | mvh.virtualHelixRemovedSignal.disconnect(vhItem.virtualHelixRemovedSlot)
26 |
27 | for strandSet in mvh.getStrandSets():
28 | strandSet.strandsetStrandAddedSignal.disconnect(vhItem.strandAddedSlot)
29 | # strandSet.decoratorAddedSignal.disconnect(vhItem.decoratorAddedSlot)
--------------------------------------------------------------------------------
/cadnano2/controllers/mayacontrollers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/controllers/mayacontrollers/__init__.py
--------------------------------------------------------------------------------
/cadnano2/controllers/viewrootcontroller.py:
--------------------------------------------------------------------------------
1 | class ViewRootController():
2 | def __init__(self, viewRoot, modelDocument):
3 | self._viewRoot = viewRoot
4 | self._modelDocument = modelDocument
5 | self.connectSignals()
6 |
7 | def connectSignals(self):
8 | mD = self._modelDocument
9 | vR = self._viewRoot
10 | mD.documentPartAddedSignal.connect(vR.partAddedSlot)
11 | mD.documentClearSelectionsSignal.connect(vR.clearSelectionsSlot)
12 | mD.documentSelectionFilterChangedSignal.connect(vR.selectionFilterChangedSlot)
13 | mD.documentViewResetSignal.connect(vR.resetRootItemSlot)
14 |
15 | def disconnectSignals(self):
16 | mD = self._modelDocument
17 | vR = self._viewRoot
18 | mD.documentPartAddedSignal.disconnect(vR.partAddedSlot)
19 | mD.documentClearSelectionsSignal.disconnect(vR.clearSelectionsSlot)
20 | mD.documentSelectionFilterChangedSignal.disconnect(vR.selectionFilterChangedSlot)
21 | mD.documentViewResetSignal.disconnect(vR.resetRootItemSlot)
--------------------------------------------------------------------------------
/cadnano2/data/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | """
3 | __init__.py
4 |
5 | Created by Shawn Douglas on 2011-01-23.
6 |
7 | """
8 |
--------------------------------------------------------------------------------
/cadnano2/data/mayadefaultmodules.txt:
--------------------------------------------------------------------------------
1 | heapq
2 | maya.app.startup.traceback
3 | maya.app.os
4 | functools
5 | _bisect
6 | maya.types
7 | logging.os
8 | encodings.encodings
9 | maya.OpenMaya
10 | collections
11 | logging.thread
12 | _sre
13 | zipimport
14 | maya
15 | string
16 | SocketServer
17 | maya.sys
18 | maya.app.general.sys
19 | maya.app.general.threading
20 | maya.app.general.cPickle
21 | maya.app.general.types
22 | maya.app.general.CommandPort
23 | bisect
24 | signal
25 | threading
26 | cStringIO
27 | logging.threading
28 | maya._OpenMaya
29 | maya.weakref
30 | atexit
31 | maya.mel
32 | encodings
33 | logging.traceback
34 | abc
35 | maya.standalone
36 | re
37 | select
38 | logging.string
39 | UserDict
40 | new
41 | maya.app.general.StringIO
42 | maya.app.commands
43 | maya.cmds
44 | maya.app.startup.os
45 | maya.re
46 | swig_runtime_data3
47 | maya.traceback
48 | Queue
49 | codecs
50 | logging.sys
51 | maya.app.general.socket
52 | _functools
53 | logging
54 | socket
55 | thread
56 | StringIO
57 | traceback
58 | weakref
59 | itertools
60 | maya.app.general.SocketServer
61 | os
62 | maya.app.startup.atexit
63 | _collections
64 | maya.app.startup.basic
65 | maya.app.startup.maya
66 | maya.app.general.operator
67 | __builtin__
68 | maya.app.general.time
69 | maya.app.baseUI
70 | maya.app.general
71 | operator
72 | maya.app.sys
73 | _heapq
74 | maya.new
75 | posixpath
76 | errno
77 | _socket
78 | sre_constants
79 | logging.codecs
80 | os.path
81 | maya.mel.melutils
82 | _warnings
83 | maya.logging
84 | cPickle
85 | encodings.__builtin__
86 | _codecs
87 | maya.app.maya
88 | maya.app.general.select
89 | logging.atexit
90 | maya.app.startup
91 | maya.app.general.maya
92 | maya.app.startup.gui
93 | keyword
94 | logging.time
95 | posix
96 | encodings.aliases
97 | exceptions
98 | sre_parse
99 | copy_reg
100 | sre_compile
101 | logging.cStringIO
102 | maya.utils
103 | site
104 | __main__
105 | logging.types
106 | maya.app.general.Queue
107 | strop
108 | maya.maya
109 | maya.app
110 | encodings.codecs
111 | _abcoll
112 | genericpath
113 | stat
114 | _ssl
115 | warnings
116 | encodings.ascii
117 | time
118 | encodings.utf_8
119 | sys
120 | maya.os
121 | types
122 | _weakref
123 | maya.app.startup.sys
124 | maya.app.general.errno
125 | maya.app.general.os
126 | linecache
127 | maya.test
128 | maya.OpenMayaRender
129 | maya._OpenMayaRender
130 | PyQt4.QtGui
131 | PyQt4.QtCore
132 | PyQt4
133 | maya._OpenMayaUI
134 | maya.OpenMayaUI
135 | sip
136 | json
137 | model.exceptions
138 | model.collections
139 | ui
--------------------------------------------------------------------------------
/cadnano2/dummyqt/QtCore.py:
--------------------------------------------------------------------------------
1 | QObject = object
2 |
3 | class Qt(object):
4 | pass
5 |
6 | class pyqtSignal(object):
7 | def __init__(self, *args):
8 | """ We don't actually do anything with argtypes because
9 | the real Qt will perform checks in the Gui version of
10 | cadnano which should suffice. """
11 | self.signalEmitters = {}
12 | self.argtypes = args
13 | def __get__(self, emitter):
14 | try:
15 | return self.signalEmitters.get(emitter)
16 | except KeyError:
17 | self.signalEmitters[emitter] = pyqtBoundSignal()
18 | return emitter
19 |
20 | class pyqtBoundSignal(object):
21 | def __init__(self):
22 | self.targets = {}
23 | def connect(self, target):
24 | self.targets.add(target)
25 | def disconnect(self, target):
26 | self.targets.remove(target)
27 | def emit(self, *args):
28 | for t in self.targets:
29 | t(*args)
--------------------------------------------------------------------------------
/cadnano2/dummyqt/QtGui.py:
--------------------------------------------------------------------------------
1 | class QUndoCommand(object):
2 | children = []
3 | name = "untitled"
4 | def undo(self):
5 | for c in reversed(self.children):
6 | c.undo()
7 | def redo(self):
8 | for c in self.children:
9 | c.redo()
10 |
11 | class QUndoStack(object):
12 | undoCmds = []
13 | macroStack = [] # list of lists
14 | macroNameStack = []
15 | index = 0
16 | clean = True
17 | def isClean(self):
18 | return self.clean
19 | def setClean(self):
20 | self.clean = True
21 | def clean(self):
22 | self.clean = True
23 | self.undoCmds = []
24 | self.index = 0
25 | def beginMacro(self, macroName):
26 | self.macroStack.append([])
27 | self.macroNameStack.append(macroName)
28 | self.clean = False
29 | def push(self, cmd):
30 | if self.macroStack:
31 | self.macroStack[-1].append(cmd)
32 | else:
33 | self.undoCmds.append(cmd)
34 | self.index = len(self.undoCmds) - 1
35 | cmd.redo()
36 | self.clean = False
37 | def endMacro(self):
38 | l = len(self.macroStack)
39 | if l == 0:
40 | assert(False) # Can't end a macro that wasn't begun
41 | cmd = QUndoCommand()
42 | cmd.children = self.macroStack.pop()
43 | cmd.name = self.macroNameStack.pop()
44 | if l == 1:
45 | self.undoCmds.append(cmd)
46 | self.index = len(self.undoCmds) - 1
47 | else:
48 | self.macroStack[-1].append(cmd)
49 | self.clean = False
50 | def undo(self):
51 | assert(not self.macroStack) # Can't undo in the middle of a macro!
52 | if self.index > 0:
53 | cmd = self.undoCmds[self.index]
54 | self.index = self.index - 1
55 | cmd.undo()
56 | def redo(self):
57 | assert(not macroStack) # Can't redo in the middle of a macro
58 | if self.index < len(self.undoCmds) - 1:
59 | cmd = self.undoCmds[self.index + 1]
60 | self.index = self.index + 1
61 | cmd.redo()
62 |
63 | class QColor(object):
64 | r = 0
65 | g = 0
66 | b = 0
67 | a = 0
68 | def __init__(self, *args):
69 | if len(args) == 1:
70 | assert(type(args[0]) == str)
71 | hvals = re.findall('[0-9a-fA-F]{2}', args[0])
72 | hvals = [int(hv, 16) for hv in hvals]
73 | elif len(args) == 3:
74 | hvals = list(args)
75 | elif len(args) == 4:
76 | hvals = list(args)
77 | else:
78 | hvals = []
79 | while len(hvals) < 3:
80 | hvals.append(0)
81 | if len(hvals) < 4:
82 | hvals.append(255)
83 | for hv in hvals:
84 | assert(0 <= hv <= 255)
85 | r, g, b, a = hvals
86 |
87 | class QFont(object):
88 | dummy = True
89 | Bold = None
90 | def __init__(self, *args):
91 | pass
92 |
93 | class QFontMetricsF(object):
94 | def __init__(self, *args):
95 | pass
96 |
--------------------------------------------------------------------------------
/cadnano2/dummyqt/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/dummyqt/__init__.py
--------------------------------------------------------------------------------
/cadnano2/icons/add-bases.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
76 |
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-app-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-app-icon.ico
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-app-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-app-icon.png
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-app-icon_shelf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-app-icon_shelf.png
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-document-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-document-icon.ico
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-document-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-document-icon.png
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2-icon_doc-legacy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2-icon_doc-legacy.png
--------------------------------------------------------------------------------
/cadnano2/icons/cadnano2_installer-bkg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/cadnano2_installer-bkg.png
--------------------------------------------------------------------------------
/cadnano2/icons/data-export-staples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/data-export-staples.png
--------------------------------------------------------------------------------
/cadnano2/icons/data-new_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/data-new_32.png
--------------------------------------------------------------------------------
/cadnano2/icons/data-open_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/data-open_32.png
--------------------------------------------------------------------------------
/cadnano2/icons/data-save_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/data-save_32.png
--------------------------------------------------------------------------------
/cadnano2/icons/data-svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/data-svg.png
--------------------------------------------------------------------------------
/cadnano2/icons/export-staples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/export-staples.png
--------------------------------------------------------------------------------
/cadnano2/icons/export-staples.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-endpoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-endpoint.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-handle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-handle.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-part.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-part.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-scaf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-scaf.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-stap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-stap.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-strand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-strand.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-filter-xover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-filter-xover.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-new-honeycomb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-new-honeycomb.png
--------------------------------------------------------------------------------
/cadnano2/icons/part-new-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/part-new-square.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-addseq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-addseq.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-addseq.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/cadnano2/icons/path-autobreak.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-autobreak.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-break_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-break_48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-edit_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-edit_32.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-erase_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-erase_32.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-erase_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-erase_48x48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-force-xover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-force-xover.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-frame.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-insert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-insert.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-insert_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-insert_48x48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-loop.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-loop_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-loop_48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-modify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-modify.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-move.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-paint_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-paint_48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-pen_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-pen_48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-sequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-sequence.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-skip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-skip.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-skip_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-skip_48x48.png
--------------------------------------------------------------------------------
/cadnano2/icons/path-staple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/path-staple.png
--------------------------------------------------------------------------------
/cadnano2/icons/remove-bases.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
77 |
--------------------------------------------------------------------------------
/cadnano2/icons/slice-delete-last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-delete-last.png
--------------------------------------------------------------------------------
/cadnano2/icons/slice-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-edit.png
--------------------------------------------------------------------------------
/cadnano2/icons/slice-go-first.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-go-first.png
--------------------------------------------------------------------------------
/cadnano2/icons/slice-go-last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-go-last.png
--------------------------------------------------------------------------------
/cadnano2/icons/slice-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-move.png
--------------------------------------------------------------------------------
/cadnano2/icons/slice-renumber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/slice-renumber.png
--------------------------------------------------------------------------------
/cadnano2/icons/source/cadnano2-icon.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/cadnano2-icon.pdf
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-endpoint.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-endpoint.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-handle.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-handle.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-scaf.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-scaf.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-stap.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-stap.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-strand.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-strand.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-filter-xover.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-filter-xover.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-new-honeycomb.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-new-honeycomb.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/part-new-square.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/part-new-square.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-addseq.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-addseq.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-break.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-break.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-frame.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-frame.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-insert.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-insert.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-loop.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-loop.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-paint.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-paint.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-sequence.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-sequence.ai
--------------------------------------------------------------------------------
/cadnano2/icons/source/path-skip.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/icons/source/path-skip.ai
--------------------------------------------------------------------------------
/cadnano2/include/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/include/__init__.py
--------------------------------------------------------------------------------
/cadnano2/include/fetchfile.py:
--------------------------------------------------------------------------------
1 | from urllib.request import Request, urlopen
2 | from urllib.error import URLError, HTTPError
3 | import sys
4 | from os.path import basename, dirname, splitext, exists
5 | import os
6 | import shutil
7 | import tarfile
8 |
9 | def fetchFile(filename, baseurl, filemode='b', filetype='gz', filepath=None):
10 | """
11 |
12 | filepath - is optional file path location to store the fetched file
13 | """
14 | # create the url and the request
15 | url = baseurl + '/' + filename
16 | request = Request(url)
17 |
18 | # Open the url
19 | try:
20 | f_url = urlopen(request)
21 | print("downloading " + url)
22 |
23 | # Open our local file for writing
24 | f_dest = open(filename, "w" + filemode)
25 |
26 | # Write to our local file
27 | f_dest.write(f_url.read())
28 | f_dest.close()
29 |
30 | # handle errors
31 | except HTTPError as e:
32 | print("HTTP Error:", e.code , url)
33 | except URLError as e:
34 | print("URL Error:", e.reason , url)
35 |
36 | filename_out = filename
37 | # unzip if possible
38 | if filetype == 'gz':
39 |
40 | # get the extracted folder name
41 | filename_out = splitext(filename)[0]
42 | temp = splitext(filename_out)
43 | if temp[1] == '.tar':
44 | filename_out = temp[0]
45 |
46 | # open the archive
47 | try:
48 | f_zip= tarfile.open(filename, mode='r')
49 | except tarfile.ReadError as e:
50 | print("unable to read archive", e.code)
51 | print("extracting " + filename_out)
52 | try:
53 | if filepath:
54 | # remove existing folder
55 | if os.path.exists(filepath + '/' + filename_out):
56 | print("file exists")
57 | shutil.rmtree(filepath + '/' + filename_out)
58 | else:
59 | print("file does not exist", filename_out)
60 | f_zip.extractall(path=filepath)
61 | else:
62 | # remove existing folder
63 | if os.path.exists(filename_out):
64 | print("file exists")
65 | shutil.rmtree(filename_out)
66 | else:
67 | print("file does not exist", filename_out)
68 | f_zip.extractall()
69 | except tarfile.ExtractError as e:
70 | print("unable to extract archive", e.code)
71 | f_zip.close()
72 | # remove the archive
73 | print("removing the downloaded archive", filename)
74 | os.remove(filename)
75 | print("done")
76 | return filename_out
77 | # end def
78 |
79 | if __name__ == '__main__':
80 | argv = sys.argv
81 | url = argv[1]
82 | filename = basename(url)
83 | base_url = dirname(url)
84 | fetchFile(filename, base_url)
85 |
86 |
--------------------------------------------------------------------------------
/cadnano2/include/getdependencies.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | from .fetchfile import fetchFile
5 | import shutil
6 | from os.path import basename, dirname, splitext, exists, split, abspath
7 | import os
8 |
9 | # list of tuples of the url and the subdirectory to copy to the include directory
10 | urls = [('http://pypi.python.org/packages/source/n/networkx/networkx-1.6.tar.gz', 'networkx')
11 | ]
12 |
13 | # this is intended to be run in the include folder of cadnano2
14 | if __name__ == '__main__':
15 | for urlBlock in urls:
16 | url, subfolder_name = urlBlock
17 | filename = basename(url)
18 | base_url = dirname(url)
19 | folder = fetchFile(filename, base_url)
20 | this_dirname, this_filename = split(abspath(__file__))
21 | os.chdir(this_dirname)
22 | if subfolder_name:
23 | subfolder_path = folder + '/' + subfolder_name
24 | # remove existing folder
25 | if os.path.exists(subfolder_name):
26 | print("file exists")
27 | shutil.rmtree(subfolder_name)
28 | else:
29 | print("file does not exist", subfolder_name)
30 | shutil.move(subfolder_path, subfolder_name)
31 | shutil.rmtree(folder)
32 | # end for
33 |
--------------------------------------------------------------------------------
/cadnano2/main.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """
4 | main.py
5 |
6 | Created by Shawn Douglas on 2010-09-26.
7 | """
8 |
9 | import sys
10 | import os
11 | from importlib.metadata import version
12 | sys.path.insert(0, '.')
13 | from . import cadnano
14 |
15 | if "-t" in sys.argv:
16 | os.environ['CADNANO_IGNORE_ENV_VARS_EXCEPT_FOR_ME'] = 'YES'
17 |
18 | cadnano.initAppWithGui()
19 |
20 | welcome_message = """
21 | Thank you for using Cadnano2 ({})!
22 |
23 | We invite you to support the project by citing this reference:
24 |
25 | Rapid prototyping of 3D DNA-origami shapes with caDNAno
26 | Douglas et al. Nucleic Acids Res: 37(15):5001–6 (2009)
27 | https://doi.org/10.1093/nar/gkp436
28 |
29 | Report bugs at https://github.com/douglaslab/cadnano2 (include terminal output)
30 | Contact: shawn.douglas [at] ucsf.edu
31 | """
32 |
33 | version = version("cadnano2")
34 |
35 | def main(args=None):
36 | print(welcome_message.format(version))
37 | app = cadnano.app()
38 | if "-p" in sys.argv:
39 | print("Collecting profile data into cadnano.profile")
40 | import cProfile
41 | cProfile.run('app.exec_()', 'cadnano.profile')
42 | print("Done collecting profile data. Use -P to print it out.")
43 | exit()
44 | elif "-P" in sys.argv:
45 | from pstats import Stats
46 | s = Stats('cadnano.profile')
47 | print("Internal Time Top 10:")
48 | s.sort_stats('cumulative').print_stats(10)
49 | print("")
50 | print("Total Time Top 10:")
51 | s.sort_stats('time').print_stats(10)
52 | exit()
53 | elif "-t" in sys.argv:
54 | print("running tests")
55 | from tests.runall import main as runTests
56 | runTests(useXMLRunner=False)
57 | exit()
58 | app.exec_()
59 |
60 |
61 | if __name__ == '__main__':
62 | sys.exit(main() or 0)
--------------------------------------------------------------------------------
/cadnano2/model/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ["document", "enum", "decorators", "io", "oligo", "parts", "strand", "strands", "strandset", "virtualhelix"]
--------------------------------------------------------------------------------
/cadnano2/model/decorators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/model/decorators/__init__.py
--------------------------------------------------------------------------------
/cadnano2/model/decorators/decorator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | from operator import attrgetter
5 | import cadnano2.util as util
6 | from array import array
7 |
8 | # import Qt stuff into the module namespace with PySide, PyQt4 independence
9 | util.qtWrapImport('QtCore', globals(), ['QObject', 'Qt'])
10 | util.qtWrapImport('QtGui', globals(), ['QUndoStack', 'QUndoCommand'])
11 |
12 | class Decorator(object):
13 | """
14 | Decorators do not affect an applied sequence
15 | """
16 | def __init__(self, index):
17 | if self.__class__ == Decorator:
18 | e = "Decorator should be subclassed."
19 | raise NotImplementedError(e)
20 | self._index = idex
21 | self._dType = None
22 | self._privateSequence = None
23 | # end def
24 |
25 | def privateLength(self):
26 | """
27 | This is the length of a sequence that is immutable by the strand
28 | """
29 | return length(self._privateSequence)
30 |
31 | def decoratorType(self):
32 | return self._dtype
33 | # end class
--------------------------------------------------------------------------------
/cadnano2/model/decorators/insertion.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | class Insertion(object):
6 | """
7 | Insertions do affect an applied sequence and do not store a sequence
8 | themselves. They are a skip if the length is less than 0
9 | """
10 | def __init__(self, index, length):
11 | self._length = length
12 | self._index = index
13 | # end def
14 |
15 | def length(self):
16 | """
17 | This is the length of a sequence that is immutable by the strand
18 | """
19 | return self._length
20 |
21 | def setLength(self, length):
22 | self._length = length
23 | # end def
24 |
25 | def updateIdx(self, delta):
26 | self._index += delta
27 | # end def
28 |
29 | def idx(self):
30 | return self._index
31 | # end def
32 |
33 | def isSkip(self):
34 | return self.length() < 0
35 | # end class
--------------------------------------------------------------------------------
/cadnano2/model/decorators/modifier.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | class Modifier(object):
6 | """
7 | Modifiers do affect an applied sequence and do not store a sequence
8 | themselves. They cause a base changed to another sequence.
9 | Modifiers DO NOT affect the length of a strand
10 | """
11 | def __init__(self, idx):
12 | if self.__class__ == Modifier:
13 | e = "Modifier should be subclassed."
14 | raise NotImplementedError(e)
15 | self._mType = None
16 | self._lowIdx = idx
17 | self._highIdx = self._lowIdx
18 | self._privateSequence = None
19 | # end def
20 |
21 | def length(self):
22 | """
23 | This is the length of a sequence that is immutable by the strand
24 | """
25 | return self._highIdx - self._lowIdx + 1
26 |
27 | def modifierType(self):
28 | return self._mtype
29 | # end class
--------------------------------------------------------------------------------
/cadnano2/model/enum.py:
--------------------------------------------------------------------------------
1 |
2 | class LatticeType:
3 | Honeycomb = 0
4 | Square = 1
5 |
6 |
7 | class EndType:
8 | FivePrime = 0
9 | ThreePrime = 1
10 |
11 |
12 | class StrandType:
13 | Scaffold = 0
14 | Staple = 1
15 |
16 |
17 | class Parity:
18 | Even = 0
19 | Odd = 1
20 |
21 |
22 | class BreakType:
23 | Left5Prime = 0
24 | Left3Prime = 1
25 | Right5Prime = 2
26 | Right3Prime = 3
27 |
28 |
29 | class Crossovers:
30 | honeycombScafLeft = [[1, 11], [8, 18], [4, 15]]
31 | honeycombScafRight = [[2, 12], [9, 19], [5, 16]]
32 | honeycombStapLeft = [[6], [13], [20]]
33 | honeycombStapRight = [[7], [14], [0]]
34 | squareScafLeft = [[4, 26, 15], [18, 28, 7], [10, 20, 31], [2, 12, 23]]
35 | squareScafRight = [[5, 27, 16], [19, 29, 8], [11, 21, 0], [3, 13, 24]]
36 | squareStapLeft = [[31], [23], [15], [7]]
37 | squareStapRight = [[0], [24], [16], [8]]
38 |
39 |
40 | class HandleOrient:
41 | LeftUp = 0
42 | RightUp = 1
43 | LeftDown = 2
44 | RightDown = 3
45 |
--------------------------------------------------------------------------------
/cadnano2/model/io/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/model/io/__init__.py
--------------------------------------------------------------------------------
/cadnano2/model/io/decoder.py:
--------------------------------------------------------------------------------
1 | import json
2 | from .legacydecoder import import_legacy_dict
3 | from cadnano2.ui.dialogs.ui_latticetype import Ui_LatticeType
4 | import cadnano2.util as util
5 | import cadnano2.cadnano as cadnano
6 | if cadnano.app().isGui(): # headless:
7 | from cadnano2.ui.dialogs.ui_latticetype import Ui_LatticeType
8 | util.qtWrapImport('QtWidgets', globals(), ['QDialog', 'QDialogButtonBox'])
9 |
10 |
11 | def decode(document, string):
12 | if cadnano.app().isGui():
13 | # from ui.dialogs.ui_latticetype import Ui_LatticeType
14 | # util.qtWrapImport('QtGui', globals(), ['QDialog', 'QDialogButtonBox'])
15 | dialog = QDialog()
16 | dialogLT = Ui_LatticeType() # reusing this dialog, should rename
17 | dialogLT.setupUi(dialog)
18 |
19 | # try: # try to do it fast
20 | # try:
21 | # import cjson
22 | # packageObject = cjson.decode(string)
23 | # except: # fall back to if cjson not available or on decode error
24 | # packageObject = json.loads(string)
25 | # except ValueError:
26 | # dialogLT.label.setText("Error decoding JSON object.")
27 | # dialogLT.buttonBox.setStandardButtons(QDialogButtonBox.Ok)
28 | # dialog.exec()
29 | # return
30 | packageObject = json.loads(string)
31 |
32 | if packageObject.get('.format', None) != 'caDNAno2':
33 | import_legacy_dict(document, packageObject)
--------------------------------------------------------------------------------
/cadnano2/model/io/encoder.py:
--------------------------------------------------------------------------------
1 | from json import dumps
2 | from .legacyencoder import legacy_dict_from_doc
3 |
4 |
5 | def encode(document, helixOrderList, io):
6 | obj = legacy_dict_from_doc(document, io.name, helixOrderList)
7 | json_string = dumps(obj, separators=(',',':')) # compact encoding
8 | io.write(json_string)
9 |
--------------------------------------------------------------------------------
/cadnano2/model/io/legacyencoder.py:
--------------------------------------------------------------------------------
1 | from os.path import basename
2 | from cadnano2.model.enum import StrandType
3 |
4 |
5 | def legacy_dict_from_doc(document, fname, helixOrderList):
6 | part = document.selectedPart()
7 | numBases = part.maxBaseIdx()+1
8 |
9 | # iterate through virtualhelix list
10 | vhList = []
11 | for row, col in helixOrderList:
12 | vh = part.virtualHelixAtCoord((row, col))
13 | # insertions and skips
14 | insertionDict = part.insertions()[(row, col)]
15 | insts = [0 for i in range(numBases)]
16 | skips = [0 for i in range(numBases)]
17 | for idx, insertion in insertionDict.items():
18 | if insertion.isSkip():
19 | skips[idx] = insertion.length()
20 | else:
21 | insts[idx] = insertion.length()
22 | # colors
23 | stapColors = []
24 | for strand in vh.stapleStrandSet():
25 | if strand.connection5p() == None:
26 | c = str(strand.oligo().color())[1:] # drop the hash
27 | stapColors.append([strand.idx5Prime(), int(c, 16)])
28 | scafColors = set()
29 | for strand in vh.scaffoldStrandSet():
30 | if strand.connection5p() == None or \
31 | (strand == strand.oligo().strand5p() and strand.oligo().isLoop()):
32 | c = str(strand.oligo().color())[1:] # drop the hash
33 | scafColors.add((strand.idx5Prime(), int(c, 16)))
34 |
35 | vhDict = {"row": row,
36 | "col": col,
37 | "num": vh.number(),
38 | "scaf": vh.getLegacyStrandSetArray(StrandType.Scaffold),
39 | "stap": vh.getLegacyStrandSetArray(StrandType.Staple),
40 | "loop": insts,
41 | "skip": skips,
42 | "scafLoop": [],
43 | "stapLoop": [],
44 | "stap_colors": stapColors,
45 | "scaf_colors": list(scafColors)}
46 | vhList.append(vhDict)
47 | bname = basename(str(fname))
48 | obj = {"name": bname, "vstrands": vhList}
49 | return obj
50 |
--------------------------------------------------------------------------------
/cadnano2/model/parts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/model/parts/__init__.py
--------------------------------------------------------------------------------
/cadnano2/model/parts/honeycombpart.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | from cadnano2.cadnano import app
5 | from .part import Part
6 | from cadnano2.model.enum import LatticeType
7 |
8 |
9 | class Crossovers:
10 | honeycombScafLow = [[1, 11], [8, 18], [4, 15]]
11 | honeycombScafHigh = [[2, 12], [9, 19], [5, 16]]
12 | honeycombStapLow = [[6], [13], [20]]
13 | honeycombStapHigh = [[7], [14], [0]]
14 |
15 |
16 | root3 = 1.732051
17 |
18 |
19 | class HoneycombPart(Part):
20 | _step = 21 # 32 in square
21 | _turnsPerStep = 2.0
22 | _helicalPitch = _step/_turnsPerStep
23 | _twistPerBase = 360/_helicalPitch # degrees
24 | _twistOffset = 0 # degrees
25 |
26 | _activeBaseIndex = _step
27 | _subStepSize = _step / 3
28 | # Used in VirtualHelix::potentialCrossoverList
29 | _scafL = Crossovers.honeycombScafLow
30 | _scafH = Crossovers.honeycombScafHigh
31 | _stapL = Crossovers.honeycombStapLow
32 | _stapH = Crossovers.honeycombStapHigh
33 |
34 | def __init__(self, *args, **kwargs):
35 | super(HoneycombPart, self).__init__(self, *args, **kwargs)
36 | self._maxRow = kwargs.get('maxRow', app().prefs.honeycombRows)
37 | self._maxCol = kwargs.get('maxCol', app().prefs.honeycombCols)
38 | self._maxBase = int(kwargs.get('maxSteps', app().prefs.honeycombSteps) * self._step - 1)
39 |
40 | def crossSectionType(self):
41 | """Returns the cross-section type of the DNA part."""
42 | return LatticeType.Honeycomb
43 |
44 | def isEvenParity(self, row, column):
45 | return (row % 2) == (column % 2)
46 | # end def
47 |
48 | def isOddParity(self, row, column):
49 | return (row % 2) ^ (column % 2)
50 | # end def
51 |
52 | def getVirtualHelixNeighbors(self, virtualHelix):
53 | """
54 | returns the list of neighboring virtualHelices based on parity of an
55 | input virtualHelix
56 |
57 | If a potential neighbor doesn't exist, None is returned in it's place
58 | """
59 | neighbors = []
60 | vh = virtualHelix
61 | if vh == None:
62 | return neighbors
63 |
64 | # assign the method to a a local variable
65 | getVH = self.virtualHelixAtCoord
66 | # get the vh's row and column r,c
67 | (r, c) = vh.coord()
68 |
69 | if self.isEvenParity(r, c):
70 | neighbors.append(getVH((r,c+1))) # p0 neighbor (p0 is a direction)
71 | neighbors.append(getVH((r-1,c))) # p1 neighbor
72 | neighbors.append(getVH((r,c-1))) # p2 neighbor
73 | else:
74 | neighbors.append(getVH((r,c-1))) # p0 neighbor (p0 is a direction)
75 | neighbors.append(getVH((r+1,c))) # p1 neighbor
76 | neighbors.append(getVH((r,c+1))) # p2 neighbor
77 | # For indices of available directions, use range(0, len(neighbors))
78 | return neighbors # Note: the order and presence of Nones is important
79 | # end def
80 |
81 | def latticeCoordToPositionXY(self, row, column, scaleFactor=1.0):
82 | """make sure self._radius is a float"""
83 | radius = self._radius
84 | x = column*radius*root3
85 | if self.isOddParity(row, column): # odd parity
86 | y = row*radius*3 + radius
87 | else: # even parity
88 | y = row*radius*3
89 | return scaleFactor*x, scaleFactor*y
90 | # end def
91 |
92 | def positionToCoord(self, x, y, scaleFactor=1.0):
93 | radius = self._radius
94 | column = int(x/(radius*root3*scaleFactor) + 0.5)
95 |
96 | rowTemp = y/(radius*scaleFactor)
97 | if (rowTemp % 3) + 0.5 > 1.0:
98 | # odd parity
99 | row = int((rowTemp-1)/3 + 0.5)
100 | else:
101 | # even parity
102 | row = int(rowTemp/3 + 0.5)
103 | # end def
104 |
105 | ########################## Archiving / Unarchiving #########################
106 | def fillSimpleRep(self, sr):
107 | super(HoneycombPart, self).fillSimpleRep(sr)
108 | sr['.class'] = 'HoneycombPart'
109 |
--------------------------------------------------------------------------------
/cadnano2/model/parts/squarepart.py:
--------------------------------------------------------------------------------
1 | from cadnano2.cadnano import app
2 | from cadnano2.model.enum import LatticeType
3 | from .part import Part
4 |
5 |
6 | class Crossovers:
7 | squareScafLow = [[4, 26, 15], [18, 28, 7], [10, 20, 31], [2, 12, 23]]
8 | squareScafHigh = [[5, 27, 16], [19, 29, 8], [11, 21, 0], [3, 13, 24]]
9 | squareStapLow = [[31], [23], [15], [7]]
10 | squareStapHigh = [[0], [24], [16], [8]]
11 |
12 |
13 | class SquarePart(Part):
14 | _step = 32 # 21 in honeycomb
15 | _subStepSize = _step / 4
16 | _turnsPerStep = 3.0
17 | _helicalPitch = _step/_turnsPerStep
18 | _twistPerBase = 360/_helicalPitch # degrees
19 | _twistOffset = 180 + _twistPerBase/2 # degrees
20 |
21 | # Used in VirtualHelix::potentialCrossoverList
22 | _scafL = Crossovers.squareScafLow
23 | _scafH = Crossovers.squareScafHigh
24 | _stapL = Crossovers.squareStapLow
25 | _stapH = Crossovers.squareStapHigh
26 |
27 | def __init__(self, *args, **kwargs):
28 | super(SquarePart, self).__init__(self, *args, **kwargs)
29 | self._maxRow = kwargs.get('maxRow', app().prefs.squareRows)
30 | self._maxCol = kwargs.get('maxCol', app().prefs.squareCols)
31 | self._maxBase = int(kwargs.get('maxSteps', app().prefs.squareSteps) * self._step - 1)
32 |
33 | def crossSectionType(self):
34 | return LatticeType.Square
35 | # end def
36 |
37 | def isEvenParity(self, row, column):
38 | return (row % 2) == (column % 2)
39 | # end def
40 |
41 | def isOddParity(self, row, column):
42 | return (row % 2) ^ (column % 2)
43 | # end def
44 |
45 | def getVirtualHelixNeighbors(self, virtualHelix):
46 | """
47 | returns the list of neighboring virtualHelices based on parity of an
48 | input virtualHelix
49 |
50 | If a potential neighbor doesn't exist, None is returned in it's place
51 | """
52 | neighbors = []
53 | vh = virtualHelix
54 | if vh == None:
55 | return neighbors
56 |
57 | # assign the method to a a local variable
58 | getVH = self.virtualHelixAtCoord
59 | # get the vh's row and column r,c
60 | (r, c) = vh.coord()
61 |
62 | if self.isEvenParity(r, c):
63 | neighbors.append(getVH((r,c+1))) # p0 neighbor (p0 is a direction)
64 | neighbors.append(getVH((r+1,c))) # p1 neighbor
65 | neighbors.append(getVH((r,c-1))) # p2 neighbor
66 | neighbors.append(getVH((r-1,c))) # p2 neighbor
67 | else:
68 | neighbors.append(getVH((r,c-1))) # p0 neighbor (p0 is a direction)
69 | neighbors.append(getVH((r-1,c))) # p1 neighbor
70 | neighbors.append(getVH((r,c+1))) # p2 neighbor
71 | neighbors.append(getVH((r+1,c))) # p3 neighbor
72 | # For indices of available directions, use range(0, len(neighbors))
73 | return neighbors # Note: the order and presence of Nones is important
74 | # end def
75 |
76 | def latticeCoordToPositionXY(self, row, column, scaleFactor=1.0):
77 | """
78 | make sure self._radius is a float
79 | """
80 | radius = self._radius
81 | y = row*2*radius
82 | x = column*2*radius
83 | return scaleFactor*x, scaleFactor*y
84 | # end def
85 |
86 | def positionToCoord(self, x, y, scaleFactor=1.0):
87 | """
88 | """
89 | radius = self._radius
90 | row = int(y/(2*radius*scaleFactor) + 0.5)
91 | column = int(x/(2*radius*scaleFactor) + 0.5)
92 | return row, column
93 | # end def
94 |
95 | def fillSimpleRep(self, sr):
96 | super(SquarePart, self).fillSimpleRep(sr)
97 | sr['.class'] = 'SquarePart'
98 |
--------------------------------------------------------------------------------
/cadnano2/osx/CNApplicationDelegate.py:
--------------------------------------------------------------------------------
1 | """
2 | This file houses the code that allows the opening of cadnano files by dragging
3 | to the icon in the dock or double clicking on the icon.
4 | """
5 |
6 | import objc, os
7 | from Foundation import *
8 | from AppKit import *
9 | from controllers.documentcontroller import DocumentController
10 | from cadnano2.model.io.decoder import decode
11 | from cadnano2.cadnano import app as sharedCadnanoObj
12 |
13 |
14 | class CNApplicationDelegate(NSObject):
15 | def application_openFile_(self, app, f):
16 | if f == "main.py": # ignore
17 | return
18 | extension = os.path.splitext(f)[1].lower()
19 | if extension not in ('.nno', '.json', '.cadnano'):
20 | print("Could not open file %s (bad extension %s)"%(f, extension))
21 | return
22 | dc = list(sharedCadnanoObj().documentControllers)[0]
23 | decode(dc.document(), file(str(f)).read())
24 | return None
25 |
26 | def application_openFiles_(self, app, fs):
27 | if fs.isKindOfClass_(NSCFString):
28 | self.application_openFile_(app, fs)
29 | return
30 | for f in fs:
31 | self.application_openFiles_(app, f)
32 |
33 | def applicationShouldTerminate_(self, app):
34 | for dc in sharedCadnanoObj().documentControllers:
35 | if not dc.maybeSave():
36 | return NSTerminateCancel
37 | return NSTerminateNow
38 |
39 | sharedDelegate = CNApplicationDelegate.alloc().init()
40 | NSApplication.sharedApplication().setDelegate_(sharedDelegate)
41 |
--------------------------------------------------------------------------------
/cadnano2/osx/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/osx/__init__.py
--------------------------------------------------------------------------------
/cadnano2/plugins/autobreak/Makefile:
--------------------------------------------------------------------------------
1 | $(eval PYUIC_VERSION = -v $(shell pyuic5 -version 2> /dev/null):/output)
2 |
3 | all: autobreakconfig_ui.py
4 |
5 | autobreakconfig_ui.py : autobreakconfig.ui
6 | ifdef PYUIC_VERSION
7 | pyuic5 $< > $@
8 | else
9 | @echo "ERROR: pyuic5 not found"
10 | endif
--------------------------------------------------------------------------------
/cadnano2/plugins/autobreak/__init__.py:
--------------------------------------------------------------------------------
1 | from .autobreakconfig import AutobreakConfig
2 | import cadnano, util
3 | util.qtWrapImport('QtGui', globals(), ['QAction', 'QIcon', 'QPixmap'])
4 |
5 |
6 | class AutobreakHandler(object):
7 | def __init__(self, document, window):
8 | self.doc, self.win = document, window
9 | icon10 = QIcon()
10 | icon10.addPixmap(QPixmap(":/pathtools/autobreak"), QIcon.Mode.Normal, QIcon.State.Off)
11 | self.actionAutoBreak = QAction(window)
12 | self.actionAutoBreak.setIcon(icon10)
13 | self.actionAutoBreak.setText('AutoBreak')
14 | self.actionAutoBreak.setToolTip("Click this button to generate a default set of staples.")
15 | self.actionAutoBreak.setObjectName("actionAutoBreak")
16 | self.actionAutoBreak.triggered.connect(self.actionAutobreakSlot)
17 | self.win.menuPlugins.addAction(self.actionAutoBreak)
18 | # add to main tool bar
19 | self.win.topToolBar.insertAction(self.win.actionFiltersLabel, self.actionAutoBreak)
20 | self.win.topToolBar.insertSeparator(self.win.actionFiltersLabel)
21 | self.configDialog = None
22 |
23 | def actionAutobreakSlot(self):
24 | """Only show the dialog if staple strands exist."""
25 | part = self.doc.controller().activePart()
26 | if part != None: # is there a part?
27 | for o in list(part.oligos()):
28 | if o.isStaple(): # is there a staple oligo?
29 | if self.configDialog == None:
30 | self.configDialog = AutobreakConfig(self.win, self)
31 | self.configDialog.show()
32 | return
33 |
34 |
35 | def documentWindowWasCreatedSlot(doc, win):
36 | doc.autobreakHandler = AutobreakHandler(doc, win)
37 |
38 | # Initialization
39 | for c in cadnano.app().documentControllers:
40 | doc, win = c.document(), c.window()
41 | doc.autobreakHandler = AutobreakHandler(doc, win)
42 | cadnano.app().documentWindowWasCreatedSignal.connect(documentWindowWasCreatedSlot)
43 |
--------------------------------------------------------------------------------
/cadnano2/plugins/autobreak/autobreakconfig.py:
--------------------------------------------------------------------------------
1 | """
2 | config
3 | Created by Jonathan deWerd on 2012-01-19.
4 | """
5 | import cadnano2.util as util
6 | import cadnano2.cadnano as cadnano
7 | from . import autobreakconfig_ui
8 | from . import autobreak
9 | util.qtWrapImport('QtGui', globals(), ['QKeySequence'])
10 | util.qtWrapImport('QtCore', globals(), ['Qt'])
11 | util.qtWrapImport('QtWidgets', globals(), ['QDialog', 'QDialogButtonBox'])
12 |
13 |
14 | class AutobreakConfig(QDialog, autobreakconfig_ui.Ui_Dialog):
15 | def __init__(self, parent, handler):
16 | QDialog.__init__(self, parent, Qt.WindowType.Sheet)
17 | self.setupUi(self)
18 | self.handler = handler
19 | fb = self.buttonBox.button(QDialogButtonBox.Cancel)
20 | fb.setShortcut(QKeySequence(Qt.CTRL | Qt.Key.Key_R ))
21 |
22 | def keyPressEvent(self, e):
23 | return QDialog.keyPressEvent(self, e)
24 |
25 | def closeDialog(self):
26 | self.close()
27 |
28 | def accept(self):
29 | part = self.handler.doc.controller().activePart()
30 | if part != None:
31 | settings = {\
32 | 'stapleScorer' : autobreak.tgtLengthStapleScorer,\
33 | 'minStapleLegLen' : self.minLegLengthSpinBox.value(),\
34 | 'minStapleLen' : self.minLengthSpinBox.value(),\
35 | 'maxStapleLen' : self.maxLengthSpinBox.value(),\
36 | }
37 | self.handler.win.pathGraphicsView.setViewportUpdateOn(False)
38 | # print "pre verify"
39 | # part.verifyOligos()
40 | # print "breakStaples"
41 | autobreak.breakStaples(part, settings)
42 | # print "post break verify"
43 | # part.verifyOligos()
44 | self.handler.win.pathGraphicsView.setViewportUpdateOn(True)
45 | self.close()
46 |
--------------------------------------------------------------------------------
/cadnano2/plugins/test.py:
--------------------------------------------------------------------------------
1 | import cadnano
2 | print("Plugin loaded, has access to cadnano: %s"%cadnano)
3 |
--------------------------------------------------------------------------------
/cadnano2/tests/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['cadnanoguitestcase']
2 |
--------------------------------------------------------------------------------
/cadnano2/tests/cadnanoguitestcase.py:
--------------------------------------------------------------------------------
1 | # from PyQt4.QtCore import *
2 | # from PyQt4.QtGui import *
3 | import cadnano
4 | import tests.guitestcase
5 |
6 | main = tests.guitestcase.main
7 |
8 |
9 | class CadnanoGuiTestCase(tests.guitestcase.GUITestCase):
10 | """
11 | SEE: http://docs.python.org/library/unittest.html
12 | """
13 | def setUp(self):
14 | """
15 | The setUp method is called before running any test. It is used
16 | to set the general conditions for the tests to run correctly.
17 | For GUI Tests, you always have to call setWidget to tell the
18 | framework what you will be testing.
19 | """
20 | import sys
21 |
22 | self.app = cadnano.initAppWithGui() # kick off a Gui style app
23 | self.documentController = list(self.app.documentControllers)[0]
24 | self.mainWindow = self.documentController.win
25 |
26 | # Include this or the automatic build will hang
27 | self.app.dontAskAndJustDiscardUnsavedChanges = True
28 |
29 | # By setting the widget to the main window we can traverse and
30 | # interact with any part of it. Also, tearDown will close
31 | # the application so we don't need to worry about that.
32 | self.setWidget(self.mainWindow, False, None)
33 |
34 | def tearDown(self):
35 | """
36 | The tearDown method is called at the end of running each test,
37 | generally used to clean up any objects created in setUp
38 | """
39 | tests.guitestcase.GUITestCase.tearDown(self)
40 |
41 | if __name__ == '__main__':
42 | tests.guitestcase.main()
43 |
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/tests/functionaltestinputs/__init__.py
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/gap_vs_skip.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
2 | 0[22],0[11],ACCGTC?TATCA,12,#f74308
3 | 2[22],2[11],ACCGTCTATCA,11,#03b6a2
4 |
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/gap_vs_skip.json:
--------------------------------------------------------------------------------
1 | {"name":"Wed Oct 19 2011 15:03:02 GMT-0400","vstrands":[{"stap":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[0,12,-1,-1],[0,13,0,11],[0,14,0,12],[0,15,0,13],[0,16,0,14],[0,17,0,15],[0,18,0,16],[0,19,0,17],[0,20,0,18],[0,21,0,19],[0,22,0,20],[-1,-1,0,21],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scaf":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,0,12],[0,11,0,13],[0,12,0,14],[0,13,0,15],[0,14,0,17],[-1,-1,-1,-1],[0,15,0,18],[0,17,0,19],[0,18,0,20],[0,19,0,21],[0,20,0,22],[0,21,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"row":3,"loop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"num":0,"col":15,"stap_colors":[[22,16204552]]},{"stap":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[2,12,-1,-1],[2,13,2,11],[2,14,2,12],[2,15,2,13],[2,16,2,14],[2,17,2,15],[2,18,2,16],[2,19,2,17],[2,20,2,18],[2,21,2,19],[2,22,2,20],[-1,-1,2,21],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scaf":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,2,12],[2,11,2,13],[2,12,2,14],[2,13,2,15],[2,14,2,16],[2,15,2,17],[2,16,2,18],[2,17,2,19],[2,18,2,20],[2,19,2,21],[2,20,2,22],[2,21,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"row":3,"loop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"num":2,"col":17,"stap_colors":[[22,243362]]}]}
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/loop_size_1.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
0[20],0[14],GTCTATCA,8,#cc0000
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/loop_size_1.json:
--------------------------------------------------------------------------------
1 | {"vstrands":[{"stap":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[0,15,-1,-1],[0,16,0,14],[0,17,0,15],[0,18,0,16],[0,19,0,17],[0,20,0,18],[-1,-1,0,19],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scaf":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,0,15],[0,14,0,16],[0,15,0,17],[0,16,0,18],[0,17,0,19],[0,18,0,20],[0,19,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"row":11,"loop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"num":0,"stap_colors":[[20,13369344]],"col":15}],"name":"Thu Jul 14 2011 16:17:14 GMT-0400"}
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/loops_and_skips.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
0[41],0[0],ATTAAAGAACGTGGACTCCAACGTCAAAGGGCGAAAAACCGTCTATCA,48,#cc0000
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/loops_and_skips.json:
--------------------------------------------------------------------------------
1 | {"vstrands":[{"stap":[[0,1,-1,-1],[0,2,0,0],[0,3,0,1],[0,4,0,2],[0,5,0,3],[0,6,0,4],[0,7,0,5],[0,8,0,6],[0,9,0,7],[0,10,0,8],[0,11,0,9],[0,12,0,10],[0,13,0,11],[0,14,0,12],[0,15,0,13],[0,16,0,14],[0,17,0,15],[0,18,0,16],[0,19,0,17],[0,20,0,18],[0,21,0,19],[0,22,0,20],[0,23,0,21],[0,24,0,22],[0,25,0,23],[0,26,0,24],[0,27,0,25],[0,28,0,26],[0,29,0,27],[0,30,0,28],[0,31,0,29],[0,32,0,30],[0,33,0,31],[0,34,0,32],[0,35,0,33],[0,36,0,34],[0,37,0,35],[0,38,0,36],[0,39,0,37],[0,40,0,38],[0,41,0,39],[-1,-1,0,40]],"scaf":[[-1,-1,0,1],[0,0,0,2],[0,1,0,3],[0,2,0,4],[0,3,0,5],[0,4,0,6],[0,5,0,7],[0,6,0,8],[0,7,0,9],[0,8,0,10],[0,9,0,11],[0,10,0,12],[0,11,0,13],[0,12,0,14],[0,13,0,15],[0,14,0,16],[0,15,0,17],[0,16,0,18],[0,17,0,19],[0,18,0,20],[0,19,0,21],[0,20,0,22],[0,21,0,23],[0,22,0,24],[0,23,0,25],[0,24,0,26],[0,25,0,27],[0,26,0,28],[0,27,0,29],[0,28,0,30],[0,29,0,31],[0,30,0,32],[0,31,0,33],[0,32,0,34],[0,33,0,35],[0,34,0,36],[0,35,0,37],[0,36,0,38],[0,37,0,39],[0,38,0,40],[0,39,0,41],[0,40,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,-1,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,-1,0,0,0,0,-1,0,0,0,0,-1,0,0,-1,0,0,0,0,-1,0,0,-1,0,0,0],"row":12,"loop":[0,0,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,3,0,0,0,0,0,0,4,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0],"num":0,"stap_colors":[[41,13369344]],"col":16}],"name":"Thu Jul 14 2011 16:11:51 GMT-0400"}
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/simple42.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
2 | 0[41],0[0],GAACGTGGACTCCAACGTCAAAGGGCGAAAAACCGTCTATCA,42,#cc0000
3 |
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/simple42legacy.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
0[41],0[0],GAACGTGGACTCCAACGTCAAAGGGCGAAAAACCGTCTATCA,42,#cc0000
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/simple42legacy.json:
--------------------------------------------------------------------------------
1 | {"name":"Thu Jul 14 2011 11:29:39 GMT-0400","vstrands":[{"stap":[[0,1,-1,-1],[0,2,0,0],[0,3,0,1],[0,4,0,2],[0,5,0,3],[0,6,0,4],[0,7,0,5],[0,8,0,6],[0,9,0,7],[0,10,0,8],[0,11,0,9],[0,12,0,10],[0,13,0,11],[0,14,0,12],[0,15,0,13],[0,16,0,14],[0,17,0,15],[0,18,0,16],[0,19,0,17],[0,20,0,18],[0,21,0,19],[0,22,0,20],[0,23,0,21],[0,24,0,22],[0,25,0,23],[0,26,0,24],[0,27,0,25],[0,28,0,26],[0,29,0,27],[0,30,0,28],[0,31,0,29],[0,32,0,30],[0,33,0,31],[0,34,0,32],[0,35,0,33],[0,36,0,34],[0,37,0,35],[0,38,0,36],[0,39,0,37],[0,40,0,38],[0,41,0,39],[-1,-1,0,40]],"scaf":[[-1,-1,0,1],[0,0,0,2],[0,1,0,3],[0,2,0,4],[0,3,0,5],[0,4,0,6],[0,5,0,7],[0,6,0,8],[0,7,0,9],[0,8,0,10],[0,9,0,11],[0,10,0,12],[0,11,0,13],[0,12,0,14],[0,13,0,15],[0,14,0,16],[0,15,0,17],[0,16,0,18],[0,17,0,19],[0,18,0,20],[0,19,0,21],[0,20,0,22],[0,21,0,23],[0,22,0,24],[0,23,0,25],[0,24,0,26],[0,25,0,27],[0,26,0,28],[0,27,0,29],[0,28,0,30],[0,29,0,31],[0,30,0,32],[0,31,0,33],[0,32,0,34],[0,33,0,35],[0,34,0,36],[0,35,0,37],[0,36,0,38],[0,37,0,39],[0,38,0,40],[0,39,0,41],[0,40,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"row":12,"stap_colors":[[41,13369344]],"loop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"num":0,"col":16}]}
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/skip.csv:
--------------------------------------------------------------------------------
1 | Start,End,Sequence,Length,Color
0[20],0[14],CTATCA,6,#cc0000
--------------------------------------------------------------------------------
/cadnano2/tests/functionaltestinputs/skip.json:
--------------------------------------------------------------------------------
1 | {"vstrands":[{"stap":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[0,15,-1,-1],[0,16,0,14],[0,17,0,15],[0,18,0,16],[0,19,0,17],[0,20,0,18],[-1,-1,0,19],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scaf":[[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,0,15],[0,14,0,16],[0,15,0,17],[0,16,0,18],[0,17,0,19],[0,18,0,20],[0,19,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]],"scafLoop":[],"stapLoop":[],"skip":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"row":11,"loop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"num":0,"stap_colors":[[20,13369344]],"col":15}],"name":"Thu Jul 14 2011 16:42:54 GMT-0400"}
--------------------------------------------------------------------------------
/cadnano2/tests/modeltests.py:
--------------------------------------------------------------------------------
1 | """
2 | modeltests.py
3 |
4 | Created by Shawn Douglas on 2011-06-28.
5 |
6 | Instructions: copypaste the following script into TextMate's
7 | Bundles > Bundle Editor > Show Bundle Editor > Python > Run Project Unit Tests
8 |
9 | cd "$TM_PROJECT_DIRECTORY"
10 | find . -name "*tests.py" -exec "${TM_PYTHON:-python}" '{}' \;|pre
11 |
12 | """
13 |
14 | import sys
15 | sys.path.insert(0, '.')
16 |
17 | import tests.cadnanoguitestcase
18 | from tests.cadnanoguitestcase import CadnanoGuiTestCase
19 | import time
20 | from cadnano2.model.virtualhelix import VirtualHelix
21 | from cadnano2.model.enum import StrandType
22 |
23 |
24 | class ModelTests(CadnanoGuiTestCase):
25 | """
26 | Create new tests by adding methods to this class that begin with "test".
27 | See for more detail: http://docs.python.org/library/unittest.html
28 |
29 | Run model tests by calling "python -m tests.modeltests" from cadnano2 root
30 | directory.
31 | """
32 | def setUp(self):
33 | """
34 | The setUp method is called before running any test. It is used
35 | to set the general conditions for the tests to run correctly.
36 | """
37 | CadnanoGuiTestCase.setUp(self)
38 | # Add extra model-test-specific initialization here
39 |
40 | def tearDown(self):
41 | """
42 | The tearDown method is called at the end of running each test,
43 | generally used to clean up any objects created in setUp
44 | """
45 | CadnanoGuiTestCase.tearDown(self)
46 | # Add model-test-specific cleanup here
47 |
48 | def testModel1(self):
49 | """docstring for testModel1"""
50 | pass
51 |
52 |
53 | if __name__ == '__main__':
54 | print("Running Model Tests")
55 | tests.cadnanoguitestcase.main()
56 |
--------------------------------------------------------------------------------
/cadnano2/tests/runall.py:
--------------------------------------------------------------------------------
1 | """
2 | runtests.py
3 | Helper file to run tests with 1 command and output the results to an XML file.
4 | Usage: From the main cadnano folder: python -m tests.runtests
5 | Created by Flo Mazzoldi on 2011-06-15.
6 |
7 | My TextMate Script:
8 |
9 | cd "$TM_PROJECT_DIRECTORY"
10 | CADNANO_RUN_PLAINTEXT_TESTS=YES CADNANO_IGNORE_ENV_VARS_EXCEPT_FOR_ME=YES python tests/runall.py | pre
11 | """
12 |
13 | import glob
14 | import os
15 | import unittest
16 | from .xmlrunner import XMLTestRunner
17 | # from unittests import UnitTests
18 | # from modeltests import ModelTests
19 | from .functionaltests import FunctionalTests
20 | # from recordedtests.template import RecordedTests
21 |
22 | def main(useXMLRunner=True):
23 | # load hard-coded tests
24 | # unitsuite = unittest.makeSuite(UnitTests)
25 | # modelsuite = unittest.makeSuite(ModelTests)
26 | funsuite = unittest.makeSuite(FunctionalTests)
27 |
28 | # combine and run tests
29 | # alltests = unittest.TestSuite([unitsuite, modelsuite, funsuite])
30 | alltests = unittest.TestSuite([funsuite])
31 | if useXMLRunner:
32 | stream = file("testresults.xml", "w")
33 | runner = XMLTestRunner(stream)
34 | result = runner.run(alltests)
35 | stream.close()
36 | else:
37 | runner = unittest.TextTestRunner(verbosity=2)
38 | result = runner.run(alltests)
39 | return result
40 |
41 |
42 | if __name__ == "__main__":
43 | textRunner = os.environ.get('CADNANO_RUN_PLAINTEXT_TESTS', None) == "YES"
44 | main(not textRunner)
45 |
--------------------------------------------------------------------------------
/cadnano2/tests/unittests.py:
--------------------------------------------------------------------------------
1 | """
2 | unittests.py
3 |
4 | Created by Shawn Douglas on 2011-06-28.
5 | """
6 |
7 | import sys, os
8 | sys.path.insert(0, '.')
9 |
10 | import time, code
11 | from PyQt4.QtCore import *
12 | from PyQt4.QtGui import *
13 | import tests.cadnanoguitestcase
14 | from tests.cadnanoguitestcase import CadnanoGuiTestCase
15 | from cadnano2.model.enum import StrandType
16 | from cadnano2.model.virtualhelix import VirtualHelix
17 | import unittest
18 | from rangeset import RangeSet, rangeIntersection
19 | import random
20 | seed = random.Random().randint(0,1<<32)
21 | enviroseed = os.environ.get('UNITTESTS_PRNG_SEED', False)
22 | if enviroseed != False:
23 | seed = int(enviroseed)
24 | del enviroseed
25 | print("Seeding tests.unittests; use setenv UNITTESTS_PRNG_SEED=%i to replay."%seed)
26 |
27 |
28 | class UnitTests(CadnanoGuiTestCase):
29 | """
30 | Unit tests should test individual modules, and do not necessarily need
31 | to simulate user interaction.
32 |
33 | Create new tests by adding methods to this class that begin with "test".
34 | See for more detail: http://docs.python.org/library/unittest.html
35 |
36 | Run unit tests by calling "python -m test.unittests" from cadnano2 root
37 | directory.
38 | """
39 | def setUp(self):
40 | """
41 | The setUp method is called before running any test. It is used
42 | to set the general conditions for the tests to run correctly.
43 | """
44 | CadnanoGuiTestCase.setUp(self)
45 | self.prng = random.Random(seed)
46 | # Add extra unit-test-specific initialization here
47 |
48 | def tearDown(self):
49 | """
50 | The tearDown method is called at the end of running each test,
51 | generally used to clean up any objects created in setUp
52 | """
53 | CadnanoGuiTestCase.tearDown(self)
54 | # Add unit-test-specific cleanup here
55 |
56 | def testUnit1(self):
57 | """docstring for testUnit1"""
58 | pass
59 |
60 | if __name__ == '__main__':
61 | tc = UnitTests()
62 | tc.setUp()
63 | # tc.testRangeSet_addRange_removeRange()
64 | tests.cadnanoguitestcase.main()
65 |
--------------------------------------------------------------------------------
/cadnano2/ui/Makefile:
--------------------------------------------------------------------------------
1 | IMAGES = mainwindow/images/data-svg.png mainwindow/images/data-new_32.png mainwindow/images/data-open_32.png mainwindow/images/data-save_32.png mainwindow/images/part-new-honeycomb.png mainwindow/images/part-new-square.png mainwindow/images/slice-delete-last.png mainwindow/images/slice-move.png mainwindow/images/slice-renumber.png mainwindow/images/slice-edit.png mainwindow/images/slice-go-last.png mainwindow/images/slice-go-first.png mainwindow/images/add-bases.svg mainwindow/images/remove-bases.svg mainwindow/images/path-insert.png mainwindow/images/path-pen_48.png mainwindow/images/path-paint_48.png mainwindow/images/path-move.png mainwindow/images/path-skip.png mainwindow/images/path-force-xover.png mainwindow/images/path-break_48.png mainwindow/images/path-erase_32.png mainwindow/images/path-edit_32.png mainwindow/images/export-staples.png mainwindow/images/path-modify.png mainwindow/images/path-addseq.png mainwindow/images/path-autobreak.png mainwindow/images/part-filter-part.png mainwindow/images/part-filter-endpoint.png mainwindow/images/part-filter-xover.png mainwindow/images/part-filter-strand.png
2 | DIALOGIMAGES = dialogs/images/path-edit_32.png dialogs/images/path-force-xover.png dialogs/images/path-paint_48.png
3 |
4 | $(eval PYUIC_VERSION = -v $(shell pyuic6 -version 2> /dev/null):/output)
5 | # $(eval PYRCC_VERSION = -v $(shell pyrcc6 -version 2> /dev/null):/output)
6 |
7 | all: mainwindow/ui_mainwindow.py dialogs/ui_preferences.py dialogs/ui_latticetype.py dialogs/ui_addseq.py dialogs/ui_about.py dialogs/ui_warning.py
8 |
9 | # mainwindow/icons_rc.py : mainwindow/ui.mainwindow.icons.qrc $(IMAGES)
10 | # ifdef PYRCC_VERSION
11 | # pyrcc6 -o $@ $<
12 | # else
13 | # @echo "ERROR: pyrcc6 not found 1" $(PYUIC_VERSION) $(PYRCC_VERSION)
14 | # pyrcc6 -o $@ $<
15 | # endif
16 |
17 | # dialogs/dialogicons_rc.py : dialogs/ui.dialogs.dialogicons.qrc $(DIALOGIMAGES)
18 | # ifdef PYRCC_VERSION
19 | # pyrcc6 -o $@ $<
20 | # else
21 | # @echo "ERROR: pyrcc6 not found 2" $(PYUIC_VERSION) $(PYRCC_VERSION)
22 | # endif
23 |
24 | mainwindow/ui_mainwindow.py : mainwindow/mainwindow.ui
25 | ifdef PYUIC_VERSION
26 | pyuic6 $< > $@
27 | else
28 | @echo "ERROR: pyuic6 not found"
29 | endif
30 |
31 | dialogs/ui_preferences.py : dialogs/preferences.ui
32 | ifdef PYUIC_VERSION
33 | pyuic6 $< > $@
34 | else
35 | @echo "ERROR: pyuic6 not found"
36 | endif
37 |
38 | dialogs/ui_latticetype.py : dialogs/latticetype.ui
39 | ifdef PYUIC_VERSION
40 | pyuic6 $< > $@
41 | else
42 | @echo "ERROR: pyuic6 not found"
43 | endif
44 |
45 | dialogs/ui_addseq.py : dialogs/addseq.ui
46 | ifdef PYUIC_VERSION
47 | pyuic6 $< > $@
48 | else
49 | @echo "ERROR: pyuic6 not found"
50 | endif
51 |
52 | dialogs/ui_about.py : dialogs/about.ui
53 | ifdef PYUIC_VERSION
54 | pyuic6 $< > $@
55 | else
56 | @echo "ERROR: pyuic6 not found"
57 | endif
58 |
59 | dialogs/ui_warning.py : dialogs/warning.ui
60 | ifdef PYUIC_VERSION
61 | pyuic6 $< > $@
62 | else
63 | @echo "ERROR: pyuic6 not found"
64 | endif
65 |
66 |
--------------------------------------------------------------------------------
/cadnano2/ui/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/__init__.py
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/__init__.py
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/addseq.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | AddSeqDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 500
10 | 500
11 |
12 |
13 |
14 | Choose a sequence
15 |
16 |
17 | true
18 |
19 |
20 | -
21 |
22 |
23 | 0
24 |
25 |
26 |
27 | Standard
28 |
29 |
30 |
-
31 |
32 |
33 |
34 |
35 |
36 | true
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 | Qt::Horizontal
45 |
46 |
47 |
48 | 40
49 | 20
50 |
51 |
52 |
53 |
54 | -
55 |
56 |
57 | Qt::Horizontal
58 |
59 |
60 |
61 | 40
62 | 20
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | Custom
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 |
80 |
81 | -
82 |
83 |
84 | QDialogButtonBox::Apply|QDialogButtonBox::Cancel
85 |
86 |
87 | true
88 |
89 |
90 |
91 |
92 |
93 |
94 | customButtonBox
95 | tabWidget
96 | seqTextEdit
97 |
98 |
99 |
100 |
101 | customButtonBox
102 | rejected()
103 | AddSeqDialog
104 | reject()
105 |
106 |
107 | 315
108 | 485
109 |
110 |
111 | 321
112 | 243
113 |
114 |
115 |
116 |
117 | customButtonBox
118 | clicked(QAbstractButton*)
119 | AddSeqDialog
120 | accept()
121 |
122 |
123 | 68
124 | 485
125 |
126 |
127 | 80
128 | 243
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/cadnano2-about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/cadnano2-about.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/part-honeycomb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/part-honeycomb.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/part-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/part-square.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/path-addseq.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/path-edit_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/path-edit_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/path-force-xover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/path-force-xover.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/path-paint_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/path-paint_48.png
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/images/source/cadnano2-about.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/dialogs/images/source/cadnano2-about.ai
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/latticetype.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | LatticeType
4 |
5 |
6 |
7 | 0
8 | 0
9 | 215
10 | 80
11 |
12 |
13 |
14 |
15 | 0
16 | 0
17 |
18 |
19 |
20 | Import
21 |
22 |
23 | false
24 |
25 |
26 | -
27 |
28 |
29 | Is this a square lattice design?
30 |
31 |
32 |
33 | -
34 |
35 |
36 | Qt::Horizontal
37 |
38 |
39 | QDialogButtonBox::No|QDialogButtonBox::Yes
40 |
41 |
42 | true
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | buttonBox
52 | accepted()
53 | LatticeType
54 | accept()
55 |
56 |
57 | 248
58 | 254
59 |
60 |
61 | 157
62 | 274
63 |
64 |
65 |
66 |
67 | buttonBox
68 | rejected()
69 | LatticeType
70 | reject()
71 |
72 |
73 | 316
74 | 260
75 |
76 |
77 | 286
78 | 274
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/ui.dialogs.dialogicons.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/path-addseq.svg
4 | images/path-edit_32.png
5 | images/path-force-xover.png
6 | images/path-paint_48.png
7 |
8 |
9 | images/part-honeycomb.png
10 | images/part-square.png
11 |
12 |
13 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/ui_addseq.py:
--------------------------------------------------------------------------------
1 | # Form implementation generated from reading ui file 'dialogs/addseq.ui'
2 | #
3 | # Created by: PyQt6 UI code generator 6.1.1
4 | #
5 | # WARNING: Any manual changes made to this file will be lost when pyuic6 is
6 | # run again. Do not edit this file unless you know what you are doing.
7 |
8 |
9 | from PyQt6 import QtCore, QtGui, QtWidgets
10 |
11 |
12 | class Ui_AddSeqDialog(object):
13 | def setupUi(self, AddSeqDialog):
14 | AddSeqDialog.setObjectName("AddSeqDialog")
15 | AddSeqDialog.resize(500, 500)
16 | AddSeqDialog.setModal(True)
17 | self.dialogGridLayout = QtWidgets.QGridLayout(AddSeqDialog)
18 | self.dialogGridLayout.setObjectName("dialogGridLayout")
19 | self.tabWidget = QtWidgets.QTabWidget(AddSeqDialog)
20 | self.tabWidget.setObjectName("tabWidget")
21 | self.tabStandard = QtWidgets.QWidget()
22 | self.tabStandard.setObjectName("tabStandard")
23 | self.standardTabGridLayout = QtWidgets.QGridLayout(self.tabStandard)
24 | self.standardTabGridLayout.setObjectName("standardTabGridLayout")
25 | self.groupBox = QtWidgets.QGroupBox(self.tabStandard)
26 | self.groupBox.setTitle("")
27 | self.groupBox.setFlat(True)
28 | self.groupBox.setObjectName("groupBox")
29 | self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
30 | self.verticalLayout.setObjectName("verticalLayout")
31 | self.standardTabGridLayout.addWidget(self.groupBox, 0, 1, 1, 1)
32 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
33 | self.standardTabGridLayout.addItem(spacerItem, 0, 2, 1, 1)
34 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
35 | self.standardTabGridLayout.addItem(spacerItem1, 0, 0, 1, 1)
36 | self.tabWidget.addTab(self.tabStandard, "")
37 | self.tabCustom = QtWidgets.QWidget()
38 | self.tabCustom.setObjectName("tabCustom")
39 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tabCustom)
40 | self.verticalLayout_2.setObjectName("verticalLayout_2")
41 | self.seqTextEdit = QtWidgets.QTextEdit(self.tabCustom)
42 | self.seqTextEdit.setObjectName("seqTextEdit")
43 | self.verticalLayout_2.addWidget(self.seqTextEdit)
44 | self.tabWidget.addTab(self.tabCustom, "")
45 | self.dialogGridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
46 | self.customButtonBox = QtWidgets.QDialogButtonBox(AddSeqDialog)
47 | self.customButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Apply|QtWidgets.QDialogButtonBox.StandardButton.Cancel)
48 | self.customButtonBox.setCenterButtons(True)
49 | self.customButtonBox.setObjectName("customButtonBox")
50 | self.dialogGridLayout.addWidget(self.customButtonBox, 1, 0, 1, 1)
51 |
52 | self.retranslateUi(AddSeqDialog)
53 | self.tabWidget.setCurrentIndex(0)
54 | self.customButtonBox.rejected.connect(AddSeqDialog.reject)
55 | self.customButtonBox.clicked['QAbstractButton*'].connect(AddSeqDialog.accept)
56 | QtCore.QMetaObject.connectSlotsByName(AddSeqDialog)
57 | AddSeqDialog.setTabOrder(self.customButtonBox, self.tabWidget)
58 | AddSeqDialog.setTabOrder(self.tabWidget, self.seqTextEdit)
59 |
60 | def retranslateUi(self, AddSeqDialog):
61 | _translate = QtCore.QCoreApplication.translate
62 | AddSeqDialog.setWindowTitle(_translate("AddSeqDialog", "Choose a sequence"))
63 | self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabStandard), _translate("AddSeqDialog", "Standard"))
64 | self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabCustom), _translate("AddSeqDialog", "Custom"))
65 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/ui_latticetype.py:
--------------------------------------------------------------------------------
1 | # Form implementation generated from reading ui file 'dialogs/latticetype.ui'
2 | #
3 | # Created by: PyQt6 UI code generator 6.1.1
4 | #
5 | # WARNING: Any manual changes made to this file will be lost when pyuic6 is
6 | # run again. Do not edit this file unless you know what you are doing.
7 |
8 |
9 | from PyQt6 import QtCore, QtGui, QtWidgets
10 |
11 |
12 | class Ui_LatticeType(object):
13 | def setupUi(self, LatticeType):
14 | LatticeType.setObjectName("LatticeType")
15 | LatticeType.resize(215, 80)
16 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
17 | sizePolicy.setHorizontalStretch(0)
18 | sizePolicy.setVerticalStretch(0)
19 | sizePolicy.setHeightForWidth(LatticeType.sizePolicy().hasHeightForWidth())
20 | LatticeType.setSizePolicy(sizePolicy)
21 | LatticeType.setSizeGripEnabled(False)
22 | self.verticalLayout = QtWidgets.QVBoxLayout(LatticeType)
23 | self.verticalLayout.setObjectName("verticalLayout")
24 | self.label = QtWidgets.QLabel(LatticeType)
25 | self.label.setObjectName("label")
26 | self.verticalLayout.addWidget(self.label)
27 | self.buttonBox = QtWidgets.QDialogButtonBox(LatticeType)
28 | self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
29 | self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.No|QtWidgets.QDialogButtonBox.StandardButton.Yes)
30 | self.buttonBox.setCenterButtons(True)
31 | self.buttonBox.setObjectName("buttonBox")
32 | self.verticalLayout.addWidget(self.buttonBox)
33 |
34 | self.retranslateUi(LatticeType)
35 | self.buttonBox.accepted.connect(LatticeType.accept)
36 | self.buttonBox.rejected.connect(LatticeType.reject)
37 | QtCore.QMetaObject.connectSlotsByName(LatticeType)
38 |
39 | def retranslateUi(self, LatticeType):
40 | _translate = QtCore.QCoreApplication.translate
41 | LatticeType.setWindowTitle(_translate("LatticeType", "Import"))
42 | self.label.setText(_translate("LatticeType", "Is this a square lattice design?"))
43 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/ui_warning.py:
--------------------------------------------------------------------------------
1 | # Form implementation generated from reading ui file 'dialogs/warning.ui'
2 | #
3 | # Created by: PyQt6 UI code generator 6.1.1
4 | #
5 | # WARNING: Any manual changes made to this file will be lost when pyuic6 is
6 | # run again. Do not edit this file unless you know what you are doing.
7 |
8 |
9 | from PyQt6 import QtCore, QtGui, QtWidgets
10 |
11 |
12 | class Ui_Warning(object):
13 | def setupUi(self, Warning, name="Warning"):
14 | Warning.setObjectName(name)
15 | Warning.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
16 | Warning.resize(400, 300)
17 | self.buttonBox = QtWidgets.QDialogButtonBox(Warning)
18 | self.buttonBox.setGeometry(QtCore.QRect(30, 250, 341, 32))
19 | self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
20 | self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Ok)
21 | self.buttonBox.setObjectName("buttonBox")
22 | self.title = QtWidgets.QLabel(Warning)
23 | self.title.setGeometry(QtCore.QRect(20, 30, 361, 31))
24 | font = QtGui.QFont()
25 | font.setPointSize(24)
26 | self.title.setFont(font)
27 | self.title.setObjectName("title")
28 | self.message = QtWidgets.QLabel(Warning)
29 | self.message.setGeometry(QtCore.QRect(20, 80, 361, 151))
30 | self.message.setWordWrap(True)
31 | self.message.setObjectName("message")
32 |
33 | self.retranslateUi(Warning)
34 | self.buttonBox.accepted.connect(Warning.accept)
35 | self.buttonBox.rejected.connect(Warning.reject)
36 | QtCore.QMetaObject.connectSlotsByName(Warning)
37 |
38 | def retranslateUi(self, Warning):
39 | _translate = QtCore.QCoreApplication.translate
40 | Warning.setWindowTitle(_translate("Warning", "Dialog"))
41 | self.title.setText(_translate("Warning", "Warning"))
42 | self.message.setText(_translate("Warning", "Text here."))
43 |
--------------------------------------------------------------------------------
/cadnano2/ui/dialogs/warning.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Warning
4 |
5 |
6 | Qt::ApplicationModal
7 |
8 |
9 |
10 | 0
11 | 0
12 | 400
13 | 300
14 |
15 |
16 |
17 | Dialog
18 |
19 |
20 |
21 |
22 | 30
23 | 250
24 | 341
25 | 32
26 |
27 |
28 |
29 | Qt::Horizontal
30 |
31 |
32 | QDialogButtonBox::Ok
33 |
34 |
35 |
36 |
37 |
38 | 20
39 | 30
40 | 361
41 | 31
42 |
43 |
44 |
45 |
46 | 24
47 |
48 |
49 |
50 | Warning
51 |
52 |
53 |
54 |
55 |
56 | 20
57 | 80
58 | 361
59 | 151
60 |
61 |
62 |
63 | Text here.
64 |
65 |
66 | true
67 |
68 |
69 |
70 |
71 |
72 |
73 | buttonBox
74 | accepted()
75 | Warning
76 | accept()
77 |
78 |
79 | 248
80 | 254
81 |
82 |
83 | 157
84 | 274
85 |
86 |
87 |
88 |
89 | buttonBox
90 | rejected()
91 | Warning
92 | reject()
93 |
94 |
95 | 316
96 | 260
97 |
98 |
99 | 286
100 | 274
101 |
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/__init__.py
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/add-bases.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
76 |
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-app-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-app-icon.ico
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-app-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-app-icon.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-app-icon_shelf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-app-icon_shelf.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-document-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-document-icon.ico
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-document-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-document-icon.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2-icon_doc-legacy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2-icon_doc-legacy.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/cadnano2_installer-bkg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/cadnano2_installer-bkg.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/data-export-staples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/data-export-staples.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/data-new_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/data-new_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/data-open_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/data-open_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/data-save_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/data-save_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/data-svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/data-svg.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/export-staples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/export-staples.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/export-staples.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-endpoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-endpoint.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-handle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-handle.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-part.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-part.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-scaf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-scaf.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-stap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-stap.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-strand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-strand.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-filter-xover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-filter-xover.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-new-honeycomb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-new-honeycomb.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/part-new-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/part-new-square.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-addseq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-addseq.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-addseq.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-autobreak.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-autobreak.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-break_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-break_48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-edit_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-edit_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-erase_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-erase_32.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-erase_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-erase_48x48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-force-xover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-force-xover.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-frame.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-insert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-insert.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-insert_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-insert_48x48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-loop.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-loop_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-loop_48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-modify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-modify.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-move.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-paint_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-paint_48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-pen_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-pen_48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-sequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-sequence.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-skip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-skip.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-skip_48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-skip_48x48.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/path-staple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/path-staple.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/remove-bases.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
77 |
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-delete-last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-delete-last.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-edit.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-go-first.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-go-first.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-go-last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-go-last.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-move.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/slice-renumber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/slice-renumber.png
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/cadnano2-icon.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/cadnano2-icon.pdf
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-endpoint.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-endpoint.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-handle.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-handle.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-scaf.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-scaf.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-stap.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-stap.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-strand.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-strand.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-filter-xover.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-filter-xover.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-new-honeycomb.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-new-honeycomb.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/part-new-square.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/part-new-square.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-addseq.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-addseq.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-break.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-break.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-frame.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-frame.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-insert.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-insert.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-loop.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-loop.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-paint.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-paint.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-sequence.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-sequence.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/images/source/path-skip.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/ui/mainwindow/images/source/path-skip.ai
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/svgbutton.py:
--------------------------------------------------------------------------------
1 | import cadnano2.util as util
2 | util.qtWrapImport('QtCore', globals(), ['QObject', 'pyqtSignal', 'Qt'])
3 | util.qtWrapImport('QtWidgets', globals(), ['QGraphicsObject'])
4 | util.qtWrapImport('QtSvg', globals(), ['QSvgRenderer'])
5 |
6 |
7 | class SVGButton(QGraphicsObject):
8 | def __init__(self, fname, parent=None):
9 | super(SVGButton, self).__init__(parent)
10 | self.svg = QSvgRenderer(fname)
11 |
12 | def paint(self, painter, options, widget):
13 | self.svg.render(painter, self.boundingRect())
14 |
15 | def boundingRect(self):
16 | return self.svg.viewBoxF()
17 |
18 | clicked = pyqtSignal()
19 | def mousePressEvent(self, event):
20 | self.clicked.emit()
--------------------------------------------------------------------------------
/cadnano2/ui/mainwindow/ui.mainwindow.icons.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/data-svg.png
4 | images/data-new_32.png
5 | images/export-staples.png
6 | images/data-open_32.png
7 | images/data-save_32.png
8 |
9 |
10 | images/part-filter-scaf.png
11 | images/part-filter-stap.png
12 | images/part-filter-strand.png
13 | images/part-filter-handle.png
14 | images/part-filter-part.png
15 | images/part-filter-xover.png
16 | images/part-filter-endpoint.png
17 | images/part-new-honeycomb.png
18 | images/part-new-square.png
19 |
20 |
21 | images/slice-delete-last.png
22 | images/slice-move.png
23 | images/slice-renumber.png
24 | images/slice-edit.png
25 | images/slice-go-last.png
26 | images/slice-go-first.png
27 |
28 |
29 | images/path-autobreak.png
30 | images/path-modify.png
31 | images/add-bases.svg
32 | images/path-addseq.png
33 | images/remove-bases.svg
34 | images/path-insert_48x48.png
35 | images/path-frame.png
36 | images/path-paint_48.png
37 | images/path-move.png
38 | images/path-skip_48x48.png
39 | images/path-force-xover.png
40 | images/path-break_48.png
41 | images/path-edit_32.png
42 | images/path-erase_48x48.png
43 | images/path-staple.png
44 |
45 |
46 |
--------------------------------------------------------------------------------
/cadnano2/views/QGraphicsScene-event-dispatching-overview.txt:
--------------------------------------------------------------------------------
1 | Here is a brief overview of the functions through which a mouse press event will descend until it finally reaches a QGraphicsItem.
2 |
3 | ----- Run loop sends a mouse press ------
4 | bool QGraphicsScene::event(QEvent *event) //Returns true
5 | void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
6 | void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
7 | mouseEvent->ignore()
8 | cachedItemsUnderMouse = QGraphicsScenePrivate::itemsAtPosition(...)
9 | activate window, widget (modal panel can intercept)
10 | go in order through cachedItemsUnderMouse, try to setFocusItem on them
11 | foreach thru cachedItemsUnderMouse again
12 | check the item's acceptedMouseButtons, skip if required
13 | grab the mouse
14 | *** ACCEPT THE EVENT ***
15 | void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
16 | bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
17 | return item->sceneEvent(event)
18 | ignore retval of sendEvent
19 | *** if mouseEvent->isAccepted() return ***
20 | ungrab
21 | propagate to view
22 |
23 | ----- QGraphicsItem receives a mouse press -----
24 | The only default event->accept()ing that goes on is for popup widget closing
25 | bool QGraphicsItem::sceneEvent(QEvent *event)
26 | void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
27 | ignore mousePressEvent retval and return true
28 |
29 | ----- Rubber Banding -----
30 | void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
31 | If dragMode is QGraphicsView::RubberBandDrag and scene interaction allowed, proceed.
32 | If rubberBanding, proceed
33 | Dirty the viewport
34 | void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
35 | const QTransform &deviceTransform)
36 | foreach item in QGraphicsScene::items(selection rect, descending order)
37 | if (item->flags() & QGraphicsItem::ItemIsSelectable)
38 | item->setSelected(true)
39 | foreach unselectedItem
40 | item->setSelected(false)
41 | emit selectionChanged();
--------------------------------------------------------------------------------
/cadnano2/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/pathview/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/pathview/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/pathview/colorpanel.py:
--------------------------------------------------------------------------------
1 | from cadnano2.views import styles
2 | import cadnano2.util as util
3 | util.qtWrapImport('QtCore', globals(), ['QRectF', 'Qt'])
4 | util.qtWrapImport('QtGui', globals(), ['QBrush', 'QFont'])
5 | util.qtWrapImport('QtWidgets', globals(), ['QApplication',
6 | 'QColorDialog',
7 | 'QGraphicsItem',
8 | 'QGraphicsSimpleTextItem'])
9 |
10 | _font = QFont(styles.thefont, 12, QFont.Weight.Bold)
11 |
12 |
13 | class ColorPanel(QGraphicsItem):
14 | _scafColors = styles.scafColors
15 | _stapColors = styles.stapColors
16 | _pen = Qt.PenStyle.NoPen
17 |
18 | def __init__(self, parent=None):
19 | super(ColorPanel, self).__init__(parent)
20 | self.rect = QRectF(0, 0, 30, 30)
21 | self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations)
22 | self.colordialog = QColorDialog()
23 | # self.colordialog.setOption(QColorDialog.DontUseNativeDialog)
24 | self._scafColorIndex = 0 # init on -1, painttool will cycle to 0
25 | self._stapColorIndex = -1 # init on -1, painttool will cycle to 0
26 | self._scafColor = self._scafColors[self._scafColorIndex]
27 | self._stapColor = self._stapColors[self._stapColorIndex]
28 | self._scafBrush = QBrush(self._scafColor)
29 | self._stapBrush = QBrush(self._stapColor)
30 | self._initLabel()
31 | self.hide()
32 |
33 | def _initLabel(self):
34 | self._label = label = QGraphicsSimpleTextItem("scaf\nstap", parent=self)
35 | label.setPos(32, 0)
36 | label.setFont(_font)
37 | # label.setBrush(_labelbrush)
38 | # label.hide()
39 |
40 | def boundingRect(self):
41 | return self.rect
42 |
43 | def paint(self, painter, option, widget=None):
44 | painter.setPen(self._pen)
45 | painter.setBrush(self._scafBrush)
46 | painter.drawRect(0, 0, 30, 15)
47 | painter.setBrush(self._stapBrush)
48 | painter.drawRect(0, 15, 30, 15)
49 |
50 | def nextColor(self):
51 | if QApplication.keyboardModifiers() & Qt.KeyboardModifier.ShiftModifier:
52 | self._scafColorIndex += 1
53 | if self._scafColorIndex == len(self._scafColors):
54 | self._scafColorIndex = 0
55 | self._scafColor = self._scafColors[self._scafColorIndex]
56 | self._scafBrush.setColor(self._scafColor)
57 | else:
58 | self._stapColorIndex += 1
59 | if self._stapColorIndex == len(self._stapColors):
60 | self._stapColorIndex = 0
61 | self._stapColor = self._stapColors[self._stapColorIndex]
62 | self._stapBrush.setColor(self._stapColor)
63 | self.update()
64 |
65 | def prevColor(self):
66 | self._scafColorIndex -= 1
67 | self._stapColorIndex -= 1
68 |
69 | def color(self):
70 | return self._stapColor
71 |
72 | def scafColorName(self):
73 | return self._scafColor.name()
74 |
75 | def stapColorName(self):
76 | return self._stapColor.name()
77 |
78 | def changeScafColor(self):
79 | self.update()
80 |
81 | def changeStapColor(self):
82 | self._stapColor = self.colordialog.currentColor()
83 | self._stapBrush = QBrush(self._stapColor)
84 | self.update()
85 |
86 | def mousePressEvent(self, event):
87 | if event.pos().y() < 10:
88 | newColor = self.colordialog.getColor(self._scafColor)
89 | if newColor.isValid() and newColor.name() != self._scafColor.name():
90 | self._scafColor = newColor
91 | self._scafBrush = QBrush(newColor)
92 | if not newColor in self._scafColors:
93 | self._scafColors.insert(self._scafColorIndex, newColor)
94 | self.update()
95 | else:
96 | newColor = self.colordialog.getColor(self._stapColor)
97 | if newColor.isValid() and newColor.name() != self._stapColor.name():
98 | self._stapColor = newColor
99 | self._stapBrush = QBrush(newColor)
100 | if not newColor in self._stapColors:
101 | self._stapColors.insert(self._stapColorIndex, newColor)
102 | self.update()
103 |
104 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/pathview/strand/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/abstractstranditem.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | # from exceptions import NotImplementedError
5 | import cadnano2.util as util
6 | util.qtWrapImport('QtGui', globals(), ['QGraphicsPathItem'])
7 |
8 |
9 | class AbstractStrandItem(QGraphicsPathItem):
10 | def __init__(self, parent):
11 | """The parent should be a VirtualHelixItem."""
12 | if self.__class__ == AbstractStrandItem:
13 | raise NotImplementedError("AbstractStrandItem should be subclassed.")
14 | super(AbstractStrandItem, self).__init__(parent)
15 | self._strand = None
16 | self._oligo = None
17 |
18 | ### SIGNALS ###
19 |
20 | ### SLOTS ###
21 | def oligoAppeareanceChanged(self):
22 | """docstring for oligoAppeareanceChanged"""
23 | pass
24 |
25 | def hasNewOligoSlot(self, oligo):
26 | """docstring for hasNewOligoSlot"""
27 | self._oligo = oligo
28 | # redraw
29 |
30 | def strandRemovedSlot(self, strand):
31 | """docstring for strandRemovedSlot"""
32 | pass
33 |
34 | def decoratorAddedSlot(self, decorator):
35 | """docstring for decoratorAddedSlot"""
36 | pass
37 |
38 | ### METHODS ###
39 | def connectSignals(self):
40 | self._oligo.appearanceChangedSignal.connect(self.oligoAppeareanceChanged)
41 | self._strand.strandHasNewOligoSignal.connect(self.hasNewOligoSlot)
42 | self._strand.destroyedSignal.connect(self.strandRemovedSlot)
43 | self._strand.decoratorAddedSignal.connect(self.decoratorAddedSlot)
44 |
45 | def disconnectSignals(self):
46 | self._oligo.appearanceChangedSignal.disconnect(self.oligoAppeareanceChanged)
47 | self._strand.strandHasNewOligoSignal.disconnect(self.hasNewOligoSlot)
48 | self._strand.destroyedSignal.disconnect(self.strandRemovedSlot)
49 | self._strand.decoratorAddedSignal.disconnect(self.decoratorAddedSlot)
50 |
51 | ### COMMANDS ###
52 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/decorators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/pathview/strand/decorators/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/decorators/abstractdecoratoritem.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | import cadnano2.util as util
5 | util.qtWrapImport('QtGui', globals(), ['QGraphicsPathItem'])
6 |
7 |
8 | class AbstractDecoratorItem(QGraphicsPathItem):
9 | def __init__(self, parent):
10 | """The parent should be a VirtualHelixItem."""
11 | if self.__class__ == AbstractDecoratorItem:
12 | e = "AbstractDecoratorItem should be subclassed."
13 | raise NotImplementedError(e)
14 | super(AbstractDecoratorItem, self).__init__(parent)
15 | self._strand = None
16 | self._oligo = None
17 |
18 | ### SIGNALS ###
19 |
20 | ### SLOTS ###
21 | def strandResizedSlot(self):
22 | """docstring for strandResizedSlot"""
23 | pass
24 |
25 | def sequenceAddedSlot(self, oligo):
26 | """docstring for sequenceAddedSlot"""
27 | pass
28 |
29 | def decoratorRemovedSlot(self, oligo):
30 | """docstring for sequenceClearedSlot"""
31 | pass
32 |
33 | ### METHODS ###
34 |
35 | ### COMMANDS ###
36 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/decorators/fluorophoreitem.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | import cadnano2.util as util
5 |
6 |
7 | class FluorophoreItem(AbstractDecoratorItem):
8 | def __init__(self, parent):
9 | """The parent should be a VirtualHelixItem."""
10 | super(FluorophoreItem, self).__init__(parent)
11 |
12 | ### SIGNALS ###
13 |
14 | ### SLOTS ###
15 |
16 | ### METHODS ###
17 |
18 | ### COMMANDS ###
19 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/decorators/skipitem.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | import cadnano2.util as util
5 |
6 |
7 | class SkipItem(AbstractDecoratorItem):
8 | def __init__(self, parent):
9 | """The parent should be a VirtualHelixItem."""
10 | super(SkipItem, self).__init__(parent)
11 |
12 | ### SIGNALS ###
13 |
14 | ### SLOTS ###
15 |
16 | ### METHODS ###
17 |
18 | ### COMMANDS ###
19 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/strand/decorators/stapleextensionitem.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 |
5 | class StapleExtensionItem(AbstractDecoratorItem):
6 | def __init__(self, parent):
7 | """The parent should be a VirtualHelixItem."""
8 | super(StapleExtensionItem, self).__init__(parent)
9 |
10 | ### SIGNALS ###
11 |
12 | ### SLOTS ###
13 |
14 | ### METHODS ###
15 |
16 | ### COMMANDS ###
17 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/pathview/tools/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/breaktool.py:
--------------------------------------------------------------------------------
1 | from .abstractpathtool import AbstractPathTool
2 | from cadnano2.views import styles
3 | import cadnano2.util as util
4 | util.qtWrapImport('QtCore', globals(), ['QPointF', 'QRectF', 'Qt'])
5 | util.qtWrapImport('QtGui', globals(), ['QBrush', 'QFont', 'QPainterPath',
6 | 'QPen', 'QPolygonF'])
7 | util.qtWrapImport('QtWidgets', globals(), ['QGraphicsItem'])
8 |
9 | _bw = styles.PATH_BASE_WIDTH
10 | _pen = QPen(styles.redstroke, 1)
11 | _rect = QRectF(0, 0, _bw, _bw)
12 | _pathArrowLeft = QPainterPath()
13 | _l3poly = QPolygonF()
14 | _l3poly.append(QPointF(_bw, 0))
15 | _l3poly.append(QPointF(0.25 * _bw, 0.5 * _bw))
16 | _l3poly.append(QPointF(_bw, _bw))
17 | _pathArrowLeft.addPolygon(_l3poly)
18 | _pathArrowRight = QPainterPath()
19 | _r3poly = QPolygonF() # right-hand 3' arr
20 | _r3poly.append(QPointF(0, 0))
21 | _r3poly.append(QPointF(0.75 * _bw, 0.5 * _bw))
22 | _r3poly.append(QPointF(0, _bw))
23 | _pathArrowRight.addPolygon(_r3poly)
24 |
25 |
26 | class BreakTool(AbstractPathTool):
27 | """
28 | docstring for BreakTool
29 | """
30 | def __init__(self, controller):
31 | super(BreakTool, self).__init__(controller)
32 | self._isTopStrand = True
33 |
34 | def __repr__(self):
35 | return "breakTool" # first letter should be lowercase
36 |
37 | def paint(self, painter, option, widget=None):
38 | super(BreakTool, self).paint(painter, option, widget)
39 | painter.setPen(_pen)
40 | if self._isTopStrand:
41 | painter.drawPath(self._pathArrowRight)
42 | else:
43 | painter.drawPath(self._pathArrowLeft)
44 |
45 | def setTopStrand(self, isTop):
46 | """
47 | Called in hoverMovePathHelix to set whether breaktool is hovering
48 | over a top strand (goes 5' to 3' left to right) or bottom strand.
49 | """
50 | self._isTopStrand = isTop
51 |
52 | def hoverMove(self, item, event, flag=None):
53 | """
54 | flag is for the case where an item in the path also needs to
55 | implement the hover method
56 | """
57 | self.updateLocation(item, item.mapToScene(QPointF(event.position())))
58 | posScene = item.mapToScene(QPointF(event.position()))
59 | posItem = item.mapFromScene(posScene)
60 | self.setTopStrand(self.helixIndex(posItem)[1] == 0)
61 | newPosition = self.helixPos(posItem)
62 | if newPosition != None:
63 | self.setPos(newPosition)
64 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/erasetool.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from .abstractpathtool import AbstractPathTool
3 | import cadnano2.util as util
4 | util.qtWrapImport('QtCore', globals(), [])
5 | util.qtWrapImport('QtGui', globals(), [])
6 |
7 |
8 | class EraseTool(AbstractPathTool):
9 | """
10 | docstring for EraseTool
11 | """
12 | def __init__(self, controller):
13 | super(EraseTool, self).__init__(controller)
14 |
15 | def __repr__(self):
16 | return "eraseTool" # first letter should be lowercase
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/insertiontool.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from .abstractpathtool import AbstractPathTool
3 | import cadnano2.util as util
4 | util.qtWrapImport('QtCore', globals(), [])
5 | util.qtWrapImport('QtGui', globals(), [])
6 |
7 |
8 | class InsertionTool(AbstractPathTool):
9 | """
10 | docstring for InsertionTool
11 | """
12 | def __init__(self, controller):
13 | super(InsertionTool, self).__init__(controller)
14 |
15 | def __repr__(self):
16 | return "insertionTool" # first letter should be lowercase
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/painttool.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from .abstractpathtool import AbstractPathTool
3 | import cadnano2.util as util
4 | util.qtWrapImport('QtCore', globals(), [])
5 | util.qtWrapImport('QtGui', globals(), [])
6 | util.qtWrapImport('QtWidgets', globals(), ['QApplication'])
7 |
8 |
9 | class PaintTool(AbstractPathTool):
10 | """
11 | Handles visibility and color cycling for the paint tool.
12 | """
13 | def __init__(self, controller):
14 | super(PaintTool, self).__init__(controller)
15 | self._isMacrod = False
16 |
17 | def __repr__(self):
18 | return "paintTool" # first letter should be lowercase
19 |
20 | def setActive(self, willBeActive):
21 | """Show the ColorPicker widget when active, hide when inactive."""
22 | if willBeActive:
23 | self._window.pathColorPanel.show()
24 | else:
25 | self._window.pathColorPanel.hide()
26 | self._window.pathColorPanel.prevColor()
27 |
28 | def widgetClicked(self):
29 | """Cycle through colors on 'p' keypress"""
30 | self._window.pathColorPanel.nextColor()
31 |
32 | def customMouseRelease(self, event):
33 | if self._isMacrod:
34 | self._isMacrod = False
35 | self._window.undoStack().endMacro()
36 | # end def
37 |
38 | def isMacrod(self):
39 | return self._isMacrod
40 | # end def
41 |
42 | def setMacrod(self):
43 | self._isMacrod = True
44 | self._window.undoStack().beginMacro("Group Paint")
45 | self._window.pathGraphicsView.addToPressList(self)
46 | # end def
47 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/pathtoolmanager.py:
--------------------------------------------------------------------------------
1 | import os
2 | from cadnano2.cadnano import app
3 | from .selecttool import SelectTool
4 | from .penciltool import PencilTool
5 | from .breaktool import BreakTool
6 | from .erasetool import EraseTool
7 | from .insertiontool import InsertionTool
8 | from .skiptool import SkipTool
9 | from .painttool import PaintTool
10 | from .addseqtool import AddSeqTool
11 | import cadnano2.util as util
12 |
13 | # import Qt stuff into the module namespace with PySide, PyQt4 independence
14 | util.qtWrapImport('QtCore', globals(), ['QObject', 'pyqtSignal'])
15 | util.qtWrapImport('QtGui', globals(), [ 'QActionGroup'])
16 |
17 |
18 | class PathToolManager(QObject):
19 | """
20 | Manages the interactions between Path widgets / UI elements and the model.
21 | """
22 | def __init__(self, win):
23 | super(PathToolManager, self).__init__()
24 | self.window = win
25 | self._activeTool = None
26 | self._activePart = None
27 | self.selectTool = SelectTool(self)
28 | self.pencilTool = PencilTool(self)
29 | self.breakTool = BreakTool(self)
30 | self.eraseTool = EraseTool(self)
31 | self.insertionTool = InsertionTool(self)
32 | self.skipTool = SkipTool(self)
33 | self.paintTool = PaintTool(self) # (self, win.pathGraphicsView.toolbar)
34 | self.addSeqTool = AddSeqTool(self)
35 |
36 | def installTool(toolName, window):
37 | toolWidget = getattr(window, 'actionPath' + toolName)
38 | lToolName = toolName[0].lower() + toolName[1:]
39 | tool = getattr(self, lToolName + 'Tool')
40 | tool.actionName = 'actionPath' + toolName
41 |
42 | def clickHandler(self):
43 | toolWidget.setChecked(True)
44 | self.setActiveTool(tool)
45 | if hasattr(tool, 'widgetClicked'):
46 | tool.widgetClicked()
47 | selectToolMethodName = 'choose' + toolName + 'Tool'
48 | setattr(self.__class__, selectToolMethodName, clickHandler)
49 | handler = getattr(self, selectToolMethodName)
50 | toolWidget.triggered.connect(handler)
51 | return toolWidget
52 |
53 | tools = ('Select', 'Pencil', 'Break', 'Erase', 'Insertion', 'Skip', 'Paint', 'AddSeq')
54 | ag = QActionGroup(win)
55 | # Call installTool on every tool
56 | list(map((lambda toolName: ag.addAction(installTool(toolName, win))), tools))
57 | ag.setExclusive(True)
58 | # Select the preferred Startup tool
59 | startupToolName = app().prefs.getStartupToolName()
60 | getattr(self, 'choose' + startupToolName + 'Tool')()
61 |
62 | ### SIGNALS ###
63 | activeToolChangedSignal = pyqtSignal(str)
64 |
65 | ### SLOTS ###
66 |
67 | ### METHODS ###
68 | def activePart(self):
69 | return self._activePart
70 |
71 | def setActivePart(self, part):
72 | self._activePart = part
73 |
74 | def activeTool(self):
75 | return self._activeTool
76 |
77 | def setActiveTool(self, newActiveTool):
78 | if newActiveTool == self._activeTool:
79 | return
80 | if self.lastLocation():
81 | newActiveTool.updateLocation(*self.lastLocation())
82 | if self._activeTool:
83 | self._activeTool.setActive(False)
84 | if str(newActiveTool) == "selectTool":
85 | self.window.activateSelection(True)
86 | elif str(newActiveTool) == "paintTool":
87 | self.window.activateSelection(True)
88 | else:
89 | self.window.activateSelection(False)
90 | self._activeTool = newActiveTool
91 | self._activeTool.setActive(True)
92 | self.activeToolChangedSignal.emit(self._activeTool.actionName)
93 |
94 | def isSelectToolActive(self):
95 | if self.activeTool() == self.selectTool:
96 | return True
97 | return False
98 |
99 | def lastLocation(self):
100 | """(PathHelix, posInScene) or None, depending on where
101 | the mouse is (basically, pathHelix and position of
102 | the last event seen by the active tool)"""
103 | if self._activeTool == None:
104 | return None
105 | return self._activeTool.lastLocation()
106 | # end class
107 |
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/selecttool.py:
--------------------------------------------------------------------------------
1 | from .abstractpathtool import AbstractPathTool
2 | import cadnano2.util as util
3 | util.qtWrapImport('QtCore', globals(), [])
4 | util.qtWrapImport('QtGui', globals(), [])
5 |
6 |
7 | class SelectTool(AbstractPathTool):
8 | """
9 | SelectTool is the default tool. It allows editing of breakpoints
10 | (by clicking and dragging) and toggling of crossovers.
11 | """
12 | def __init__(self, controller):
13 | super(SelectTool, self).__init__(controller)
14 |
15 | def __repr__(self):
16 | return "selectTool" # first letter should be lowercase
--------------------------------------------------------------------------------
/cadnano2/views/pathview/tools/skiptool.py:
--------------------------------------------------------------------------------
1 | from .abstractpathtool import AbstractPathTool
2 | import cadnano2.util as util
3 | util.qtWrapImport('QtCore', globals(), [])
4 | util.qtWrapImport('QtGui', globals(), [])
5 |
6 |
7 | class SkipTool(AbstractPathTool):
8 | """
9 | docstring for SkipTool
10 | """
11 | def __init__(self, controller):
12 | super(SkipTool, self).__init__(controller)
13 |
14 | def __repr__(self):
15 | return "skipTool" # first letter should be lowercase
--------------------------------------------------------------------------------
/cadnano2/views/sliceview/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/sliceview/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/sliceview/activesliceitem.py:
--------------------------------------------------------------------------------
1 | """
2 | activeslicehandle.py
3 | Created by Shawn on 2011-02-05.
4 | """
5 |
6 | from cadnano2.controllers.itemcontrollers.activesliceitemcontroller import ActiveSliceItemController
7 | import cadnano2.util as util
8 |
9 | # import Qt stuff into the module namespace with PySide, PyQt4 independence
10 | util.qtWrapImport('QtCore', globals(), ['QPointF', 'QRectF', 'Qt', 'QObject',\
11 | 'pyqtSignal', 'pyqtSlot', 'QEvent'])
12 | util.qtWrapImport('QtGui', globals(), ['QBrush',
13 | 'QFont',
14 | 'QPen',
15 | 'QDrag',
16 | 'QUndoCommand'])
17 | util.qtWrapImport('QtWidgets', globals(), ['QGraphicsItem',
18 | 'QGraphicsRectItem',
19 | 'QGraphicsSimpleTextItem'])
20 |
21 |
22 | class ActiveSliceItem(QGraphicsRectItem):
23 | """ActiveSliceItem for the Slice View"""
24 | def __init__(self, partItem, activeBaseIndex):
25 | super(ActiveSliceItem, self).__init__(partItem)
26 | self._partItem = partItem
27 | self._controller = ActiveSliceItemController(self, partItem.part())
28 | self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemHasNoContents)
29 | # end def
30 |
31 | ### SLOTS ###
32 | def strandChangedSlot(self, sender, vh):
33 | if vh == None:
34 | return
35 | partItem = self._partItem
36 | vhi = partItem.getVirtualHelixItemByCoord(*vh.coord())
37 | activeBaseIdx = partItem.part().activeBaseIndex()
38 | isActiveNow = vh.hasStrandAtIdx(activeBaseIdx)
39 | vhi.setActiveSliceView(isActiveNow, activeBaseIdx)
40 | # end def
41 |
42 | def updateIndexSlot(self, sender, newActiveSliceZIndex):
43 | part = self.part()
44 | if part.numberOfVirtualHelices() == 0:
45 | return
46 | newlyActiveVHs = set()
47 | activeBaseIdx = part.activeBaseIndex()
48 | for vhi in self._partItem._virtualHelixHash.values():
49 | vh = vhi.virtualHelix()
50 | if vh:
51 | isActiveNow = vh.hasStrandAtIdx(activeBaseIdx)
52 | vhi.setActiveSliceView(isActiveNow, activeBaseIdx)
53 | # end def
54 |
55 | def updateRectSlot(self, part):
56 | pass
57 | # end def
58 |
59 | ### ACCESSORS ###
60 | def part(self):
61 | return self._partItem.part()
62 | # end def
63 |
64 | ### PUBLIC METHODS FOR DRAWING / LAYOUT ###
65 | def removed(self):
66 | self._partItem = None
67 | self._controller.disconnectSignals()
68 | self.controller = None
69 | # end def
70 |
--------------------------------------------------------------------------------
/cadnano2/views/sliceview/slicerootitem.py:
--------------------------------------------------------------------------------
1 | from cadnano2.controllers.viewrootcontroller import ViewRootController
2 | from .partitem import PartItem
3 | import cadnano2.util as util
4 | util.qtWrapImport('QtCore', globals(), ['pyqtSignal', 'QObject'])
5 | util.qtWrapImport('QtWidgets', globals(), ['QGraphicsRectItem'])
6 |
7 |
8 | class SliceRootItem(QGraphicsRectItem):
9 | """
10 | PathRootItem is the root item in the PathView. It gets added directly
11 | to the pathscene by DocumentWindow. It receives two signals
12 | (partAddedSignal and selectedPartChangedSignal) via its ViewRootController.
13 |
14 | PathRootItem must instantiate its own controller to receive signals
15 | from the model.
16 | """
17 | def __init__(self, rect, parent, window, document):
18 | super(SliceRootItem, self).__init__(rect, parent)
19 | self._window = window
20 | self._document = document
21 | self._controller = ViewRootController(self, document)
22 | self._instanceItems = {}
23 |
24 | ### SIGNALS ###
25 |
26 | ### SLOTS ###
27 | def partAddedSlot(self, sender, modelPart):
28 | """
29 | Receives notification from the model that a part has been added.
30 | Views that subclass AbstractView should override this method.
31 | """
32 | self._modelPart = modelPart
33 | partItem = PartItem(modelPart, parent=self)
34 | self._instanceItems[partItem] = partItem
35 | self.setModifyState(self._window.actionModify.isChecked())
36 | # end def
37 |
38 | def selectedChangedSlot(self, itemDict):
39 | """docstring for selectedChangedSlot"""
40 | pass
41 | # end def
42 |
43 | def selectionFilterChangedSlot(self, filterNameList):
44 | pass
45 | # end def
46 |
47 | def clearSelectionsSlot(self, doc):
48 | self.scene().views()[0].clearSelectionLockAndCallbacks()
49 | # end def
50 |
51 | def resetRootItemSlot(self, doc):
52 | pass
53 | # end def
54 |
55 | ### ACCESSORS ###
56 | def sliceToolManager(self):
57 | """docstring for sliceToolManager"""
58 | return self._window.sliceToolManager
59 | # end def
60 |
61 | def window(self):
62 | return self._window
63 | # end def
64 |
65 | ### METHODS ###
66 | def removePartItem(self, partItem):
67 | del self._instanceItems[partItem]
68 | # end def
69 |
70 | def resetDocumentAndController(self, document):
71 | """docstring for resetDocumentAndController"""
72 | self._document = document
73 | self._controller = ViewRootController(self, document)
74 | if len(self._instanceItems) > 0:
75 | raise ImportError
76 | # end def
77 |
78 | def setModifyState(self, bool):
79 | """docstring for setModifyState"""
80 | for partItem in self._instanceItems:
81 | partItem.setModifyState(bool)
82 | # end def
83 |
--------------------------------------------------------------------------------
/cadnano2/views/sliceview/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/sliceview/tools/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/sliceview/tools/slicetoolmanager.py:
--------------------------------------------------------------------------------
1 | import cadnano2.util as util
2 | # import Qt stuff into the module namespace with PySide, PyQt4 independence
3 | util.qtWrapImport('QtCore', globals(), ['pyqtSignal', 'QObject'])
4 | util.qtWrapImport('QtGui', globals(), [ 'QActionGroup'])
5 |
6 |
7 | class SliceToolManager(QObject):
8 | """Manages interactions between the slice widgets/UI and the model."""
9 | def __init__(self, win):
10 | """
11 | We store mainWindow because a controller's got to have
12 | references to both the layer above (UI) and the layer below (model)
13 | """
14 | super(SliceToolManager, self).__init__()
15 | self._window = win
16 | self._connectWindowSignalsToSelf()
17 |
18 | ### SIGNALS ###
19 | activeSliceSetToFirstIndexSignal = pyqtSignal()
20 | activeSliceSetToLastIndexSignal = pyqtSignal()
21 | activePartRenumber = pyqtSignal()
22 |
23 | ### SLOTS ###
24 | def activeSliceFirstSlot(self):
25 | """
26 | Use a signal to notify the ActiveSliceHandle to move. A signal is used
27 | because the SliceToolManager must be instantiated first, and the
28 | ActiveSliceHandle can later subscribe.
29 | """
30 | part = self._window.selectedPart()
31 | if part != None:
32 | part.setActiveBaseIndex(0)
33 |
34 | def activeSliceLastSlot(self):
35 | part = self._window.selectedPart()
36 | if part != None:
37 | part.setActiveBaseIndex(part.maxBaseIdx()-1)
38 |
39 | ### METHODS ###
40 | def _connectWindowSignalsToSelf(self):
41 | """This method serves to group all the signal & slot connections
42 | made by SliceToolManager"""
43 | self._window.actionSliceFirst.triggered.connect(self.activeSliceFirstSlot)
44 | self._window.actionSliceLast.triggered.connect(self.activeSliceLastSlot)
45 |
--------------------------------------------------------------------------------
/cadnano2/views/solidview/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/cadnano2/views/solidview/__init__.py
--------------------------------------------------------------------------------
/cadnano2/views/solidview/mayaUI.py:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | #
3 | # Copyright 2011 Autodesk, Inc. All rights reserved.
4 | #
5 | # The MIT License
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | # this software and associated documentation files (the "Software"), to deal in
9 | # the Software without restriction, including without limitation the rights to
10 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | # of the Software, and to permit persons to whom the Software is furnished to do
12 | # so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in all
15 | # copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | # SOFTWARE.
24 | #
25 | ###############################################################################
26 |
27 |
28 | import maya.cmds as cmds
29 | import maya.mel as mel
30 |
31 | # Original States
32 | hiddenElements = []
33 | elementsToHide = ["toolBar", "dockControl"]
34 | mainMenuBarVisible = None
35 | gridVisible = None
36 |
37 | modelEditors = []
38 | backgroundColors = []
39 | """
40 | Hideable Stuff:
41 | UIElements
42 | Grid
43 | MainMenuBar
44 | """
45 |
46 | def simplifyUI():
47 | hideUIElements()
48 | hideMainMenuBar()
49 | hideGrid()
50 | #mel.eval("toggleModelEditorBarsInAllPanels 0;")
51 |
52 | def restoreUI():
53 | restoreUIElements()
54 | restoreMainMenuBar()
55 | restoreGrid()
56 | #mel.eval("toggleModelEditorBarsInAllPanels 1;")
57 |
58 | def setViewportQuality():
59 | global modelEditors
60 | global backgroundColors
61 | backgroundColors.append(cmds.displayRGBColor('background',q=True))
62 | backgroundColors.append(cmds.displayRGBColor('backgroundTop',q=True))
63 | backgroundColors.append(cmds.displayRGBColor('backgroundBottom',q=True))
64 | cmds.displayRGBColor('background', 1, 1, 1)
65 | cmds.displayRGBColor('backgroundTop', 0.762112, 0.87892, 1)
66 | cmds.displayRGBColor('backgroundBottom', 1, 1, 1)
67 |
68 | for i in cmds.lsUI(panels=True):
69 | if cmds.modelEditor(i, query=True, exists=True):
70 | sts = cmds.modelEditor(i, query=True, stateString=True)
71 | sts = sts.replace("$editorName", i)
72 | modelEditors.append(sts)
73 | cmds.modelEditor(i, edit=True, displayAppearance="smoothShaded", lineWidth=2)
74 | #, rendererName="hwRender_OpenGL_Renderer")
75 |
76 | def restoreViewportQuality():
77 | global modelEditors
78 | global backgroundColors
79 | bc = backgroundColors
80 | cmds.displayRGBColor('background', bc[0][0], bc[0][1], bc[0][2])
81 | cmds.displayRGBColor('backgroundTop', bc[1][0], bc[1][1], bc[1][2])
82 | cmds.displayRGBColor('backgroundBottom', bc[2][0], bc[2][1], bc[2][2])
83 |
84 | for e in modelEditors:
85 | mel.eval(e)
86 |
87 | def hideMainMenuBar():
88 | global mainMenuBarVisible
89 | mainMenuBarVisible = cmds.optionVar(q="mainWindowMenubarVis")
90 | #mel.eval("setMainMenubarVisible 0;")
91 |
92 | def restoreMainMenuBar():
93 | global mainMenuBarVisible
94 | #mel.eval("setMainMenubarVisible " + str(mainMenuBarVisible) + ";")
95 |
96 | def hideUIElements():
97 | global hiddenElements
98 | global elementsToHide
99 | for i in cmds.lsUI(ctl=True):
100 | for e in elementsToHide:
101 | if i.find(e) != -1 and cmds.control(i, q=True, visible=True):
102 | hiddenElements.append(i)
103 | #print "hiding... " + i
104 | cmds.control(i, e=True, visible=False)
105 | break
106 |
107 | def restoreUIElements():
108 | global hiddenElements
109 | for e in hiddenElements:
110 | #print "restoring... " + e
111 | cmds.control(e, e=True, visible=True)
112 | hiddenElements = []
113 |
114 | def hideGrid():
115 | global gridVisible
116 | gridVisible = cmds.optionVar(q="showGrid")
117 | cmds.grid(toggle=0)
118 |
119 | def restoreGrid():
120 | global gridVisible
121 | cmds.grid(toggle=gridVisible)
122 |
--------------------------------------------------------------------------------
/dist/cadnano2-2.4.0-py3-none-any.whl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/dist/cadnano2-2.4.0-py3-none-any.whl
--------------------------------------------------------------------------------
/dist/cadnano2-2.4.0.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglaslab/cadnano2/239ecc851407b64b44a8a4bdecdd5eb4848868f5/dist/cadnano2-2.4.0.tar.gz
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools", "wheel"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [project]
6 | name = "cadnano2"
7 | version = "2.4.13"
8 | description = "Cadnano2 for PyQt6"
9 | authors = [
10 | {name = "Shawn Douglas", email = "shawn.douglas@ucsf.edu"},
11 | ]
12 | readme = "README.md"
13 | license = {text = "MIT"}
14 | requires-python = ">=3.8"
15 | dependencies = [
16 | "PyQt6",
17 | ]
18 | classifiers = [
19 | "Development Status :: 4 - Beta",
20 | "Intended Audience :: Science/Research",
21 | "License :: OSI Approved :: MIT License",
22 | "Operating System :: OS Independent",
23 | "Programming Language :: Python :: 3",
24 | ]
25 |
26 | [project.scripts]
27 | cadnano2 = "cadnano2.main:main"
28 |
29 | [tool.setuptools]
30 | packages = ["cadnano2"]
31 | package-data = {"cadnano2" = ["ui/mainwindow/images/*.svg", "ui/mainwindow/images/*.png"]}
--------------------------------------------------------------------------------