Beispiel #1
0
class ChooseSectionsPage(QIWizardPage):
    """
    page to choose the sections that should be compared in the table
    """
    def __init__(self, parent=None):
        super(ChooseSectionsPage, self).__init__(parent)
        self.selected_sections = []  # sections in the right tree
        self.sections = []  # all sections without the selected
        self.filtered_sections = []  # filtered sections without the selected
        self.initUI()

    def initUI(self):

        mainlayout = QVBoxLayout()

        # layout containing the treewidgets
        sectionlistlayout = QHBoxLayout()

        # layout for filter form
        filterbox = QGroupBox("Filter")

        self.LEsecname = QLineEdit()
        self.LEsectype = QLineEdit()
        self.LEpropname = QLineEdit()

        filterlayout = QGridLayout()
        filterlayout.addWidget(QLabel("Section Name"), 1, 0)
        filterlayout.addWidget(QLabel("Section Type"), 2, 0)
        filterlayout.addWidget(QLabel("Property Name"), 3, 0)
        filterlayout.addWidget(self.LEsecname, 1, 1)
        filterlayout.addWidget(self.LEsectype, 2, 1)
        filterlayout.addWidget(self.LEpropname, 3, 1)
        filterbox.setLayout(filterlayout)

        self.LEsecname.textChanged.connect(self.filterSections)
        self.LEsectype.textChanged.connect(self.filterSections)
        self.LEpropname.textChanged.connect(self.filterSections)

        # define layout for the trre-widgets containing the sections
        self.section_tree = QTreeWidget()
        self.section_tree.setColumnCount(2)
        self.section_tree.setHeaderLabels(["Name", "Path"])
        self.section_tree.itemDoubleClicked.connect(self.toright)

        self.selection_tree = QTreeWidget()
        self.selection_tree.setColumnCount(2)
        self.selection_tree.setHeaderLabels(["Name", "Path"])
        self.selection_tree.itemDoubleClicked.connect(self.toleft)

        self.selection_tree.setSelectionMode(3)
        self.section_tree.setSelectionMode(3)

        self.settings.register("selected_secs", self.selected_sections)

        # buttons to move items of the tree-widgets
        movebuttonlayout = QVBoxLayout()
        btn_right = QToolButton()
        btn_right.setArrowType(Qt.RightArrow)
        btn_right.clicked.connect(self.toright)
        btn_left = QToolButton()
        btn_left.setArrowType(Qt.LeftArrow)
        btn_left.clicked.connect(self.toleft)

        movebuttonlayout.addStretch(1)
        movebuttonlayout.addWidget(btn_right)
        movebuttonlayout.addSpacing(1)
        movebuttonlayout.addWidget(btn_left)
        movebuttonlayout.addStretch(1)

        sectionlistlayout.addWidget(self.section_tree)
        sectionlistlayout.addSpacing(1)
        sectionlistlayout.addLayout(movebuttonlayout)
        sectionlistlayout.addSpacing(1)
        sectionlistlayout.addWidget(self.selection_tree)

        mainlayout.addLayout(sectionlistlayout)
        self.selectallcb = QCheckBox('select all (Ctrl+A)')
        self.selectallcb.stateChanged.connect(self.selectall)
        mainlayout.addWidget(self.selectallcb)
        mainlayout.addWidget(filterbox)

        self.setTitle("Select Sections")
        self.setLayout(mainlayout)
        self.adjustSize()

    def initializePage(self):

        # load sections and properties from the selected file
        odmldoc = odml.load(self.settings.get_object("inputfilename"))
        # resolve links and includes
        odmldoc.finalize()
        for section in odmldoc.itersections():
            self.sections.append([
                section.name,
                section.get_path(), [p.name for p in section.properties],
                section.type
            ])

        # fill tree widget with sections and properties
        for line in self.sections:
            parent = QTreeWidgetItem([line[0], line[1]])
            for p in line[2]:
                QTreeWidgetItem(parent, [str(p)])
            self.section_tree.addTopLevelItem(parent)

        self.filtered_sections = list(self.sections)
        self.setTitle("Choose Sections")
        self.setSubTitle("Choose the sections you want to compare")

    def _get_selected_rows(self, tree):
        """
        function to determine the selected rows in a specified QTreeWidget
        """

        rows = []
        for index in tree.selectedIndexes():
            if index.parent().row() is -1:
                rows.append(index.row())
            else:
                # if a property is selected, the whole section containing this
                # property shall be moved
                rows.append(index.parent().row())

        # sort rownumbers in descending order to prevent shifting when moving
        # the items
        return sorted(list(set(rows)), reverse=True)

    def toright(self):
        """
        function to shift items from the left TreeWidget to the right
        """

        rows = self._get_selected_rows(self.section_tree)
        for row in rows:
            self.selection_tree.addTopLevelItem(
                self.section_tree.takeTopLevelItem(row))
            self.selected_sections.append(
                self.sections.pop(
                    self.sections.index(self.filtered_sections[row])))
            self.filtered_sections.pop(row)

    def toleft(self):
        """
        function to shift items from the right TreeWidget to the left
        """

        rows = self._get_selected_rows(self.selection_tree)
        for row in rows:
            self.section_tree.addTopLevelItem(
                self.selection_tree.takeTopLevelItem(row))
            item = self.selected_sections.pop(row)
            self.sections.append(item)
            self.filtered_sections.append(item)

    def filterSections(self):

        # find sections that match the filter
        self.filtered_sections = [
            s for s in self.sections if str(self.LEsecname.text()) in s[0]
            and str(self.LEsectype.text()) in s[3]
            and any([str(self.LEpropname.text()) in p for p in s[2]])
        ]
        # clear left treewidget
        self.section_tree.clear()

        # fill left treewidget with the filtered sections
        for line in self.filtered_sections:
            parent = QTreeWidgetItem([line[0], line[1]])
            for p in line[2]:
                QTreeWidgetItem(parent, [p])
            self.section_tree.addTopLevelItem(parent)

    def selectall(self):
        if self.selectallcb.isChecked():
            self.section_tree.selectAll()
        else:
            self.section_tree.clearSelection()

    def validatePage(self):
        if not self.settings.get_object("selected_secs"):
            QMessageBox.warning(
                self, 'No sections chosen',
                'You should choose at least two sections to be '
                'compared in the table.')
            return 0
        return 1
