Exemple #1
0
class AppMenu:
    def __init__(self, app, tray, widget, conf, build_icons):
        self.menu = QtGui.QMenu(widget)
        tray.setContextMenu(self.menu)
        self.conf = conf
        self.app = app
        self.build_icons = build_icons
        self.create_default_menu_items()

    def update(self, projects):
        projects.sort(key=self.sort_key)
        self.menu.clear()
        for project in projects:
            self.create_menu_item(project.name, self.build_icons.for_status(project.get_build_status()), project.url, project.get_last_build_time(), project.server_url)
        self.create_default_menu_items()

    def sort_key(self, p):
        if self.conf.get_sort_by_name():
            return p.name
        return p.get_last_build_time()

    def create_default_menu_items(self):
        self.menu.addSeparator()
        self.menu.addAction(QtGui.QAction("About", self.menu, triggered=self.about_clicked))
        self.menu.addAction(QtGui.QAction("Preferences", self.menu, triggered=self.preferences_clicked))
        self.menu.addAction(QtGui.QAction("Exit", self.menu, triggered=self.exit))

    def about_clicked(self, widget):
        QtGui.QMessageBox.about(self.menu, "About BuildNotify %s" % VERSION,
                                "<b>BuildNotify %s</b> has been developed using PyQt4 and serves as a build notification tool for cruise control. In case of any suggestions/bugs," % VERSION +
                                "please visit <a href=\"http://bitbucket.org/Anay/buildnotify\">http://bitbucket.org/Anay/buildnotify</a> and provide your feedback.")

    def preferences_clicked(self, widget):
        self.preferences_dialog = PreferencesDialog(self.conf, self.menu)
        if self.preferences_dialog.exec_() == QtGui.QDialog.Accepted:
            self.preferences_dialog.save()
            self.app.emit(QtCore.SIGNAL('reload_project_data'))

    def exit(self, widget):
        sys.exit()

    def create_menu_item(self, label, icon, url, last_build_time, server_url):

        menu_item_label = label
        if self.conf.get_value("lastBuildTimeForProject"):
            menu_item_label = label + ", " + DistanceOfTime(last_build_time, self.conf.get_project_timezone(url, server_url)).age() + " ago"

        action = self.menu.addAction(icon, menu_item_label)
        action.setIconVisibleInMenu(True)
        receiver = lambda url=url: self.open_url(self, url)
        QtCore.QObject.connect(action, QtCore.SIGNAL('triggered()'), receiver)

    def open_url(self, something, url):
        webbrowser.open(url)
Exemple #2
0
 def editPreferences(self, *ignored_arguments):
     """Show the preferences dialog."""
     pref_dialog = PreferencesDialog(self, self.prefs)
     pref_dialog.show_all()
     response = pref_dialog.run()
     if response == gtk.RESPONSE_OK:
         pref_dialog.apply(self.prefs)
     pref_dialog.hide()
Exemple #3
0
 def __init__(self):
     self.pdialog = PreferencesDialog()
     self.pdialog.signals.settingsChanged.connect(self.initializeApi)
     self.signals = self.Signals()
     self.updateTimer = QTimer();
     QObject.connect(self.updateTimer, SIGNAL("timeout()"), self.getFileList)
     self.initializeApi()
Exemple #4
0
    def preferences(self):

        try:

            PreferencesDialog(self.root)

        except ExceptionHandler.ExceptionType as e:

            ExceptionHandler.add(e)
