diff --git a/Makefile b/Makefile
index 1c12f14..5a6bdb5 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,8 @@ carla: src/ui_carla.py src/ui_carla_control.py \
src/ui_carla_about.py src/ui_carla_database.py src/ui_carla_edit.py src/ui_carla_parameter.py src/ui_carla_plugin.py src/ui_carla_refresh.py \
src/ui_inputdialog_value.py
+caitlyn: src/ui_caitlyn.py
+
tools: \
src/ui_logs.py src/ui_render.py \
src/ui_settings_app.py src/ui_settings_jack.py
@@ -125,6 +127,9 @@ src/ui_claudia_launcher.py: resources/ui/claudia_launcher.ui
src/ui_claudia_launcher_app.py: resources/ui/claudia_launcher_app.ui
$(PYUIC) $< -o $@
+src/ui_caitlyn.py: resources/ui/caitlyn.ui
+ $(PYUIC) $< -o $@
+
src/ui_carla.py: resources/ui/carla.ui
$(PYUIC) $< -o $@
diff --git a/resources/ui/caitlyn.ui b/resources/ui/caitlyn.ui
new file mode 100644
index 0000000..9111206
--- /dev/null
+++ b/resources/ui/caitlyn.ui
@@ -0,0 +1,504 @@
+
+
+ CaitlynMainW
+
+
+
+ 0
+ 0
+ 712
+ 445
+
+
+
+ Caitlyn
+
+
+
+ -
+
+
+ Qt::ScrollBarAlwaysOn
+
+
+ Qt::ScrollBarAlwaysOn
+
+
+
+
+
+
+
+
+ :/16x16/application-exit.png:/16x16/application-exit.png
+
+
+ &Quit
+
+
+ Ctrl+Q
+
+
+
+
+
+ :/16x16/document-new.png:/16x16/document-new.png
+
+
+ &New...
+
+
+ Ctrl+N
+
+
+
+
+
+ :/16x16/document-open.png:/16x16/document-open.png
+
+
+ &Open...
+
+
+ Ctrl+O
+
+
+
+
+
+ :/16x16/document-save.png:/16x16/document-save.png
+
+
+ &Save
+
+
+ Ctrl+S
+
+
+
+
+
+ :/16x16/document-save-as.png:/16x16/document-save-as.png
+
+
+ Save &As...
+
+
+ Ctrl+Shift+S
+
+
+
+
+ 1
+
+
+
+
+ &About Catia
+
+
+
+
+ true
+
+
+
+ :/16x16/media-playback-start.png:/16x16/media-playback-start.png
+
+
+ &Play
+
+
+ Ctrl+Shift+P
+
+
+
+
+
+ :/16x16/media-playback-stop.png:/16x16/media-playback-stop.png
+
+
+ &Stop
+
+
+ Ctrl+Shift+X
+
+
+
+
+
+ :/16x16/media-seek-backward.png:/16x16/media-seek-backward.png
+
+
+ &Backwards
+
+
+ Ctrl+Shift+B
+
+
+
+
+
+ :/16x16/media-seek-forward.png:/16x16/media-seek-forward.png
+
+
+ &Forwards
+
+
+ Ctrl+Shift+F
+
+
+
+
+
+ :/16x16/view-refresh.png:/16x16/view-refresh.png
+
+
+ &Refresh
+
+
+ Ctrl+R
+
+
+
+
+
+ :/16x16/view-sort-ascending.png:/16x16/view-sort-ascending.png
+
+
+ &Arrange
+
+
+ Ctrl+G
+
+
+
+
+
+ :/16x16/zoom-fit-best.png:/16x16/zoom-fit-best.png
+
+
+ Auto-Fit
+
+
+
+
+
+ :/16x16/zoom-in.png:/16x16/zoom-in.png
+
+
+ Zoom In
+
+
+ Ctrl++
+
+
+
+
+
+ :/16x16/zoom-out.png:/16x16/zoom-out.png
+
+
+ Zoom Out
+
+
+ Ctrl+-
+
+
+
+
+
+ :/16x16/zoom-original.png:/16x16/zoom-original.png
+
+
+ Zoom 100%
+
+
+ Ctrl+1
+
+
+
+
+
+ :/16x16/edit-clear.png:/16x16/edit-clear.png
+
+
+ Clear &Xruns
+
+
+
+
+
+ :/16x16/configure.png:/16x16/configure.png
+
+
+ Configure JACK
+
+
+
+
+ Configure Canvas
+
+
+
+
+ true
+
+
+ Show Toolbar
+
+
+
+
+ true
+
+
+ Show Statusbar
+
+
+
+
+
+ :/16x16/configure.png:/16x16/configure.png
+
+
+ Configure Catia
+
+
+ Ctrl+P
+
+
+
+
+
+ :/16x16/media-playback-start.png:/16x16/media-playback-start.png
+
+
+ Start JACK Server
+
+
+ F5
+
+
+
+
+
+ :/16x16/media-playback-stop.png:/16x16/media-playback-stop.png
+
+
+ Stop JACK Server
+
+
+ F6
+
+
+
+
+ true
+
+
+ 32
+
+
+
+
+ true
+
+
+ 64
+
+
+
+
+ true
+
+
+ 128
+
+
+
+
+ true
+
+
+ 256
+
+
+
+
+ true
+
+
+ 512
+
+
+
+
+ true
+
+
+ 1024
+
+
+
+
+ true
+
+
+ 2048
+
+
+
+
+ true
+
+
+ 4096
+
+
+
+
+ true
+
+
+ 8192
+
+
+
+
+
+ :/16x16/media-playback-start.png:/16x16/media-playback-start.png
+
+
+ Start A2J Bridge
+
+
+ F7
+
+
+
+
+
+ :/16x16/media-playback-stop.png:/16x16/media-playback-stop.png
+
+
+ Stop A2J Bridge
+
+
+ F8
+
+
+
+
+ Export Hardware Ports...
+
+
+
+
+ Save As &Template...
+
+
+
+
+
+ :/16x16/document-print.png:/16x16/document-print.png
+
+
+ &Print...
+
+
+
+
+ Save &Image...
+
+
+
+
+
+ :/16x16/edit-undo.png:/16x16/edit-undo.png
+
+
+ Undo
+
+
+
+
+
+ :/16x16/edit-redo.png:/16x16/edit-redo.png
+
+
+ Redo
+
+
+
+
+ About Qt
+
+
+
+
+
+ :/16x16/configure.png:/16x16/configure.png
+
+
+ Configure Canvas
+
+
+
+
+ Sync Now
+
+
+
+
+ false
+
+
+ (none)
+
+
+
+
+
+ :/16x16/media-record.png:/16x16/media-record.png
+
+
+ JACK &Render
+
+
+
+
+ &Logs
+
+
+
+
+ true
+
+
+ 16
+
+
+
+
+
+
+
+
+ act_quit
+ triggered()
+ CaitlynMainW
+ close()
+
+
+ -1
+ -1
+
+
+ 336
+ 291
+
+
+
+
+
diff --git a/src/caitlyn.py b/src/caitlyn.py
new file mode 100755
index 0000000..d3b050e
--- /dev/null
+++ b/src/caitlyn.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# JACK Sequencer
+# Copyright (C) 2012 Filipe Coelho
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# For a full copy of the GNU General Public License see the COPYING file
+
+# Imports (Global)
+from PyQt4.QtCore import qFatal, QSettings
+from PyQt4.QtCore import QLineF, QPointF, QRectF, QSizeF
+from PyQt4.QtGui import QGraphicsItem, QGraphicsScene
+from PyQt4.QtGui import QPainter
+from PyQt4.QtGui import QApplication, QMainWindow
+
+# Imports (Custom Stuff)
+import ui_caitlyn
+from shared_settings import *
+
+try:
+ from PyQt4.QtOpenGL import QGLWidget
+ hasGL = True
+except:
+ hasGL = False
+
+# ------------------------------------------------------------------------------
+# Caitlyn Qt Graphics Scene
+
+class CaitlynCanvasScene(QGraphicsScene):
+ def __init__(self, parent, view):
+ QGraphicsScene.__init__(self, parent)
+
+ self.m_view = view
+ if not self.m_view:
+ qFatal("CaitlynCanvasScene() - invalid view")
+
+# ------------------------------------------------------------------------------
+# Caitlyn items
+
+class CaitlynCanvasTimelineTopBar(QGraphicsItem):
+ def __init__(self, scene, parent=None):
+ QGraphicsItem.__init__(self, parent, scene)
+
+ # horizontal length, matches min(full length of song, window)
+ self.m_length = 100
+
+ def boundingRect(self):
+ return QRectF(0, 0, self.m_length*4, 4)
+
+ def paint(self, painter, option, widget):
+ painter.setRenderHint(QPainter.Antialiasing, False)
+
+ painter.drawRect(0, 0, self.m_length*14, 16)
+
+class CaitlynCanvasBox(QGraphicsItem):
+ def __init__(self, scene, parent=None):
+ QGraphicsItem.__init__(self, parent, scene)
+
+ self.m_length = 1.0
+
+ def length(self):
+ return self.m_length
+
+ def boundingRect(self):
+ return QRectF(0, 0, self.m_length*4, 4)
+
+ def paint(self, painter, option, widget):
+ painter.setRenderHint(QPainter.Antialiasing, False)
+
+ painter.drawRect(0, 0, self.m_length*14, 16)
+
+# ------------------------------------------------------------------------------
+# Caitlyn Main Window
+
+class CaitlynMainW(QMainWindow, ui_caitlyn.Ui_CaitlynMainW):
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent)
+ self.setupUi(self)
+
+ self.settings = QSettings("Cadence", "Caitlyn")
+ self.loadSettings(True)
+
+ self.scene = CaitlynCanvasScene(self, self.graphicsView)
+ self.graphicsView.setScene(self.scene)
+ self.graphicsView.setRenderHint(QPainter.Antialiasing, False)
+ self.graphicsView.setRenderHint(QPainter.TextAntialiasing, False)
+
+ self.item1 = CaitlynCanvasBox(self.scene)
+
+ def saveSettings(self):
+ self.settings.setValue("Geometry", self.saveGeometry())
+
+ def loadSettings(self, geometry):
+ if geometry:
+ self.restoreGeometry(self.settings.value("Geometry", ""))
+
+ self.m_savedSettings = {
+ "Main/RefreshInterval": self.settings.value("Main/RefreshInterval", 120, type=int)
+ }
+
+ def closeEvent(self, event):
+ self.scene.removeItem(self.item1)
+
+ self.saveSettings()
+ QMainWindow.closeEvent(self, event)
+
+#--------------- main ------------------
+if __name__ == '__main__':
+ # App initialization
+ app = QApplication(sys.argv)
+ app.setApplicationName("Caitlyn")
+ app.setApplicationVersion(VERSION)
+ app.setOrganizationName("Cadence")
+ #app.setWindowIcon(QIcon(":/scalable/caitlyn.svg"))
+
+ # Show GUI
+ gui = CaitlynMainW()
+
+ # Set-up custom signal handling
+ setUpSignals(gui)
+
+ gui.show()
+
+ # App-Loop and exit
+ sys.exit(app.exec_())