class Window(QMainWindow):

	def __init__(self):
		super().__init__()
		self.devices = []
		self.init_search_for_cameras()

		# Menu Bar
		self.menu_bar = self.menuBar()
		self.status_bar = self.statusBar()

		# Root Menus
		file_menu = self.menu_bar.addMenu("File")
		view_menu = self.menu_bar.addMenu("View")
		view_language_menu = view_menu.addMenu ("Language")
		tools_menu = self.menu_bar.addMenu("Tools")
		help_menu = self.menu_bar.addMenu("Help")

		# Create Menu Actions
		self.quit_action = QAction("Exit", self)
		self.quit_action.setShortcut("Ctrl+q")

		self.refresh_action = QAction("Refresh", self)
		self.refresh_action.setShortcut("Ctrl+r")

		self.help_action = QAction("About AXIS IP Utility", self)
		self.help_action.setShortcut("Ctrl+h")

		self.assign_network_parameters_action = QAction("Assign Network Parameters", self)
		self.assign_network_parameters_action.setShortcut("Ctrl+c")

		self.assign_ip_address_action = QAction("Assign IP Address", self)
		self.assign_ip_address_action.setShortcut("Ctrl+a")

		self.assign_serial_no_ip_address_action = QAction("Assign IP Address Using Serial Number", self)
		self.assign_serial_no_ip_address_action.setShortcut("Ctrl+n")

		self.test_ip_address_action = QAction("Test IP Address", self)
		self.test_ip_address_action.setShortcut("Ctrl+t")

		self.open_in_web_browser = QAction("Open in Web Browser", self)
		self.open_in_web_browser.setShortcut("Ctrl+o")

		self.language_english_action = QAction("English", self)

		# Add Menu Actions
		file_menu.addAction(self.quit_action)

		tools_menu.addAction(self.assign_network_parameters_action)
		tools_menu.addAction(self.assign_ip_address_action)
		tools_menu.addAction(self.assign_serial_no_ip_address_action)
		tools_menu.addSeparator()
		tools_menu.addAction(self.test_ip_address_action)
		tools_menu.addSeparator()
		tools_menu.addAction(self.refresh_action)

		help_menu.addAction(self.help_action)

		view_language_menu.addAction(self.language_english_action)

		# List
		self.devices = []
		self.devices_tree = QTreeWidget()
		self.devices_tree.setSortingEnabled(True)

		self.devices_tree.headerItem().setText(0, "Name")
		self.devices_tree.headerItem().setText(1, "IP Address")
		self.devices_tree.headerItem().setText(2, "Serial Number")

		self.devices_tree.setColumnWidth(0, 260)
		self.devices_tree.setColumnWidth(1, 130)

		self.devices_tree.header().setSectionResizeMode(0, QHeaderView.Interactive)
		self.devices_tree.header().setSectionResizeMode(1, QHeaderView.Interactive)
		self.devices_tree.header().setSectionResizeMode(2, QHeaderView.Interactive)

		self.devices_tree.customContextMenuRequested.connect(self.open_menu)
		self.devices_tree.setContextMenuPolicy(Qt.CustomContextMenu)

		# Layout
		self.text_filter = QLineEdit()
		self.text_filter.setPlaceholderText("Type to filter...")

		self.layout = QVBoxLayout()
		self.layout.addWidget(self.text_filter)
		self.layout.addWidget(self.devices_tree)
		self.main_widget = QWidget()
		self.main_widget.setLayout(self.layout)
		self.setCentralWidget(self.main_widget)

		# Events
		self.quit_action.triggered.connect(self.quit_trigger)
		self.refresh_action.triggered.connect(self.refresh_trigger)

		self.text_filter.textChanged.connect(self.search_devices)

		self.open_in_web_browser.triggered.connect(self.open_in_web_browser_trigger)
		self.devices_tree.itemDoubleClicked.connect(self.open_in_web_browser_trigger)

		# Show Window
		self.setWindowTitle("AXIS IP Utility in Python - Erik Wilhelm Gren 2019")

		self.label = QLabel()
		self.label.setText("Interface: {}".format(socket.gethostbyname(socket.gethostname())))
		self.status_bar.addPermanentWidget(self.label)
		self.update_status_bar()
		self.resize(640, 300)
		self.show()

	def update_status_bar(self):
		self.set_status_bar(("{} device{}".format(len(self.devices), ("" if len(self.devices) == 1 else "s"))))

	def set_status_bar(self, text):
		self.status_bar.showMessage(text)

	def search_devices(self):
		query = self.text_filter.text()
		# print(query)
		if query == "":
			all_items = self.devices_tree.findItems("", Qt.MatchFlag(1), 0)
			for item in all_items:
				item.setHidden(False)
			self.update_status_bar()
		else:
			all_items = self.devices_tree.findItems("", Qt.MatchFlag(1), 0)
			for item in all_items:
				item.setHidden(True)

			items = self.devices_tree.findItems(query, Qt.MatchFlag(1), 0) + self.devices_tree.findItems(query, Qt.MatchFlag(1), 1) + self.devices_tree.findItems(query, Qt.MatchFlag(1), 2)
			for item in items:
				item.setHidden(False)
				print(item.text(0))
			self.set_status_bar("{} device{}".format(len(items), ("" if len(items) == 1 else "s")))

	def add_camera(self, camera):
		self.devices.append(camera)

		devices_tree_item = QTreeWidgetItem(self.devices_tree)
		devices_tree_item.setText(0, camera.name)
		devices_tree_item.setText(1, camera.ip_address)
		devices_tree_item.setText(2, camera.serial_number)

		self.update_status_bar()

	def refresh_trigger(self):
		self.reset()
		self.reset_search_for_cameras() # SOMETHING'S BROKEN ON WINDOWS 10!

	def reset(self):
		if(self.zeroconf):
			self.zeroconf.close()

		if(self.devices_tree):
			self.devices_tree.clearSelection()
			self.devices_tree.clear()

		if(self.devices):
			self.devices = []

		self.update_status_bar()

	def reset_search_for_cameras(self):
		self.zeroconf = Zeroconf()
		self.listener = CameraListener(self)
		self.browser = ServiceBrowser(self.zeroconf, "_http._tcp.local.", self.listener)

	def init_search_for_cameras(self):
		self.zeroconf = Zeroconf()
		self.listener = CameraListener(self)
		self.browser = ServiceBrowser(self.zeroconf, "_http._tcp.local.", self.listener)

	def open_menu(self, position):
		menu = QMenu()

		menu.addAction(self.open_in_web_browser)
		menu.exec_(self.devices_tree.viewport().mapToGlobal(position))

	def open_in_web_browser_trigger(self):
		item = self.devices_tree.selectedItems()
		if item:
			ip_address = item[0].text(1)
			url = "http://{}/".format(ip_address)
			webbrowser.open(url)

	def quit_trigger(self):
		qApp.quit()