class WordNotify_Window(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setupUi(self)                  # UI init

        self.initPreferences()              # prefs init
        self.initDictList()                 # dicts init
        self.initSysTray()                  # sys tray init
        self.sysTray.show()                 # sys tray is visible

        self.connect(self.dictListView, QtCore.SIGNAL('clicked(QModelIndex)'), self.selectDict)
        self.connect(self.dictListView, QtCore.SIGNAL('doubleClicked(QModelIndex)'), self.editDict)
        self.connect(self.stopPushButton, QtCore.SIGNAL('clicked()'), self.stopClicked)
        self.connect(self.startPushButton, QtCore.SIGNAL('clicked()'), self.startClicked)
        self.connect(self.optionsPushButton, QtCore.SIGNAL('clicked()'), self.optionsClicked)
        self.connect(self.dictNewPushButton, QtCore.SIGNAL('clicked()'), self.newDict)
        self.connect(self.dictAddPushButton, QtCore.SIGNAL('clicked()'), self.addDict)
        self.connect(self.dictEditPushButton, QtCore.SIGNAL('clicked()'), self.editDict)
        self.connect(self.dictRemovePushButton, QtCore.SIGNAL('clicked()'), self.removeDict)
        self.connect(self.actionAbout, QtCore.SIGNAL('triggered()'), self.about)
        self.connect(self.actionAbout_Qt, QtCore.SIGNAL('triggered()'), self.aboutQt)
        self.connect(self.actionQuit, QtCore.SIGNAL('triggered()'), self.quit)
        self.connect(self.actionStart, QtCore.SIGNAL('triggered()'), self.startClicked)
        self.connect(self.actionStop, QtCore.SIGNAL('triggered()'), self.stopClicked)
        self.connect(self.actionShowHide, QtCore.SIGNAL('triggered()'), self.show_hideTriggered)
        self.connect(self.actionNew, QtCore.SIGNAL('triggered()'), self.newDict)
        self.connect(self.actionAdd, QtCore.SIGNAL('triggered()'), self.addDict)
        self.connect(self.actionEdit, QtCore.SIGNAL('triggered()'), self.editDict)
        self.connect(self.actionRemove, QtCore.SIGNAL('triggered()'), self.removeDict)
        self.connect(self.actionPreferences, QtCore.SIGNAL('triggered()'), self.optionsClicked)

    def initPreferences(self):
        self.preferences = QtCore.QSettings("preferences.cfg", QtCore.QSettings.IniFormat)  # reading cfg ini file
        self.preferences.setIniCodec('UTF-8')

    def initSysTray(self):
        self.sysTray = QtGui.QSystemTrayIcon()          # creating sys tray
        iconPath = os.path.join(os.getcwd(), "icon.png")   # unicoded icon path
        iconPath = iconPath.decode('utf-8')             # unicoded icon path
        self.sysTray.setIcon(QtGui.QIcon(iconPath))     # setting icon
        rightClickMenu = QtGui.QMenu()                  # creating menu
        rightClickMenu.addAction(self.actionStart)      # adding actions to menu
        rightClickMenu.addAction(self.actionStop)       # adding actions to menu
        rightClickMenu.addSeparator()                   # adding separator
        rightClickMenu.addAction(self.actionShowHide)   # adding actions to menu
        rightClickMenu.addSeparator()                   # adding separator
        rightClickMenu.addAction(self.actionAbout)      # adding actions to menu
        rightClickMenu.addAction(self.actionAbout_Qt)   # adding actions to menu
        rightClickMenu.addSeparator()                   # separator
        self.actionQuit.setIcon(QtGui.QIcon("icons/exit.png"))
        rightClickMenu.addAction(self.actionQuit)       # adding actions to menu
        self.sysTray.setContextMenu(rightClickMenu)     # setting menu for systray
        self.sysTray.activated.connect(self.click_trap) # signal for icon left click

    def click_trap(self, value):
        if value == self.sysTray.Trigger:   # left click!
            self.show_hideTriggered()       # invoking show/hide event

    def show_hideTriggered(self):
        if self.isHidden():         # check if MainWindow is hidden
            self.show()             # if True then Show
        else:
            self.hide()             # else Hide

    def initDictList(self):
        dictsPath = os.path.join(os.getcwd(), "dicts")      # setting path with current path + dicts
        dictsPath = dictsPath.decode('utf-8')
        self.model = QtGui.QFileSystemModel()               # creating FS model
        self.modelIndex = QtCore.QModelIndex()              # creating model index
        self.model.setRootPath(dictsPath)                   # setting path for model
        self.modelIndex = self.model.index(dictsPath)       # getting model index
        self.dictListView.setModel(self.model)              # setting model for ListView
        self.dictListView.setRootIndex(self.modelIndex)     # setting index for ListView

        currentIndex = self.preferences.value("dict")       # reading index from cfg
        currentIndex = currentIndex.toString()              # translation to QString

        self.dictListView.setAutoScroll(True)               # autoscrolling
        self.dictListView.setCurrentIndex(self.model.index(currentIndex))   # setting index
        self.dictListView.scrollTo(self.model.index(currentIndex))  # scroll to current index

    def selectDict(self):
        currentIndex = self.dictListView.currentIndex()         # getting current index
        filePath = self.model.filePath(currentIndex)            # getting file path from index
        self.debug("%d %s" % (currentIndex.row(), filePath))    # debug info current row & file path
        self.preferences.setValue("index", currentIndex.row())  # saving row to cfg
        self.preferences.setValue("dict", filePath)             # saving file path to cfg
        self.preferences.sync()                                 # updating cfg file

    def newDict(self):
        selectDialog = QtGui.QFileDialog()
        newDictPath = selectDialog.getSaveFileName(self, self.tr('Name of new dict...'), 'dicts', 'TXT Files (*.txt)')
        if newDictPath != "":
            self.editorForm = EditorForm()
            self.editorForm.filePathLabel.setText(newDictPath)
            self.editorForm.show()
#            QtGui.QMessageBox.information(self, "CREATED", newDictPath + "\nHas been created!")

    def addDict(self):
        selectDialog = QtGui.QFileDialog()
        addDictPath = selectDialog.getOpenFileName(self, self.tr('Select dict...'), '', 'TXT Files (*.txt)')
        if addDictPath != "":
            addDictPath = str(addDictPath.toUtf8())
            addDictPath = addDictPath.decode('utf-8')
            shutil.copy(os.path.abspath(addDictPath), "dicts")
            QtGui.QMessageBox.information(self, self.tr("ADDED"), addDictPath + self.tr("\nHas been added to \'dicts\' directory!"))

    def editDict(self):
        filePath = self.preferences.value("dict")
        filePath = filePath.toString()
        filePath = str(filePath.toUtf8())
        filePath = filePath.decode('utf-8')

        f = open(filePath, 'r')
        data = f.read()
        f.close()

        data = QtCore.QString.fromUtf8(data)
        self.editorForm = EditorForm()
        self.editorForm.plainTextEdit.setPlainText(data)
        self.editorForm.filePathLabel.setText(filePath)
        self.editorForm.show()

    def removeDict(self):
        filePath = self.preferences.value("dict")
        filePath = filePath.toString()
        reply = QtGui.QMessageBox.question(self, self.tr("DELETION"), self.tr("Really delete?\n") + filePath, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            filePath = str(filePath.toUtf8())
            filePath = filePath.decode('utf-8')
            os.remove(os.path.abspath(filePath))
            QtGui.QMessageBox.information(self, self.tr("DELETED"), filePath + self.tr("\nHas been deleted!"))

    def initTimer(self):
        self.timer = QtCore.QTimer()
        self.timer.start(self.delay)
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.timerUpdate)

    def timerUpdate(self):
        dictSize = len(self.myDict)
        #random.shuffle(self.myList)
        randNumber = random.randrange(1, dictSize)
        randLine = self.myDict[randNumber]
        #self.debug("%d %s" % (randnumber, randline.rstrip()))

        if (len(randLine) < 3):
            head, body, extra = randLine[0], randLine[1], ''
        else:
            head, body, extra = randLine[0], randLine[1], randLine[2]

        self.debug("[%d/%d] %s ― %s ― %s" % (randNumber, dictSize, head, body, extra))

        head = QtCore.QString.fromUtf8(head)
        body = body + "\n" + extra
        body = body.rstrip()
        #extra = QtCore.QString.fromUtf8(extra)
        body = QtCore.QString.fromUtf8(body)

        if self.notifyd == True:
            #head = str(head)
            #body = str(body)
            head = unicode(head)
            body = unicode(body)
            body = "<b><i>" + body + "</i></b>"
            iconPath = os.path.join(os.getcwd(), "icon.png")   # unicoded icon path
            iconPath = iconPath.decode('utf-8')
            self.showNotifyd(head, body, iconPath, self.timeout)
        elif self.notifyd == False:
            self.sysTray.showMessage(head, body, self.noicon, self.timeout)
        else:
            QtGui.QMessageBox.information(self, self.tr("ERROR"), self.tr("Unexpected error occurred!"))
            self.debug("Unexpected error occurred!")

    def showNotifyd(self, head, body, icon, timeout):
        #msg = pynotify.Notification(head, body, icon)
        #msg.set_timeout(timeout)
        #msg.show()
        ncmd = "notify-send"
        subprocess.call([ncmd, "-t", str(timeout), "-i", icon, head, body])

    def startClicked(self):
        #self.hide()
        filePath = self.preferences.value("dict").toString()
        self.timeout = self.preferences.value("timeout").toInt()[0]*1000
        self.delay = self.preferences.value("delay").toInt()[0]*1000
        if self.preferences.value("notifyd").toString() == "true":
            self.notifyd = True
            #global pynotify
            #import pynotify
            #pynotify.init("init")
        else:
            self.notifyd = False
        self.icon = QtGui.QSystemTrayIcon.Information
        self.noicon = QtGui.QSystemTrayIcon.NoIcon
        self.myDict = {}
        self.myIndex = 0
        filePath = str(filePath.toUtf8())
        filePath = filePath.decode('utf-8')

        with open(filePath, 'rb') as f:
            reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
            for line in reader:
                self.myIndex += 1
                self.myDict[self.myIndex] = line
        f.close()

        #random.shuffle(self.myList)

        self.initTimer()
        self.sysTray.showMessage("qWordNotify", self.tr("Timer started!"), self.icon, 1000)
        self.debug("Timer started!")

    def stopClicked(self):
        self.timer.stop()
        self.sysTray.showMessage("qWordNotify", self.tr("Timer stopped!"), self.icon, 1000)
        self.debug("Timer stopped!")

    def optionsClicked(self):
        self.prefDialog = PreferencesDialog()
        self.prefDialog.setModal(True)
        self.prefDialog.show()

    def about(self):
        QtGui.QMessageBox.information(self, self.tr("About qWordNotify"), "<b>qWordNotify 0.1</b><br>(c) 2014 Anonymous")

    def aboutQt(self):
        QtGui.QApplication.aboutQt()

    def closeEvent(self,event):
        reply=QtGui.QMessageBox.question(self, self.tr("QUITTING"), self.tr("Are you sure to quit?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        if reply==QtGui.QMessageBox.Yes:
            self.preferences.sync()
            event.accept()
        else:
            event.ignore()

    def quit(self):
        QtGui.qApp.quit()

    def debug(self, msg):
        print "DEBUG:", msg
        
    def tr(self, text):
        return QtCore.QCoreApplication.translate("WordNotify_Window", text)
 def on_preferences_clicked(self, widget):
     dialog = PreferencesDialog()
     dialog.dialog.set_transient_for(widget.get_toplevel())
     dialog.run()
     dialog.destroy()
 def __init__(self):
     self.pdialog = PreferencesDialog()
     self.pdialog.signals.settingsChanged.connect(self.initializeApi)
     self.signals = self.Signals()
     self.initializeApi()
class CloudHandle(object):

    fileList = []

    def __init__(self):
        self.pdialog = PreferencesDialog()
        self.pdialog.signals.settingsChanged.connect(self.initializeApi)
        self.signals = self.Signals()
        self.initializeApi()

    def initializeApi(self):
        self.connected = False
        try:
            username = self.pdialog.settings['username']
            password = self.pdialog.settings['password']
            if username == '' or password == '':
                raise ValueError('Empty password or username')
            self.api = CloudApi(username, password)
            self.getFileList()
        except (KeyError, ValueError):
            self.pdialog.show()
            print "Error reading settings"

    def getFileList(self):
        self.api.getFileList(self.pdialog.settings['list_size'],
                             self.gotFileList)

    def gotFileList(self, l):
        self.connected = True
        self.fileList = l
        self.signals.gotFileList.emit(l)

    def addItem(self, url):
        url = str(url)
        if urlparse.urlparse(url).scheme == "file":
            self.api.uploadFile(url, self.itemAdded)
        else:
            self.api.bookmark(url, self.itemAdded)
        self.signals.uploadStarted.emit()

    def itemAdded(self, item):
        self.fileList.insert(0, item)
        self.fileList.pop()
        self.signals.gotFileList.emit(self.fileList)
        if self.pdialog.settings['auto_clipboard']:
            self.signals.loadClipboard.emit(item['url'])
        if self.pdialog.settings['notifications']:
            if item['item_type'] == 'bookmark':
                self.notify('Bookmarked - ' + item['name'], item['url'])
            else:
                self.notify('File Uploaded - ' + item['name'], item['url'])
        self.signals.uploadFinished.emit()

    def deleteItem(self, url):
        url = str(url)
        self.api.delete(url, self.deleted)

    def deleted(self, x):
        self.getFileList()
        if self.pdialog.settings['notifications']:
            self.notify("Deleted - " + x['name'],
                        'This item was removed from your CloudApp')

    def showPreferences(self):
        self.pdialog.show()

    def notify(self, title, text, icon=None):
        try:
            import pynotify
            if pynotify.init("Cloud App"):
                n = pynotify.Notification(title, text)
                n.set_timeout(5)
                n.show()
            else:
                print "there was a problem initializing the pynotify module"
        except:
            print "you don't seem to have pynotify installed"

    class Signals(QObject):
        gotFileList = pyqtSignal(list)
        loadClipboard = pyqtSignal(str)
        uploadStarted = pyqtSignal()
        uploadFinished = pyqtSignal()
Exemple #9
0
class JackMixer(SerializedObject):

    # scales suitable as meter scales
    meter_scales = [
        scale.K20(),
        scale.K14(),
        scale.IEC268(),
        scale.Linear70dB(),
        scale.IEC268Minimalistic()
    ]

    # scales suitable as volume slider scales
    slider_scales = [scale.Linear30dB(), scale.Linear70dB()]

    # name of settings file that is currently open
    current_filename = None

    _init_solo_channels = None

    def __init__(self, client_name='jack_mixer'):
        self.visible = False
        self.nsm_client = None

        if os.environ.get('NSM_URL'):
            self.nsm_client = NSMClient(
                prettyName="jack_mixer",
                saveCallback=self.nsm_save_cb,
                openOrNewCallback=self.nsm_open_cb,
                supportsSaveStatus=False,
                hideGUICallback=self.nsm_hide_cb,
                showGUICallback=self.nsm_show_cb,
                exitProgramCallback=self.nsm_exit_cb,
                loggingLevel="error",
            )
            self.nsm_client.announceGuiVisibility(self.visible)
        else:
            self.visible = True
            self.create_mixer(client_name, with_nsm=False)

    def create_mixer(self, client_name, with_nsm=True):
        self.mixer = jack_mixer_c.Mixer(client_name)
        if not self.mixer:
            raise RuntimeError("Failed to create Mixer instance.")

        self.create_ui(with_nsm)
        self.window.set_title(client_name)

        self.monitor_channel = self.mixer.add_output_channel(
            "Monitor", True, True)
        self.save = False

        GLib.timeout_add(33, self.read_meters)
        GLib.timeout_add(50, self.midi_events_check)

        if with_nsm:
            GLib.timeout_add(200, self.nsm_react)

    def new_menu_item(self, title, callback=None, accel=None, enabled=True):
        menuitem = Gtk.MenuItem.new_with_mnemonic(title)
        menuitem.set_sensitive(enabled)
        if callback:
            menuitem.connect("activate", callback)
        if accel:
            key, mod = Gtk.accelerator_parse(accel)
            menuitem.add_accelerator("activate", self.menu_accelgroup, key,
                                     mod, Gtk.AccelFlags.VISIBLE)
        return menuitem

    def create_ui(self, with_nsm):
        self.channels = []
        self.output_channels = []
        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        self.window.set_icon_name('jack_mixer')
        self.gui_factory = gui.Factory(self.window, self.meter_scales,
                                       self.slider_scales)
        self.gui_factory.connect('midi-behavior-mode-changed',
                                 self.on_midi_behavior_mode_changed)
        self.gui_factory.emit_midi_behavior_mode()

        self.vbox_top = Gtk.VBox()
        self.window.add(self.vbox_top)

        self.menu_accelgroup = Gtk.AccelGroup()
        self.window.add_accel_group(self.menu_accelgroup)

        self.menubar = Gtk.MenuBar()
        self.vbox_top.pack_start(self.menubar, False, True, 0)

        mixer_menu_item = Gtk.MenuItem.new_with_mnemonic("_Mixer")
        self.menubar.append(mixer_menu_item)
        edit_menu_item = Gtk.MenuItem.new_with_mnemonic('_Edit')
        self.menubar.append(edit_menu_item)
        help_menu_item = Gtk.MenuItem.new_with_mnemonic('_Help')
        self.menubar.append(help_menu_item)

        self.width = 420
        self.height = 420
        self.paned_position = 210
        self.window.set_default_size(self.width, self.height)

        self.mixer_menu = Gtk.Menu()
        mixer_menu_item.set_submenu(self.mixer_menu)

        self.mixer_menu.append(
            self.new_menu_item('New _Input Channel', self.on_add_input_channel,
                               "<Control>N"))
        self.mixer_menu.append(
            self.new_menu_item('New Output _Channel',
                               self.on_add_output_channel,
                               "<Shift><Control>N"))

        self.mixer_menu.append(Gtk.SeparatorMenuItem())
        if not with_nsm:
            self.mixer_menu.append(
                self.new_menu_item('_Open...', self.on_open_cb, "<Control>O"))

        self.mixer_menu.append(
            self.new_menu_item('_Save', self.on_save_cb, "<Control>S"))

        if not with_nsm:
            self.mixer_menu.append(
                self.new_menu_item('Save _As...', self.on_save_as_cb,
                                   "<Shift><Control>S"))

        self.mixer_menu.append(Gtk.SeparatorMenuItem())
        if with_nsm:
            self.mixer_menu.append(
                self.new_menu_item('_Hide', self.nsm_hide_cb, "<Control>W"))
        else:
            self.mixer_menu.append(
                self.new_menu_item('_Quit', self.on_quit_cb, "<Control>Q"))

        edit_menu = Gtk.Menu()
        edit_menu_item.set_submenu(edit_menu)

        self.channel_edit_input_menu_item = self.new_menu_item(
            '_Edit Input Channel', enabled=False)
        edit_menu.append(self.channel_edit_input_menu_item)
        self.channel_edit_input_menu = Gtk.Menu()
        self.channel_edit_input_menu_item.set_submenu(
            self.channel_edit_input_menu)

        self.channel_edit_output_menu_item = self.new_menu_item(
            'E_dit Output Channel', enabled=False)
        edit_menu.append(self.channel_edit_output_menu_item)
        self.channel_edit_output_menu = Gtk.Menu()
        self.channel_edit_output_menu_item.set_submenu(
            self.channel_edit_output_menu)

        self.channel_remove_input_menu_item = self.new_menu_item(
            '_Remove Input Channel', enabled=False)
        edit_menu.append(self.channel_remove_input_menu_item)
        self.channel_remove_input_menu = Gtk.Menu()
        self.channel_remove_input_menu_item.set_submenu(
            self.channel_remove_input_menu)

        self.channel_remove_output_menu_item = self.new_menu_item(
            'Re_move Output Channel', enabled=False)
        edit_menu.append(self.channel_remove_output_menu_item)
        self.channel_remove_output_menu = Gtk.Menu()
        self.channel_remove_output_menu_item.set_submenu(
            self.channel_remove_output_menu)

        edit_menu.append(Gtk.SeparatorMenuItem())
        edit_menu.append(
            self.new_menu_item('Shrink Input Channels',
                               self.on_narrow_input_channels_cb,
                               "<Control>minus"))
        edit_menu.append(
            self.new_menu_item('Expand Input Channels',
                               self.on_widen_input_channels_cb,
                               "<Control>plus"))
        edit_menu.append(Gtk.SeparatorMenuItem())

        edit_menu.append(
            self.new_menu_item('_Clear', self.on_channels_clear, "<Control>X"))
        edit_menu.append(Gtk.SeparatorMenuItem())
        edit_menu.append(
            self.new_menu_item('_Preferences', self.on_preferences_cb,
                               "<Control>P"))

        help_menu = Gtk.Menu()
        help_menu_item.set_submenu(help_menu)

        help_menu.append(self.new_menu_item('_About', self.on_about, "F1"))

        self.hbox_top = Gtk.HBox()
        self.vbox_top.pack_start(self.hbox_top, True, True, 0)

        self.scrolled_window = Gtk.ScrolledWindow()
        self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                        Gtk.PolicyType.AUTOMATIC)

        self.hbox_inputs = Gtk.Box()
        self.hbox_inputs.set_spacing(0)
        self.hbox_inputs.set_border_width(0)
        self.hbox_top.set_spacing(0)
        self.hbox_top.set_border_width(0)
        self.scrolled_window.add(self.hbox_inputs)
        self.hbox_outputs = Gtk.Box()
        self.hbox_outputs.set_spacing(0)
        self.hbox_outputs.set_border_width(0)
        self.scrolled_output = Gtk.ScrolledWindow()
        self.scrolled_output.set_policy(Gtk.PolicyType.AUTOMATIC,
                                        Gtk.PolicyType.AUTOMATIC)
        self.scrolled_output.add(self.hbox_outputs)
        self.paned = Gtk.HPaned()
        self.paned.set_wide_handle(True)
        self.hbox_top.pack_start(self.paned, True, True, 0)
        self.paned.pack1(self.scrolled_window, True, False)
        self.paned.pack2(self.scrolled_output, True, False)
        self.window.connect("destroy", Gtk.main_quit)
        self.window.connect('delete-event', self.on_delete_event)

    def nsm_react(self):
        self.nsm_client.reactToMessage()
        return True

    def nsm_hide_cb(self, *args):
        self.window.hide()
        self.visible = False
        self.nsm_client.announceGuiVisibility(False)

    def nsm_show_cb(self):
        width, height = self.window.get_size()
        self.window.show_all()
        self.paned.set_position(self.paned_position / self.width * width)

        self.visible = True
        self.nsm_client.announceGuiVisibility(True)

    def nsm_open_cb(self, path, session_name, client_name):
        self.create_mixer(client_name, with_nsm=True)
        self.current_filename = path + '.xml'
        if os.path.isfile(self.current_filename):
            f = open(self.current_filename, 'r')
            self.load_from_xml(f, from_nsm=True)
            f.close()
        else:
            f = open(self.current_filename, 'w')
            f.close()

    def nsm_save_cb(self, path, session_name, client_name):
        self.current_filename = path + '.xml'
        f = open(self.current_filename, 'w')
        self.save_to_xml(f)
        f.close()

    def nsm_exit_cb(self, path, session_name, client_name):
        Gtk.main_quit()

    def on_midi_behavior_mode_changed(self, gui_factory, value):
        self.mixer.midi_behavior_mode = value

    def on_delete_event(self, widget, event):
        if self.nsm_client:
            self.nsm_hide_cb()
            return True

        return self.on_quit_cb()

    def sighandler(self, signum, frame):
        log.debug("Signal %d received.", signum)
        if signum == signal.SIGUSR1:
            self.save = True
        elif signum == signal.SIGTERM:
            self.on_quit_cb()
        elif signum == signal.SIGINT:
            self.on_quit_cb()
        else:
            log.warning("Unknown signal %d received.", signum)

    def cleanup(self):
        log.debug("Cleaning jack_mixer.")
        if not self.mixer:
            return

        for channel in self.channels:
            channel.unrealize()

        self.mixer.destroy()

    def on_open_cb(self, *args):
        dlg = Gtk.FileChooserDialog(title='Open',
                                    parent=self.window,
                                    action=Gtk.FileChooserAction.OPEN)
        dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
        dlg.set_default_response(Gtk.ResponseType.OK)
        if dlg.run() == Gtk.ResponseType.OK:
            filename = dlg.get_filename()
            try:
                f = open(filename, 'r')
                self.load_from_xml(f)
            except Exception as e:
                error_dialog(self.window, "Failed loading settings (%s)", e)
            else:
                self.current_filename = filename
            finally:
                f.close()
        dlg.destroy()

    def on_save_cb(self, *args):
        if not self.current_filename:
            return self.on_save_as_cb()
        f = open(self.current_filename, 'w')
        self.save_to_xml(f)
        f.close()

    def on_save_as_cb(self, *args):
        dlg = Gtk.FileChooserDialog(title='Save',
                                    parent=self.window,
                                    action=Gtk.FileChooserAction.SAVE)
        dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                        Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
        dlg.set_default_response(Gtk.ResponseType.OK)
        if dlg.run() == Gtk.ResponseType.OK:
            self.current_filename = dlg.get_filename()
            self.on_save_cb()
        dlg.destroy()

    def on_quit_cb(self, *args):
        if not self.nsm_client and self.gui_factory.get_confirm_quit():
            dlg = Gtk.MessageDialog(parent=self.window,
                                    message_type=Gtk.MessageType.QUESTION,
                                    buttons=Gtk.ButtonsType.NONE)
            dlg.set_markup("<b>Quit application?</b>")
            dlg.format_secondary_markup(
                "All jack_mixer ports will be closed and connections lost,"
                "\nstopping all sound going through jack_mixer.\n\n"
                "Are you sure?")
            dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                            Gtk.STOCK_QUIT, Gtk.ResponseType.OK)
            response = dlg.run()
            dlg.destroy()
            if response != Gtk.ResponseType.OK:
                return True

        Gtk.main_quit()

    def on_narrow_input_channels_cb(self, widget):
        for channel in self.channels:
            channel.narrow()

    def on_widen_input_channels_cb(self, widget):
        for channel in self.channels:
            channel.widen()

    preferences_dialog = None

    def on_preferences_cb(self, widget):
        if not self.preferences_dialog:
            self.preferences_dialog = PreferencesDialog(self)
        self.preferences_dialog.show()
        self.preferences_dialog.present()

    def on_add_channel(self, inout="input", default_name="Input"):
        dialog = getattr(self, '_add_{}_dialog'.format(inout), None)
        values = getattr(self, '_add_{}_values'.format(inout), {})

        if dialog == None:
            cls = NewInputChannelDialog if inout == 'input' else NewOutputChannelDialog
            dialog = cls(app=self)
            setattr(self, '_add_{}_dialog'.format(inout), dialog)

        names = {
            ch.channel_name
            for ch in (
                self.channels if inout == 'input' else self.output_channels)
        }
        values.setdefault('name', default_name)
        while True:
            if values['name'] in names:
                values['name'] = add_number_suffix(values['name'])
            else:
                break

        dialog.fill_ui(**values)
        dialog.set_transient_for(self.window)
        dialog.show()
        ret = dialog.run()
        dialog.hide()

        if ret == Gtk.ResponseType.OK:
            result = dialog.get_result()
            setattr(self, '_add_{}_values'.format(inout), result)
            method = getattr(
                self,
                'add_channel' if inout == 'input' else 'add_output_channel')
            channel = method(**result)
            if self.visible or self.nsm_client == None:
                self.window.show_all()

    def on_add_input_channel(self, widget):
        return self.on_add_channel("input", "Input")

    def on_add_output_channel(self, widget):
        return self.on_add_channel("output", "Output")

    def on_edit_input_channel(self, widget, channel):
        log.debug('Editing input channel "%s".', channel.channel_name)
        channel.on_channel_properties()

    def remove_channel_edit_input_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_input_menu.remove(widget)

    def on_remove_input_channel(self, widget, channel):
        log.debug('Removing input channel "%s".', channel.channel_name)
        self.channel_remove_input_menu.remove(widget)
        self.channel_edit_input_menu.foreach(
            self.remove_channel_edit_input_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.channels[i] is channel:
                channel.unrealize()
                del self.channels[i]
                self.hbox_inputs.remove(channel.get_parent())
                break
        if not self.channels:
            self.channel_edit_input_menu_item.set_sensitive(False)
            self.channel_remove_input_menu_item.set_sensitive(False)

    def on_edit_output_channel(self, widget, channel):
        log.debug('Editing output channel "%s".', channel.channel_name)
        channel.on_channel_properties()

    def remove_channel_edit_output_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_output_menu.remove(widget)

    def on_remove_output_channel(self, widget, channel):
        log.debug('Removing output channel "%s".', channel.channel_name)
        self.channel_remove_output_menu.remove(widget)
        self.channel_edit_output_menu.foreach(
            self.remove_channel_edit_output_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.output_channels[i] is channel:
                channel.unrealize()
                del self.output_channels[i]
                self.hbox_outputs.remove(channel.get_parent())
                break
        if not self.output_channels:
            self.channel_edit_output_menu_item.set_sensitive(False)
            self.channel_remove_output_menu_item.set_sensitive(False)

    def rename_channels(self, container, parameters):
        if (container.get_label() == parameters['oldname']):
            container.set_label(parameters['newname'])

    def on_channel_rename(self, oldname, newname):
        rename_parameters = {'oldname': oldname, 'newname': newname}
        self.channel_edit_input_menu.foreach(self.rename_channels,
                                             rename_parameters)
        self.channel_edit_output_menu.foreach(self.rename_channels,
                                              rename_parameters)
        self.channel_remove_input_menu.foreach(self.rename_channels,
                                               rename_parameters)
        self.channel_remove_output_menu.foreach(self.rename_channels,
                                                rename_parameters)
        log.debug('Renaming channel from "%s" to "%s".', oldname, newname)

    def on_channels_clear(self, widget):
        dlg = Gtk.MessageDialog(
            parent=self.window,
            modal=True,
            message_type=Gtk.MessageType.WARNING,
            text="Are you sure you want to clear all channels?",
            buttons=Gtk.ButtonsType.OK_CANCEL)
        if not widget or dlg.run() == Gtk.ResponseType.OK:
            for channel in self.output_channels:
                channel.unrealize()
                self.hbox_outputs.remove(channel.get_parent())
            for channel in self.channels:
                channel.unrealize()
                self.hbox_inputs.remove(channel.get_parent())
            self.channels = []
            self.output_channels = []
            self.channel_edit_input_menu = Gtk.Menu()
            self.channel_edit_input_menu_item.set_submenu(
                self.channel_edit_input_menu)
            self.channel_edit_input_menu_item.set_sensitive(False)
            self.channel_remove_input_menu = Gtk.Menu()
            self.channel_remove_input_menu_item.set_submenu(
                self.channel_remove_input_menu)
            self.channel_remove_input_menu_item.set_sensitive(False)
            self.channel_edit_output_menu = Gtk.Menu()
            self.channel_edit_output_menu_item.set_submenu(
                self.channel_edit_output_menu)
            self.channel_edit_output_menu_item.set_sensitive(False)
            self.channel_remove_output_menu = Gtk.Menu()
            self.channel_remove_output_menu_item.set_submenu(
                self.channel_remove_output_menu)
            self.channel_remove_output_menu_item.set_sensitive(False)
        dlg.destroy()

    def add_channel(self, name, stereo, volume_cc, balance_cc, mute_cc,
                    solo_cc, value):
        try:
            channel = InputChannel(self, name, stereo, value)
            self.add_channel_precreated(channel)
        except Exception:
            error_dialog(self.window, "Channel creation failed.")
            return
        if volume_cc != -1:
            channel.channel.volume_midi_cc = volume_cc
        else:
            channel.channel.autoset_volume_midi_cc()
        if balance_cc != -1:
            channel.channel.balance_midi_cc = balance_cc
        else:
            channel.channel.autoset_balance_midi_cc()
        if mute_cc != -1:
            channel.channel.mute_midi_cc = mute_cc
        else:
            channel.channel.autoset_mute_midi_cc()
        if solo_cc != -1:
            channel.channel.solo_midi_cc = solo_cc
        else:
            channel.channel.autoset_solo_midi_cc()

        return channel

    def add_channel_precreated(self, channel):
        frame = Gtk.Frame()
        frame.add(channel)
        self.hbox_inputs.pack_start(frame, False, True, 0)
        channel.realize()

        channel_edit_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_edit_input_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_input_channel,
                                       channel)
        self.channel_edit_input_menu_item.set_sensitive(True)

        channel_remove_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_remove_input_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_input_channel, channel)
        self.channel_remove_input_menu_item.set_sensitive(True)

        self.channels.append(channel)

        for outputchannel in self.output_channels:
            channel.add_control_group(outputchannel)

        # create post fader output channel matching the input channel
        channel.post_fader_output_channel = self.mixer.add_output_channel(
            channel.channel.name + ' Out', channel.channel.is_stereo, True)
        channel.post_fader_output_channel.volume = 0
        channel.post_fader_output_channel.set_solo(channel.channel, True)

        channel.connect('input-channel-order-changed',
                        self.on_input_channel_order_changed)

    def on_input_channel_order_changed(self, widget, source_name, dest_name):
        self.channels.clear()

        channel_box = self.hbox_inputs
        frames = channel_box.get_children()

        for f in frames:
            c = f.get_child()
            if source_name == c._channel_name:
                source_frame = f
                break

        for f in frames:
            c = f.get_child()
            if (dest_name == c._channel_name):
                pos = frames.index(f)
                channel_box.reorder_child(source_frame, pos)
                break

        for frame in self.hbox_inputs.get_children():
            c = frame.get_child()
            self.channels.append(c)

    def read_meters(self):
        for channel in self.channels:
            channel.read_meter()
        for channel in self.output_channels:
            channel.read_meter()
        return True

    def midi_events_check(self):
        for channel in self.channels + self.output_channels:
            channel.midi_events_check()
        return True

    def add_output_channel(self, name, stereo, volume_cc, balance_cc, mute_cc,
                           display_solo_buttons, color, value):
        try:
            channel = OutputChannel(self, name, stereo, value)
            channel.display_solo_buttons = display_solo_buttons
            channel.color = color
            self.add_output_channel_precreated(channel)
        except Exception:
            error_dialog(self.window, "Channel creation failed")
            return

        if volume_cc != -1:
            channel.channel.volume_midi_cc = volume_cc
        else:
            channel.channel.autoset_volume_midi_cc()
        if balance_cc != -1:
            channel.channel.balance_midi_cc = balance_cc
        else:
            channel.channel.autoset_balance_midi_cc()
        if mute_cc != -1:
            channel.channel.mute_midi_cc = mute_cc
        else:
            channel.channel.autoset_mute_midi_cc()

        return channel

    def add_output_channel_precreated(self, channel):
        frame = Gtk.Frame()
        frame.add(channel)
        self.hbox_outputs.pack_end(frame, False, True, 0)
        self.hbox_outputs.reorder_child(frame, 0)
        channel.realize()

        channel_edit_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_edit_output_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_output_channel,
                                       channel)
        self.channel_edit_output_menu_item.set_sensitive(True)

        channel_remove_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_remove_output_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_output_channel,
                                         channel)
        self.channel_remove_output_menu_item.set_sensitive(True)

        self.output_channels.append(channel)
        channel.connect('output-channel-order-changed',
                        self.on_output_channel_order_changed)

    def on_output_channel_order_changed(self, widget, source_name, dest_name):
        self.output_channels.clear()
        channel_box = self.hbox_outputs

        frames = channel_box.get_children()

        for f in frames:
            c = f.get_child()
            if source_name == c._channel_name:
                source_frame = f
                break

        for f in frames:
            c = f.get_child()
            if (dest_name == c._channel_name):
                pos = len(frames) - 1 - frames.index(f)
                channel_box.reorder_child(source_frame, pos)
                break

        for frame in self.hbox_outputs.get_children():
            c = frame.get_child()
            self.output_channels.append(c)

    _monitored_channel = None

    def get_monitored_channel(self):
        return self._monitored_channel

    def set_monitored_channel(self, channel):
        if self._monitored_channel:
            if channel.channel.name == self._monitored_channel.channel.name:
                return
        self._monitored_channel = channel
        if type(channel) is InputChannel:
            # reset all solo/mute settings
            for in_channel in self.channels:
                self.monitor_channel.set_solo(in_channel.channel, False)
                self.monitor_channel.set_muted(in_channel.channel, False)
            self.monitor_channel.set_solo(channel.channel, True)
            self.monitor_channel.prefader = True
        else:
            self.monitor_channel.prefader = False
        self.update_monitor(channel)

    monitored_channel = property(get_monitored_channel, set_monitored_channel)

    def update_monitor(self, channel):
        if self._monitored_channel is not channel:
            return
        self.monitor_channel.volume = channel.channel.volume
        self.monitor_channel.balance = channel.channel.balance
        if type(self.monitored_channel) is OutputChannel:
            # sync solo/muted channels
            for input_channel in self.channels:
                self.monitor_channel.set_solo(
                    input_channel.channel,
                    channel.channel.is_solo(input_channel.channel))
                self.monitor_channel.set_muted(
                    input_channel.channel,
                    channel.channel.is_muted(input_channel.channel))

    def get_input_channel_by_name(self, name):
        for input_channel in self.channels:
            if input_channel.channel.name == name:
                return input_channel
        return None

    def on_about(self, *args):
        about = Gtk.AboutDialog()
        about.set_name('jack_mixer')
        about.set_program_name('jack_mixer')
        about.set_copyright(
            'Copyright © 2006-2020\nNedko Arnaudov, Frédéric Péters, Arnout Engelen, Daniel Sheeler'
        )
        about.set_license("""\
jack_mixer 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 (at your
option) any later version.

jack_mixer 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.

You should have received a copy of the GNU General Public License along
with jack_mixer; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA""")
        about.set_authors([
            'Nedko Arnaudov <*****@*****.**>',
            'Christopher Arndt <*****@*****.**>',
            'Arnout Engelen <*****@*****.**>',
            'John Hedges <*****@*****.**>',
            'Olivier Humbert <*****@*****.**>',
            'Sarah Mischke <*****@*****.**>',
            'Frédéric Péters <*****@*****.**>',
            'Daniel Sheeler <*****@*****.**>',
            'Athanasios Silis <*****@*****.**>',
        ])
        about.set_logo_icon_name('jack_mixer')
        about.set_version(__version__)
        about.set_website('https://rdio.space/jackmixer/')

        about.run()
        about.destroy()

    def save_to_xml(self, file):
        log.debug("Saving to XML...")
        b = XmlSerialization()
        s = Serializator()
        s.serialize(self, b)
        b.save(file)

    def load_from_xml(self, file, silence_errors=False, from_nsm=False):
        log.debug("Loading from XML...")
        self.unserialized_channels = []
        b = XmlSerialization()
        try:
            b.load(file)
        except:
            if silence_errors:
                return
            raise
        self.on_channels_clear(None)
        s = Serializator()
        s.unserialize(self, b)
        for channel in self.unserialized_channels:
            if isinstance(channel, InputChannel):
                if self._init_solo_channels and channel.channel_name in self._init_solo_channels:
                    channel.solo = True
                self.add_channel_precreated(channel)
        self._init_solo_channels = None
        for channel in self.unserialized_channels:
            if isinstance(channel, OutputChannel):
                self.add_output_channel_precreated(channel)
        del self.unserialized_channels
        width, height = self.window.get_size()
        if self.visible or not from_nsm:
            self.window.show_all()
        self.paned.set_position(self.paned_position / self.width * width)
        self.window.resize(self.width, self.height)

    def serialize(self, object_backend):
        width, height = self.window.get_size()
        object_backend.add_property('geometry', '%sx%s' % (width, height))
        pos = self.paned.get_position()
        object_backend.add_property('paned_position', '%s' % pos)
        solo_channels = []
        for input_channel in self.channels:
            if input_channel.channel.solo:
                solo_channels.append(input_channel)
        if solo_channels:
            object_backend.add_property(
                'solo_channels',
                '|'.join([x.channel.name for x in solo_channels]))
        object_backend.add_property('visible', '%s' % str(self.visible))

    def unserialize_property(self, name, value):
        if name == 'geometry':
            width, height = value.split('x')
            self.width = int(width)
            self.height = int(height)
            return True
        if name == 'solo_channels':
            self._init_solo_channels = value.split('|')
            return True
        if name == 'visible':
            self.visible = value == 'True'
            return True
        if name == 'paned_position':
            self.paned_position = int(value)
            return True
        return False

    def unserialize_child(self, name):
        if name == InputChannel.serialization_name():
            channel = InputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

        if name == OutputChannel.serialization_name():
            channel = OutputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

        if name == gui.Factory.serialization_name():
            return self.gui_factory

    def serialization_get_childs(self):
        '''Get child objects that required and support serialization'''
        childs = self.channels[:] + self.output_channels[:] + [
            self.gui_factory
        ]
        return childs

    def serialization_name(self):
        return "jack_mixer"

    def main(self):
        if not self.mixer:
            return

        if self.visible or self.nsm_client == None:
            width, height = self.window.get_size()
            self.window.show_all()
            if hasattr(self, 'paned_position'):
                self.paned.set_position(self.paned_position / self.width *
                                        width)

        signal.signal(signal.SIGUSR1, self.sighandler)
        signal.signal(signal.SIGTERM, self.sighandler)
        signal.signal(signal.SIGINT, self.sighandler)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)

        Gtk.main()
