Ejemplo n.º 1
0
class WingedBox(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle('WingedBox')
        pixmap = QPixmap(config.images['icon'])
        self.setWindowIcon(QIcon(pixmap))

        self.user = ''
        self.password = ''

        self._vbox = QVBoxLayout(self)
        self._login = Login(self, HOME_WINGED_PATH)
        self._vbox.addWidget(self._login)
        self._winged = Winged(self, pref)
        self._winged.setVisible(False)
        self._vbox.addWidget(self._winged)

        #SystemTray Menu
        self._menu = QMenu('WingedBox')
        self._myfiles = self._menu.addAction(QIcon(config.images['icon']), 'Files')
        self._myfiles.setEnabled(False)
        self._init = self._menu.addAction(self.style().standardIcon(QStyle.SP_DialogOkButton), 'Init Session')
        self._close = self._menu.addAction(self.style().standardIcon(QStyle.SP_DialogCloseButton), 'Close Session')
        self._close.setVisible(False)
        self._menu.addSeparator()
        self._properties = self._menu.addAction('Preferences')
        self._menu.addSeparator()
        exit = self._menu.addAction(self.style().standardIcon(QStyle.SP_TitleBarCloseButton), 'Exit')

        #SystemTray
        self._tray = QSystemTrayIcon(QIcon(pixmap), self)
        self._tray.setToolTip('WingedBox')
        self._tray.setVisible(True)
        self._tray.setContextMenu(self._menu)

        #Signal -> Slot
        self.connect(exit, SIGNAL("triggered()"), sys.exit)
        self.connect(self._myfiles, SIGNAL("triggered()"), self.show)
        self.connect(self._init, SIGNAL("triggered()"), self.show)
        self.connect(self._properties, SIGNAL("triggered()"), self.show_properties)
        self.connect(self._close, SIGNAL("triggered()"), self.disconnect)

    def show_properties(self):
        self.prop = preferences.Preferences(self, pref)
        self.prop.show()

    def disconnect(self):
        self.user = ''
        self.password = ''
        self._myfiles.setEnabled(False)
        self._init.setVisible(True)
        self._close.setVisible(False)
        self._winged.hide()
        self._login.show()

    def closeEvent(self, event):
        event.ignore()
        self.hide()
class KerberusSystray(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        icono = 'kerby-activo.ico'
        pixmap = QPixmap(icono)
        ##setear el nombre de la ventana
        self.setWindowTitle('Kerberus Control Parental')
        #colocar el icono cargado a la ventana
        self.setWindowIcon(QIcon(pixmap))
        ##creamos objeto Style para hacer uso de los iconos de Qt
	self.style = self.style()
        self.filtradoHabilitado = True

        if not os.path.isfile('dontShowMessage'):
            self.mostrarMensaje = True
            self.noMostrarMasMensaje()
        else:
            self.mostrarMensaje = False

        #Menu
        self.menu = QMenu('Kerberus')

        #accion deshabilitar filtrado
        self.deshabilitarFiltradoAction = self.menu.addAction(
                            self.style.standardIcon(QStyle.SP_DialogNoButton),
                            'Deshabilitar Filtrado'
                            )
        #accion habilitar filtrado
        self.habilitarFiltradoAction = self.menu.addAction(
                            self.style.standardIcon(QStyle.SP_DialogYesButton),
                            'Habilitar Filtrado'
                            )
        self.habilitarFiltradoAction.setVisible(False)
        #cambiar password
        self.cambiarPasswordAction = self.menu.addAction(
                self.style.standardIcon(QStyle.SP_BrowserReload),
                'Cambiar password de administrador'
                )
        #accion salir
        self.exitAction = self.menu.addAction(
                self.style.standardIcon(QStyle.SP_TitleBarCloseButton),
                'Salir')

        #SIGNAL->SLOT
        QObject.connect(
                self.exitAction,
                SIGNAL("triggered()"),
                lambda: sys.exit()
                )
        QObject.connect(
                self.menu, SIGNAL("clicked()"),
                lambda: self.menu.popup(QCursor.pos())
                )
        QObject.connect(
                self.deshabilitarFiltradoAction,
                SIGNAL("triggered()"),
                self.deshabilitarFiltradoWindow
                )
        QObject.connect(
                self.habilitarFiltradoAction,
                SIGNAL("triggered()"),
                self.habilitarFiltradoWindow
                )
        QObject.connect(
                self.cambiarPasswordAction,
                SIGNAL("triggered()"),
                self.cambiarPasswordWindow
                )

        #SystemTray
        #self.tray = QSystemTrayIcon(QIcon(pixmap), self)
        self.tray = QSystemTrayIcon(self.style.standardIcon(QStyle.SP_DialogYesButton), self)
        self.tray.setToolTip('Kerberus Control Parental - Activado')
        self.tray.setContextMenu(self.menu)
        self.tray.setVisible(True)



        QObject.connect(
                self.tray,
                SIGNAL("messageClicked()"),
                self.noMostrarMasMensaje
                )

        if self.mostrarMensaje:
            self.tray.showMessage(
                    u'Kerberus Control Parental',
                    u'Filtro de Protección para menores de edad Activado',
                    2000
                    )

    #def closeEvent(self, event):
        #event.ignore()
        #self.hide()

    def noMostrarMasMensaje(self):
        try:
            open('dontShowMessage','a').close()
        except IOError:
            print 'No se pudo crear el archivo dontShowMessage'

    def deshabilitarFiltradoWindow(self):
        webbrowser.open(
                'http://inicio.kerberus.com.ar/!DeshabilitarFiltrado!',
                new=2
                )
        self.habilitarFiltradoAction.setVisible(True)
        self.deshabilitarFiltradoAction.setVisible(False)
        self.tray.setIcon(self.style.standardIcon(QStyle.SP_DialogNoButton))
        self.tray.setToolTip('Kerberus Control Parental')

    def habilitarFiltradoWindow(self):
        webbrowser.open(
                'http://inicio.kerberus.com.ar/!HabilitarFiltrado!',
                new=2
                )
        self.habilitarFiltradoAction.setVisible(False)
        self.deshabilitarFiltradoAction.setVisible(True)
        self.tray.setIcon(self.style.standardIcon(QStyle.SP_DialogYesButton))
        self.tray.setToolTip('Kerberus Control Parental - Activado')

    def cambiarPasswordWindow(self):
        webbrowser.open(
                'http://inicio.kerberus.com.ar/!CambiarPassword!',
                new=2
                )
Ejemplo n.º 3
0
class MainWindow(QMainWindow):
    groups = dict()
    typeQListWidgetHeader = 1000
    showHostsInGroups = False
    currentGroupName = None  # used to simple detect currently selected group to show menu

    def __init__(self):
        super(MainWindow, self).__init__()
        self.config = Config()
        self.db = Database(self.config.getConnectionString())

        cryptoKey = self.getCryptoKey()
        self.hosts = Hosts(self.db, cryptoKey)

        # menu used for each host
        self.hostMenu = QMenu()
        self.editAction = QAction(QIcon(':/ico/edit.svg'), "Edit",
                                  self.hostMenu)
        self.editAction.triggered.connect(self.editHost)
        self.hostMenu.addAction(self.editAction)

        # menu used for headers of groups
        self.groupsHeaderMenu = QMenu()
        self.editGroupAction = QAction(QIcon(':/ico/edit.svg'), "Edit group",
                                       self.groupsHeaderMenu)
        self.editGroupAction.triggered.connect(self.editGroup)
        self.deleteGroupAction = QAction(QIcon(':/ico/remove.svg'),
                                         "Delete group", self.groupsHeaderMenu)
        self.deleteGroupAction.triggered.connect(self.deleteGroup)
        self.groupsHeaderMenu.addAction(self.editGroupAction)
        self.groupsHeaderMenu.addAction(self.deleteGroupAction)

        self.duplicateAction = QAction(QIcon(':/ico/copy.svg'), "Duplicate",
                                       self.hostMenu)
        self.duplicateAction.triggered.connect(self.duplicateHost)
        self.hostMenu.addAction(self.duplicateAction)

        # todo: confirm for delete action
        self.deleteAction = QAction(QIcon(':/ico/remove.svg'), "Delete",
                                    self.hostMenu)
        self.deleteAction.triggered.connect(self.deleteHost)
        self.hostMenu.addAction(self.deleteAction)

        self.connectFramelessMenu = actions.generateScreenChoseMenu(
            self.hostMenu, self.connectFrameless, ':/ico/frameless.svg',
            "Connect frameless")
        self.hostMenu.addMenu(self.connectFramelessMenu)

        self.assignGroupAction = QAction("Assign group", self.hostMenu)
        self.assignGroupAction.triggered.connect(self.assignGroup)
        self.hostMenu.addAction(self.assignGroupAction)

        # setup main window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # when top level changed, we changing dock title bar
        self.dockWidgetTileBar = DockWidgetTitleBar()
        self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)
        self.ui.hostsDock.topLevelChanged.connect(self.dockLevelChanged)

        # set global menu
        self.globalMenu = QMenu()
        self.globalMenu.addAction(QIcon(':/ico/add.svg'), 'Add host',
                                  self.addHost)

        # groups menu
        self.groupsMenu = QMenu("Groups")
        self.groupsMenu.aboutToShow.connect(self.setGroupsMenu)
        self.globalMenu.addMenu(self.groupsMenu)

        # disable menu indicator
        self.ui.menu.setStyleSheet(
            "QPushButton::menu-indicator {image: none;}")
        self.positionMenu = QMenu("Dock position")
        self.positionMenu.addAction(
            "Left", lambda: self.setDockPosition(Qt.LeftDockWidgetArea))
        self.positionMenu.addAction(
            "Right", lambda: self.setDockPosition(Qt.RightDockWidgetArea))
        self.positionMenu.addAction("Float", self.setDockFloat)
        self.globalMenu.addMenu(self.positionMenu)
        self.globalMenu.addAction('Change tray icon visibility',
                                  self.changeTrayIconVisibility)
        self.globalMenu.addAction('Settings', self.showSettings)
        self.globalMenu.addAction('Quit', self.close)
        self.ui.menu.setMenu(self.globalMenu)

        # set events on hosts list
        self.ui.hostsList.itemDoubleClicked.connect(self.slotConnectHost)
        self.ui.hostsList.itemClicked.connect(self.slotShowHost)
        self.ui.hostsList.customContextMenuRequested.connect(
            self.slotShowHostContextMenu)

        # set tab widget
        self.tabWidget = MyTabWidget()
        self.setCentralWidget(self.tabWidget)
        self.tabWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tabWidget.customContextMenuRequested.connect(
            self.showCentralWidgetContextMenu)

        # set tray icon
        self.tray = QSystemTrayIcon(QIcon(":/ico/myrdp.svg"))
        self.tray.activated.connect(self.trayActivated)

        self.trayMenu = QMenu()
        self.trayMenu.addAction("Hide tray icon",
                                self.changeTrayIconVisibility)
        self.connectHostMenuTray = ConnectHostMenu(self.hosts)
        self.connectHostMenuTray.triggered.connect(
            self.connectHostFromTrayMenu)
        self.trayMenu.addMenu(self.connectHostMenuTray)
        self.trayMenu.addAction("Quit", self.close)

        self.tray.setContextMenu(self.trayMenu)
        self.restoreSettings()
        # host list
        self.ui.filter.textChanged.connect(self.setHostList)
        self.setHostList()

    def getCryptoKey(self, passphrase=None):
        try:
            return self.config.getPrivateKey(passphrase)
        except ValueError:
            passwordDialog = PasswordDialog()
            retCode = passwordDialog.exec_()
            if retCode == QtGui.QDialog.Accepted:
                return self.getCryptoKey(passwordDialog.getPassword())
            else:
                raise SystemError("Password required")

    def showSettings(self):
        settingsWidget = self.findChild(QWidget, "settings")
        if settingsWidget is None:
            self.settingsWidget = SettingsPage()
            self.settingsWidget.setObjectName("settings")
            self.tabWidget.insertTab(0, self.settingsWidget,
                                     QIcon(":/ico/settings.svg"), 'Settings')

        index = self.tabWidget.indexOf(self.settingsWidget)
        self.tabWidget.setCurrentIndex(index)

    def connectHostFromMenu(self, action):
        self.connectHost(unicode(action.text()))

    def connectHostFromTrayMenu(self, action):
        tabPage = self.connectHost(unicode(action.text()))
        if not self.isVisible():
            self.tabWidget.setDetached(True, tabPage)

    def trayActivated(self, reason):
        if reason != QSystemTrayIcon.Trigger:
            return
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.activateWindow()

    def changeTrayIconVisibility(self):
        if self.tray.isVisible():
            self.tray.hide()
            if not self.isVisible():
                self.show()
        else:
            self.tray.show()

    def refreshGroups(self):
        groupList = self.hosts.getGroupsList()
        for group in groupList:
            if group not in self.groups:
                # add new groups as visible
                self.groups[group] = True

        # remove not existing groups
        keysToDelete = set(self.groups.keys()) - set(groupList)
        for key in keysToDelete:
            self.groups.pop(key)

    def assignGroup(self):
        groups = self.hosts.getGroupsList()
        assignGroupDialog = AssignGroupDialog(groups)
        groupToAssign = assignGroupDialog.assign()
        if groupToAssign is not False:  # None could be used to unassign the group
            groupToAssign = None if groupToAssign.isEmpty() else unicode(
                groupToAssign)
            for hostName in self.getSelectedHosts():
                self.hosts.assignGroup(hostName, groupToAssign)
            self.db.tryCommit()
            self.setHostList()

    def setGroupsMenu(self):
        self.groupsMenu.clear()
        addGroupAction = self.groupsMenu.addAction('Add group')
        addGroupAction.triggered.connect(self.addGroup)

        deleteGroupAction = self.groupsMenu.addAction('Delete group')
        deleteGroupAction.triggered.connect(self.showDeleteGroupDialog)

        showHostsInGroupsAction = self.groupsMenu.addAction(
            'Show host list in groups')
        showHostsInGroupsAction.triggered.connect(self.changeHostListView)
        showHostsInGroupsAction.setCheckable(True)
        showHostsInGroupsAction.setChecked(self.showHostsInGroups)

        self.groupsMenu.addSeparator()
        for group, checked in self.groups.items():
            action = QAction(group, self.groupsMenu)
            action.setCheckable(True)
            action.setChecked(checked)
            action.triggered.connect(self.groupsVisibilityChanged)
            self.groupsMenu.addAction(action)

    def addGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.add()
        self._processHostSubmit(resp)

    def groupsVisibilityChanged(self, checked):
        currentGroup = unicode(self.sender().text())
        self.groups[currentGroup] = checked
        self.setHostList()

    def setDockPosition(self, dockWidgetArea):
        if self.ui.hostsDock.isFloating():
            self.ui.hostsDock.setFloating(False)
        self.addDockWidget(dockWidgetArea, self.ui.hostsDock)

    def setDockFloat(self):
        if self.ui.hostsDock.isFloating():
            return
        # default title bar must be set before is float because sometimes window make strange crash
        self.ui.hostsDock.setTitleBarWidget(None)
        self.ui.hostsDock.setFloating(True)

    def dockLevelChanged(self, isFloating):
        if isFloating:
            # changing title bar widget if is not none, probably true will be only once on start with saved float state
            if self.ui.hostsDock.titleBarWidget():
                self.ui.hostsDock.setTitleBarWidget(None)
        else:
            self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)

    def showFramelessWidget(self):
        self.t.show()
        self.t.setGeometry(self.frameGeometry())

    def getCurrentHostListItemName(self):
        return self.ui.hostsList.currentItem().text()

    def getSelectedHosts(self):
        return [host.text() for host in self.ui.hostsList.selectedItems()]

    def findHostItemByName(self, name):
        result = self.ui.hostsList.findItems(name, Qt.MatchExactly)
        resultLen = len(result)
        if resultLen != 1:  # should be only one host
            logger.error("Host not found. Got %d results" % resultLen)
        return result[0]

    def showCentralWidgetContextMenu(self, pos):
        menu = QMenu()
        title = self.ui.hostsDock.windowTitle()

        hostsDockAction = menu.addAction(title)
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.ui.hostsDock.isVisible())
        hostsDockAction.triggered.connect(self.changeHostsDockWidgetVisibility)

        hostsDockAction = menu.addAction("Tray icon")
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.tray.isVisible())
        hostsDockAction.triggered.connect(self.changeTrayIconVisibility)

        connectHostMenuTray = ConnectHostMenu(self.hosts, "Connect")
        connectHostMenuTray.triggered.connect(self.connectHostFromMenu)
        menu.addMenu(connectHostMenuTray)

        menu.exec_(self.tabWidget.mapToGlobal(pos))

    def changeHostListView(self, checked):
        self.showHostsInGroups = checked
        self.setHostList()

    def changeHostsDockWidgetVisibility(self):
        isVisible = self.ui.hostsDock.isVisible()
        self.ui.hostsDock.setVisible(not isVisible)

    def isHostListHeader(self, item):
        if not item or item.type() == self.typeQListWidgetHeader:
            return True
        return False

    def slotShowHostContextMenu(self, pos):
        def changeMenusVisibility(isEnabled):
            self.connectFramelessMenu.setEnabled(isEnabled)
            self.editAction.setEnabled(isEnabled)
            self.duplicateAction.setEnabled(isEnabled)

        # ignore context menu for group headers
        item = self.ui.hostsList.itemAt(pos)

        if self.isHostListHeader(item):
            item = self.ui.hostsList.itemAt(pos)
            widgetItem = self.ui.hostsList.itemWidget(item)
            if widgetItem:
                self.currentGroupName = widgetItem.text()  # yea I'm so dirty
                if self.currentGroupName != unassignedGroupName:
                    self.groupsHeaderMenu.exec_(
                        self.ui.hostsList.mapToGlobal(pos))
            return

        if len(self.ui.hostsList.selectedItems()) == 1:  # single menu
            changeMenusVisibility(True)
        else:
            changeMenusVisibility(False)

        self.hostMenu.exec_(self.ui.hostsList.mapToGlobal(pos))

    def _processHostSubmit(self, resp):
        if resp["code"]:
            self.setHostList()
        hostName = resp.get("name")
        if hostName:
            hostItem = self.findHostItemByName(hostName)
            self.slotConnectHost(hostItem)

    def addHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        self._processHostSubmit(hostDialog.add())

    def editHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.edit(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def editGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.edit(self.currentGroupName)
        self._processHostSubmit(resp)

    def deleteGroup(self):
        retCode = self.showOkCancelMessageBox(
            "Do you want to remove selected group? All assigned hosts "
            "to this group will be unassigned.", "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        self.hosts.deleteGroup(self.currentGroupName)
        self.setHostList()

    def showDeleteGroupDialog(self):
        deleteGroupDialog = DeleteGroupDialog(self.hosts)
        deleteGroupDialog.deleteGroup()
        self.setHostList()

    def duplicateHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.duplicate(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def deleteHost(self):
        retCode = self.showOkCancelMessageBox(
            "Do you want to remove selected hosts?", "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        for host in self.getSelectedHosts():
            self.hosts.delete(host)
        self.setHostList()

    def connectFrameless(self, screenIndex=None):
        self.connectHost(self.getCurrentHostListItemName(),
                         frameless=True,
                         screenIndex=screenIndex)

    # Fix to release keyboard from QX11EmbedContainer, when we leave widget through wm border
    def leaveEvent(self, event):
        keyG = QWidget.keyboardGrabber()
        if keyG is not None:
            keyG.releaseKeyboard()
        event.accept()  # needed?

    def setHostList(self):
        """ set hosts list in list view """
        self.ui.hostsList.clear()
        self.refreshGroups()
        hostFilter = self.ui.filter.text()
        if self.showHostsInGroups:
            self.showHostListInGroups(hostFilter)
        else:
            self.showHostList(hostFilter)

    def showHostList(self, hostFilter):
        groupFilter = [
            group for group, visibility in self.groups.items() if visibility
        ]
        hosts = self.hosts.getHostsListByHostNameAndGroup(
            hostFilter, groupFilter)
        self.ui.hostsList.addItems(hosts)

    def showHostListInGroups(self, hostFilter):
        hosts = self.hosts.getGroupedHostNames(hostFilter)
        for group, hostsList in hosts.items():
            if self.groups.get(group, True):
                if group is None:
                    group = unassignedGroupName
                groupHeader = QtGui.QListWidgetItem(
                    type=self.typeQListWidgetHeader)
                groupLabel = QtGui.QLabel(unicode(group))
                groupLabel.setProperty('class', 'group-title')
                self.ui.hostsList.addItem(groupHeader)
                self.ui.hostsList.setItemWidget(groupHeader, groupLabel)
                self.ui.hostsList.addItems(hostsList)

    def slotShowHost(self, item):
        # on one click we activating tab and showing options
        self.tabWidget.activateTab(item)

    def slotConnectHost(self, item):
        if self.isHostListHeader(item):
            return
        self.connectHost(unicode(item.text()))

    def connectHost(self, hostId, frameless=False, screenIndex=None):
        hostId = unicode(hostId)  # sometimes hostId comes as QString
        tabPage = self.tabWidget.createTab(hostId)
        tabPage.reconnectionNeeded.connect(self.connectHost)

        if frameless:
            self.tabWidget.detachFrameless(tabPage, screenIndex)

        try:
            execCmd, opts = self.getCmd(tabPage, hostId)
        except LookupError:
            logger.error(u"Host {} not found.".format(hostId))
            return

        ProcessManager.start(hostId, tabPage, execCmd, opts)
        return tabPage

    def getCmd(self, tabPage, hostName):
        host = self.hosts.get(hostName)

        # set tabPage widget
        width, height = tabPage.setSizeAndGetCurrent()
        # 1et widget winId to embed rdesktop
        winId = tabPage.x11.winId()

        # set remote desktop client, at this time works only with freerdp
        remoteClientType, remoteClientOptions = self.config.getRdpClient()
        remoteClient = ClientFactory(remoteClientType, **remoteClientOptions)
        remoteClient.setWindowParameters(winId, width, height)
        remoteClient.setUserAndPassword(host.user, host.password)
        remoteClient.setAddress(host.address)
        return remoteClient.getComposedCommand()

    def saveSettings(self):
        self.config.setValue("geometry", self.saveGeometry())
        self.config.setValue("windowState", self.saveState())
        self.config.setValue('trayIconVisibility', self.tray.isVisible())
        self.config.setValue('mainWindowVisibility', self.isVisible())
        self.config.setValue('groups', self.groups)
        self.config.setValue('showHostsInGroups', self.showHostsInGroups)

    def restoreSettings(self):
        try:
            self.restoreGeometry(
                self.config.getValue("geometry").toByteArray())
            self.restoreState(
                self.config.getValue("windowState").toByteArray())
        except Exception:
            logger.debug("No settings to restore")

        # restore tray icon state
        trayIconVisibility = self.config.getValue('trayIconVisibility',
                                                  "true").toBool()
        self.tray.setVisible(trayIconVisibility)

        self.showHostsInGroups = self.config.getValue('showHostsInGroups',
                                                      'false').toBool()

        if self.tray.isVisible():
            mainWindowVisibility = self.config.getValue(
                'mainWindowVisibility', "true").toBool()
            self.setVisible(mainWindowVisibility)
        else:  # it tray icon is not visible, always show main window
            self.show()

        self.groups = {
            unicode(k): v
            for k, v in self.config.getValue('groups',
                                             {}).toPyObject().items()
        }

    def closeEvent(self, event):
        if not ProcessManager.hasActiveProcess:
            self.saveSettings()
            QCoreApplication.exit()
            return

        ret = self.showOkCancelMessageBox("Are you sure do you want to quit?",
                                          "Exit confirmation")
        if ret == QMessageBox.Cancel:
            event.ignore()
            return

        self.saveSettings()
        ProcessManager.killemall()
        event.accept()
        QCoreApplication.exit()

    def showOkCancelMessageBox(self, messageBoxText, windowTitle):
        msgBox = QMessageBox(self, text=messageBoxText)
        msgBox.setWindowTitle(windowTitle)
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msgBox.setIcon(QMessageBox.Question)
        return msgBox.exec_()
Ejemplo n.º 4
0
class MainWindow(QMainWindow):
    groups = dict()
    typeQListWidgetHeader = 1000
    showHostsInGroups = False
    currentGroupName = None  # used to simple detect currently selected group to show menu

    def __init__(self):
        super(MainWindow, self).__init__()
        self.config = Config()
        self.db = Database(self.config.getConnectionString())

        cryptoKey = self.getCryptoKey()
        self.hosts = Hosts(self.db, cryptoKey)

        # menu used for each host
        self.hostMenu = QMenu()
        self.editAction = QAction(QIcon(':/ico/edit.svg'), "Edit", self.hostMenu)
        self.editAction.triggered.connect(self.editHost)
        self.hostMenu.addAction(self.editAction)

        # menu used for headers of groups
        self.groupsHeaderMenu = QMenu()
        self.editGroupAction = QAction(QIcon(':/ico/edit.svg'), "Edit group", self.groupsHeaderMenu)
        self.editGroupAction.triggered.connect(self.editGroup)
        self.deleteGroupAction = QAction(QIcon(':/ico/remove.svg'), "Delete group", self.groupsHeaderMenu)
        self.deleteGroupAction.triggered.connect(self.deleteGroup)
        self.groupsHeaderMenu.addAction(self.editGroupAction)
        self.groupsHeaderMenu.addAction(self.deleteGroupAction)

        self.duplicateAction = QAction(QIcon(':/ico/copy.svg'), "Duplicate", self.hostMenu)
        self.duplicateAction.triggered.connect(self.duplicateHost)
        self.hostMenu.addAction(self.duplicateAction)

        # todo: confirm for delete action
        self.deleteAction = QAction(QIcon(':/ico/remove.svg'), "Delete", self.hostMenu)
        self.deleteAction.triggered.connect(self.deleteHost)
        self.hostMenu.addAction(self.deleteAction)

        self.connectFramelessMenu = actions.generateScreenChoseMenu(self.hostMenu, self.connectFrameless,
                                                                    ':/ico/frameless.svg', "Connect frameless")
        self.hostMenu.addMenu(self.connectFramelessMenu)

        self.assignGroupAction = QAction("Assign group", self.hostMenu)
        self.assignGroupAction.triggered.connect(self.assignGroup)
        self.hostMenu.addAction(self.assignGroupAction)

        # setup main window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # when top level changed, we changing dock title bar
        self.dockWidgetTileBar = DockWidgetTitleBar()
        self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)
        self.ui.hostsDock.topLevelChanged.connect(self.dockLevelChanged)

        # set global menu
        self.globalMenu = QMenu()
        self.globalMenu.addAction(QIcon(':/ico/add.svg'), 'Add host', self.addHost)

        # groups menu
        self.groupsMenu = QMenu("Groups")
        self.groupsMenu.aboutToShow.connect(self.setGroupsMenu)
        self.globalMenu.addMenu(self.groupsMenu)

        # disable menu indicator
        self.ui.menu.setStyleSheet("QPushButton::menu-indicator {image: none;}")
        self.positionMenu = QMenu("Dock position")
        self.positionMenu.addAction("Left", lambda: self.setDockPosition(Qt.LeftDockWidgetArea))
        self.positionMenu.addAction("Right", lambda: self.setDockPosition(Qt.RightDockWidgetArea))
        self.positionMenu.addAction("Float", self.setDockFloat)
        self.globalMenu.addMenu(self.positionMenu)
        self.globalMenu.addAction('Change tray icon visibility', self.changeTrayIconVisibility)
        self.globalMenu.addAction('Settings', self.showSettings)
        self.globalMenu.addAction('Quit', self.close)
        self.ui.menu.setMenu(self.globalMenu)

        # set events on hosts list
        self.ui.hostsList.itemDoubleClicked.connect(self.slotConnectHost)
        self.ui.hostsList.itemClicked.connect(self.slotShowHost)
        self.ui.hostsList.customContextMenuRequested.connect(self.slotShowHostContextMenu)

        # set tab widget
        self.tabWidget = MyTabWidget()
        self.setCentralWidget(self.tabWidget)
        self.tabWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tabWidget.customContextMenuRequested.connect(self.showCentralWidgetContextMenu)

        # set tray icon
        self.tray = QSystemTrayIcon(QIcon(":/ico/myrdp.svg"))
        self.tray.activated.connect(self.trayActivated)

        self.trayMenu = QMenu()
        self.trayMenu.addAction("Hide tray icon", self.changeTrayIconVisibility)
        self.connectHostMenuTray = ConnectHostMenu(self.hosts)
        self.connectHostMenuTray.triggered.connect(self.connectHostFromTrayMenu)
        self.trayMenu.addMenu(self.connectHostMenuTray)
        self.trayMenu.addAction("Quit", self.close)

        self.tray.setContextMenu(self.trayMenu)
        self.restoreSettings()
        # host list
        self.ui.filter.textChanged.connect(self.setHostList)
        self.setHostList()

    def getCryptoKey(self, passphrase=None):
        try:
            return self.config.getPrivateKey(passphrase)
        except ValueError:
            passwordDialog = PasswordDialog()
            retCode = passwordDialog.exec_()
            if retCode == QtGui.QDialog.Accepted:
                return self.getCryptoKey(passwordDialog.getPassword())
            else:
                raise SystemError("Password required")

    def showSettings(self):
        settingsWidget = self.findChild(QWidget, "settings")
        if settingsWidget is None:
            self.settingsWidget = SettingsPage()
            self.settingsWidget.setObjectName("settings")
            self.tabWidget.insertTab(0, self.settingsWidget, QIcon(":/ico/settings.svg"), 'Settings')

        index = self.tabWidget.indexOf(self.settingsWidget)
        self.tabWidget.setCurrentIndex(index)

    def connectHostFromMenu(self, action):
        self.connectHost(unicode(action.text()))

    def connectHostFromTrayMenu(self, action):
        tabPage = self.connectHost(unicode(action.text()))
        if not self.isVisible():
            self.tabWidget.setDetached(True, tabPage)

    def trayActivated(self, reason):
        if reason != QSystemTrayIcon.Trigger:
            return
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.activateWindow()

    def changeTrayIconVisibility(self):
        if self.tray.isVisible():
            self.tray.hide()
            if not self.isVisible():
                self.show()
        else:
            self.tray.show()

    def refreshGroups(self):
        groupList = self.hosts.getGroupsList()
        for group in groupList:
            if group not in self.groups:
                # add new groups as visible
                self.groups[group] = True

        # remove not existing groups
        keysToDelete = set(self.groups.keys()) - set(groupList)
        for key in keysToDelete:
            self.groups.pop(key)

    def assignGroup(self):
        groups = self.hosts.getGroupsList()
        assignGroupDialog = AssignGroupDialog(groups)
        groupToAssign = assignGroupDialog.assign()
        if groupToAssign is not False:  # None could be used to unassign the group
            groupToAssign = None if groupToAssign.isEmpty() else unicode(groupToAssign)
            for hostName in self.getSelectedHosts():
                self.hosts.assignGroup(hostName, groupToAssign)
            self.db.tryCommit()
            self.setHostList()

    def setGroupsMenu(self):
        self.groupsMenu.clear()
        addGroupAction = self.groupsMenu.addAction('Add group')
        addGroupAction.triggered.connect(self.addGroup)

        deleteGroupAction = self.groupsMenu.addAction('Delete group')
        deleteGroupAction.triggered.connect(self.showDeleteGroupDialog)

        showHostsInGroupsAction = self.groupsMenu.addAction('Show host list in groups')
        showHostsInGroupsAction.triggered.connect(self.changeHostListView)
        showHostsInGroupsAction.setCheckable(True)
        showHostsInGroupsAction.setChecked(self.showHostsInGroups)

        self.groupsMenu.addSeparator()
        for group, checked in self.groups.items():
            action = QAction(group, self.groupsMenu)
            action.setCheckable(True)
            action.setChecked(checked)
            action.triggered.connect(self.groupsVisibilityChanged)
            self.groupsMenu.addAction(action)

    def addGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.add()
        self._processHostSubmit(resp)

    def groupsVisibilityChanged(self, checked):
        currentGroup = unicode(self.sender().text())
        self.groups[currentGroup] = checked
        self.setHostList()

    def setDockPosition(self, dockWidgetArea):
        if self.ui.hostsDock.isFloating():
            self.ui.hostsDock.setFloating(False)
        self.addDockWidget(dockWidgetArea, self.ui.hostsDock)

    def setDockFloat(self):
        if self.ui.hostsDock.isFloating():
            return
        # default title bar must be set before is float because sometimes window make strange crash
        self.ui.hostsDock.setTitleBarWidget(None)
        self.ui.hostsDock.setFloating(True)

    def dockLevelChanged(self, isFloating):
        if isFloating:
            # changing title bar widget if is not none, probably true will be only once on start with saved float state
            if self.ui.hostsDock.titleBarWidget():
                self.ui.hostsDock.setTitleBarWidget(None)
        else:
            self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)

    def showFramelessWidget(self):
        self.t.show()
        self.t.setGeometry(self.frameGeometry())

    def getCurrentHostListItemName(self):
        return self.ui.hostsList.currentItem().text()

    def getSelectedHosts(self):
        return [host.text() for host in self.ui.hostsList.selectedItems()]

    def findHostItemByName(self, name):
        result = self.ui.hostsList.findItems(name, Qt.MatchExactly)
        resultLen = len(result)
        if resultLen != 1:  # should be only one host
            logger.error("Host not found. Got %d results" % resultLen)
        return result[0]

    def showCentralWidgetContextMenu(self, pos):
        menu = QMenu()
        title = self.ui.hostsDock.windowTitle()

        hostsDockAction = menu.addAction(title)
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.ui.hostsDock.isVisible())
        hostsDockAction.triggered.connect(self.changeHostsDockWidgetVisibility)

        hostsDockAction = menu.addAction("Tray icon")
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.tray.isVisible())
        hostsDockAction.triggered.connect(self.changeTrayIconVisibility)

        connectHostMenuTray = ConnectHostMenu(self.hosts, "Connect")
        connectHostMenuTray.triggered.connect(self.connectHostFromMenu)
        menu.addMenu(connectHostMenuTray)

        menu.exec_(self.tabWidget.mapToGlobal(pos))

    def changeHostListView(self, checked):
        self.showHostsInGroups = checked
        self.setHostList()

    def changeHostsDockWidgetVisibility(self):
        isVisible = self.ui.hostsDock.isVisible()
        self.ui.hostsDock.setVisible(not isVisible)

    def isHostListHeader(self, item):
        if not item or item.type() == self.typeQListWidgetHeader:
            return True
        return False

    def slotShowHostContextMenu(self, pos):
        def changeMenusVisibility(isEnabled):
            self.connectFramelessMenu.setEnabled(isEnabled)
            self.editAction.setEnabled(isEnabled)
            self.duplicateAction.setEnabled(isEnabled)

        # ignore context menu for group headers
        item = self.ui.hostsList.itemAt(pos)

        if self.isHostListHeader(item):
            item = self.ui.hostsList.itemAt(pos)
            widgetItem = self.ui.hostsList.itemWidget(item)
            if widgetItem:
                self.currentGroupName = widgetItem.text()  # yea I'm so dirty
                if self.currentGroupName != unassignedGroupName:
                    self.groupsHeaderMenu.exec_(self.ui.hostsList.mapToGlobal(pos))
            return

        if len(self.ui.hostsList.selectedItems()) == 1:  # single menu
            changeMenusVisibility(True)
        else:
            changeMenusVisibility(False)

        self.hostMenu.exec_(self.ui.hostsList.mapToGlobal(pos))

    def _processHostSubmit(self, resp):
        if resp["code"]:
            self.setHostList()
        hostName = resp.get("name")
        if hostName:
            hostItem = self.findHostItemByName(hostName)
            self.slotConnectHost(hostItem)

    def addHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        self._processHostSubmit(hostDialog.add())

    def editHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.edit(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def editGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.edit(self.currentGroupName)
        self._processHostSubmit(resp)

    def deleteGroup(self):
        retCode = self.showOkCancelMessageBox("Do you want to remove selected group? All assigned hosts "
                                              "to this group will be unassigned.",
                                              "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        self.hosts.deleteGroup(self.currentGroupName)
        self.setHostList()

    def showDeleteGroupDialog(self):
        deleteGroupDialog = DeleteGroupDialog(self.hosts)
        deleteGroupDialog.deleteGroup()
        self.setHostList()

    def duplicateHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.duplicate(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def deleteHost(self):
        retCode = self.showOkCancelMessageBox("Do you want to remove selected hosts?",
                                              "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        for host in self.getSelectedHosts():
            self.hosts.delete(host)
        self.setHostList()

    def connectFrameless(self, screenIndex=None):
        self.connectHost(self.getCurrentHostListItemName(), frameless=True, screenIndex=screenIndex)

    # Fix to release keyboard from QX11EmbedContainer, when we leave widget through wm border
    def leaveEvent(self, event):
        keyG = QWidget.keyboardGrabber()
        if keyG is not None:
            keyG.releaseKeyboard()
        event.accept()  # needed?

    def setHostList(self):
        """ set hosts list in list view """
        self.ui.hostsList.clear()
        self.refreshGroups()
        hostFilter = self.ui.filter.text()
        if self.showHostsInGroups:
            self.showHostListInGroups(hostFilter)
        else:
            self.showHostList(hostFilter)

    def showHostList(self, hostFilter):
        groupFilter = [group for group, visibility in self.groups.items() if visibility]
        hosts = self.hosts.getHostsListByHostNameAndGroup(hostFilter, groupFilter)
        self.ui.hostsList.addItems(hosts)

    def showHostListInGroups(self, hostFilter):
        hosts = self.hosts.getGroupedHostNames(hostFilter)
        for group, hostsList in hosts.items():
            if self.groups.get(group, True):
                if group is None:
                    group = unassignedGroupName
                groupHeader = QtGui.QListWidgetItem(type=self.typeQListWidgetHeader)
                groupLabel = QtGui.QLabel(unicode(group))
                groupLabel.setProperty('class', 'group-title')
                self.ui.hostsList.addItem(groupHeader)
                self.ui.hostsList.setItemWidget(groupHeader, groupLabel)
                self.ui.hostsList.addItems(hostsList)

    def slotShowHost(self, item):
        # on one click we activating tab and showing options
        self.tabWidget.activateTab(item)

    def slotConnectHost(self, item):
        if self.isHostListHeader(item):
            return
        self.connectHost(unicode(item.text()))

    def connectHost(self, hostId, frameless=False, screenIndex=None):
        hostId = unicode(hostId)  # sometimes hostId comes as QString
        tabPage = self.tabWidget.createTab(hostId)
        tabPage.reconnectionNeeded.connect(self.connectHost)

        if frameless:
            self.tabWidget.detachFrameless(tabPage, screenIndex)

        try:
            execCmd, opts = self.getCmd(tabPage, hostId)
        except LookupError:
            logger.error(u"Host {} not found.".format(hostId))
            return

        ProcessManager.start(hostId, tabPage, execCmd, opts)
        return tabPage

    def getCmd(self, tabPage, hostName):
        host = self.hosts.get(hostName)

        # set tabPage widget
        width, height = tabPage.setSizeAndGetCurrent()
        # 1et widget winId to embed rdesktop
        winId = tabPage.x11.winId()

        # set remote desktop client, at this time works only with freerdp
        remoteClientType, remoteClientOptions = self.config.getRdpClient()
        remoteClient = ClientFactory(remoteClientType, **remoteClientOptions)
        remoteClient.setWindowParameters(winId, width, height)
        remoteClient.setUserAndPassword(host.user, host.password)
        remoteClient.setAddress(host.address)
        return remoteClient.getComposedCommand()

    def saveSettings(self):
        self.config.setValue("geometry", self.saveGeometry())
        self.config.setValue("windowState", self.saveState())
        self.config.setValue('trayIconVisibility', self.tray.isVisible())
        self.config.setValue('mainWindowVisibility', self.isVisible())
        self.config.setValue('groups', self.groups)
        self.config.setValue('showHostsInGroups', self.showHostsInGroups)

    def restoreSettings(self):
        try:
            self.restoreGeometry(self.config.getValue("geometry").toByteArray())
            self.restoreState(self.config.getValue("windowState").toByteArray())
        except Exception:
            logger.debug("No settings to restore")

        # restore tray icon state
        trayIconVisibility = self.config.getValue('trayIconVisibility', "true").toBool()
        self.tray.setVisible(trayIconVisibility)

        self.showHostsInGroups = self.config.getValue('showHostsInGroups', 'false').toBool()

        if self.tray.isVisible():
            mainWindowVisibility = self.config.getValue('mainWindowVisibility', "true").toBool()
            self.setVisible(mainWindowVisibility)
        else:  # it tray icon is not visible, always show main window
            self.show()

        self.groups = {unicode(k): v for k, v in self.config.getValue('groups', {}).toPyObject().items()}

    def closeEvent(self, event):
        if not ProcessManager.hasActiveProcess:
            self.saveSettings()
            QCoreApplication.exit()
            return

        ret = self.showOkCancelMessageBox("Are you sure do you want to quit?",
                                          "Exit confirmation")
        if ret == QMessageBox.Cancel:
            event.ignore()
            return

        self.saveSettings()
        ProcessManager.killemall()
        event.accept()
        QCoreApplication.exit()

    def showOkCancelMessageBox(self, messageBoxText, windowTitle):
        msgBox = QMessageBox(self, text=messageBoxText)
        msgBox.setWindowTitle(windowTitle)
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msgBox.setIcon(QMessageBox.Question)
        return msgBox.exec_()
Ejemplo n.º 5
0
class MainWindow(QMainWindow):
    def __init__(self, config):
        super(MainWindow, self).__init__()
        self.config = Config(config)
        db = Database(self.config.getConnectionString())
        db.create()
        self.hosts = Hosts(db)

        # menu used for each host
        self.hostMenu = QMenu()
        self.hostMenu.addAction(QIcon(":/ico/edit.svg"), "Edit", self.editHost)
        self.hostMenu.addAction(QIcon(":/ico/remove.svg"), "Delete", self.deleteHost)
        actions.addActionWithScreenChose(
            self.hostMenu, self.connectFrameless, ":/ico/frameless.svg", "Connect frameless"
        )

        # setup main window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # when top level changed, we changing dock title bar
        self.dockWidgetTileBar = DockWidgetTitleBar()
        self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)
        self.ui.hostsDock.topLevelChanged.connect(self.dockLevelChanged)

        # set global menu
        self.globalMenu = QMenu()
        self.globalMenu.addAction(QIcon(":/ico/add.svg"), "Add host", self.addHost)
        # disable menu indicator
        self.ui.menu.setStyleSheet("QPushButton::menu-indicator {image: none;}")
        self.positionMenu = QMenu("Dock position")
        self.positionMenu.addAction("Left", lambda: self.setDockPosition(Qt.LeftDockWidgetArea))
        self.positionMenu.addAction("Right", lambda: self.setDockPosition(Qt.RightDockWidgetArea))
        self.positionMenu.addAction("Float", self.setDockFloat)
        self.globalMenu.addMenu(self.positionMenu)
        self.globalMenu.addAction("Change tray icon visibility", self.changeTrayIconVisibility)
        self.globalMenu.addAction("Quit", self.close)
        self.ui.menu.setMenu(self.globalMenu)

        # set events on hosts list
        self.ui.hostsList.itemDoubleClicked.connect(self.slotConnectHost)
        self.ui.hostsList.itemClicked.connect(self.slotShowHost)
        self.ui.hostsList.customContextMenuRequested.connect(self.slotShowHostContextMenu)

        # set tab widget
        self.tabWidget = MyTabWidget()
        self.setCentralWidget(self.tabWidget)

        # set tray icon
        self.tray = QSystemTrayIcon(QIcon(":/ico/myrdp.svg"))
        self.tray.activated.connect(self.trayActivated)

        self.trayMenu = QMenu()
        self.trayMenu.addAction("Hide tray icon", self.changeTrayIconVisibility)
        self.trayMenu.addAction("Quit", self.close)

        self.tray.setContextMenu(self.trayMenu)

        # host list
        self.ui.filter.textChanged.connect(self.setHostList)
        self.setHostList()
        self.restoreSettings()

    def trayActivated(self, reason):
        if reason != QSystemTrayIcon.Trigger:
            return
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.activateWindow()

    def changeTrayIconVisibility(self):
        if self.tray.isVisible():
            self.tray.hide()
            if not self.isVisible():
                self.show()
        else:
            self.tray.show()

    def setDockPosition(self, dockWidgetArea):
        if self.ui.hostsDock.isFloating():
            self.ui.hostsDock.setFloating(False)
        self.addDockWidget(dockWidgetArea, self.ui.hostsDock)

    def setDockFloat(self):
        if self.ui.hostsDock.isFloating():
            return
        # default title bar must be set before is float because sometimes window make strange crash
        self.ui.hostsDock.setTitleBarWidget(None)
        self.ui.hostsDock.setFloating(True)

    def dockLevelChanged(self, isFloating):
        if isFloating:
            # changing title bar widget if is not none, probably true will be only once on start with saved float state
            if self.ui.hostsDock.titleBarWidget():
                self.ui.hostsDock.setTitleBarWidget(None)
        else:
            self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)

    def showFramelessWidget(self):
        self.t.show()
        self.t.setGeometry(self.frameGeometry())

    def getCurrentHostListItemName(self):
        return self.ui.hostsList.currentItem().text()

    def findHostItemByName(self, name):
        result = self.ui.hostsList.findItems(name, Qt.MatchExactly)
        resultLen = len(result)
        if resultLen != 1:  # should be only one host
            logging.error("Host not found. Got %d results" % resultLen)
        return result[0]

    def slotShowHostContextMenu(self, pos):
        """ slot needed to show menu in proper position, or i'm doing something wrong
        """
        self.hostMenu.exec_(self.ui.hostsList.mapToGlobal(pos))

    def addHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.add()
        if resp["code"]:
            self.setHostList()
        hostName = resp.get("name")
        if hostName:
            hostItem = self.findHostItemByName(hostName)
            self.slotConnectHost(hostItem)

    def editHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.edit(self.getCurrentHostListItemName())
        if resp["code"]:
            self.setHostList()

    def deleteHost(self):
        self.hosts.delete(self.getCurrentHostListItemName())
        self.setHostList()

    def connectFrameless(self, screenIndex=None):
        self.connectHost(self.getCurrentHostListItemName(), frameless=True, screenIndex=screenIndex)

    # Fix to release keyboard from QX11EmbedContainer, when we leave widget through wm border
    def leaveEvent(self, event):
        keyG = QWidget.keyboardGrabber()
        if keyG is not None:
            keyG.releaseKeyboard()
        event.accept()  # needed?

    def setHostList(self):
        """ set hosts list in list view """
        self.ui.hostsList.clear()
        self.ui.hostsList.addItems(self.hosts.getFilteredHostsNames(self.ui.filter.text()))

    def slotShowHost(self, item):
        # on one click we activating tab and showing options
        self.tabWidget.activateTab(item)

    def slotConnectHost(self, item):
        self.connectHost(unicode(item.text()))

    def connectHost(self, hostId, frameless=False, screenIndex=None):
        hostId = unicode(hostId)  # sometimes hostId comes as QString
        tabPage = self.tabWidget.createTab(hostId)
        tabPage.reconnectionNeeded.connect(self.connectHost)

        if frameless:
            self.tabWidget.detachFrameless(tabPage, screenIndex)

        execCmd, opts = self.getCmd(tabPage, hostId)
        ProcessManager.start(hostId, tabPage, execCmd, opts)

    def getCmd(self, tabPage, hostName):
        host = self.hosts.get(hostName)

        # set tabPage widget
        width, height = tabPage.setSizeAndGetCurrent()
        # 1et widget winId to embed rdesktop
        winId = tabPage.x11.winId()

        # set remote desktop client, at this time works only with freerdp
        remoteClientType, remoteClientOptions = self.config.getRdpClient()
        remoteClient = ClientFactory(remoteClientType, **remoteClientOptions)
        remoteClient.setWindowParameters(winId, width, height)
        remoteClient.setUserAndPassword(host.user, host.password)
        remoteClient.setAddress(host.address)
        return remoteClient.getComposedCommand()

    def saveSettings(self):
        settings = QSettings("MyRDP")
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("windowState", self.saveState())
        settings.setValue("trayIconVisibility", self.tray.isVisible())

    def restoreSettings(self):
        settings = QSettings("MyRDP")

        try:
            self.restoreGeometry(settings.value("geometry").toByteArray())
            self.restoreState(settings.value("windowState").toByteArray())
        except Exception:
            logging.debug("No settings to restore")

        # restore tray icon state
        trayIconVisibility = settings.value("trayIconVisibility").toBool()
        self.tray.setVisible(trayIconVisibility)

    def closeEvent(self, event):
        if not ProcessManager.hasActiveProcess:
            self.saveSettings()
            return

        msgBox = QMessageBox(self, text="Are you sure do you want to quit?")
        msgBox.setWindowTitle("Exit confirmation")
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        ret = msgBox.exec_()
        if ret == QMessageBox.Cancel:
            event.ignore()
            return

        self.saveSettings()
        ProcessManager.killemall()
        event.accept()
Ejemplo n.º 6
0
class QChatWindow(QMainWindow):
    newClientSignal = pyqtSignal(str)
    clientReadySignal = pyqtSignal(str)
    smpRequestSignal = pyqtSignal(int, str, str, int)
    handleErrorSignal = pyqtSignal(str, int)
    sendMessageToTabSignal = pyqtSignal(str, str, str)

    def __init__(self, restartCallback, connectionManager=None, messageQueue=None):
        QMainWindow.__init__(self)

        self.restartCallback = restartCallback
        self.connectionManager = connectionManager
        self.messageQueue = messageQueue
        self.newClientSignal.connect(self.newClientSlot)
        self.clientReadySignal.connect(self.clientReadySlot)
        self.smpRequestSignal.connect(self.smpRequestSlot)
        self.handleErrorSignal.connect(self.handleErrorSlot)
        self.sendMessageToTabSignal.connect(self.sendMessageToTab)

        self.chatTabs = QTabWidget(self)
        self.chatTabs.setTabsClosable(True)
        self.chatTabs.setMovable(True)
        self.chatTabs.tabCloseRequested.connect(self.closeTab)
        self.chatTabs.currentChanged.connect(self.tabChanged)

        self.statusBar = self.statusBar()
        self.systemTrayIcon = QSystemTrayIcon(self)
        self.systemTrayIcon.setVisible(True)

        self.__setMenubar()

        vbox = QVBoxLayout()
        vbox.addWidget(self.chatTabs)

        # Add the completeted layout to the window
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(vbox)
        self.setCentralWidget(self.centralWidget)

        qtUtils.resizeWindow(self, 700, 400)
        qtUtils.centerWindow(self)

        # Title and icon
        self.setWindowTitle("Cryptully")
        self.setWindowIcon(QIcon(qtUtils.getAbsoluteImagePath('icon.png')))


    def connectedToServer(self):
        # Add an initial tab once connected to the server
        self.addNewTab()


    def newClient(self, nick):
        # This function is called from a bg thread. Send a signal to get on the UI thread
        self.newClientSignal.emit(nick)


    @pyqtSlot(str)
    def newClientSlot(self, nick):
        nick = str(nick)

        # Show a system notifcation of the new client if not the current window
        if not self.isActiveWindow():
            qtUtils.showDesktopNotification(self.systemTrayIcon, "Chat request from %s" % nick, '')

        # Show the accept dialog
        accept = QAcceptDialog.getAnswer(self, nick)

        if not accept:
            self.connectionManager.newClientRejected(nick)
            return

        # If nick already has a tab, reuse it
        if self.isNickInTabs(nick):
            self.getTabByNick(nick)[0].enable()
        else:
            self.addNewTab(nick)

        self.connectionManager.newClientAccepted(nick)


    def addNewTab(self, nick=None):
        newTab = QChatTab(self, nick)
        self.chatTabs.addTab(newTab, nick if nick is not None else "New Chat")
        self.chatTabs.setCurrentWidget(newTab)
        newTab.setFocus()


    def clientReady(self, nick):
        # Use a signal to call the client ready slot on the UI thread since
        # this function is called from a background thread
        self.clientReadySignal.emit(nick)


    @pyqtSlot(str)
    def clientReadySlot(self, nick):
        nick = str(nick)
        tab, tabIndex = self.getTabByNick(nick)
        self.chatTabs.setTabText(tabIndex, nick)
        tab.showNowChattingMessage()

        # Set the window title if the tab is the selected tab
        if tabIndex == self.chatTabs.currentIndex():
            self.setWindowTitle(nick)


    def smpRequest(self, type, nick, question='', errno=0):
        self.smpRequestSignal.emit(type, nick, question, errno)


    @pyqtSlot(int, str, str, int)
    def smpRequestSlot(self, type, nick, question='', errno=0):
        if type == constants.SMP_CALLBACK_REQUEST:
            answer, clickedButton = QSMPRespondDialog.getAnswer(nick, question)

            if clickedButton == constants.BUTTON_OKAY:
                self.connectionManager.respondSMP(str(nick), str(answer))
        elif type == constants.SMP_CALLBACK_COMPLETE:
            QMessageBox.information(self, "%s Authenticated" % nick,
                "Your chat session with %s has been succesfully authenticated. The conversation is verfied as secure." % nick)
        elif type == constants.SMP_CALLBACK_ERROR:
            if errno == errors.ERR_SMP_CHECK_FAILED:
                QMessageBox.warning(self, errors.TITLE_PROTOCOL_ERROR, errors.PROTOCOL_ERROR % (nick))
            elif errno == errors.ERR_SMP_MATCH_FAILED:
                QMessageBox.critical(self, errors.TITLE_SMP_MATCH_FAILED, errors.SMP_MATCH_FAILED)


    def handleError(self, nick, errno):
        self.handleErrorSignal.emit(nick, errno)


    @pyqtSlot(str, int)
    def handleErrorSlot(self, nick, errno):
        # If no nick was given, disable all tabs
        nick = str(nick)
        if nick == '':
            self.__disableAllTabs()
        else:
            try:
                tab = self.getTabByNick(nick)[0]
                tab.resetOrDisable()
            except:
                self.__disableAllTabs()

        if errno == errors.ERR_CONNECTION_ENDED:
            QMessageBox.warning(self, errors.TITLE_CONNECTION_ENDED, errors.CONNECTION_ENDED % (nick))
        elif errno == errors.ERR_NICK_NOT_FOUND:
            QMessageBox.information(self, errors.TITLE_NICK_NOT_FOUND, errors.NICK_NOT_FOUND % (nick))
            tab.nick = None
        elif errno == errors.ERR_CONNECTION_REJECTED:
            QMessageBox.warning(self, errors.TITLE_CONNECTION_REJECTED, errors.CONNECTION_REJECTED % (nick))
            tab.nick = None
        elif errno == errors.ERR_BAD_HANDSHAKE:
            QMessageBox.warning(self, errors.TITLE_PROTOCOL_ERROR, errors.PROTOCOL_ERROR % (nick))
        elif errno == errors.ERR_CLIENT_EXISTS:
            QMessageBox.information(self, errors.TITLE_CLIENT_EXISTS, errors.CLIENT_EXISTS % (nick))
        elif errno == errors.ERR_SELF_CONNECT:
            QMessageBox.warning(self, errors.TITLE_SELF_CONNECT, errors.SELF_CONNECT)
        elif errno == errors.ERR_SERVER_SHUTDOWN:
            QMessageBox.critical(self, errors.TITLE_SERVER_SHUTDOWN, errors.SERVER_SHUTDOWN)
        elif errno == errors.ERR_ALREADY_CONNECTED:
            QMessageBox.information(self, errors.TITLE_ALREADY_CONNECTED, errors.ALREADY_CONNECTED % (nick))
        elif errno == errors.ERR_INVALID_COMMAND:
            QMessageBox.warning(self, errors.TITLE_INVALID_COMMAND, errors.INVALID_COMMAND % (nick))
        elif errno == errors.ERR_NETWORK_ERROR:
            QMessageBox.critical(self, errors.TITLE_NETWORK_ERROR, errors.NETWORK_ERROR)
        elif errno == errors.ERR_BAD_HMAC:
            QMessageBox.critical(self, errors.TITLE_BAD_HMAC, errors.BAD_HMAC)
        elif errno == errors.ERR_BAD_DECRYPT:
            QMessageBox.warning(self, errors.TITLE_BAD_DECRYPT, errors.BAD_DECRYPT)
        elif errno == errors.ERR_KICKED:
            QMessageBox.critical(self, errors.TITLE_KICKED, errors.KICKED)
        elif errno == errors.ERR_NICK_IN_USE:
            QMessageBox.warning(self, errors.TITLE_NICK_IN_USE, errors.NICK_IN_USE)
            self.restartCallback()
        elif errno == errors.ERR_MESSAGE_REPLAY:
            QMessageBox.critical(self, errors.TITLE_MESSAGE_REPLAY, errors.MESSAGE_REPLAY)
        elif errno == errors.ERR_MESSAGE_DELETION:
            QMessageBox.critical(self, errors.TITLE_MESSAGE_DELETION, errors.MESSAGE_DELETION)
        elif errno == errors.ERR_PROTOCOL_VERSION_MISMATCH:
            QMessageBox.critical(self, errors.TITLE_PROTOCOL_VERSION_MISMATCH, errors.PROTOCOL_VERSION_MISMATCH)
            self.restartCallback()
        else:
            QMessageBox.warning(self, errors.TITLE_UNKNOWN_ERROR, errors.UNKNOWN_ERROR % (nick))


    def __disableAllTabs(self):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            curTab.resetOrDisable()


    def postMessage(self, command, sourceNick, payload):
        self.sendMessageToTabSignal.emit(command, sourceNick, payload)


    @pyqtSlot(str, str, str)
    def sendMessageToTab(self, command, sourceNick, payload):
        # If a typing command, update the typing status in the tab, otherwise
        # show the message in the tab
        tab, tabIndex = self.getTabByNick(sourceNick)
        if command == constants.COMMAND_TYPING:
            # Show the typing status in the status bar if the tab is the selected tab
            if tabIndex == self.chatTabs.currentIndex():
                payload = int(payload)
                if payload == constants.TYPING_START:
                    self.statusBar.showMessage("%s is typing" % sourceNick)
                elif payload == constants.TYPING_STOP_WITHOUT_TEXT:
                    self.statusBar.showMessage('')
                elif payload == constants.TYPING_STOP_WITH_TEXT:
                    self.statusBar.showMessage("%s has entered text" % sourceNick)
        elif command == constants.COMMAND_SMP_0:
            print('got request for smp in tab %d' % (tabIndex))
        else:
            tab.appendMessage(payload, constants.RECEIVER)

            # Update the unread message count if the message is not intended for the currently selected tab
            if tabIndex != self.chatTabs.currentIndex():
                tab.unreadCount += 1
                self.chatTabs.setTabText(tabIndex, "%s (%d)" % (tab.nick, tab.unreadCount))
            else:
                # Clear the typing status if the current tab
                self.statusBar.showMessage('')

            # Show a system notifcation of the new message if not the current window or tab or the
            # scrollbar of the tab isn't at the bottom
            chatLogScrollbar = tab.widgetStack.widget(2).chatLog.verticalScrollBar()
            if not self.isActiveWindow() or tabIndex != self.chatTabs.currentIndex() or \
               chatLogScrollbar.value() != chatLogScrollbar.maximum():
                qtUtils.showDesktopNotification(self.systemTrayIcon, sourceNick, payload)


    @pyqtSlot(int)
    def tabChanged(self, index):
        # Reset the unread count for the tab when it's switched to
        tab = self.chatTabs.widget(index)

        # Change the window title to the nick
        if tab is None or tab.nick is None:
            self.setWindowTitle("Cryptully")
        else:
            self.setWindowTitle(tab.nick)

        if tab is not None and tab.unreadCount != 0:
            tab.unreadCount = 0
            self.chatTabs.setTabText(index, tab.nick)


    @pyqtSlot(int)
    def closeTab(self, index):
        tab = self.chatTabs.widget(index)
        self.connectionManager.closeChat(tab.nick)

        self.chatTabs.removeTab(index)

        # Show a new tab if there are now no tabs left
        if self.chatTabs.count() == 0:
            self.addNewTab()


    def getTabByNick(self, nick):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            if curTab.nick == nick:
                return (curTab, i)
        return None


    def isNickInTabs(self, nick):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            if curTab.nick == nick:
                return True
        return False


    def __setMenubar(self):
        newChatIcon = QIcon(qtUtils.getAbsoluteImagePath('new_chat.png'))
        helpIcon    = QIcon(qtUtils.getAbsoluteImagePath('help.png'))
        exitIcon    = QIcon(qtUtils.getAbsoluteImagePath('exit.png'))
        menuIcon    = QIcon(qtUtils.getAbsoluteImagePath('menu.png'))

        newChatAction  = QAction(newChatIcon, '&New chat', self)
        authChatAction = QAction(newChatIcon, '&Authenticate chat', self)
        helpAction     = QAction(helpIcon, 'Show &help', self)
        exitAction     = QAction(exitIcon, '&Exit', self)

        newChatAction.triggered.connect(lambda: self.addNewTab())
        authChatAction.triggered.connect(self.__showAuthDialog)
        helpAction.triggered.connect(self.__showHelpDialog)
        exitAction.triggered.connect(self.__exit)

        newChatAction.setShortcut('Ctrl+N')
        helpAction.setShortcut('Ctrl+H')
        exitAction.setShortcut('Ctrl+Q')

        optionsMenu = QMenu()

        optionsMenu.addAction(newChatAction)
        optionsMenu.addAction(authChatAction)
        optionsMenu.addAction(helpAction)
        optionsMenu.addAction(exitAction)

        optionsMenuButton = QToolButton()
        newChatButton     = QToolButton()
        exitButton        = QToolButton()

        newChatButton.clicked.connect(lambda: self.addNewTab())
        exitButton.clicked.connect(self.__exit)

        optionsMenuButton.setIcon(menuIcon)
        newChatButton.setIcon(newChatIcon)
        exitButton.setIcon(exitIcon)

        optionsMenuButton.setMenu(optionsMenu)
        optionsMenuButton.setPopupMode(QToolButton.InstantPopup)

        toolbar = QToolBar(self)
        toolbar.addWidget(optionsMenuButton)
        toolbar.addWidget(newChatButton)
        toolbar.addWidget(exitButton)
        self.addToolBar(Qt.LeftToolBarArea, toolbar)


    def __showAuthDialog(self):
        client = self.connectionManager.getClient(self.chatTabs.currentWidget().nick)

        if client is None:
            QMessageBox.information(self, "Not Available", "You must be chatting with someone before you can authenticate the connection.")
            return

        try:
            question, answer, clickedButton = QSMPInitiateDialog.getQuestionAndAnswer()
        except AttributeError:
            QMessageBox.information(self, "Not Available", "Encryption keys are not available until you are chatting with someone")

        if clickedButton == constants.BUTTON_OKAY:
            client.initiateSMP(str(question), str(answer))


    def __showHelpDialog(self):
        QHelpDialog(self).show()


    def __exit(self):
        if QMessageBox.Yes == QMessageBox.question(self, "Confirm Exit", "Are you sure you want to exit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No):
            qtUtils.exitApp()
Ejemplo n.º 7
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self._init_menu()
        self._init_actions()
        self._init_models()
        self.lt = ListenThread(self.add_new_device)
        self._install_akmods = False
        self._main_pko = PackageKitQt()

        # right frame
        self.comboBoxModules.currentIndexChanged.connect(self._handle_select_module)
        self.buttonBoxDetails.clicked.connect(self._handle_rbb)

        self.__debug_mode__ = True

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setIcon(QIcon(":/img/gears"))
        self.trayIcon.activated.connect(self._handle_tray_icon_activate)
        self.hide()

    def closeEvent(self, event):
        event.ignore()
        self.hide()

    def _init_menu(self):
        self.actionFileExit.triggered.connect(self._handle_exit)

        self.listView.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.listViewActions.setContextMenuPolicy(Qt.ActionsContextMenu)

        # context menu for listView
        for act in self.menuDevices.actions():
            self.listView.addAction(act)
        # context menu for listViewActions
        for act in self.menuActions.actions():
            self.listViewActions.addAction(act)

    def _init_actions(self):
        self.actionDevicesDisable.triggered.connect(self._handle_disable_device)
        self.actionDevicesDisableAll.triggered.connect(self._handle_disable_all)
        self.actionActionsDelete.triggered.connect(self._handle_remove_current_action)
        self.actionActionsClear.triggered.connect(self._handle_clean_actions)
        self.actionActionsApply.triggered.connect(self._handle_apply_actions)

    def _init_models(self):
        self.model = DevicesListModel(self)
        self.listView.setModel(self.model)
        self.listView.selectionModel().currentChanged.connect(self._handle_select_item)

        self.act_model = ActionsModel(self)
        self.listViewActions.setModel(self.act_model)
        self.listViewActions.selectionModel().currentChanged.connect(self._handle_action_select_item)

        self.act_model.actionDeleted.connect(self.model.reset_changes)
        self.model.dataChanged.connect(self._handle_data_changed_in_model)

    def _init_pk(self):
        if self._main_pko is None:
            self._main_pko = PackageKitQt()

    def add_new_device(self, dev):
        self.model.add_new_device(dev)
        self.show_notification()

    def disen_device_notif(self, device_id, disable=False):
        if disable:
            self.lt.disable_device_notif(device_id)
        else:
            self.lt.enable_device_notif(device_id)

    def show_notification(self):
        # if self.isHidden():
        #    self.show()
        self.trayIcon.setVisible(True)

    def start_listen(self):
        self.lt.start()

    def _right_frame_apply(self, idx):
        d = self.model.device_by_index(idx)
        sel_cb_idx = self.comboBoxModules.currentIndex()
        sel_module = str(self.comboBoxModules.itemData(sel_cb_idx).toString())
        if sel_module == d.current_driver():
            return

        self.act_model.remove_actions_by_devid(d.device_id(), sel_module)
        pkgsi = d.packages_to_install(sel_module)
        pkgsr = d.packages_to_remove(sel_module)
        if len(pkgsi) > 0:
            self.act_model.add_new_action(d.device_id(), sel_module, pkgsi, 0)
        if len(pkgsr) > 0:
            rem_mds = str(", ").join(d.device_modules(sel_module))
            self.act_model.add_new_action(d.device_id(), rem_mds, pkgsr, 1)
        d.set_selected_driver(sel_module)
        self.set_right_frame(idx)

    def _current_device(self, idx=None):
        cur_idx = idx
        if idx is None:
            cur_idx = self.listView.selectionModel().currentIndex()
        return self.model.device_by_index(cur_idx)

    def set_right_frame(self, idx):
        self.comboBoxModules.clear()
        d = self._current_device(idx)
        curdrv = QString()
        if d.current_driver() is None or len(d.current_driver()) == 0:
            curdrv = self.tr("Not installed")
        else:
            curdrv = QString("- %s -" % d.current_driver())
        self.comboBoxModules.addItem(curdrv, QString(d.current_driver()))

        self.lineEditName.setText(d.device_name())
        our_sel_idx = -1
        for m in d.device_modules():
            devmod = QString()
            if m == d.current_driver():
                continue
            elif m == d.selected_driver():
                devmod = QString("* %s *" % m)
                our_sel_idx = self.comboBoxModules.count()
            else:
                devmod = QString("%s" % m)
            self.comboBoxModules.addItem(devmod, QString(m))

        if our_sel_idx != -1:
            self.comboBoxModules.setCurrentIndex(our_sel_idx)

    def _do_resolve_packages(self, pkgs, to_remove=False):
        if len(pkgs) == 0:
            return []
        self.debug_print(pkgs)
        self._init_pk()
        pkc = self._main_pko.getTransaction()
        pkc.SetHints()
        filt = "none"
        if to_remove:
            filt = "installed"
            pkc.SearchNames(filt, pkgs)
            if pkc.has_error():
                return []
            pkg_ids = pkc.get_package_ids()
            return pkg_ids

        pkc.Resolve(filt, pkgs)
        if pkc.has_error():
            return []
        pkg_ids = pkc.get_package_ids()

        return pkg_ids

    def _do_install_packages(self, pkgs):
        if len(pkgs) == 0:
            return
        print "Begin install packages"
        self._init_pk()
        pkc = self._main_pko.getTransaction()  # PackageKitClient()
        pkc.SetHints()
        pkc.InstallPackages(False, pkgs)
        if pkc.has_error():
            err_code, err_msg = pkc.error()
            self.debug_print("Error: [%s] %s" % (err_code, err_msg))

    def _do_remove_packages(self, pkgs):
        if len(pkgs) == 0:
            return
        print "Begin remove packages"
        self._init_pk()
        pkc = self._main_pko.getTransaction()
        pkc.RemovePackages(pkgs, True, True)
        if pkc.has_error():
            err_code, err_msg = pkc.error()
            self.debug_print("Error: [%s] %s" % (err_code, err_msg))

    def _do_only_ids(self, pkgs):
        res_ids = []
        if pkgs is None:
            return res_ids
        if len(pkgs) == 0:
            return res_ids
        print pkgs
        for installed, id, summary in pkgs:
            res_ids.append(id)
        return res_ids

    def _debug_print_pkg_ids(self, pkg_ids):
        if pkg_ids is None:
            return
        elif len(pkg_ids) == 0:
            return
        for pkg_id in pkg_ids:
            self.debug_print("+ Installed: %s" % (pkg_id))

    def _do_act(self):
        pkgs_to_install, pkgs_to_remove = self.act_model.get_packages(self._install_akmods)
        if len(pkgs_to_install) + len(pkgs_to_remove) == 0:
            QMessageBox.information(self, self.tr("Empty actions"), self.tr("Nothing to install/remove"))
            return

        # Resolve all packages
        pkg_ids_install = self._do_resolve_packages(pkgs_to_install)
        pkg_ids_remove = self._do_resolve_packages(pkgs_to_remove, True)

        self.debug_print("To install: %s" % pkg_ids_install)
        self.debug_print("To remove: %s" % pkg_ids_remove)

        self._do_remove_packages(pkg_ids_remove)
        self._do_install_packages(pkg_ids_install)

        print "Packages to install:"
        self._debug_print_pkg_ids(pkg_ids_install)

        print "Packages to remove:"
        self._debug_print_pkg_ids(pkg_ids_remove)
        res = QMessageBox.question(
            self,
            self.tr("Operations done"),
            self.tr("All operations applied. You may reboot a system. Reboot now?"),
            QMessageBox.Yes and QMessageBox.No,
            QMessageBox.Yes,
        )
        if res == QMessageBox.Yes:
            print "rebooting"

    def debug_print(self, msg):
        if not self.__debug_mode__:
            return
        print (msg)

    # slots
    def _handle_data_changed_in_model(self, begin_idx, end_idx):
        cur_idx = self.listView.selectionModel().currentIndex()
        if not cur_idx.isValid():
            return
        cur_row = cur_idx.row()
        row_range = range(begin_idx.row(), end_idx.row())
        if len(row_range) == 0:
            row_range = [begin_idx.row()]
        if cur_row in row_range:
            self.set_right_frame(cur_idx)

    def _handle_remove_current_action(self):
        cur_idx = self.listViewActions.selectionModel().currentIndex()
        self.act_model.removeRows(cur_idx.row(), 1)

    def _handle_clean_actions(self):
        self.act_model.clearRows()

    def _handle_disable_all(self):
        devs = self.model.disable_all_devices()
        self.disen_device_notif(devs, True)
        self.trayIcon.hide()

    def _handle_disable_device(self):
        cur_idx = self.listView.selectionModel().currentIndex()
        this_is_hide_item = self.model.index_is_hide(cur_idx)
        need_id = self.model.index_hide(cur_idx, not this_is_hide_item)
        self._handle_select_item(cur_idx, cur_idx)

        self.disen_device_notif(need_id, not this_is_hide_item)

    def _handle_exit(self):
        self.hide()

    def _handle_action_select_item(self, cur_idx, prev_idx):
        self.actionActionsDelete.setEnabled(cur_idx.isValid())

    def _handle_select_item(self, current_idx, prev_idx):
        self.actionDevicesDisable.setEnabled(current_idx.isValid())
        if not current_idx.isValid():
            return

        if self.model.index_is_hide(current_idx):
            self.actionDevicesDisable.setText(self.tr("&Enable notification"))
        else:
            self.actionDevicesDisable.setText(self.tr("&Disable notification"))
        self.set_right_frame(current_idx)

    def _handle_rbb(self, but):
        cur_idx = self.listView.selectionModel().currentIndex()
        if self.buttonBoxDetails.buttonRole(but) == QDialogButtonBox.ResetRole:
            self.set_right_frame(cur_idx)
        elif self.buttonBoxDetails.buttonRole(but) == QDialogButtonBox.ApplyRole:
            self._right_frame_apply(cur_idx)

    def _handle_select_module(self, module_index):
        if module_index == -1:
            self.labelDetails.setText("")
            return
        selection_module_name = str(self.comboBoxModules.itemData(module_index).toString())
        d = self._current_device()
        pkgsi = d.packages_to_install(selection_module_name)
        pkgsr = d.packages_to_remove(selection_module_name)
        detail_html = QString("<h4>%1 </h4>").arg(self.tr("For installing this module need:"))
        if len(pkgsi) > 0:
            detail_html += QString("<p>%1 <ul>").arg(self.tr("Packages to install:"))
            for p in pkgsi:
                detail_html += QString("<li>%1</li>").arg(p)
            detail_html += QString("</ul></p>")
        if len(pkgsr) > 0:
            detail_html += QString("<p>%1 <ul>").arg(self.tr("Packages to remove: "))
            for p in pkgsr:
                detail_html += QString("<li>%1</li>").arg(p)
            detail_html += QString("</ul></p>")

        self.labelDetails.setText(detail_html)

    def _handle_apply_actions(self):
        if self.act_model.pkgs_to_install_exist():
            result = QMessageBox.question(
                self,
                self.tr("Install akmods too"),
                self.tr("Do you have install also akmod (automated kernel module) packages too?"),
                QMessageBox.Yes and QMessageBox.No,
                QMessageBox.Yes,
            )
            if result == QMessageBox.Yes:
                self._install_akmods = True

        self.setEnabled(False)
        self._do_act()
        self.setEnabled(True)

    def _handle_tray_icon_activate(self, reason):
        if self.isHidden():
            self.show()
        else:
            self.hide()
Ejemplo n.º 8
0
class QChatWindow(QMainWindow):
    newClientSignal = pyqtSignal(str)
    clientReadySignal = pyqtSignal(str)
    smpRequestSignal = pyqtSignal(int, str, str, int)
    handleErrorSignal = pyqtSignal(str, int)
    sendMessageToTabSignal = pyqtSignal(str, str, str)

    def __init__(self,
                 restartCallback,
                 connectionManager=None,
                 messageQueue=None):
        QMainWindow.__init__(self)

        self.restartCallback = restartCallback
        self.connectionManager = connectionManager
        self.messageQueue = messageQueue
        self.newClientSignal.connect(self.newClientSlot)
        self.clientReadySignal.connect(self.clientReadySlot)
        self.smpRequestSignal.connect(self.smpRequestSlot)
        self.handleErrorSignal.connect(self.handleErrorSlot)
        self.sendMessageToTabSignal.connect(self.sendMessageToTab)

        self.chatTabs = QTabWidget(self)
        self.chatTabs.setTabsClosable(True)
        self.chatTabs.setMovable(True)
        self.chatTabs.tabCloseRequested.connect(self.closeTab)
        self.chatTabs.currentChanged.connect(self.tabChanged)

        self.statusBar = self.statusBar()
        self.systemTrayIcon = QSystemTrayIcon(self)
        self.systemTrayIcon.setVisible(True)

        self.__setMenubar()

        vbox = QVBoxLayout()
        vbox.addWidget(self.chatTabs)

        # Add the completeted layout to the window
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(vbox)
        self.setCentralWidget(self.centralWidget)

        qtUtils.resizeWindow(self, 700, 400)
        qtUtils.centerWindow(self)

        # Title and icon
        self.setWindowTitle("Cryptully")
        self.setWindowIcon(QIcon(qtUtils.getAbsoluteImagePath('icon.png')))

    def connectedToServer(self):
        # Add an initial tab once connected to the server
        self.addNewTab()

    def newClient(self, nick):
        # This function is called from a bg thread. Send a signal to get on the UI thread
        self.newClientSignal.emit(nick)

    @pyqtSlot(str)
    def newClientSlot(self, nick):
        nick = str(nick)

        # Show a system notifcation of the new client if not the current window
        if not self.isActiveWindow():
            qtUtils.showDesktopNotification(self.systemTrayIcon,
                                            "Chat request from %s" % nick, '')

        # Show the accept dialog
        accept = QAcceptDialog.getAnswer(self, nick)

        if not accept:
            self.connectionManager.newClientRejected(nick)
            return

        # If nick already has a tab, reuse it
        if self.isNickInTabs(nick):
            self.getTabByNick(nick)[0].enable()
        else:
            self.addNewTab(nick)

        self.connectionManager.newClientAccepted(nick)

    def addNewTab(self, nick=None):
        newTab = QChatTab(self, nick)
        self.chatTabs.addTab(newTab, nick if nick is not None else "New Chat")
        self.chatTabs.setCurrentWidget(newTab)
        newTab.setFocus()

    def clientReady(self, nick):
        # Use a signal to call the client ready slot on the UI thread since
        # this function is called from a background thread
        self.clientReadySignal.emit(nick)

    @pyqtSlot(str)
    def clientReadySlot(self, nick):
        nick = str(nick)
        tab, tabIndex = self.getTabByNick(nick)
        self.chatTabs.setTabText(tabIndex, nick)
        tab.showNowChattingMessage()

        # Set the window title if the tab is the selected tab
        if tabIndex == self.chatTabs.currentIndex():
            self.setWindowTitle(nick)

    def smpRequest(self, type, nick, question='', errno=0):
        self.smpRequestSignal.emit(type, nick, question, errno)

    @pyqtSlot(int, str, str, int)
    def smpRequestSlot(self, type, nick, question='', errno=0):
        if type == constants.SMP_CALLBACK_REQUEST:
            answer, clickedButton = QSMPRespondDialog.getAnswer(nick, question)

            if clickedButton == constants.BUTTON_OKAY:
                self.connectionManager.respondSMP(str(nick), str(answer))
        elif type == constants.SMP_CALLBACK_COMPLETE:
            QMessageBox.information(
                self, "%s Authenticated" % nick,
                "Your chat session with %s has been succesfully authenticated. The conversation is verfied as secure."
                % nick)
        elif type == constants.SMP_CALLBACK_ERROR:
            if errno == errors.ERR_SMP_CHECK_FAILED:
                QMessageBox.warning(self, errors.TITLE_PROTOCOL_ERROR,
                                    errors.PROTOCOL_ERROR % (nick))
            elif errno == errors.ERR_SMP_MATCH_FAILED:
                QMessageBox.critical(self, errors.TITLE_SMP_MATCH_FAILED,
                                     errors.SMP_MATCH_FAILED)

    def handleError(self, nick, errno):
        self.handleErrorSignal.emit(nick, errno)

    @pyqtSlot(str, int)
    def handleErrorSlot(self, nick, errno):
        # If no nick was given, disable all tabs
        nick = str(nick)
        if nick == '':
            self.__disableAllTabs()
        else:
            try:
                tab = self.getTabByNick(nick)[0]
                tab.resetOrDisable()
            except:
                self.__disableAllTabs()

        if errno == errors.ERR_CONNECTION_ENDED:
            QMessageBox.warning(self, errors.TITLE_CONNECTION_ENDED,
                                errors.CONNECTION_ENDED % (nick))
        elif errno == errors.ERR_NICK_NOT_FOUND:
            QMessageBox.information(self, errors.TITLE_NICK_NOT_FOUND,
                                    errors.NICK_NOT_FOUND % (nick))
            tab.nick = None
        elif errno == errors.ERR_CONNECTION_REJECTED:
            QMessageBox.warning(self, errors.TITLE_CONNECTION_REJECTED,
                                errors.CONNECTION_REJECTED % (nick))
            tab.nick = None
        elif errno == errors.ERR_BAD_HANDSHAKE:
            QMessageBox.warning(self, errors.TITLE_PROTOCOL_ERROR,
                                errors.PROTOCOL_ERROR % (nick))
        elif errno == errors.ERR_CLIENT_EXISTS:
            QMessageBox.information(self, errors.TITLE_CLIENT_EXISTS,
                                    errors.CLIENT_EXISTS % (nick))
        elif errno == errors.ERR_SELF_CONNECT:
            QMessageBox.warning(self, errors.TITLE_SELF_CONNECT,
                                errors.SELF_CONNECT)
        elif errno == errors.ERR_SERVER_SHUTDOWN:
            QMessageBox.critical(self, errors.TITLE_SERVER_SHUTDOWN,
                                 errors.SERVER_SHUTDOWN)
        elif errno == errors.ERR_ALREADY_CONNECTED:
            QMessageBox.information(self, errors.TITLE_ALREADY_CONNECTED,
                                    errors.ALREADY_CONNECTED % (nick))
        elif errno == errors.ERR_INVALID_COMMAND:
            QMessageBox.warning(self, errors.TITLE_INVALID_COMMAND,
                                errors.INVALID_COMMAND % (nick))
        elif errno == errors.ERR_NETWORK_ERROR:
            QMessageBox.critical(self, errors.TITLE_NETWORK_ERROR,
                                 errors.NETWORK_ERROR)
        elif errno == errors.ERR_BAD_HMAC:
            QMessageBox.critical(self, errors.TITLE_BAD_HMAC, errors.BAD_HMAC)
        elif errno == errors.ERR_BAD_DECRYPT:
            QMessageBox.warning(self, errors.TITLE_BAD_DECRYPT,
                                errors.BAD_DECRYPT)
        elif errno == errors.ERR_KICKED:
            QMessageBox.critical(self, errors.TITLE_KICKED, errors.KICKED)
        elif errno == errors.ERR_NICK_IN_USE:
            QMessageBox.warning(self, errors.TITLE_NICK_IN_USE,
                                errors.NICK_IN_USE)
            self.restartCallback()
        elif errno == errors.ERR_MESSAGE_REPLAY:
            QMessageBox.critical(self, errors.TITLE_MESSAGE_REPLAY,
                                 errors.MESSAGE_REPLAY)
        elif errno == errors.ERR_MESSAGE_DELETION:
            QMessageBox.critical(self, errors.TITLE_MESSAGE_DELETION,
                                 errors.MESSAGE_DELETION)
        elif errno == errors.ERR_PROTOCOL_VERSION_MISMATCH:
            QMessageBox.critical(self, errors.TITLE_PROTOCOL_VERSION_MISMATCH,
                                 errors.PROTOCOL_VERSION_MISMATCH)
            self.restartCallback()
        else:
            QMessageBox.warning(self, errors.TITLE_UNKNOWN_ERROR,
                                errors.UNKNOWN_ERROR % (nick))

    def __disableAllTabs(self):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            curTab.resetOrDisable()

    def postMessage(self, command, sourceNick, payload):
        self.sendMessageToTabSignal.emit(command, sourceNick, payload)

    @pyqtSlot(str, str, str)
    def sendMessageToTab(self, command, sourceNick, payload):
        # If a typing command, update the typing status in the tab, otherwise
        # show the message in the tab
        tab, tabIndex = self.getTabByNick(sourceNick)
        if command == constants.COMMAND_TYPING:
            # Show the typing status in the status bar if the tab is the selected tab
            if tabIndex == self.chatTabs.currentIndex():
                payload = int(payload)
                if payload == constants.TYPING_START:
                    self.statusBar.showMessage("%s is typing" % sourceNick)
                elif payload == constants.TYPING_STOP_WITHOUT_TEXT:
                    self.statusBar.showMessage('')
                elif payload == constants.TYPING_STOP_WITH_TEXT:
                    self.statusBar.showMessage("%s has entered text" %
                                               sourceNick)
        elif command == constants.COMMAND_SMP_0:
            print(('got request for smp in tab %d' % (tabIndex)))
        else:
            tab.appendMessage(payload, constants.RECEIVER)

            # Update the unread message count if the message is not intended for the currently selected tab
            if tabIndex != self.chatTabs.currentIndex():
                tab.unreadCount += 1
                self.chatTabs.setTabText(
                    tabIndex, "%s (%d)" % (tab.nick, tab.unreadCount))
            else:
                # Clear the typing status if the current tab
                self.statusBar.showMessage('')

            # Show a system notifcation of the new message if not the current window or tab or the
            # scrollbar of the tab isn't at the bottom
            chatLogScrollbar = tab.widgetStack.widget(
                2).chatLog.verticalScrollBar()
            if not self.isActiveWindow() or tabIndex != self.chatTabs.currentIndex() or \
               chatLogScrollbar.value() != chatLogScrollbar.maximum():
                qtUtils.showDesktopNotification(self.systemTrayIcon,
                                                sourceNick, payload)

    @pyqtSlot(int)
    def tabChanged(self, index):
        # Reset the unread count for the tab when it's switched to
        tab = self.chatTabs.widget(index)

        # Change the window title to the nick
        if tab is None or tab.nick is None:
            self.setWindowTitle("Cryptully")
        else:
            self.setWindowTitle(tab.nick)

        if tab is not None and tab.unreadCount != 0:
            tab.unreadCount = 0
            self.chatTabs.setTabText(index, tab.nick)

    @pyqtSlot(int)
    def closeTab(self, index):
        tab = self.chatTabs.widget(index)
        self.connectionManager.closeChat(tab.nick)

        self.chatTabs.removeTab(index)

        # Show a new tab if there are now no tabs left
        if self.chatTabs.count() == 0:
            self.addNewTab()

    def getTabByNick(self, nick):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            if curTab.nick == nick:
                return (curTab, i)
        return None

    def isNickInTabs(self, nick):
        for i in range(0, self.chatTabs.count()):
            curTab = self.chatTabs.widget(i)
            if curTab.nick == nick:
                return True
        return False

    def __setMenubar(self):
        newChatIcon = QIcon(qtUtils.getAbsoluteImagePath('new_chat.png'))
        helpIcon = QIcon(qtUtils.getAbsoluteImagePath('help.png'))
        exitIcon = QIcon(qtUtils.getAbsoluteImagePath('exit.png'))
        menuIcon = QIcon(qtUtils.getAbsoluteImagePath('menu.png'))

        newChatAction = QAction(newChatIcon, '&New chat', self)
        authChatAction = QAction(newChatIcon, '&Authenticate chat', self)
        helpAction = QAction(helpIcon, 'Show &help', self)
        exitAction = QAction(exitIcon, '&Exit', self)

        newChatAction.triggered.connect(lambda: self.addNewTab())
        authChatAction.triggered.connect(self.__showAuthDialog)
        helpAction.triggered.connect(self.__showHelpDialog)
        exitAction.triggered.connect(self.__exit)

        newChatAction.setShortcut('Ctrl+N')
        helpAction.setShortcut('Ctrl+H')
        exitAction.setShortcut('Ctrl+Q')

        optionsMenu = QMenu()

        optionsMenu.addAction(newChatAction)
        optionsMenu.addAction(authChatAction)
        optionsMenu.addAction(helpAction)
        optionsMenu.addAction(exitAction)

        optionsMenuButton = QToolButton()
        newChatButton = QToolButton()
        exitButton = QToolButton()

        newChatButton.clicked.connect(lambda: self.addNewTab())
        exitButton.clicked.connect(self.__exit)

        optionsMenuButton.setIcon(menuIcon)
        newChatButton.setIcon(newChatIcon)
        exitButton.setIcon(exitIcon)

        optionsMenuButton.setMenu(optionsMenu)
        optionsMenuButton.setPopupMode(QToolButton.InstantPopup)

        toolbar = QToolBar(self)
        toolbar.addWidget(optionsMenuButton)
        toolbar.addWidget(newChatButton)
        toolbar.addWidget(exitButton)
        self.addToolBar(Qt.LeftToolBarArea, toolbar)

    def __showAuthDialog(self):
        client = self.connectionManager.getClient(
            self.chatTabs.currentWidget().nick)

        if client is None:
            QMessageBox.information(
                self, "Not Available",
                "You must be chatting with someone before you can authenticate the connection."
            )
            return

        try:
            question, answer, clickedButton = QSMPInitiateDialog.getQuestionAndAnswer(
            )
        except AttributeError:
            QMessageBox.information(
                self, "Not Available",
                "Encryption keys are not available until you are chatting with someone"
            )

        if clickedButton == constants.BUTTON_OKAY:
            client.initiateSMP(str(question), str(answer))

    def __showHelpDialog(self):
        QHelpDialog(self).show()

    def __exit(self):
        if QMessageBox.Yes == QMessageBox.question(
                self, "Confirm Exit", "Are you sure you want to exit?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No):
            qtUtils.exitApp()
class KerberusSystray(QWidget):
    def __init__(self):
        self.chequeos_activos = True
        self.ultimo_estado_kerberus = True
        QWidget.__init__(self)
        #icono = 'kerby-activo.ico'
        #pixmap = QPixmap(icono)
        self.style = self.style()
        ##setear el nombre de la ventana
        self.setWindowTitle('Kerberus Control Parental')
        #colocar el icono cargado a la ventana
        self.setWindowIcon(self.style.standardIcon(
            QStyle.SP_DialogYesButton))

        self.filtradoHabilitado = True

        if not os.path.isfile('dontShowMessage'):
            self.mostrarMensaje = True
            self.noMostrarMasMensaje()
        else:
            self.mostrarMensaje = False

        #Menu
        self.menu = QMenu('Kerberus')

        #accion configurar Dominios
        self.configurarDominiosAction = self.menu.addAction(
                            'Permitir/Denegar dominios'
                            )
        #accion deshabilitar filtrado
        self.deshabilitarFiltradoAction = self.menu.addAction(
                            'Deshabilitar Filtrado'
                            )
        #accion habilitar filtrado
        self.habilitarFiltradoAction = self.menu.addAction(
                            'Habilitar Filtrado'
                            )
        self.habilitarFiltradoAction.setVisible(False)
        #cambiar password
        self.cambiarPasswordAction = self.menu.addAction(
                'Cambiar password de administrador'
                )
        #recordar password
        self.recordarPasswordAction = self.menu.addAction(
                'Recordar password del administrador'
                )

        #accion salir
        self.exitAction = self.menu.addAction(
                'Salir')

        #SIGNAL->SLOT
        QObject.connect(
                self.exitAction,
                SIGNAL("triggered()"),
                #lambda: sys.exit()
                self.salir
                )
        # esta conexion es utilizada para refrezcar el icono en caso de
        # que se desactive/active kerberus
        QObject.connect(
                self,
                SIGNAL("update()"),
                #lambda: sys.exit()
                self.setIconStatus
                )

        QObject.connect(
                self.menu, SIGNAL("clicked()"),
                lambda: self.menu.popup(QCursor.pos())
                )
        QObject.connect(
                self.deshabilitarFiltradoAction,
                SIGNAL("triggered()"),
                self.deshabilitarFiltradoWindow
                )
        QObject.connect(
                self.habilitarFiltradoAction,
                SIGNAL("triggered()"),
                self.habilitarFiltradoWindow
                )
        QObject.connect(
                self.cambiarPasswordAction,
                SIGNAL("triggered()"),
                self.cambiarPasswordWindow
                )
        QObject.connect(
                self.configurarDominiosAction,
                SIGNAL("triggered()"),
                self.configurarDominios
                )
        QObject.connect(
                self.recordarPasswordAction,
                SIGNAL("triggered()"),
                self.recordarPasswordWindow
                )
        
        #SystemTray
        #self.tray = QSystemTrayIcon(QIcon(pixmap), self)
        self.tray = QSystemTrayIcon(self.style.standardIcon(
            QStyle.SP_DialogYesButton), self)
        self.tray.setToolTip('Kerberus Control Parental - Activado')
        self.tray.setContextMenu(self.menu)
        self.tray.setVisible(True)

        QObject.connect(
                self.tray,
                SIGNAL("messageClicked()"),
                self.noMostrarMasMensaje
                )

        if self.mostrarMensaje:
            self.tray.showMessage(
                    u'Kerberus Control Parental',
                    u'Filtro de Protección para menores de edad Activado',
                    2000
                    )

        # Lanzo el thead que verifica si esta activo o no kerberus
        self.t = threading.Thread(target=self.chequeosPeriodicos)
        self.t.start()

    def chequeosPeriodicos(self):
        while self.chequeos_activos:
            time.sleep(3)
            status = self.checkKerberusStatus()
            if status != self.ultimo_estado_kerberus:
                self.ultimo_estado_kerberus = status
                self.emit(SIGNAL('update()'))

    def setIconStatus(self):
        if self.ultimo_estado_kerberus:
            self.habilitarFiltradoAction.setVisible(False)
            self.deshabilitarFiltradoAction.setVisible(True)
            self.tray.setIcon(self.style.standardIcon(
                QStyle.SP_DialogYesButton))
            self.tray.setToolTip('Kerberus Control Parental - Activado')
            self.tray.showMessage(
                    u'Kerberus Control Parental',
                    u'Filtro de Protección para menores de edad Activado',
                    2000
                    )
        else:
            self.habilitarFiltradoAction.setVisible(True)
            self.deshabilitarFiltradoAction.setVisible(False)
            self.tray.setIcon(self.style.standardIcon(
                QStyle.SP_DialogNoButton))
            self.tray.setToolTip('Kerberus Control Parental - Inactivo')
            self.tray.showMessage(
                    u'Kerberus Control Parental',
                    u'Filtro de Protección para menores de edad Desactivado',
                    2000
                    )

    def salir(self):
        self.chequeos_activos = False
        sys.exit()

    def configurarDominios(self):
        admin = adminPanel()
        admin.show()

    def noMostrarMasMensaje(self):
        try:
            open('dontShowMessage', 'a').close()
        except IOError:
            print 'No se pudo crear el archivo dontShowMessage'

    def deshabilitarFiltradoWindow(self):
        url = 'http://%s:%s/!DeshabilitarFiltrado!' % ('inicio.kerberus.com.ar',
                                                        '80')
        webbrowser.open(
                url,
                new=2
                )

    def checkKerberusStatus(self):
        try:
            url = 'http://%s:%s/' % (config.BIND_ADDRESS, config.BIND_PORT)
            con = httplib.HTTPConnection(config.BIND_ADDRESS, config.BIND_PORT)
            con.request(method='KERBERUSESTADO', url=url)
            respuesta = con.getresponse().read()
            return respuesta == 'Activo'
        except:
            return False

    def habilitarFiltradoWindow(self):
        url = "http://%s:%s/!HabilitarFiltrado!" % ('inicio.kerberus.com.ar',
                                                    '80')
        webbrowser.open(
                url,
                new=2
                )

    def cambiarPasswordWindow(self):
        url = "http://%s:%s/!CambiarPassword!" % ('inicio.kerberus.com.ar',
                                                 '80')
        webbrowser.open(
                url,
                new=2
                )

    def recordarPasswordWindow(self):
        url = "http://%s:%s/!RecordarPassword!" % ('inicio.kerberus.com.ar',
                                                 '80')
        webbrowser.open(
                url,
                new=2
                )