Beispiel #3
0
class GuiProjectEditReplace(QWidget):
    def __init__(self, theParent, theProject):
        QWidget.__init__(self, theParent)

        self.theParent = theParent
        self.theProject = theProject
        self.arChanged = False

        self.outerBox = QVBoxLayout()
        self.bottomBox = QHBoxLayout()
        self.listBox = QTreeWidget()
        self.listBox.setHeaderLabels(["Keyword", "Replace With"])
        self.listBox.itemSelectionChanged.connect(self._selectedItem)
        self.listBox.setIndentation(0)

        for aKey, aVal in self.theProject.autoReplace.items():
            newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
            self.listBox.addTopLevelItem(newItem)

        self.editKey = QLineEdit()
        self.editValue = QLineEdit()
        self.saveButton = QPushButton(QIcon.fromTheme("document-save"), "")
        self.addButton = QPushButton(QIcon.fromTheme("list-add"), "")
        self.delButton = QPushButton(QIcon.fromTheme("list-remove"), "")

        self.editKey.setEnabled(False)
        self.editValue.setEnabled(False)

        self.saveButton.clicked.connect(self._saveEntry)
        self.addButton.clicked.connect(self._addEntry)
        self.delButton.clicked.connect(self._delEntry)

        self.bottomBox.addWidget(self.editKey, 2)
        self.bottomBox.addWidget(self.editValue, 3)
        self.bottomBox.addWidget(self.saveButton)
        self.bottomBox.addWidget(self.addButton)
        self.bottomBox.addWidget(self.delButton)

        self.outerBox.addWidget(self.listBox)
        self.outerBox.addLayout(self.bottomBox)
        self.setLayout(self.outerBox)

        return

    def getNewList(self):
        newList = {}
        for n in range(self.listBox.topLevelItemCount()):
            tItem = self.listBox.topLevelItem(n)
            aKey = self._stripNotAllowed(tItem.text(0))
            aVal = tItem.text(1)
            if len(aKey) > 0:
                newList[aKey] = aVal
        return newList

    ##
    #  Internal Functions
    ##

    def _selectedItem(self):
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        editKey = self._stripNotAllowed(selItem.text(0))
        editVal = selItem.text(1)
        self.editKey.setText(editKey)
        self.editValue.setText(editVal)
        self.editKey.setEnabled(True)
        self.editValue.setEnabled(True)
        self.editKey.selectAll()
        self.editKey.setFocus()
        return True

    def _saveEntry(self):

        selItem = self._getSelectedItem()
        if selItem is None:
            return False

        newKey = self.editKey.text()
        newVal = self.editValue.text()
        saveKey = self._stripNotAllowed(newKey)

        if len(saveKey) > 0 and len(newVal) > 0:
            selItem.setText(0, "<%s>" % saveKey)
            selItem.setText(1, newVal)
            self.editKey.clear()
            self.editValue.clear()
            self.editKey.setEnabled(False)
            self.editValue.setEnabled(False)
            self.listBox.clearSelection()
            self.arChanged = True

        return

    def _addEntry(self):
        saveKey = "<keyword%d>" % (self.listBox.topLevelItemCount() + 1)
        newVal = ""
        newItem = QTreeWidgetItem([saveKey, newVal])
        self.listBox.addTopLevelItem(newItem)
        return True

    def _delEntry(self):
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        self.listBox.takeTopLevelItem(
            self.listBox.indexOfTopLevelItem(selItem))
        self.arChanged = True
        return True

    def _getSelectedItem(self):
        selItem = self.listBox.selectedItems()
        if len(selItem) == 0:
            return None
        return selItem[0]

    def _stripNotAllowed(self, theKey):
        retKey = ""
        for c in theKey:
            if c.isalnum():
                retKey += c
        return retKey