Exemple #10
0
 def on_mi_preferences_activate(self, widget):
     dlg = PreferencesDialog()
     dlg.run()
Exemple #11
0
 def on_preferences(self, event):
     with PreferencesDialog() as dlg:
         dlg.ShowModal()
Exemple #12
0
 def openPreferences(self):
     prefDiag = PreferencesDialog(self.settings, self)
     prefDiag.exec_()
Exemple #13
0
class CloudHandle(object):
    
    fileList = []
    
    def __init__(self):
        self.pdialog = PreferencesDialog()
        self.pdialog.signals.settingsChanged.connect(self.initializeApi)
        self.signals = self.Signals()
        self.updateTimer = QTimer();
        QObject.connect(self.updateTimer, SIGNAL("timeout()"), self.getFileList)
        self.initializeApi()

    def initializeApi(self):
        self.updateTimer.stop();
        self.connected = False
        try:
            username = self.pdialog.settings['username']
            password = self.pdialog.settings['password']
            if username == '' or password == '':
               raise ValueError('Empty password or username')
            self.api = CloudApi(username, password)
            self.getFileList()
            self.updateTimer.start(30000);
        except (KeyError, ValueError):
            self.pdialog.show()
            logging.warn("Couldn't reading settings")
        
    def getFileList(self):
        self.api.getFileList(self.pdialog.settings['list_size'], self.gotFileList)
        
    def gotFileList(self, l):
        self.connected = True
        self.fileList = l
        self.signals.gotFileList.emit(l)
        
    def addItem(self, url):
        url = str(url)
        if urllib.parse.urlparse(url).scheme == "file":
            self.api.uploadFile(url, self.itemAdded)
        else:
            self.api.bookmark(url, self.itemAdded)
        self.signals.uploadStarted.emit()
            
    def itemAdded(self, item):
        self.fileList.insert(0, item)
        self.fileList.pop()
        self.signals.gotFileList.emit(self.fileList)
        if self.pdialog.settings['auto_clipboard']:
            self.signals.loadClipboard.emit(item['url'])
        if self.pdialog.settings['notifications']:
            if item['item_type'] == 'bookmark':
                self.notify('Bookmarked - '+item['name'], item['url'])
            else:
                self.notify('File Uploaded - '+item['name'], item['url'])
        self.signals.uploadFinished.emit()
        
    def deleteItem(self, url):
        url = str(url)
        self.api.delete(url, self.deleted)
        
    def deleted(self, x):
        self.getFileList()
        if self.pdialog.settings['notifications']:
            self.notify("Deleted - "+x['name'], 'This item was removed from your CloudApp')

    def showPreferences(self):
        self.pdialog.show()
        
    def notify(self, title, text, icon="dialog-information"):
        try:
            from gi.repository import Notify as pynotify
            if pynotify.init("Cloud App"):
                n = pynotify.Notification.new(title, text, icon)
                n.set_timeout(5)
                n.show()
            else:
                logging.error("there was a problem initializing the pynotify module")
        except:
            logging.info("you don't seem to have pynotify installed")
        
        
    class Signals(QObject):
        gotFileList = pyqtSignal(list)
        loadClipboard = pyqtSignal(str)
        uploadStarted = pyqtSignal()
        uploadFinished = pyqtSignal()