Beispiel #4
0
class GuiProjectEditReplace(QWidget):

    def __init__(self, theParent, theProject):
        QWidget.__init__(self, theParent)

        self.mainConf   = nw.CONFIG
        self.theParent  = theParent
        self.theTheme   = theParent.theTheme
        self.theProject = theProject
        self.optState   = theProject.optState
        self.arChanged  = False

        self.outerBox  = QVBoxLayout()
        self.bottomBox = QHBoxLayout()

        wCol0 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectSettings", "replaceColW", 100)
        )
        self.listBox = QTreeWidget()
        self.listBox.setHeaderLabels(["Keyword", "Replace With"])
        self.listBox.itemSelectionChanged.connect(self._selectedItem)
        self.listBox.setColumnWidth(0, wCol0)
        self.listBox.setIndentation(0)

        for aKey, aVal in self.theProject.autoReplace.items():
            newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
            self.listBox.addTopLevelItem(newItem)

        self.listBox.sortByColumn(0, Qt.AscendingOrder)
        self.listBox.setSortingEnabled(True)

        self.editKey    = QLineEdit()
        self.editValue  = QLineEdit()
        self.saveButton = QPushButton(self.theTheme.getIcon("done"), "")
        self.addButton  = QPushButton(self.theTheme.getIcon("add"), "")
        self.delButton  = QPushButton(self.theTheme.getIcon("remove"), "")
        self.saveButton.setToolTip("Save entry")
        self.addButton.setToolTip("Add new entry")
        self.delButton.setToolTip("Delete selected entry")

        self.editKey.setEnabled(False)
        self.editKey.setMaxLength(40)
        self.editValue.setEnabled(False)
        self.editValue.setMaxLength(80)

        self.saveButton.clicked.connect(self._saveEntry)
        self.addButton.clicked.connect(self._addEntry)
        self.delButton.clicked.connect(self._delEntry)

        self.bottomBox.addWidget(self.editKey, 2)
        self.bottomBox.addWidget(self.editValue, 3)
        self.bottomBox.addWidget(self.saveButton)
        self.bottomBox.addWidget(self.addButton)
        self.bottomBox.addWidget(self.delButton)

        self.outerBox.addWidget(QLabel("<b>Text Replace List for Preview and Export</b>"))
        self.outerBox.addWidget(self.listBox)
        self.outerBox.addLayout(self.bottomBox)
        self.setLayout(self.outerBox)

        return

    def getNewList(self):
        """Extract the list from the widget.
        """
        newList = {}
        for n in range(self.listBox.topLevelItemCount()):
            tItem = self.listBox.topLevelItem(n)
            aKey = self._stripNotAllowed(tItem.text(0))
            aVal = tItem.text(1)
            if len(aKey) > 0:
                newList[aKey] = aVal
        return newList

    ##
    #  Internal Functions
    ##

    def _selectedItem(self):
        """Extract the details from the selected item and populate the
        edit form.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        editKey = self._stripNotAllowed(selItem.text(0))
        editVal = selItem.text(1)
        self.editKey.setText(editKey)
        self.editValue.setText(editVal)
        self.editKey.setEnabled(True)
        self.editValue.setEnabled(True)
        self.editKey.selectAll()
        self.editKey.setFocus()
        return True

    def _saveEntry(self):
        """Save the form data into the list widget.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False

        newKey  = self.editKey.text()
        newVal  = self.editValue.text()
        saveKey = self._stripNotAllowed(newKey)

        if len(saveKey) > 0 and len(newVal) > 0:
            selItem.setText(0, "<%s>" % saveKey)
            selItem.setText(1, newVal)
            self.editKey.clear()
            self.editValue.clear()
            self.editKey.setEnabled(False)
            self.editValue.setEnabled(False)
            self.listBox.clearSelection()
            self.arChanged = True

        return

    def _addEntry(self):
        """Add a new list entry.
        """
        saveKey = "<keyword%d>" % (self.listBox.topLevelItemCount() + 1)
        newVal  = ""
        newItem = QTreeWidgetItem([saveKey, newVal])
        self.listBox.addTopLevelItem(newItem)
        return True

    def _delEntry(self):
        """Delete the selected entry.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        self.listBox.takeTopLevelItem(self.listBox.indexOfTopLevelItem(selItem))
        self.arChanged = True
        return True

    def _getSelectedItem(self):
        """Extract the currently selected item.
        """
        selItem = self.listBox.selectedItems()
        if len(selItem) == 0:
            return None
        return selItem[0]

    def _stripNotAllowed(self, theKey):
        """Clean up the replace key string.
        """
        retKey = ""
        for c in theKey:
            if c.isalnum():
                retKey += c
        return retKey
Beispiel #5
0
class ModelManager(QWidget):
    """
    The main window for MolaQT. It manages optimisation models optionally using an openLCA database.
    """

    def __init__(self, system):
        super().__init__()
        self.system = system

        # model config file
        self.controller_config_file = None

        # workflow for building model
        self.controller = QLabel()

        # db tree
        self.db_tree = QTreeWidget()
        self.db_tree.setHeaderLabels(['Database'])
        self.db_tree.setMinimumWidth(250)
        self.db_tree.itemDoubleClicked.connect(self.load_model)

        # context menu for db tree
        self.db_tree.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.duplicate_model_action = QAction("Duplicate model")
        self.duplicate_model_action.triggered.connect(lambda: self.rename_model(copy=True))
        self.db_tree.addAction(self.duplicate_model_action)
        self.rename_model_action = QAction("Rename model")
        self.rename_model_action.triggered.connect(self.rename_model)
        self.db_tree.addAction(self.rename_model_action)
        self.delete_model_action = QAction("Delete model")
        self.delete_model_action.triggered.connect(self.delete_model)
        self.db_tree.addAction(self.delete_model_action)

        # model configurations that don't use a database
        self.no_db = QTreeWidgetItem(self.db_tree, ['None'])
        self.no_db.setExpanded(True)

        # find the user sqlite databases and add them to db_tree
        self.db_items = {}
        db_files = list(system['data_path'].glob('*.sqlite'))
        for db_file in db_files:
            self.db_items[db_file] = QTreeWidgetItem(self.db_tree, [db_file.stem])
            self.db_items[db_file].setExpanded(True)

        # add each model config to its database item by examining db_file entry
        config_item = []
        for cf in system['config_path'].glob('*.json'):
            with open(str(cf)) as fp:
                config_json = json.load(fp)
            if 'db_file' in config_json and config_json['db_file'] is not None:
                config_db = Path(config_json['db_file'])
                if config_db.exists():
                    config_item.append(QTreeWidgetItem(self.db_items[config_db], [cf.stem]))
            else:
                config_item.append(QTreeWidgetItem(self.no_db, [cf.stem]))

        # arrange widgets in splitter
        box = QHBoxLayout()
        self.splitter = QSplitter()
        self.splitter.addWidget(self.db_tree)
        self.splitter.addWidget(self.controller)
        self.splitter.setStretchFactor(1, 2)
        box.addWidget(self.splitter)

        self.setLayout(box)

    def load_model(self, item, col):
        if self.db_tree.indexOfTopLevelItem(item) == -1:
            config_file = self.system['config_path'].joinpath(item.text(0))
            logging.info('Loading model %s' % config_file)
            self.set_controller(config_file.with_suffix('.json'))

    def new_model(self):
        dialog = md.NewModelDialog(system=self.system, parent=self, db_files=self.db_items.keys())
        if dialog.exec():
            name, specification_class, controller_class, database, doc_file = dialog.get_inputs()
            config_file = self.system['config_path'].joinpath(name + '.json')
            if config_file.exists():
                QMessageBox.about(self, "Error", "Configuration file " + str(config_file.absolute()) +
                                  " already exists")
            else:
                if database:
                    item = QTreeWidgetItem(self.db_items[database], [config_file.stem])
                else:
                    item = QTreeWidgetItem(self.no_db, [config_file.stem])

                self.db_tree.clearSelection()
                item.setSelected(True)

                self.controller_config_file = config_file

                # get a new config dict
                new_config = mqu.get_new_config(specification_class, database, doc_file, controller_class)

                # instantiate controller using config
                new_controller = controller_class(new_config, self.system)

                # open new controller widget
                self.replace_controller(new_controller)

                return config_file

        return None

    def save_model(self):
        try:
            if self.is_model_loaded():
                config = self.controller.get_config()
                with open(str(self.controller_config_file), 'w') as fp:
                    json.dump(config, fp, indent=4)
                self.controller.saved = True

                logging.info('Saved model configuration to %s' % self.controller_config_file)

                return self.controller_config_file
            else:
                logging.info("Nothing to save")

        except Exception as e:
            md.critical_error_box('Critical error', str(e))

        return None

    def close_model(self):
        if self.controller_config_file is not None:
            choice = None
            if not self.controller.saved:
                choice = QMessageBox.question(self, 'Model not saved', "Confirm close?",
                                              QMessageBox.Yes | QMessageBox.No)

            if choice == QMessageBox.Yes or self.controller.saved:
                self.replace_controller(QLabel())
                logging.info('Closed model %s' % self.controller_config_file)
                return True

        return False

    def build_model(self):
        if self.is_model_loaded():
            # TODO: this requires the controller to have a model_build widget and button clicked method
            if hasattr(self.controller, 'model_build') and hasattr(self.controller.model_build, 'build_button_clicked'):
                ok = self.controller.model_build.build_button_clicked()
                return ok

    def run_model(self):
        if self.is_model_loaded():
            # TODO: this requires the controller to have a model_solve widget and button clicked method
            if hasattr(self.controller, 'model_solve') and hasattr(self.controller.model_solve, 'run_button_clicked'):
                ok = self.controller.model_solve.run_button_clicked()
                return ok

    def start_console(self):
        self.qt_console = QtConsoleWindow(manager=self)
        self.qt_console.show()

    def delete_model(self):
        index = self.db_tree.selectedItems()[0]
        if index.parent() is not None:
            db_index = index.parent()
            model_name = index.text(0)
            choice = QMessageBox.question(
                self,
                'Delete model',
                'Confirm delete ' + model_name + ' from ' + db_index.text(0) + '?',
                QMessageBox.Yes | QMessageBox.No
            )
            if choice == QMessageBox.Yes:
                db_index.removeChild(index)
                self.replace_controller(QLabel())
                self.system['config_path'].joinpath(model_name).with_suffix('.json').unlink()
                logging.info("Deleted %s" % model_name)
            else:
                pass

    def rename_model(self, copy=False):
        index = self.db_tree.selectedItems()[0]
        if index.parent() is not None:
            db_index = index.parent()
            model_name = index.text(0)
            dialog = md.RenameModelDialog(current_model_name=model_name, parent=self)
            if dialog.exec():
                old_config_path = self.system['config_path'].joinpath(model_name).with_suffix('.json')
                new_model_name = dialog.new_model_name.text()
                new_config_path = self.system['config_path'].joinpath(new_model_name).with_suffix('.json')
                if new_config_path.exists():
                    QMessageBox.about(self, "Error", "Configuration file " + str(new_config_path.absolute()) +
                                      " already exists")
                elif self.is_model_load() and not self.controller.saved:
                    QMessageBox.about(self, "Error", "Model not saved")
                else:
                    if self.controller is not None:
                        self.replace_controller(QLabel())
                    if copy:

                        new_config_path.write_text(old_config_path.read_text())
                    else:
                        db_index.removeChild(index)
                        old_config_path.rename(new_config_path)
                    qtw = QTreeWidgetItem(db_index, [new_model_name])
                    db_index.addChild(qtw)
                    self.db_tree.clearSelection()
                    qtw.setSelected(True)
                    logging.info('Renamed {} to {}'.format(model_name, dialog.new_model_name.text()))

    def set_controller(self, config_file):
        self.controller_config_file = config_file
        if self.parent() is not None:
            self.parent().setWindowTitle(config_file.stem + ' - molaqt')

        if not config_file.exists():
            logging.error("Cannot find configuration file %s" % config_file)
            return False

        # get configuration
        with open(config_file) as fp:
            user_config = json.load(fp)

        # instantiate controller using config if available otherwise default to StandardController
        if 'controller' in user_config:
            search = re.search("<class '(.*?)\.(.*?)\.(.*?)'>", user_config['controller'])
            class_name = search.group(3)
            class_ = getattr(mc, class_name)
            new_controller = class_(user_config, self.system)
        else:
            new_controller = mc.StandardController(user_config, self.system)

        self.replace_controller(new_controller)
        return True

    def replace_controller(self, new_controller):
        self.controller.deleteLater()  # ensures Qt webengine process gets shutdown
        self.splitter.replaceWidget(1, new_controller)
        self.splitter.update()
        self.splitter.setStretchFactor(1, 2)
        self.controller = new_controller

    def add_database(self, db_path):
        db_item = QTreeWidgetItem(self.db_tree, [db_path.stem])
        self.db_items[db_path] = db_item
        db_item.setSelected(True)

    def is_model_loaded(self):
        return not isinstance(self.controller, QLabel)
Beispiel #6
0
class GuiProjectEditReplace(QWidget):

    COL_KEY  = 0
    COL_REPL = 1

    def __init__(self, mainGui, theProject):
        QWidget.__init__(self, mainGui)

        self.mainConf   = novelwriter.CONFIG
        self.mainGui    = mainGui
        self.mainTheme  = mainGui.mainTheme
        self.theProject = theProject
        self.arChanged  = False

        wCol0 = self.mainConf.pxInt(
            self.theProject.options.getInt("GuiProjectSettings", "replaceColW", 130)
        )
        pageLabel = self.tr("Text Replace List for Preview and Export")

        # List Box
        # ========

        self.listBox = QTreeWidget()
        self.listBox.setHeaderLabels([
            self.tr("Keyword"),
            self.tr("Replace With"),
        ])
        self.listBox.itemSelectionChanged.connect(self._selectedItem)
        self.listBox.setColumnWidth(self.COL_KEY, wCol0)
        self.listBox.setIndentation(0)

        for aKey, aVal in self.theProject.autoReplace.items():
            newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
            self.listBox.addTopLevelItem(newItem)

        self.listBox.sortByColumn(self.COL_KEY, Qt.AscendingOrder)
        self.listBox.setSortingEnabled(True)

        # List Controls
        # =============

        self.addButton = QPushButton(self.mainTheme.getIcon("add"), "")
        self.addButton.clicked.connect(self._addEntry)

        self.delButton = QPushButton(self.mainTheme.getIcon("remove"), "")
        self.delButton.clicked.connect(self._delEntry)

        # Edit Form
        # =========

        self.editKey = QLineEdit()
        self.editKey.setPlaceholderText(self.tr("Select item to edit"))
        self.editKey.setEnabled(False)
        self.editKey.setMaxLength(40)

        self.editValue = QLineEdit()
        self.editValue.setEnabled(False)
        self.editValue.setMaxLength(80)

        self.saveButton = QPushButton(self.tr("Save"))
        self.saveButton.clicked.connect(self._saveEntry)

        # Assemble
        # ========

        self.listControls = QVBoxLayout()
        self.listControls.addWidget(self.addButton)
        self.listControls.addWidget(self.delButton)
        self.listControls.addStretch(1)

        self.editBox = QHBoxLayout()
        self.editBox.addWidget(self.editKey, 4)
        self.editBox.addWidget(self.editValue, 5)
        self.editBox.addWidget(self.saveButton, 0)

        self.mainBox = QVBoxLayout()
        self.mainBox.addWidget(self.listBox)
        self.mainBox.addLayout(self.editBox)

        self.innerBox = QHBoxLayout()
        self.innerBox.addLayout(self.mainBox)
        self.innerBox.addLayout(self.listControls)

        self.outerBox = QVBoxLayout()
        self.outerBox.addWidget(QLabel("<b>%s</b>" % pageLabel))
        self.outerBox.addLayout(self.innerBox)

        self.setLayout(self.outerBox)

        return

    def getNewList(self):
        """Extract the list from the widget.
        """
        newList = {}
        for n in range(self.listBox.topLevelItemCount()):
            tItem = self.listBox.topLevelItem(n)
            aKey = self._stripNotAllowed(tItem.text(0))
            aVal = tItem.text(1)
            if len(aKey) > 0:
                newList[aKey] = aVal

        return newList

    ##
    #  Internal Functions
    ##

    def _selectedItem(self):
        """Extract the details from the selected item and populate the
        edit form.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        editKey = self._stripNotAllowed(selItem.text(0))
        editVal = selItem.text(1)
        self.editKey.setText(editKey)
        self.editValue.setText(editVal)
        self.editKey.setEnabled(True)
        self.editValue.setEnabled(True)
        self.editKey.selectAll()
        self.editKey.setFocus()
        return True

    def _saveEntry(self):
        """Save the form data into the list widget.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False

        newKey = self.editKey.text()
        newVal = self.editValue.text()
        saveKey = self._stripNotAllowed(newKey)

        if len(saveKey) > 0 and len(newVal) > 0:
            selItem.setText(self.COL_KEY,  "<%s>" % saveKey)
            selItem.setText(self.COL_REPL, newVal)
            self.editKey.clear()
            self.editValue.clear()
            self.editKey.setEnabled(False)
            self.editValue.setEnabled(False)
            self.listBox.clearSelection()
            self.arChanged = True

        return

    def _addEntry(self):
        """Add a new list entry.
        """
        saveKey = "<keyword%d>" % (self.listBox.topLevelItemCount() + 1)
        newVal  = ""
        newItem = QTreeWidgetItem([saveKey, newVal])
        self.listBox.addTopLevelItem(newItem)
        return True

    def _delEntry(self):
        """Delete the selected entry.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return False
        self.listBox.takeTopLevelItem(self.listBox.indexOfTopLevelItem(selItem))
        self.arChanged = True
        return True

    def _getSelectedItem(self):
        """Extract the currently selected item.
        """
        selItem = self.listBox.selectedItems()
        if len(selItem) == 0:
            return None
        return selItem[0]

    def _stripNotAllowed(self, theKey):
        """Clean up the replace key string.
        """
        retKey = ""
        for c in theKey:
            if c.isalnum():
                retKey += c
        return retKey