Exemple #14
0
 def on_mi_preferences_activate(self, widget):
     dlg = PreferencesDialog()
     dlg.run()
Exemple #15
0
 def preferences_clicked(self, widget):
     self.preferences_dialog = PreferencesDialog(self.conf, self.menu)
     if self.preferences_dialog.exec_() == QtGui.QDialog.Accepted:
         self.preferences_dialog.save()
         self.app.emit(QtCore.SIGNAL('reload_project_data'))
Exemple #16
0
class AppMenu:
    def __init__(self, app, tray, widget, conf, build_icons):
        self.menu = QtGui.QMenu(widget)
        tray.setContextMenu(self.menu)
        self.conf = conf
        self.app = app
        self.build_icons = build_icons
        self.create_default_menu_items()

    def update(self, projects):
        projects.sort(lambda x, y:
                      (x.last_build_time - y.last_build_time).days)
        self.menu.clear()
        for project in projects:
            self.create_menu_item(
                project.name,
                self.build_icons.for_status(project.get_build_status()),
                project.url, project.last_build_time, project.server_url)
        self.create_default_menu_items()

    def create_default_menu_items(self):
        self.menu.addSeparator()
        self.menu.addAction(
            QtGui.QAction("About", self.menu, triggered=self.about_clicked))
        self.menu.addAction(
            QtGui.QAction("Preferences",
                          self.menu,
                          triggered=self.preferences_clicked))
        self.menu.addAction(
            QtGui.QAction("Exit", self.menu, triggered=self.exit))

    def about_clicked(self, widget):
        QtGui.QMessageBox.about(
            self.menu, "About BuildNotify %s" % VERSION,
            "<b>BuildNotify %s</b> has been developed using PyQt4 and serves as a build notification tool for cruise control. In case of any suggestions/bugs,"
            % VERSION +
            "please visit <a href=\"http://bitbucket.org/Anay/buildnotify\">http://bitbucket.org/Anay/buildnotify</a> and provide your feedback."
        )

    def preferences_clicked(self, widget):
        self.preferences_dialog = PreferencesDialog(self.conf, self.menu)
        if self.preferences_dialog.exec_() == QtGui.QDialog.Accepted:
            self.preferences_dialog.save()
            self.app.emit(QtCore.SIGNAL('reload_project_data'))

    def exit(self, widget):
        sys.exit()

    def create_menu_item(self, label, icon, url, last_build_time, server_url):

        menu_item_label = label
        if self.conf.get_value("lastBuildTimeForProject"):
            menu_item_label = label + ", " + DistanceOfTime(
                last_build_time, self.conf.get_project_timezone(
                    url, server_url)).age() + " ago"

        action = self.menu.addAction(icon, menu_item_label)
        action.setIconVisibleInMenu(True)
        receiver = lambda url=url: self.open_url(self, url)
        QtCore.QObject.connect(action, QtCore.SIGNAL('triggered()'), receiver)

    def open_url(self, something, url):
        webbrowser.open(url)
Exemple #17
0
class JackMixer(SerializedObject):

    # scales suitable as meter scales
    meter_scales = [
        scale.IEC268(),
        scale.Linear70dB(),
        scale.IEC268Minimalistic()
    ]

    # scales suitable as volume slider scales
    slider_scales = [scale.Linear30dB(), scale.Linear70dB()]

    # name of settngs file that is currently open
    current_filename = None

    # automatically bridged channels
    bridged_connection = list()
    unbridged_connection = list()
    bridged_channel = list()

    def __init__(self, name, lash_client):
        self.mixer = jack_mixer_c.Mixer(name)
        if not self.mixer:
            return
        self.monitor_channel = self.mixer.add_output_channel(
            "Monitor", True, True)

        self.save = False

        if lash_client:
            # Send our client name to server
            lash_event = lash.lash_event_new_with_type(lash.LASH_Client_Name)
            lash.lash_event_set_string(lash_event, name)
            lash.lash_send_event(lash_client, lash_event)

            lash.lash_jack_client_name(lash_client, name)

        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        if name != self.mixer.client_name():
            self.window.set_title(name + " (" + self.mixer.client_name() + ")")
        else:
            self.window.set_title(name)

        self.window.set_icon_name('jack_mixer')
        self.gui_factory = gui.Factory(self.window, self.meter_scales,
                                       self.slider_scales)

        self.vbox_top = gtk.VBox()
        self.window.add(self.vbox_top)

        self.menubar = gtk.MenuBar()
        self.vbox_top.pack_start(self.menubar, False)

        mixer_menu_item = gtk.MenuItem("_Mixer")
        self.menubar.append(mixer_menu_item)
        edit_menu_item = gtk.MenuItem('_Edit')
        self.menubar.append(edit_menu_item)
        help_menu_item = gtk.MenuItem('_Help')
        self.menubar.append(help_menu_item)

        self.window.set_default_size(120, 300)

        mixer_menu = gtk.Menu()
        mixer_menu_item.set_submenu(mixer_menu)

        add_input_channel = gtk.ImageMenuItem('New _Input Channel')
        mixer_menu.append(add_input_channel)
        add_input_channel.connect("activate", self.on_add_input_channel)

        add_output_channel = gtk.ImageMenuItem('New _Output Channel')
        mixer_menu.append(add_output_channel)
        add_output_channel.connect("activate", self.on_add_output_channel)

        mixer_menu.append(gtk.SeparatorMenuItem())
        bridge_system = gtk.ImageMenuItem('Bridge System Playback')
        mixer_menu.append(bridge_system)
        bridge_system.connect("activate", self.on_bridge_system)

        unbridge_system = gtk.ImageMenuItem('Unbridge System Playback')
        mixer_menu.append(unbridge_system)
        unbridge_system.connect("activate", self.on_unbridge_system)

        mixer_menu.append(gtk.SeparatorMenuItem())
        open = gtk.ImageMenuItem(gtk.STOCK_OPEN)
        mixer_menu.append(open)
        open.connect('activate', self.on_open_cb)
        save = gtk.ImageMenuItem(gtk.STOCK_SAVE)
        mixer_menu.append(save)
        save.connect('activate', self.on_save_cb)
        save_as = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS)
        mixer_menu.append(save_as)
        save_as.connect('activate', self.on_save_as_cb)

        mixer_menu.append(gtk.SeparatorMenuItem())

        quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        mixer_menu.append(quit)
        quit.connect('activate', self.on_quit_cb)

        edit_menu = gtk.Menu()
        edit_menu_item.set_submenu(edit_menu)

        self.channel_edit_input_menu_item = gtk.MenuItem('_Edit Input Channel')
        edit_menu.append(self.channel_edit_input_menu_item)
        self.channel_edit_input_menu = gtk.Menu()
        self.channel_edit_input_menu_item.set_submenu(
            self.channel_edit_input_menu)

        self.channel_edit_output_menu_item = gtk.MenuItem(
            'Edit _Output Channel')
        edit_menu.append(self.channel_edit_output_menu_item)
        self.channel_edit_output_menu = gtk.Menu()
        self.channel_edit_output_menu_item.set_submenu(
            self.channel_edit_output_menu)

        self.channel_remove_input_menu_item = gtk.MenuItem(
            'Remove _Input Channel')
        edit_menu.append(self.channel_remove_input_menu_item)
        self.channel_remove_input_menu = gtk.Menu()
        self.channel_remove_input_menu_item.set_submenu(
            self.channel_remove_input_menu)

        self.channel_remove_output_menu_item = gtk.MenuItem(
            '_Remove Output Channel')
        edit_menu.append(self.channel_remove_output_menu_item)
        self.channel_remove_output_menu = gtk.Menu()
        self.channel_remove_output_menu_item.set_submenu(
            self.channel_remove_output_menu)

        channel_remove_all_menu_item = gtk.ImageMenuItem(gtk.STOCK_CLEAR)
        edit_menu.append(channel_remove_all_menu_item)
        channel_remove_all_menu_item.connect("activate",
                                             self.on_channels_clear)

        edit_menu.append(gtk.SeparatorMenuItem())

        preferences = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
        preferences.connect('activate', self.on_preferences_cb)
        edit_menu.append(preferences)

        help_menu = gtk.Menu()
        help_menu_item.set_submenu(help_menu)

        about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
        help_menu.append(about)
        about.connect("activate", self.on_about)

        self.hbox_top = gtk.HBox()
        self.vbox_top.pack_start(self.hbox_top, True)

        self.scrolled_window = gtk.ScrolledWindow()
        self.hbox_top.pack_start(self.scrolled_window, True)

        self.hbox_inputs = gtk.HBox()
        self.hbox_inputs.set_spacing(0)
        self.hbox_inputs.set_border_width(0)
        self.hbox_top.set_spacing(0)
        self.hbox_top.set_border_width(0)
        self.channels = []
        self.output_channels = []

        self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                        gtk.POLICY_AUTOMATIC)
        self.scrolled_window.add_with_viewport(self.hbox_inputs)

        self.main_mix = MainMixChannel(self)
        self.hbox_outputs = gtk.HBox()
        self.hbox_outputs.set_spacing(0)
        self.hbox_outputs.set_border_width(0)
        frame = gtk.Frame()
        frame.add(self.main_mix)
        self.hbox_outputs.pack_start(frame, False)
        self.hbox_top.pack_start(self.hbox_outputs, False)

        self.window.connect("destroy", gtk.main_quit)

        self.trayicon = TrayIcon(self)
        self.window.connect('delete-event', self.on_delete_event)

        gobject.timeout_add(80, self.read_meters)
        self.lash_client = lash_client

        gobject.timeout_add(200, self.lash_check_events)

        gobject.timeout_add(50, self.midi_events_check)

    def on_delete_event(self, widget, event):
        if self.gui_factory.get_minimize_to_tray():
            self.window.hide()
            return True
        else:
            self.on_quit_cb()
            return False

    def sighandler(self, signum, frame):
        #print "Signal %d received" % signum
        if signum == signal.SIGUSR1:
            self.save = True
        elif signum == signal.SIGTERM:
            gtk.main_quit()
        elif signum == signal.SIGINT:
            gtk.main_quit()
        else:
            print "Unknown signal %d received" % signum

    def cleanup(self):
        print "Cleaning jack_mixer"
        if not self.mixer:
            return

        for channel in self.channels:
            channel.unrealize()

        self.mixer.destroy()

    def on_open_cb(self, *args):
        dlg = gtk.FileChooserDialog(title='Open',
                                    parent=self.window,
                                    action=gtk.FILE_CHOOSER_ACTION_OPEN,
                                    buttons=(gtk.STOCK_CANCEL,
                                             gtk.RESPONSE_CANCEL,
                                             gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dlg.set_default_response(gtk.RESPONSE_OK)
        if dlg.run() == gtk.RESPONSE_OK:
            filename = dlg.get_filename()
            try:
                f = file(filename, 'r')
                self.load_from_xml(f)
            except:
                err = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL,
                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
                                        "Failed loading settings.")
                err.run()
                err.destroy()
            else:
                self.current_filename = filename
            finally:
                f.close()
        dlg.destroy()

    def on_save_cb(self, *args):
        if not self.current_filename:
            return self.on_save_as_cb()
        f = file(self.current_filename, 'w')
        self.save_to_xml(f)
        f.close()

    def on_save_as_cb(self, *args):
        dlg = gtk.FileChooserDialog(title='Save',
                                    parent=self.window,
                                    action=gtk.FILE_CHOOSER_ACTION_SAVE,
                                    buttons=(gtk.STOCK_CANCEL,
                                             gtk.RESPONSE_CANCEL,
                                             gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        dlg.set_default_response(gtk.RESPONSE_OK)
        if dlg.run() == gtk.RESPONSE_OK:
            self.current_filename = dlg.get_filename()
            self.on_save_cb()
        dlg.destroy()

    def on_quit_cb(self, *args):
        self.on_unbridge_system()
        gtk.main_quit()

    preferences_dialog = None

    def on_preferences_cb(self, widget):
        if not self.preferences_dialog:
            self.preferences_dialog = PreferencesDialog(self)
        self.preferences_dialog.show()
        self.preferences_dialog.present()

    def on_add_input_channel(self, widget):
        dialog = NewChannelDialog(app=self)
        dialog.set_transient_for(self.window)
        dialog.show()
        ret = dialog.run()
        dialog.hide()

        if ret == gtk.RESPONSE_OK:
            result = dialog.get_result()
            channel = self.add_channel(**result)
            self.window.show_all()

    def on_add_output_channel(self, widget):
        dialog = NewOutputChannelDialog(app=self)
        dialog.set_transient_for(self.window)
        dialog.show()
        ret = dialog.run()
        dialog.hide()

        if ret == gtk.RESPONSE_OK:
            result = dialog.get_result()
            channel = self.add_output_channel(**result)
            self.window.show_all()

    @staticmethod
    def remove_last_digit(mystr):
        digits = re.findall(r'\d+', mystr)
        if len(digits) == 0:
            return mystr

        lastdigit = digits[len(digits) - 1]
        return mystr[:-len(str(lastdigit))]

    def on_bridge_system(self, widget):
        connections = self.mixer.get_systemport_connections()

        for i in range(0, len(connections)):
            actConnection = connections[i]
            actConnectionNoDigit = self.remove_last_digit(actConnection)

            # search if channel exists
            channelExists = False
            for c in range(len(self.channels)):
                if self.channels[
                        c].channel_name == actConnection or self.channels[
                            c].channel_name == actConnectionNoDigit:
                    channelExists = True
                    break

            lastChar = actConnection[len(actConnection) - 1]
            if lastChar == 'R' or lastChar == 'r' or lastChar == 'L' or lastChar == 'l':
                for c in range(len(self.channels)):
                    if self.channels[c].channel_name == actConnection[:-1]:
                        channelExists = True
                        break

            # search for other ports => possible stereo
            sameConnectionCount = 0
            for j in range(0, len(connections)):
                if self.remove_last_digit(
                        connections[j]) == actConnectionNoDigit:
                    sameConnectionCount += 1

            stereo = (sameConnectionCount == 2)

            if stereo:
                name = actConnectionNoDigit
            else:
                name = actConnection
                # search for 'L' - 'R' paired stereo
                if actConnection[len(actConnection) -
                                 1] == 'L' or actConnection[len(actConnection)
                                                            - 1] == 'l':
                    for j in range(0, len(connections)):
                        if connections[
                                j] == actConnection[:-1] + 'R' or connections[
                                    j] == actConnection[:-1] + 'r':
                            name = actConnection[:-1]
                            stereo = True
                            break

                else:
                    if actConnection[len(actConnection) -
                                     1] == 'R' or actConnection[
                                         len(actConnection) - 1] == 'r':
                        for j in range(0, len(connections)):
                            if connections[
                                    j] == actConnection[:-1] + 'L' or connections[
                                        j] == actConnection[:-1] + 'l':
                                name = actConnection[:-1]
                                stereo = True
                                break

            if not channelExists:
                c = self.add_channel(name, stereo, 0, 0)
                self.bridged_channel.append(c)

            # connect and disconnect (bridge) ports
            if stereo:
                system_port_connections = self.mixer.get_port_system_connections(
                    actConnection)
                for k in range(0, len(system_port_connections)):
                    if channelExists:
                        self.mixer.connect_ports(
                            actConnection,
                            self.mixer.client_name() + ':' + name + ' R')
                        self.mixer.connect_ports(
                            self.mixer.client_name() + ':' + name + ' Out R',
                            system_port_connections[k])

                        self.bridged_connection.append([
                            actConnection,
                            self.mixer.client_name() + ':' + name + ' R'
                        ])
                        self.bridged_connection.append([
                            self.mixer.client_name() + ':' + name + ' Out R',
                            system_port_connections[k]
                        ])
                    else:
                        self.mixer.connect_ports(
                            actConnection,
                            self.mixer.client_name() + ':' + name + ' L')
                        self.mixer.connect_ports(
                            self.mixer.client_name() + ':' + name + ' Out L',
                            system_port_connections[k])

                        self.bridged_connection.append([
                            actConnection,
                            self.mixer.client_name() + ':' + name + ' L'
                        ])
                        self.bridged_connection.append([
                            self.mixer.client_name() + ':' + name + ' Out L',
                            system_port_connections[k]
                        ])

                    self.mixer.disconnect_ports(actConnection,
                                                system_port_connections[k])
                    self.unbridged_connection.append(
                        [actConnection, system_port_connections[k]])
            else:  # mono
                self.mixer.connect_ports(actConnection,
                                         self.mixer.client_name() + ':' + name)
                self.bridged_connection.append(
                    [actConnection,
                     self.mixer.client_name() + ':' + name])
                system_port_connections = self.mixer.get_port_system_connections(
                    actConnection)
                for k in range(0, len(system_port_connections)):
                    self.mixer.connect_ports(
                        self.mixer.client_name() + ':' + name + ' Out',
                        system_port_connections[k])
                    self.bridged_connection.append([
                        self.mixer.client_name() + ':' + name + ' Out',
                        system_port_connections[k]
                    ])
                    self.mixer.disconnect_ports(actConnection,
                                                system_port_connections[k])
                    self.bridged_connection.append(
                        [actConnection, system_port_connections[k]])

        self.window.show_all()

    def on_unbridge_system(self, widget=None):
        print 'Unbridge System Connections'

        for connection in self.unbridged_connection:
            self.mixer.connect_ports(connection[0], connection[1])
        self.unbridged_connection[:] = []

        for connection in self.bridged_connection:
            self.mixer.disconnect_ports(connection[0], connection[1])
        self.bridged_connection[:] = []

        if widget != None:  # we are closing
            for channel in self.bridged_channel:
                self.on_remove_input_channel(widget, channel)
            self.bridged_channel[:] = []

    def on_edit_input_channel(self, widget, channel):
        print 'Editing channel "%s"' % channel.channel_name
        channel.on_channel_properties()

    def remove_channel_edit_input_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_input_menu.remove(widget)

    def on_remove_input_channel(self, widget, channel):
        print 'Removing channel "%s"' % channel.channel_name
        self.channel_remove_input_menu.remove(widget)
        self.channel_edit_input_menu.foreach(
            self.remove_channel_edit_input_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.channels[i] is channel:
                channel.unrealize()
                del self.channels[i]
                self.hbox_inputs.remove(channel.parent)
                break
        if len(self.channels) == 0:
            self.channel_remove_input_menu_item.set_sensitive(False)

    def on_edit_output_channel(self, widget, channel):
        print 'Editing channel "%s"' % channel.channel_name
        channel.on_channel_properties()

    def remove_channel_edit_output_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_output_menu.remove(widget)

    def on_remove_output_channel(self, widget, channel):
        print 'Removing channel "%s"' % channel.channel_name
        self.channel_remove_output_menu.remove(widget)
        self.channel_edit_output_menu.foreach(
            self.remove_channel_edit_output_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.output_channels[i] is channel:
                channel.unrealize()
                del self.output_channels[i]
                self.hbox_outputs.remove(channel.parent)
                break
        if len(self.output_channels) == 0:
            self.channel_remove_output_menu_item.set_sensitive(False)

    def rename_channels(self, container, parameters):
        if (container.get_label() == parameters['oldname']):
            container.set_label(parameters['newname'])

    def on_channel_rename(self, oldname, newname):
        rename_parameters = {'oldname': oldname, 'newname': newname}
        self.channel_edit_input_menu.foreach(self.rename_channels,
                                             rename_parameters)
        self.channel_edit_output_menu.foreach(self.rename_channels,
                                              rename_parameters)
        self.channel_remove_input_menu.foreach(self.rename_channels,
                                               rename_parameters)
        self.channel_remove_output_menu.foreach(self.rename_channels,
                                                rename_parameters)
        print "Renaming channel from %s to %s\n" % (oldname, newname)

    def on_channels_clear(self, widget):
        for channel in self.output_channels:
            channel.unrealize()
            self.hbox_outputs.remove(channel.parent)
        for channel in self.channels:
            channel.unrealize()
            self.hbox_inputs.remove(channel.parent)
        self.channels = []
        self.output_channels = []
        self.channel_edit_input_menu = gtk.Menu()
        self.channel_edit_input_menu_item.set_submenu(
            self.channel_edit_input_menu)
        self.channel_edit_input_menu_item.set_sensitive(False)
        self.channel_remove_input_menu = gtk.Menu()
        self.channel_remove_input_menu_item.set_submenu(
            self.channel_remove_input_menu)
        self.channel_remove_input_menu_item.set_sensitive(False)
        self.channel_edit_output_menu = gtk.Menu()
        self.channel_edit_output_menu_item.set_submenu(
            self.channel_edit_output_menu)
        self.channel_edit_output_menu_item.set_sensitive(False)
        self.channel_remove_output_menu = gtk.Menu()
        self.channel_remove_output_menu_item.set_submenu(
            self.channel_remove_output_menu)
        self.channel_remove_output_menu_item.set_sensitive(False)

    def add_channel(self, name, stereo, volume_cc, balance_cc):
        try:
            channel = InputChannel(self, name, stereo)
            self.add_channel_precreated(channel)
        except Exception:
            err = gtk.MessageDialog(
                self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "Channel creation failed")
            err.run()
            err.destroy()
            return
        if volume_cc:
            channel.channel.volume_midi_cc = int(volume_cc)
        if balance_cc:
            channel.channel.balance_midi_cc = int(balance_cc)
        if not (volume_cc or balance_cc):
            channel.channel.autoset_midi_cc()

        return channel

    def add_channel_precreated(self, channel):
        frame = gtk.Frame()
        frame.add(channel)
        self.hbox_inputs.pack_start(frame, False)
        channel.realize()

        channel_edit_menu_item = gtk.MenuItem(channel.channel_name)
        self.channel_edit_input_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_input_channel,
                                       channel)
        self.channel_edit_input_menu_item.set_sensitive(True)

        channel_remove_menu_item = gtk.MenuItem(channel.channel_name)
        self.channel_remove_input_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_input_channel, channel)
        self.channel_remove_input_menu_item.set_sensitive(True)

        self.channels.append(channel)

        for outputchannel in self.output_channels:
            channel.add_control_group(outputchannel)

        # create post fader output channel matching the input channel
        channel.post_fader_output_channel = self.mixer.add_output_channel(
            channel.channel.name + ' Out', channel.channel.is_stereo, True)
        channel.post_fader_output_channel.volume = 0
        channel.post_fader_output_channel.set_solo(channel.channel, True)

    def read_meters(self):
        for channel in self.channels:
            channel.read_meter()
        self.main_mix.read_meter()
        for channel in self.output_channels:
            channel.read_meter()
        return True

    def midi_events_check(self):
        for channel in self.channels + [self.main_mix] + self.output_channels:
            channel.midi_events_check()
        return True

    def add_output_channel(self, name, stereo, volume_cc, balance_cc,
                           display_solo_buttons):
        try:
            channel = OutputChannel(self, name, stereo)
            channel.display_solo_buttons = display_solo_buttons
            self.add_output_channel_precreated(channel)
        except Exception:
            err = gtk.MessageDialog(
                self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "Channel creation failed")
            err.run()
            err.destroy()
            return
        if volume_cc:
            channel.channel.volume_midi_cc = int(volume_cc)
        if balance_cc:
            channel.channel.balance_midi_cc = int(balance_cc)
        return channel

    def add_output_channel_precreated(self, channel):
        frame = gtk.Frame()
        frame.add(channel)
        self.hbox_outputs.pack_start(frame, False)
        channel.realize()

        channel_edit_menu_item = gtk.MenuItem(channel.channel_name)
        self.channel_edit_output_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_output_channel,
                                       channel)
        self.channel_edit_output_menu_item.set_sensitive(True)

        channel_remove_menu_item = gtk.MenuItem(channel.channel_name)
        self.channel_remove_output_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_output_channel,
                                         channel)
        self.channel_remove_output_menu_item.set_sensitive(True)

        self.output_channels.append(channel)

    _monitored_channel = None

    def get_monitored_channel(self):
        return self._monitored_channel

    def set_monitored_channel(self, channel):
        if self._monitored_channel:
            if channel.channel.name == self._monitored_channel.channel.name:
                return
        self._monitored_channel = channel
        if type(channel) is InputChannel:
            # reset all solo/mute settings
            for in_channel in self.channels:
                self.monitor_channel.set_solo(in_channel.channel, False)
                self.monitor_channel.set_muted(in_channel.channel, False)
            self.monitor_channel.set_solo(channel.channel, True)
            self.monitor_channel.prefader = True
        else:
            self.monitor_channel.prefader = False
        self.update_monitor(channel)

    monitored_channel = property(get_monitored_channel, set_monitored_channel)

    def update_monitor(self, channel):
        if self.monitored_channel is not channel:
            return
        self.monitor_channel.volume = channel.channel.volume
        self.monitor_channel.balance = channel.channel.balance
        if type(self.monitored_channel) is OutputChannel:
            # sync solo/muted channels
            for input_channel in self.channels:
                self.monitor_channel.set_solo(
                    input_channel.channel,
                    channel.channel.is_solo(input_channel.channel))
                self.monitor_channel.set_muted(
                    input_channel.channel,
                    channel.channel.is_muted(input_channel.channel))
        elif type(self.monitored_channel) is MainMixChannel:
            # sync solo/muted channels
            for input_channel in self.channels:
                self.monitor_channel.set_solo(input_channel.channel,
                                              input_channel.channel.solo)
                self.monitor_channel.set_muted(input_channel.channel,
                                               input_channel.channel.mute)

    def get_input_channel_by_name(self, name):
        for input_channel in self.channels:
            if input_channel.channel.name == name:
                return input_channel
        return None

    def on_about(self, *args):
        about = gtk.AboutDialog()
        about.set_name('jack_mixer')
        about.set_copyright(
            'Copyright © 2006-2010\nNedko Arnaudov, Frederic Peters, Arnout Engelen'
        )
        about.set_license('''\
jack_mixer 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 (at your
option) any later version.

jack_mixer 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.

You should have received a copy of the GNU General Public License along
with jack_mixer; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA''')
        about.set_authors([
            'Nedko Arnaudov <*****@*****.**>',
            'Frederic Peters <*****@*****.**>'
        ])
        about.set_logo_icon_name('jack_mixer')
        about.set_website('http://home.gna.org/jackmixer/')

        about.run()
        about.destroy()

    def lash_check_events(self):
        if self.save:
            self.save = False
            if self.current_filename:
                print "saving on SIGUSR1 request"
                self.on_save_cb()
                print "save done"
            else:
                print "not saving because filename is not known"
            return True

        if not self.lash_client:
            return True

        while lash.lash_get_pending_event_count(self.lash_client):
            event = lash.lash_get_event(self.lash_client)

            #print repr(event)

            event_type = lash.lash_event_get_type(event)
            if event_type == lash.LASH_Quit:
                print "jack_mixer: LASH ordered quit."
                gtk.main_quit()
                return False
            elif event_type == lash.LASH_Save_File:
                directory = lash.lash_event_get_string(event)
                print "jack_mixer: LASH ordered to save data in directory %s" % directory
                filename = directory + os.sep + "jack_mixer.xml"
                f = file(filename, "w")
                self.save_to_xml(f)
                f.close()
                lash.lash_send_event(self.lash_client,
                                     event)  # we crash with double free
            elif event_type == lash.LASH_Restore_File:
                directory = lash.lash_event_get_string(event)
                print "jack_mixer: LASH ordered to restore data from directory %s" % directory
                filename = directory + os.sep + "jack_mixer.xml"
                f = file(filename, "r")
                self.load_from_xml(f, silence_errors=True)
                f.close()
                lash.lash_send_event(self.lash_client, event)
            else:
                print "jack_mixer: Got unhandled LASH event, type " + str(
                    event_type)
                return True

            #lash.lash_event_destroy(event)

        return True

    def save_to_xml(self, file):
        #print "Saving to XML..."
        b = XmlSerialization()
        s = Serializator()
        s.serialize(self, b)
        b.save(file)

    def load_from_xml(self, file, silence_errors=False):
        #print "Loading from XML..."
        self.on_channels_clear(None)
        self.unserialized_channels = []
        b = XmlSerialization()
        try:
            b.load(file)
        except:
            if silence_errors:
                return
            raise
        s = Serializator()
        s.unserialize(self, b)
        for channel in self.unserialized_channels:
            if isinstance(channel, InputChannel):
                self.add_channel_precreated(channel)
        for channel in self.unserialized_channels:
            if isinstance(channel, OutputChannel):
                self.add_output_channel_precreated(channel)
        del self.unserialized_channels
        self.window.show_all()

    def serialize(self, object_backend):
        object_backend.add_property(
            'geometry', '%sx%s' %
            (self.window.allocation.width, self.window.allocation.height))

    def unserialize_property(self, name, value):
        if name == 'geometry':
            width, height = value.split('x')
            self.window.resize(int(width), int(height))
            return True

    def unserialize_child(self, name):
        if name == MainMixChannel.serialization_name():
            return self.main_mix

        if name == InputChannel.serialization_name():
            channel = InputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

        if name == OutputChannel.serialization_name():
            channel = OutputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

    def serialization_get_childs(self):
        '''Get child objects tha required and support serialization'''
        childs = self.channels[:] + self.output_channels[:]
        childs.append(self.main_mix)
        return childs

    def serialization_name(self):
        return "jack_mixer"

    def main(self):
        self.main_mix.realize()
        self.main_mix.set_monitored()

        if not self.mixer:
            return

        self.window.show_all()

        signal.signal(signal.SIGUSR1, self.sighandler)
        signal.signal(signal.SIGTERM, self.sighandler)
        signal.signal(signal.SIGINT, self.sighandler)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)

        gtk.main()