Beispiel #7
0
class GuiProjectEditStatus(QWidget):

    COL_LABEL = 0
    COL_USAGE = 1

    KEY_ROLE = Qt.UserRole
    COL_ROLE = Qt.UserRole + 1
    NUM_ROLE = Qt.UserRole + 2

    def __init__(self, mainGui, theProject, isStatus):
        QWidget.__init__(self, mainGui)

        self.mainConf   = novelwriter.CONFIG
        self.mainGui    = mainGui
        self.theProject = theProject
        self.mainTheme  = mainGui.mainTheme

        if isStatus:
            self.theStatus = self.theProject.statusItems
            pageLabel = self.tr("Novel File Status Levels")
            colSetting = "statusColW"
        else:
            self.theStatus = self.theProject.importItems
            pageLabel = self.tr("Note File Importance Levels")
            colSetting = "importColW"

        wCol0 = self.mainConf.pxInt(
            self.theProject.options.getInt("GuiProjectSettings", colSetting, 130)
        )

        self.colDeleted = []
        self.colChanged = False
        self.selColour  = QColor(100, 100, 100)

        self.iPx = self.mainTheme.baseIconSize

        # The List
        # ========

        self.listBox = QTreeWidget()
        self.listBox.setHeaderLabels([
            self.tr("Label"), self.tr("Usage"),
        ])
        self.listBox.itemSelectionChanged.connect(self._selectedItem)
        self.listBox.setColumnWidth(self.COL_LABEL, wCol0)
        self.listBox.setIndentation(0)

        for key, entry in self.theStatus.items():
            self._addItem(key, entry["name"], entry["cols"], entry["count"])

        # List Controls
        # =============

        self.addButton = QPushButton(self.mainTheme.getIcon("add"), "")
        self.addButton.clicked.connect(self._newItem)

        self.delButton = QPushButton(self.mainTheme.getIcon("remove"), "")
        self.delButton.clicked.connect(self._delItem)

        self.upButton = QPushButton(self.mainTheme.getIcon("up"), "")
        self.upButton.clicked.connect(lambda: self._moveItem(-1))

        self.dnButton = QPushButton(self.mainTheme.getIcon("down"), "")
        self.dnButton.clicked.connect(lambda: self._moveItem(1))

        # Edit Form
        # =========

        self.editName = QLineEdit()
        self.editName.setMaxLength(40)
        self.editName.setEnabled(False)
        self.editName.setPlaceholderText(self.tr("Select item to edit"))

        self.colPixmap = QPixmap(self.iPx, self.iPx)
        self.colPixmap.fill(QColor(100, 100, 100))
        self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"))
        self.colButton.setIconSize(self.colPixmap.rect().size())
        self.colButton.clicked.connect(self._selectColour)

        self.saveButton = QPushButton(self.tr("Save"))
        self.saveButton.clicked.connect(self._saveItem)

        # Assemble
        # ========

        self.listControls = QVBoxLayout()
        self.listControls.addWidget(self.addButton)
        self.listControls.addWidget(self.delButton)
        self.listControls.addWidget(self.upButton)
        self.listControls.addWidget(self.dnButton)
        self.listControls.addStretch(1)

        self.editBox = QHBoxLayout()
        self.editBox.addWidget(self.editName)
        self.editBox.addWidget(self.colButton)
        self.editBox.addWidget(self.saveButton)

        self.mainBox = QVBoxLayout()
        self.mainBox.addWidget(self.listBox)
        self.mainBox.addLayout(self.editBox)

        self.innerBox = QHBoxLayout()
        self.innerBox.addLayout(self.mainBox)
        self.innerBox.addLayout(self.listControls)

        self.outerBox = QVBoxLayout()
        self.outerBox.addWidget(QLabel("<b>%s</b>" % pageLabel))
        self.outerBox.addLayout(self.innerBox)

        self.setLayout(self.outerBox)

        return

    def getNewList(self):
        """Return list of entries.
        """
        if self.colChanged:
            newList = []
            for n in range(self.listBox.topLevelItemCount()):
                item = self.listBox.topLevelItem(n)
                newList.append({
                    "key":  item.data(self.COL_LABEL, self.KEY_ROLE),
                    "name": item.text(self.COL_LABEL),
                    "cols": item.data(self.COL_LABEL, self.COL_ROLE),
                })
            return newList, self.colDeleted

        return [], []

    ##
    #  User Actions
    ##

    def _selectColour(self):
        """Open a dialog to select the status icon colour.
        """
        if self.selColour is not None:
            newCol = QColorDialog.getColor(
                self.selColour, self, self.tr("Select Colour")
            )
            if newCol.isValid():
                self.selColour = newCol
                pixmap = QPixmap(self.iPx, self.iPx)
                pixmap.fill(newCol)
                self.colButton.setIcon(QIcon(pixmap))
                self.colButton.setIconSize(pixmap.rect().size())
        return

    def _newItem(self):
        """Create a new status item.
        """
        newItem = self._addItem(None, self.tr("New Item"), (100, 100, 100), 0)
        newItem.setBackground(self.COL_LABEL, QBrush(QColor(0, 255, 0, 70)))
        newItem.setBackground(self.COL_USAGE, QBrush(QColor(0, 255, 0, 70)))
        self.colChanged = True
        return

    def _delItem(self):
        """Delete a status item.
        """
        selItem = self._getSelectedItem()
        if selItem is not None:
            iRow = self.listBox.indexOfTopLevelItem(selItem)
            if selItem.data(self.COL_LABEL, self.NUM_ROLE) > 0:
                self.mainGui.makeAlert(self.tr(
                    "Cannot delete a status item that is in use."
                ), nwAlert.ERROR)
            else:
                self.listBox.takeTopLevelItem(iRow)
                self.colDeleted.append(selItem.data(self.COL_LABEL, self.KEY_ROLE))
                self.colChanged = True
        return

    def _saveItem(self):
        """Save changes made to a status item.
        """
        selItem = self._getSelectedItem()
        if selItem is not None:
            selItem.setText(self.COL_LABEL, simplified(self.editName.text()))
            selItem.setIcon(self.COL_LABEL, self.colButton.icon())
            selItem.setData(self.COL_LABEL, self.COL_ROLE, (
                self.selColour.red(), self.selColour.green(), self.selColour.blue()
            ))
            self.editName.setEnabled(False)
            self.colChanged = True

        return

    def _addItem(self, key, name, cols, count):
        """Add a status item to the list.
        """
        pixmap = QPixmap(self.iPx, self.iPx)
        pixmap.fill(QColor(*cols))

        item = QTreeWidgetItem()
        item.setText(self.COL_LABEL, name)
        item.setIcon(self.COL_LABEL, QIcon(pixmap))
        item.setData(self.COL_LABEL, self.KEY_ROLE, key)
        item.setData(self.COL_LABEL, self.COL_ROLE, cols)
        item.setData(self.COL_LABEL, self.NUM_ROLE, count)
        item.setText(self.COL_USAGE, self._usageString(count))

        self.listBox.addTopLevelItem(item)

        return item

    def _moveItem(self, step):
        """Move and item up or down step.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return

        tIndex = self.listBox.indexOfTopLevelItem(selItem)
        nChild = self.listBox.topLevelItemCount()
        nIndex = tIndex + step
        if nIndex < 0 or nIndex >= nChild:
            return

        cItem = self.listBox.takeTopLevelItem(tIndex)
        self.listBox.insertTopLevelItem(nIndex, cItem)
        self.listBox.clearSelection()

        cItem.setSelected(True)
        self.colChanged = True

        return

    def _selectedItem(self):
        """Extract the info of a selected item and populate the settings
        boxes and button.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return

        cols = selItem.data(self.COL_LABEL, self.COL_ROLE)
        name = selItem.text(self.COL_LABEL)

        pixmap = QPixmap(self.iPx, self.iPx)
        pixmap.fill(QColor(*cols))
        self.selColour = QColor(*cols)
        self.editName.setText(name)
        self.colButton.setIcon(QIcon(pixmap))
        self.editName.setEnabled(True)
        self.editName.selectAll()
        self.editName.setFocus()

        return

    ##
    #  Internal Functions
    ##

    def _getSelectedItem(self):
        """Get the currently selected item.
        """
        selItem = self.listBox.selectedItems()
        if len(selItem) > 0:
            return selItem[0]
        return None

    def _usageString(self, nUse):
        """Generate usage string.
        """
        if nUse == 0:
            return self.tr("Not in use")
        elif nUse == 1:
            return self.tr("Used once")
        else:
            return self.tr("Used by {0} items").format(nUse)
Beispiel #8
0
class App(QMainWindow):
    def __init__(self, ctx):
        super().__init__()

        # redefine PATH constant - fps build
        constants.PATH_GENERATED_SONG = ctx.get_resource(
            'generated/generated_song3Mul.mid')

        self.ctx = ctx
        self.playlist = []
        # Create a basic vlc instance
        if platform.system() == "Windows":  # for Windows Midi codec
            self.instance = vlc.Instance([
                "--audio-visual=visual", "--effect-list=spectrum",
                "--soundfont=" + self.ctx.get_resource('midis/soundfont.sf2')
            ])
        else:
            self.instance = vlc.Instance(
                ["--audio-visual=visual", "--effect-list=spectrum"])

        self.mediaplayer = self.instance.media_player_new()
        self.title = 'Open Deep Jockey'
        self.generateOption = generationOption.GenerationOption(self.ctx)
        self.djjudgeWindow = djjudge.Djjudge(self.ctx)
        self.width = 1024
        self.height = 512
        self.left = 256
        self.top = 256
        self.tune = []
        self.init_ui()

    def init_ui(self):
        self.initAct()
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        details.setColors(self)
        self.addControls()
        self.show()

    def addControls(self):
        # Create global container
        layout = QWidget(self)
        self.setCentralWidget(layout)
        layoutArea = QHBoxLayout()

        # create global layouts
        listArea = QVBoxLayout()  # left part of global
        playerArea = QHBoxLayout()  # central part of global
        controlArea = QVBoxLayout()  # right part of global

        # Add  to dedicated zone
        self.tree = QTreeWidget()
        self.tree.setHeaderLabels(['File', 'Rating', 'State'])
        # self.tree.setSelectionMode(QAbstractItemView.MultiSelection)
        QTreeWidgetItem(self.tree, [
            self.ctx.get_resource('midis/Hit_the_Road_Jack.mid'), '2',
            'Example'
        ])
        QTreeWidgetItem(
            self.tree,
            [self.ctx.get_resource('midis/Holiday.mid'), '4', 'Example'])
        # create Tune buttun
        self.tuneBtn = QPushButton('Set to tune')  # Tune button
        self.generateBtn = QPushButton('Nothing to tune')  # generation button
        # Add elements to list zone
        listArea.addWidget(self.tree)
        listArea.addWidget(self.tuneBtn)
        listArea.addWidget(self.generateBtn)
        # Connect each signal to their appropriate function
        self.tuneBtn.clicked.connect(self.TuneHandler)
        self.generateBtn.clicked.connect(self.GenerateHandler)

        # Create player img widget
        imgPlayer = QLabel(self)
        pixmap = QPixmap(self.ctx.get_resource('images/base.png'))
        imgPlayer.setPixmap(pixmap)
        # Create player slider
        # TODO
        # Add img to player zone
        player = QHBoxLayout()
        player.addWidget(imgPlayer)
        # Add to dedicated zone
        playerArea.addLayout(player)

        if platform.system() == "Linux":  # for Linux using the X Server
            print("Linux detected")
            self.mediaplayer.set_xwindow(int(imgPlayer.winId()))
        elif platform.system() == "Windows":  # for Windows
            print("Windows detected")
            self.mediaplayer.set_hwnd(int(imgPlayer.winId()))
        elif platform.system() == "Darwin":  # for MacOS
            print("MacOS detected")
            self.mediaplayer.set_nsobject(int(imgPlayer.winId()))
        else:
            print("fail to init vlc frame")
        # create rating widget
        ratingWidget = Rating.RatingWidget(self.ctx)
        ratingWidget.value_updated.connect(lambda value: self.rateFile(value))
        # create song controls
        volumeSlider = QSlider(Qt.Horizontal, self)
        volumeSlider.setFocusPolicy(Qt.NoFocus)
        volumeSlider.setValue(100)
        self.actionBtn = QPushButton('Play')  # action button : pause play
        self.clearBtn = QPushButton('Clear')  # stop button
        # Add buttons to song controls zone
        controls = QHBoxLayout()
        controls.addWidget(self.actionBtn)
        controls.addWidget(self.clearBtn)
        # Add to control zone
        controlArea.addWidget(ratingWidget)
        controlArea.addWidget(
            volumeSlider)  # add to controlArea directly to position it above
        controlArea.addLayout(controls)
        # Connect each signal to their appropriate function
        self.actionBtn.clicked.connect(self.actionHandler)
        self.clearBtn.clicked.connect(self.clearHandler)
        volumeSlider.valueChanged[int].connect(self.changeVolume)

        # Add to global layout
        layoutArea.addLayout(listArea)
        layoutArea.addLayout(playerArea)
        layoutArea.addLayout(controlArea)

        layout.setLayout(layoutArea)

        self.statusBar()
        # self.playlist.currentMediaChanged.connect(self.songChanged)

    def GenerateHandler(self):
        # Generate buttun pushed
        print("GenerateHandler")
        if len(self.tune) == 0:
            self.statusBar().showMessage("No item to tune")
        elif len(self.tune) == 1:
            # "Tuning 1 file"
            # TODO modulation
            self.tune.append(self.tree.currentItem().data(0, 0))
            musicfunctions.generateSongFromOneSong(self.tune[0])
            QTreeWidgetItem(self.tree,
                            [constants.PATH_GENERATED_SONG, '', "pending"])
            self.tree.clearSelection()
            self.tune = []
            self.generateBtn.setText("No item to tune")
            self.cleanTree()
        elif len(self.tune) == 2:
            # "Tuning 2 files"
            # TODO modulation
            print("Tune selection" + str(self.tune))
            musicfunctions.generateSongFromTwoSongs(
                [self.tune[0], self.tune[1]])
            QTreeWidgetItem(self.tree,
                            [constants.PATH_GENERATED_SONG, '', "pending"])
            self.tree.clearSelection()
            self.tune = []
            self.generateBtn.setText("No item to tune")
            self.cleanTree()
        else:
            print("TuneHandler error")

    def TuneHandler(self):
        # Tune buttun pushed
        print("TuneHandler")
        if len(self.tune) == 0:
            if self.tree.selectedItems():
                # select first file
                self.tune.append(self.tree.currentItem().data(0, 0))
                self.tree.currentItem().setData(2, 0, "To Tune")
                self.tree.clearSelection()
                self.generateBtn.setText("Generate")
            else:
                self.statusBar().showMessage("No item to tune selected")
        elif len(self.tune) == 1:
            if self.tree.selectedItems():
                # select second file
                self.tune.append(self.tree.currentItem().data(0, 0))
                self.tree.currentItem().setData(2, 0, "To Tune")
                self.tree.clearSelection()
            else:
                self.statusBar().showMessage("No item to tune selected")
        elif len(self.tune) == 2:
            if self.tree.selectedItems():
                # Remove first, append new one
                self.tune[0] = self.tune[1]
                self.tune[1] = self.tree.selectedItems()[0].data(0, 0)
                self.tree.currentItem().setData(2, 0, "To Tune")
                self.tree.clearSelection()
                self.generateBtn.setText("Generate")
            else:
                self.statusBar().showMessage("No item to tune selected")
        else:
            print("TuneHandler error")

    def actionHandler(self):
        if not self.tree.selectedItems():
            self.statusBar().showMessage("no media loaded")
            # shortcuts.openFile(self)
        else:
            if self.mediaplayer.is_playing():
                self.mediaplayer.pause()
                self.actionBtn.setText("Play")
            else:
                # getOpenFileName returns a tuple, so use only the actual file name
                media = self.instance.media_new(self.tree.currentItem().data(
                    0, 0))
                # Put the media in the media player
                self.mediaplayer.set_media(media)
                self.mediaplayer.play()
                self.actionBtn.setText("Pause")

    def clearHandler(self):  # TODO
        self.mediaplayer.stop()
        self.tree.clearSelection()
        self.actionBtn.setText("Play")
        self.resize(1025, 512)  # shitty workaround
        self.resize(1024, 512)  # discard mediaplayer instance
        self.statusBar().showMessage("Stopped and cleared playlist")
        print("Stopped and cleared playlist")

    def changeVolume(self, value):
        self.mediaplayer.audio_set_volume(value)

    def songChanged(self, media):  # TODO
        if not media.isNull():
            url = media.canonicalUrl()
            self.statusBar().showMessage(self.playlist[0])

    def initAct(self):
        # create menu
        menubar = self.menuBar()

        # Standard menu
        # create Action
        loadAction = QAction("Load file", self)
        loadAction.setShortcut("Ctrl+L")
        loadAction.setStatusTip('Load file')
        # connect to function
        loadAction.triggered.connect(self.openFile)
        # create Action
        exitAction = QAction("Exit App", self)
        exitAction.setShortcut("Ctrl+W")
        exitAction.setStatusTip('Leave The App')
        # connect to function
        exitAction.triggered.connect(details.on_exit)
        # Add Actions to menu
        appMenu = menubar.addMenu('App')
        appMenu.addAction(loadAction)
        appMenu.addAction(exitAction)

        # Generation from song menu
        # create Action
        optionAction = QAction("Generation options", self)
        optionAction.setShortcut("Ctrl+O")
        optionAction.setStatusTip('Setup generation options')
        # connect to function
        optionAction.triggered.connect(self.on_generateOption)
        # Add Actions to menu
        genMenu = menubar.addMenu('Generation options')
        genMenu.addAction(optionAction)

        # djjudge menu
        # create Action
        djjudgeAction = QAction("DjJudge", self)
        djjudgeAction.setShortcut("Ctrl+D")
        djjudgeAction.setStatusTip('DjJudge')
        # connect to function
        djjudgeAction.triggered.connect(self.on_djjudge)
        # Add Actions to menu
        genMenu = menubar.addMenu('DjJudge')
        genMenu.addAction(djjudgeAction)

    def openFile(self):
        song = QFileDialog.getOpenFileName(None, 'Open Music Folder', '~',
                                           'Sound Files(*.wav *.mid)')

        if song[0] != '':
            url = QUrl.fromLocalFile(song[0])
            if len(self.playlist) > 0:
                # self.playlist = []
                print("playlist not empty")
            # self.playlist.append(Media.Media(song[0]))
            QTreeWidgetItem(self.tree, [song[0], '', "pending"])
            self.statusBar().showMessage(str(song[0]) + " loaded")
            self.actionBtn.setText("Play")
            self.clearBtn.setText("Clear")
        else:
            self.statusBar().showMessage("nothing loaded")

    def rateFile(self, value):
        if self.tree.selectedItems():
            self.tree.currentItem().setData(1, 0, value +
                                            1)  # TODO manage when no item
        else:
            self.statusBar().showMessage("no media selected")

    def cleanTree(self):
        print("cleaning")
        for i in range(self.tree.topLevelItemCount()):
            self.tree.topLevelItem(i).setData(2, 0, "pending")
            print(self.tree.topLevelItem(i))

    def on_generateOption(self):
        self.generateOption.resize(1024, 512)
        self.generateOption.show()
        print("on_option")

    def on_djjudge(self):
        self.djjudgeWindow.resize(1024, 512)
        self.djjudgeWindow.show()
        print("on_djjudge")