Exemple #18
0
 def optionsClicked(self):
     self.prefDialog = PreferencesDialog()
     self.prefDialog.setModal(True)
     self.prefDialog.show()
Exemple #19
0
 def on_preferences_cb(self, widget):
     if not self.preferences_dialog:
         self.preferences_dialog = PreferencesDialog(self)
     self.preferences_dialog.show()
     self.preferences_dialog.present()
Exemple #20
0
class CloudHandle(object):

    fileList = []

    def __init__(self):
        self.pdialog = PreferencesDialog()
        self.pdialog.signals.settingsChanged.connect(self.initializeApi)
        self.signals = self.Signals()
        self.initializeApi()

    def initializeApi(self):
        self.connected = False
        try:
            username = self.pdialog.settings["username"]
            password = self.pdialog.settings["password"]
            if username == "" or password == "":
                raise ValueError("Empty password or username")
            self.api = CloudApi(username, password)
            self.getFileList()
        except (KeyError, ValueError):
            self.pdialog.show()
            print "Error reading settings"

    def getFileList(self):
        self.api.getFileList(self.pdialog.settings["list_size"], self.gotFileList)

    def gotFileList(self, l):
        self.connected = True
        self.fileList = l
        self.signals.gotFileList.emit(l)

    def addItem(self, url):
        url = str(url)
        if urlparse.urlparse(url).scheme == "file":
            self.api.uploadFile(url, self.itemAdded)
        else:
            self.api.bookmark(url, self.itemAdded)
        self.signals.uploadStarted.emit()

    def itemAdded(self, item):
        self.fileList.insert(0, item)
        self.fileList.pop()
        self.signals.gotFileList.emit(self.fileList)
        if self.pdialog.settings["auto_clipboard"]:
            self.signals.loadClipboard.emit(item["url"])
        if self.pdialog.settings["notifications"]:
            if item["item_type"] == "bookmark":
                self.notify("Bookmarked - " + item["name"], item["url"])
            else:
                self.notify("File Uploaded - " + item["name"], item["url"])
        self.signals.uploadFinished.emit()

    def deleteItem(self, url):
        url = str(url)
        self.api.delete(url, self.deleted)

    def deleted(self, x):
        self.getFileList()
        if self.pdialog.settings["notifications"]:
            self.notify("Deleted - " + x["name"], "This item was removed from your CloudApp")

    def showPreferences(self):
        self.pdialog.show()

    def notify(self, title, text, icon=None):
        try:
            import pynotify

            if pynotify.init("Cloud App"):
                n = pynotify.Notification(title, text)
                n.set_timeout(5)
                n.show()
            else:
                print "there was a problem initializing the pynotify module"
        except:
            print "you don't seem to have pynotify installed"

    class Signals(QObject):
        gotFileList = pyqtSignal(list)
        loadClipboard = pyqtSignal(str)
        uploadStarted = pyqtSignal()
        uploadFinished = pyqtSignal()
Exemple #21
0
 def preferences(self):
     dialog = PreferencesDialog(self,
                                self.lang.languages,
                                self.lang.get_current_language_index())
     if dialog.exec_():
         self.lang.select(dialog.get_language())
Exemple #22
0
 def preferrences_action_triggered(self):
     preferences_dialog = PreferencesDialog(
         settings=self.settings.value('Preferences'))
     signal = preferences_dialog.apply_signal
     signal.connect(self.apply_preferences)
     preferences_dialog.exec_()
Exemple #23
0
class JackMixer(SerializedObject):

    # scales suitable as meter scales
    meter_scales = [
        scale.IEC268(),
        scale.Linear70dB(),
        scale.IEC268Minimalistic()
    ]

    # scales suitable as volume slider scales
    slider_scales = [scale.Linear30dB(), scale.Linear70dB()]

    # name of settngs file that is currently open
    current_filename = None

    _init_solo_channels = None

    def __init__(self, name, lash_client):
        self.mixer = jack_mixer_c.Mixer(name)
        if not self.mixer:
            return
        self.monitor_channel = self.mixer.add_output_channel(
            "Monitor", True, True)

        self.save = False

        if lash_client:
            # Send our client name to server
            lash_event = lash.lash_event_new_with_type(lash.LASH_Client_Name)
            lash.lash_event_set_string(lash_event, name)
            lash.lash_send_event(lash_client, lash_event)

            lash.lash_jack_client_name(lash_client, name)

        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        if name != self.mixer.client_name():
            self.window.set_title(name + " (" + self.mixer.client_name() + ")")
        else:
            self.window.set_title(name)

        self.window.set_icon_name('jack_mixer')
        self.gui_factory = gui.Factory(self.window, self.meter_scales,
                                       self.slider_scales)

        self.vbox_top = Gtk.VBox()
        self.window.add(self.vbox_top)

        self.menubar = Gtk.MenuBar()
        self.vbox_top.pack_start(self.menubar, False, True, 0)

        mixer_menu_item = Gtk.MenuItem.new_with_mnemonic("_Mixer")
        self.menubar.append(mixer_menu_item)
        edit_menu_item = Gtk.MenuItem.new_with_mnemonic('_Edit')
        self.menubar.append(edit_menu_item)
        help_menu_item = Gtk.MenuItem.new_with_mnemonic('_Help')
        self.menubar.append(help_menu_item)

        self.window.set_default_size(120, 300)

        mixer_menu = Gtk.Menu()
        mixer_menu_item.set_submenu(mixer_menu)

        add_input_channel = Gtk.MenuItem.new_with_mnemonic(
            'New _Input Channel')
        mixer_menu.append(add_input_channel)
        add_input_channel.connect("activate", self.on_add_input_channel)

        add_output_channel = Gtk.MenuItem.new_with_mnemonic(
            'New _Output Channel')
        mixer_menu.append(add_output_channel)
        add_output_channel.connect("activate", self.on_add_output_channel)

        mixer_menu.append(Gtk.SeparatorMenuItem())
        open = Gtk.MenuItem.new_with_mnemonic('_Open')
        mixer_menu.append(open)
        open.connect('activate', self.on_open_cb)
        save = Gtk.MenuItem.new_with_mnemonic('_Save')
        mixer_menu.append(save)
        save.connect('activate', self.on_save_cb)
        save_as = Gtk.MenuItem.new_with_mnemonic('Save_As')
        mixer_menu.append(save_as)
        save_as.connect('activate', self.on_save_as_cb)

        mixer_menu.append(Gtk.SeparatorMenuItem())

        quit = Gtk.MenuItem.new_with_mnemonic('_Quit')
        mixer_menu.append(quit)
        quit.connect('activate', self.on_quit_cb)

        edit_menu = Gtk.Menu()
        edit_menu_item.set_submenu(edit_menu)

        self.channel_edit_input_menu_item = Gtk.MenuItem.new_with_mnemonic(
            '_Edit Input Channel')
        edit_menu.append(self.channel_edit_input_menu_item)
        self.channel_edit_input_menu = Gtk.Menu()
        self.channel_edit_input_menu_item.set_submenu(
            self.channel_edit_input_menu)

        self.channel_edit_output_menu_item = Gtk.MenuItem.new_with_mnemonic(
            'Edit _Output Channel')
        edit_menu.append(self.channel_edit_output_menu_item)
        self.channel_edit_output_menu = Gtk.Menu()
        self.channel_edit_output_menu_item.set_submenu(
            self.channel_edit_output_menu)

        self.channel_remove_input_menu_item = Gtk.MenuItem.new_with_mnemonic(
            'Remove _Input Channel')
        edit_menu.append(self.channel_remove_input_menu_item)
        self.channel_remove_input_menu = Gtk.Menu()
        self.channel_remove_input_menu_item.set_submenu(
            self.channel_remove_input_menu)

        self.channel_remove_output_menu_item = Gtk.MenuItem.new_with_mnemonic(
            '_Remove Output Channel')
        edit_menu.append(self.channel_remove_output_menu_item)
        self.channel_remove_output_menu = Gtk.Menu()
        self.channel_remove_output_menu_item.set_submenu(
            self.channel_remove_output_menu)

        channel_remove_all_menu_item = Gtk.MenuItem.new_with_mnemonic('Clear')
        edit_menu.append(channel_remove_all_menu_item)
        channel_remove_all_menu_item.connect("activate",
                                             self.on_channels_clear)

        edit_menu.append(Gtk.SeparatorMenuItem())

        preferences = Gtk.MenuItem.new_with_mnemonic('_Preferences')
        preferences.connect('activate', self.on_preferences_cb)
        edit_menu.append(preferences)

        help_menu = Gtk.Menu()
        help_menu_item.set_submenu(help_menu)

        about = Gtk.MenuItem.new_with_mnemonic('_About')
        help_menu.append(about)
        about.connect("activate", self.on_about)

        self.hbox_top = Gtk.HBox()
        self.vbox_top.pack_start(self.hbox_top, True, True, 0)

        self.scrolled_window = Gtk.ScrolledWindow()
        self.hbox_top.pack_start(self.scrolled_window, True, True, 0)

        self.hbox_inputs = Gtk.HBox()
        self.hbox_inputs.set_spacing(0)
        self.hbox_inputs.set_border_width(0)
        self.hbox_top.set_spacing(0)
        self.hbox_top.set_border_width(0)
        self.channels = []
        self.output_channels = []

        self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                        Gtk.PolicyType.AUTOMATIC)
        self.scrolled_window.add(self.hbox_inputs)

        self.hbox_outputs = Gtk.HBox()
        self.hbox_outputs.set_spacing(0)
        self.hbox_outputs.set_border_width(0)
        frame = Gtk.Frame()
        self.hbox_outputs.pack_start(frame, False, True, 0)
        self.hbox_top.pack_start(self.hbox_outputs, False, True, 0)

        self.window.connect("destroy", Gtk.main_quit)

        self.window.connect('delete-event', self.on_delete_event)

        GLib.timeout_add(80, self.read_meters)
        self.lash_client = lash_client

        GLib.timeout_add(200, self.lash_check_events)

        GLib.timeout_add(50, self.midi_events_check)

    def on_delete_event(self, widget, event):
        return False

    def sighandler(self, signum, frame):
        #print "Signal %d received" % signum
        if signum == signal.SIGUSR1:
            self.save = True
        elif signum == signal.SIGTERM:
            Gtk.main_quit()
        elif signum == signal.SIGINT:
            Gtk.main_quit()
        else:
            print("Unknown signal %d received" % signum)

    def cleanup(self):
        print("Cleaning jack_mixer")
        if not self.mixer:
            return

        for channel in self.channels:
            channel.unrealize()

        self.mixer.destroy()

    def on_open_cb(self, *args):
        dlg = Gtk.FileChooserDialog(
            title='Open',
            parent=self.window,
            action=Gtk.FileChooserAction.OPEN,
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN,
                     Gtk.ResponseType.OK))
        dlg.set_default_response(Gtk.ResponseType.OK)
        if dlg.run() == Gtk.ResponseType.OK:
            filename = dlg.get_filename()
            try:
                f = file(filename, 'r')
                self.load_from_xml(f)
            except:
                err = Gtk.MessageDialog(self.window, Gtk.DialogFlags.MODAL,
                                        Gtk.MessageType.ERROR,
                                        Gtk.ButtonsType.OK,
                                        "Failed loading settings.")
                err.run()
                err.destroy()
            else:
                self.current_filename = filename
            finally:
                f.close()
        dlg.destroy()

    def on_save_cb(self, *args):
        if not self.current_filename:
            return self.on_save_as_cb()
        f = file(self.current_filename, 'w')
        self.save_to_xml(f)
        f.close()

    def on_save_as_cb(self, *args):
        dlg = Gtk.FileChooserDialog(
            title='Save',
            parent=self.window,
            action=Gtk.FileChooserAction.SAVE,
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE,
                     Gtk.ResponseType.OK))
        dlg.set_default_response(Gtk.ResponseType.OK)
        if dlg.run() == Gtk.ResponseType.OK:
            self.current_filename = dlg.get_filename()
            self.on_save_cb()
        dlg.destroy()

    def on_quit_cb(self, *args):
        Gtk.main_quit()

    preferences_dialog = None

    def on_preferences_cb(self, widget):
        if not self.preferences_dialog:
            self.preferences_dialog = PreferencesDialog(self)
        self.preferences_dialog.show()
        self.preferences_dialog.present()

    def on_add_input_channel(self, widget):
        dialog = NewChannelDialog(app=self)
        dialog.set_transient_for(self.window)
        dialog.show()
        ret = dialog.run()
        dialog.hide()

        if ret == Gtk.ResponseType.OK:
            result = dialog.get_result()
            channel = self.add_channel(**result)
            self.window.show_all()

    def on_add_output_channel(self, widget):
        dialog = NewOutputChannelDialog(app=self)
        dialog.set_transient_for(self.window)
        dialog.show()
        ret = dialog.run()
        dialog.hide()

        if ret == Gtk.ResponseType.OK:
            result = dialog.get_result()
            channel = self.add_output_channel(**result)
            self.window.show_all()

    def on_edit_input_channel(self, widget, channel):
        print('Editing channel "%s"' % channel.channel_name)
        channel.on_channel_properties()

    def remove_channel_edit_input_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_input_menu.remove(widget)

    def on_remove_input_channel(self, widget, channel):
        print('Removing channel "%s"' % channel.channel_name)
        self.channel_remove_input_menu.remove(widget)
        self.channel_edit_input_menu.foreach(
            self.remove_channel_edit_input_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.channels[i] is channel:
                channel.unrealize()
                del self.channels[i]
                self.hbox_inputs.remove(channel.get_parent())
                break
        if len(self.channels) == 0:
            self.channel_remove_input_menu_item.set_sensitive(False)

    def on_edit_output_channel(self, widget, channel):
        print('Editing channel "%s"' % channel.channel_name)
        channel.on_channel_properties()

    def remove_channel_edit_output_menuitem_by_label(self, widget, label):
        if (widget.get_label() == label):
            self.channel_edit_output_menu.remove(widget)

    def on_remove_output_channel(self, widget, channel):
        print('Removing channel "%s"' % channel.channel_name)
        self.channel_remove_output_menu.remove(widget)
        self.channel_edit_output_menu.foreach(
            self.remove_channel_edit_output_menuitem_by_label,
            channel.channel_name)
        if self.monitored_channel is channel:
            channel.monitor_button.set_active(False)
        for i in range(len(self.channels)):
            if self.output_channels[i] is channel:
                channel.unrealize()
                del self.output_channels[i]
                self.hbox_outputs.remove(channel.get_parent())
                break
        if len(self.output_channels) == 0:
            self.channel_remove_output_menu_item.set_sensitive(False)

    def rename_channels(self, container, parameters):
        if (container.get_label() == parameters['oldname']):
            container.set_label(parameters['newname'])

    def on_channel_rename(self, oldname, newname):
        rename_parameters = {'oldname': oldname, 'newname': newname}
        self.channel_edit_input_menu.foreach(self.rename_channels,
                                             rename_parameters)
        self.channel_edit_output_menu.foreach(self.rename_channels,
                                              rename_parameters)
        self.channel_remove_input_menu.foreach(self.rename_channels,
                                               rename_parameters)
        self.channel_remove_output_menu.foreach(self.rename_channels,
                                                rename_parameters)
        print("Renaming channel from %s to %s\n" % (oldname, newname))

    def on_channels_clear(self, widget):
        for channel in self.output_channels:
            channel.unrealize()
            self.hbox_outputs.remove(channel.get_parent())
        for channel in self.channels:
            channel.unrealize()
            self.hbox_inputs.remove(channel.get_parent())
        self.channels = []
        self.output_channels = []
        self.channel_edit_input_menu = Gtk.Menu()
        self.channel_edit_input_menu_item.set_submenu(
            self.channel_edit_input_menu)
        self.channel_edit_input_menu_item.set_sensitive(False)
        self.channel_remove_input_menu = Gtk.Menu()
        self.channel_remove_input_menu_item.set_submenu(
            self.channel_remove_input_menu)
        self.channel_remove_input_menu_item.set_sensitive(False)
        self.channel_edit_output_menu = Gtk.Menu()
        self.channel_edit_output_menu_item.set_submenu(
            self.channel_edit_output_menu)
        self.channel_edit_output_menu_item.set_sensitive(False)
        self.channel_remove_output_menu = Gtk.Menu()
        self.channel_remove_output_menu_item.set_submenu(
            self.channel_remove_output_menu)
        self.channel_remove_output_menu_item.set_sensitive(False)

    def add_channel(self, name, stereo, volume_cc, balance_cc, mute_cc,
                    solo_cc):
        try:
            channel = InputChannel(self, name, stereo)
            self.add_channel_precreated(channel)
        except Exception:
            e = sys.exc_info()[0]
            err = Gtk.MessageDialog(
                self.window,
                Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
                "Channel creation failed")
            err.run()
            err.destroy()
            return
        if volume_cc != '-1':
            channel.channel.volume_midi_cc = int(volume_cc)
        if balance_cc != '-1':
            channel.channel.balance_midi_cc = int(balance_cc)
        if mute_cc != '-1':
            channel.channel.mute_midi_cc = int(mute_cc)
        if solo_cc != '-1':
            channel.channel.solo_midi_cc = int(solo_cc)
        if (volume_cc == '-1' and balance_cc == '-1' and mute_cc == '-1'
                and solo_cc == '-1'):
            channel.channel.autoset_midi_cc()

        return channel

    def add_channel_precreated(self, channel):
        frame = Gtk.Frame()
        frame.add(channel)
        self.hbox_inputs.pack_start(frame, False, True, 0)
        channel.realize()

        channel_edit_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_edit_input_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_input_channel,
                                       channel)
        self.channel_edit_input_menu_item.set_sensitive(True)

        channel_remove_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_remove_input_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_input_channel, channel)
        self.channel_remove_input_menu_item.set_sensitive(True)

        self.channels.append(channel)

        for outputchannel in self.output_channels:
            channel.add_control_group(outputchannel)

        # create post fader output channel matching the input channel
        channel.post_fader_output_channel = self.mixer.add_output_channel(
            channel.channel.name + ' Out', channel.channel.is_stereo, True)
        channel.post_fader_output_channel.volume = 0
        channel.post_fader_output_channel.set_solo(channel.channel, True)

    def read_meters(self):
        for channel in self.channels:
            channel.read_meter()
        for channel in self.output_channels:
            channel.read_meter()
        return True

    def midi_events_check(self):
        for channel in self.channels + self.output_channels:
            channel.midi_events_check()
        return True

    def add_output_channel(self, name, stereo, volume_cc, balance_cc, mute_cc,
                           display_solo_buttons):
        try:
            channel = OutputChannel(self, name, stereo)
            channel.display_solo_buttons = display_solo_buttons
            self.add_output_channel_precreated(channel)
        except Exception:
            err = Gtk.MessageDialog(
                self.window,
                Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
                "Channel creation failed")
            err.run()
            err.destroy()
            return
        if volume_cc != '-1':
            channel.channel.volume_midi_cc = int(volume_cc)
        if balance_cc != '-1':
            channel.channel.balance_midi_cc = int(balance_cc)
        if mute_cc != '-1':
            channel.channel.mute_midi_cc = int(mute_cc)
        return channel

    def add_output_channel_precreated(self, channel):
        frame = Gtk.Frame()
        frame.add(channel)
        self.hbox_outputs.pack_start(frame, False, True, 0)
        channel.realize()

        channel_edit_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_edit_output_menu.append(channel_edit_menu_item)
        channel_edit_menu_item.connect("activate", self.on_edit_output_channel,
                                       channel)
        self.channel_edit_output_menu_item.set_sensitive(True)

        channel_remove_menu_item = Gtk.MenuItem(label=channel.channel_name)
        self.channel_remove_output_menu.append(channel_remove_menu_item)
        channel_remove_menu_item.connect("activate",
                                         self.on_remove_output_channel,
                                         channel)
        self.channel_remove_output_menu_item.set_sensitive(True)

        self.output_channels.append(channel)

    _monitored_channel = None

    def get_monitored_channel(self):
        return self._monitored_channel

    def set_monitored_channel(self, channel):
        if self._monitored_channel:
            if channel.channel.name == self._monitored_channel.channel.name:
                return
        self._monitored_channel = channel
        if type(channel) is InputChannel:
            # reset all solo/mute settings
            for in_channel in self.channels:
                self.monitor_channel.set_solo(in_channel.channel, False)
                self.monitor_channel.set_muted(in_channel.channel, False)
            self.monitor_channel.set_solo(channel.channel, True)
            self.monitor_channel.prefader = True
        else:
            self.monitor_channel.prefader = False
        self.update_monitor(channel)

    monitored_channel = property(get_monitored_channel, set_monitored_channel)

    def update_monitor(self, channel):
        if self.monitored_channel is not channel:
            return
        self.monitor_channel.volume = channel.channel.volume
        self.monitor_channel.balance = channel.channel.balance
        self.monitor_channel.out_mute = channel.channel.out_mute
        if type(self.monitored_channel) is OutputChannel:
            # sync solo/muted channels
            for input_channel in self.channels:
                self.monitor_channel.set_solo(
                    input_channel.channel,
                    channel.channel.is_solo(input_channel.channel))
                self.monitor_channel.set_muted(
                    input_channel.channel,
                    channel.channel.is_muted(input_channel.channel))

    def get_input_channel_by_name(self, name):
        for input_channel in self.channels:
            if input_channel.channel.name == name:
                return input_channel
        return None

    def on_about(self, *args):
        about = Gtk.AboutDialog()
        about.set_name('jack_mixer')
        about.set_copyright(
            'Copyright © 2006-2020\nNedko Arnaudov, Frederic Peters, Arnout Engelen, Daniel Sheeler'
        )
        about.set_license('''\
jack_mixer 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 (at your
option) any later version.

jack_mixer 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.

You should have received a copy of the GNU General Public License along
with jack_mixer; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA''')
        about.set_authors([
            'Nedko Arnaudov <*****@*****.**>',
            'Frederic Peters <*****@*****.**>',
            'Daniel Sheeler <*****@*****.**>'
        ])
        about.set_logo_icon_name('jack_mixer')
        about.set_website('https://rdio.space/jackmixer/')

        about.run()
        about.destroy()

    def lash_check_events(self):
        if self.save:
            self.save = False
            if self.current_filename:
                print("saving on SIGUSR1 request")
                self.on_save_cb()
                print("save done")
            else:
                print("not saving because filename is not known")
            return True

        if not self.lash_client:
            return True

        while lash.lash_get_pending_event_count(self.lash_client):
            event = lash.lash_get_event(self.lash_client)

            #print repr(event)

            event_type = lash.lash_event_get_type(event)
            if event_type == lash.LASH_Quit:
                print("jack_mixer: LASH ordered quit.")
                Gtk.main_quit()
                return False
            elif event_type == lash.LASH_Save_File:
                directory = lash.lash_event_get_string(event)
                print("jack_mixer: LASH ordered to save data in directory %s" %
                      directory)
                filename = directory + os.sep + "jack_mixer.xml"
                f = file(filename, "w")
                self.save_to_xml(f)
                f.close()
                lash.lash_send_event(self.lash_client,
                                     event)  # we crash with double free
            elif event_type == lash.LASH_Restore_File:
                directory = lash.lash_event_get_string(event)
                print(
                    "jack_mixer: LASH ordered to restore data from directory %s"
                    % directory)
                filename = directory + os.sep + "jack_mixer.xml"
                f = file(filename, "r")
                self.load_from_xml(f, silence_errors=True)
                f.close()
                lash.lash_send_event(self.lash_client, event)
            else:
                print("jack_mixer: Got unhandled LASH event, type " +
                      str(event_type))
                return True

            #lash.lash_event_destroy(event)

        return True

    def save_to_xml(self, file):
        #print "Saving to XML..."
        b = XmlSerialization()
        s = Serializator()
        s.serialize(self, b)
        b.save(file)

    def load_from_xml(self, file, silence_errors=False):
        #print "Loading from XML..."
        self.on_channels_clear(None)
        self.unserialized_channels = []
        b = XmlSerialization()
        try:
            b.load(file)
        except:
            if silence_errors:
                return
            raise
        s = Serializator()
        s.unserialize(self, b)
        for channel in self.unserialized_channels:
            if isinstance(channel, InputChannel):
                if self._init_solo_channels and channel.channel_name in self._init_solo_channels:
                    channel.solo = True
                self.add_channel_precreated(channel)
        self._init_solo_channels = None
        for channel in self.unserialized_channels:
            if isinstance(channel, OutputChannel):
                self.add_output_channel_precreated(channel)
        del self.unserialized_channels
        self.window.show_all()

    def serialize(self, object_backend):
        width, height = self.window.get_size()
        object_backend.add_property('geometry', '%sx%s' % (width, height))
        solo_channels = []
        for input_channel in self.channels:
            if input_channel.channel.solo:
                solo_channels.append(input_channel)
        if solo_channels:
            object_backend.add_property(
                'solo_channels',
                '|'.join([x.channel.name for x in solo_channels]))

    def unserialize_property(self, name, value):
        if name == 'geometry':
            width, height = value.split('x')
            self.window.resize(int(width), int(height))
            return True
        if name == 'solo_channels':
            self._init_solo_channels = value.split('|')
            return True

    def unserialize_child(self, name):
        if name == InputChannel.serialization_name():
            channel = InputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

        if name == OutputChannel.serialization_name():
            channel = OutputChannel(self, "", True)
            self.unserialized_channels.append(channel)
            return channel

    def serialization_get_childs(self):
        '''Get child objects tha required and support serialization'''
        childs = self.channels[:] + self.output_channels[:]
        return childs

    def serialization_name(self):
        return "jack_mixer"

    def main(self):
        if not self.mixer:
            return

        self.window.show_all()

        signal.signal(signal.SIGUSR1, self.sighandler)
        signal.signal(signal.SIGTERM, self.sighandler)
        signal.signal(signal.SIGINT, self.sighandler)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)

        Gtk.main()
Exemple #24
0
 def preferences_clicked(self, widget):
     self.preferences_dialog = PreferencesDialog(self.conf, self.menu)
     if self.preferences_dialog.exec_() == QtGui.QDialog.Accepted:
         self.preferences_dialog.save()
         self.app.emit(QtCore.SIGNAL('reload_project_data'))
Exemple #25
0
 def __init__(self):
     self.pdialog = PreferencesDialog()
     self.pdialog.signals.settingsChanged.connect(self.initializeApi)
     self.signals = self.Signals()
     self.initializeApi()
Exemple #26
0
 def open_preferences_dialog(self):
     """Open a dialog with preferences."""
     self.preferences_dialog = PreferencesDialog(self.config)