Exemplo n.º 1
0
class Window(QtGui.QMainWindow):
    def __init__(self, simulator, parent=None):
        super(Window, self).__init__(parent)

        self.simulator = simulator

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.canvas.paintEvent = self.on_canvas_paint_event
        self.ui.canvas.resizeEvent = self.on_canvas_resize_event

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.on_timeout)
        self.timer.start(FRAME_TIME_MS)

        self.set_simulator_bounds()

    def on_canvas_paint_event(self, event):
        painter = QtGui.QPainter(self.ui.canvas)
        pixel_scale = self.ui.canvas.height() / VIEW_HEIGHT
        pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 2, Qt.SolidLine, Qt.SquareCap,
                         Qt.MiterJoin)
        brush = QtGui.QBrush(QtGui.QColor(0xE0, 0xF0, 0xFF))
        painter.setPen(pen)
        painter.setBrush(brush)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        for circle in self.simulator.circles:
            x = circle.position.x * pixel_scale + self.ui.canvas.width() / 2
            y = circle.position.y * pixel_scale + self.ui.canvas.height() / 2
            radius = circle.radius * pixel_scale
            painter.drawEllipse(QtCore.QPoint(x, y), radius, radius)

        for polygon in self.simulator.polygons:
            brush = QtGui.QBrush(QtGui.QColor(0xE0, 0xF0, 0xFF))
            painter.setBrush(brush)

            points = []
            for point in polygon.transformed_points():
                x = point.x * pixel_scale + self.ui.canvas.width() / 2
                y = point.y * pixel_scale + self.ui.canvas.height() / 2
                points.append(QtCore.QPoint(x, y))

            painter.drawPolygon(points)

    def on_canvas_resize_event(self, event):
        self.set_simulator_bounds()

    def set_simulator_bounds(self):
        unit_scale = VIEW_HEIGHT / self.ui.canvas.height()
        min_x = -self.ui.canvas.width() * unit_scale / 2 + 1
        min_y = -VIEW_HEIGHT / 2 + 1
        max_x = -min_x
        max_y = -min_y
        self.simulator.set_bounds(min_x, min_y, max_x, max_y)

    def on_timeout(self):
        self.simulator.advance(FRAME_TIME_MS / 1000.0)
        self.update()
Exemplo n.º 2
0
    def createUI(self):
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(QtGui.QHeaderView.Custom)
        self.ui.unsorted_files_view.setSortingEnabled(True)
        self.ui.unsorted_files_view.sortByColumn(1, QtCore.Qt.AscendingOrder)
Exemplo n.º 3
0
    def __init__(self, simulator, parent=None):
        super(Window, self).__init__(parent)

        self.simulator = simulator

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.canvas.paintEvent = self.on_canvas_paint_event
        self.ui.canvas.resizeEvent = self.on_canvas_resize_event

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.on_timeout)
        self.timer.start(FRAME_TIME_MS)

        self.set_simulator_bounds()
Exemplo n.º 4
0
class Main(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.createUI()
        self.createAndConnectModel()
        self.createAndConnectDelegate()
        self.populateSetTypeMenu()
        
        self.delegate.mainWindowInitialized()
        self.raise_()

    def createUI(self):
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(QtGui.QHeaderView.Custom)
        self.ui.unsorted_files_view.setSortingEnabled(True)
        self.ui.unsorted_files_view.sortByColumn(1, QtCore.Qt.AscendingOrder)

    def createAndConnectModel(self):
        self.model = UnsortedFilesModel(self)
        self.ui.unsorted_files_view.setModel(self.model)

    def createAndConnectDelegate(self):
        self.delegate = UnsortedFilesDelegate(self.model, self.ui.unsorted_files_view)
        self.ui.actionAdd.triggered.connect(self.delegate.actionFileAdd)
        self.ui.actionEdit.triggered.connect(self.delegate.actionEdit)
        self.ui.actionSortSelected.triggered.connect(self.delegate.actionSortSelected)
        self.ui.unsorted_files_view.doubleClicked.connect(self.delegate.rowDoubleClicked)
        
    def populateSetTypeMenu(self):
        file_type_manager = libentr.FileTypeManager()
        file_type_manager.register_default_types()
        for ftype in file_type_manager.list_of_types():
            set_type_action = self.ui.menuSet_Type.addAction(ftype)
            set_type_action.triggered.connect(ScopeCapturer(self.delegate.actionSetType, ftype))

    def resizeEvent(self, resizeEvent):
        self.ui.unsorted_files_view.setColumnWidth(0,500)
        self.ui.unsorted_files_view.setColumnWidth(1,400)
        self.ui.unsorted_files_view.setColumnWidth(2,250)
        self.ui.unsorted_files_view.setColumnWidth(3,250)
        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Interactive)
        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(1, QtGui.QHeaderView.Interactive)
        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(2, QtGui.QHeaderView.Interactive)
        self.ui.unsorted_files_view.horizontalHeader().setResizeMode(3, QtGui.QHeaderView.Interactive)
Exemplo n.º 5
0
    def __init__(self, fileName='', parent=None):
        super(MainPseWindow, self).__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        layout = QHBoxLayout()  # horizontal box layout

        self.view = MyQGraphicsView(self)
        self.diagram = Diagram(self)  # Diagram is QGraphicsScene
        self.view.setScene(self.diagram)  # set scene to the view

        self.view.setSceneRect(QRectF(-2000, -2000, 4000, 4000))
        self.view.centerOn(QPointF(0, 0))  # pociatocna poloha
        # vyvolanie mouseMoveEvent pri kazdom pohybe mysi
        self.view.setMouseTracking(True)

        # self.view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)

        layout.addWidget(self.view)

        self.widget = QWidget()
        self.widget.setLayout(layout)
        self.widget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setCentralWidget(self.widget)

        self.widget.customContextMenuRequested.connect(self.createContextMenu)

        self.fileName = fileName  # inicializacia diagramu pri zadanom mene diagramu
        if self.fileName == '':
            self.setWindowTitle('Untitled.pse')
        else:
            self.diagram.diagramLoad(self.fileName)
            self.setWindowTitle(self.fileName)

        self.setWindowIcon(QIcon('./icons/ikona_pse_128x128.png'))

        self.simEngine = None

        self.recentFileActs = []
        self.init_recent_files()

        self.setStatusBar(QStatusBar(self))
        self.lib_win = None  # Liblary window
Exemplo n.º 6
0
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.canvas.paintEvent = self.on_canvas_paint_event
        self.ui.canvas.mouseReleaseEvent = self.on_canvas_mouse_release_event
        self.ui.canvas.mouseMoveEvent = self.on_canvas_mouse_move_event
        self.ui.scrollArea.resizeEvent = self.on_scroll_area_resize_event

        self.ui.actionZoomIn.triggered.connect(self.on_action_zoom_in)
        self.ui.actionZoomOut.triggered.connect(self.on_action_zoom_out)
        self.ui.actionPoints.triggered.connect(self.on_action_points)
        self.ui.actionPointPoint.triggered.connect(self.on_action_point_point)
        self.ui.actionLineLine.triggered.connect(self.on_action_line_line)
        self.ui.actionLinePoint.triggered.connect(self.on_action_line_point)
        self.ui.actionPointPointLine.triggered.connect(
            self.on_action_point_point_line)
        self.ui.actionLinePointLine.triggered.connect(
            self.on_action_line_point_line)
        self.ui.actionValleyFold.triggered.connect(self.on_action_valley_fold)
        self.ui.actionExecuteFold.triggered.connect(
            self.on_action_execute_fold)

        self.ui.canvas.setMouseTracking(True)

        self.zoom = 1

        points = [
            geo.Point(0, 0),
            geo.Point(0, 1),
            geo.Point(1, 1),
            geo.Point(1, 0)
        ]
        polygon = geo.Polygon(points)
        self.sheet = paper.Sheet(polygon)
        self.highlight = None
        self.selected = []
        self.lines = []
        self.intersections = []
        self.fold = None
        self.update_actions()
Exemplo n.º 7
0
class MainPseWindow(QMainWindow):
    '''
    @if English

    Main application window.

    @endif

    @if Slovak

    Hlavne okno aplikacie.

    Ovladacie klavesy a skratky editora diagramov.

    ESC - Cancel action
    DEL - Delete selected component or net
    C   - Copy component
    M   - Move
    N   - Add net
    R   - Rotate right
    L   - Rotate left

    CTRL+1 	Start simulatora / generatora
    CTRL+2	Stop simulatora
    CTRL+3	Stop simulatora a reset komponentov

    @endif
    '''
    def __init__(self, fileName='', parent=None):
        super(MainPseWindow, self).__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        layout = QHBoxLayout()  # horizontal box layout

        self.view = MyQGraphicsView(self)
        self.diagram = Diagram(self)  # Diagram is QGraphicsScene
        self.view.setScene(self.diagram)  # set scene to the view

        self.view.setSceneRect(QRectF(-2000, -2000, 4000, 4000))
        self.view.centerOn(QPointF(0, 0))  # pociatocna poloha
        # vyvolanie mouseMoveEvent pri kazdom pohybe mysi
        self.view.setMouseTracking(True)

        # self.view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)

        layout.addWidget(self.view)

        self.widget = QWidget()
        self.widget.setLayout(layout)
        self.widget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setCentralWidget(self.widget)

        self.widget.customContextMenuRequested.connect(self.createContextMenu)

        self.fileName = fileName  # inicializacia diagramu pri zadanom mene diagramu
        if self.fileName == '':
            self.setWindowTitle('Untitled.pse')
        else:
            self.diagram.diagramLoad(self.fileName)
            self.setWindowTitle(self.fileName)

        self.setWindowIcon(QIcon('./icons/ikona_pse_128x128.png'))

        self.simEngine = None

        self.recentFileActs = []
        self.init_recent_files()

        self.setStatusBar(QStatusBar(self))
        self.lib_win = None  # Liblary window

    def createContextMenu(self):
        '''create and show context menu for component'''
        menu = QMenu(self)
        menu.addAction(self.ui.ActionEditComponent)
        menu.addSeparator()
        menu.addAction(self.ui.ActionRotateLeftComponent)
        menu.addAction(self.ui.ActionRotateRightComponent)
        menu.addSeparator()
        menu.addAction(self.ui.ActionFlipHorizontalComponent)
        menu.addAction(self.ui.ActionFlipVerticalComponent)
        menu.exec_(QCursor.pos())

    def _setGridAction(self, action):
        '''set diagram grid according to action data'''
        grid_type = action.data()
        self.diagram.setGrid(grid_type)  # hide

    def _snapGrid(self, checked):
        '''set/unset snapping on the grid, according action button'''
        self.diagram.snapOnGrid = checked

    def saveDiagram(self):
        '''!
        @if English

        @endif

        @if Slovak

        Uloženie diagramu.

        V prípade nezadaného mena vyvolá štandardný dialóg pre zadanie mena a cesty
        a uloženie diagramu do súboru.

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        # Reset vsetkych komponentov, zmazanie poli v hodnotach parametrov (ukladali by sa do suboru)
        for comp in self.diagram.componentList:
            comp.sim(SIM_RESET, 0, 0, 0)

        if self.fileName == '':
            data = QFileDialog.getSaveFileName(self,
                                               'Save',
                                               '..',
                                               filter='*.pse')
            self.fileName = data[0]

        # kontrola na nezadane meno suboru
        if self.fileName != '':

            if self.fileName.endswith('.pse') is False:
                self.fileName = self.fileName + '.pse'

            self.diagram.diagramSave(self.fileName)
            self.setWindowTitle(self.fileName)

    def saveAsDiagram(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        # Reset vsetkych komponentov, zmazanie poli v hodnotach parametrov (ukladali by sa do suboru)
        for comp in self.diagram.componentList:
            comp.sim(SIM_RESET, 0, 0, 0)

        data = QFileDialog.getSaveFileName(self,
                                           'Save As',
                                           '..',
                                           filter='*.pse')
        self.fileName = data[0]

        if self.fileName != '':
            self.fileName = self.fileName.replace('.txt', '.pse')

            if self.fileName.endswith('.pse') is False:
                self.fileName = self.fileName + '.pse'

            self.diagram.diagramSave(self.fileName)
            self.setWindowTitle(self.fileName)

    def openDiagramDialog(self):
        self.diagram.mode = MODE.MOVE

        filename = QFileDialog.getOpenFileName(self,
                                               'Open',
                                               '..',
                                               filter='*.txt *.pse')
        if isinstance(filename, tuple):
            filename = filename[0]  # cut the filter
        if filename:
            self.loadDiagram(filename)

    def loadDiagram(self, filename):
        if self.fileName != '':
            self.diagram.deleteAll()

        self.fileName = filename
        self.diagram.diagramLoad(filename)
        self.setWindowTitle(filename)
        self.add_to_recent(filename)

    def exportImage(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE

        fileName = QFileDialog.getSaveFileName(self,
                                               'Save image',
                                               '..',
                                               filter='*.png')
        fn = fileName[0]

        if fn is not None:
            if not fn.endswith('.png'):
                fn = fn + '.png'

            if six.PY2:
                geometry = self.view.viewport().geometry()
                rect = self.view.mapToScene(geometry).boundingRect()
                pixMap = QPixmap.grabWidget(self.view,
                                            x=0,
                                            y=0,
                                            width=rect.width(),
                                            height=rect.height())
            else:
                pixMap = self.view.grab()
            pixMap.save(fn)

    def simStart(self):
        '''!
        @if English

        @endif

        @if Slovak

        Spustenie simulacie.

        Funkcia vytvori objekt simulatora a spusti simulaciu. Na zaciatku simulacie
        su reinicializovane zoznamy prepojeni a komponentov. V pripade prebiehajucej
        simulacie sa simulacia restartuje.

        @todo simulacia viacerych diagramov spojenie zoznamov komponentov a prepojeni

        @endif
        '''
        self.diagram.mode = MODE.SIMULATION

        if self.simEngine:
            self.simEngine.stopSimulation()

        self.simEngine = SimulatorEngine(self.diagram)
        self.simEngine.startSimulation()

        return self.simEngine

    def simStop(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        if self.simEngine is not None:
            self.simEngine.stopSimulation()
            time.sleep(0.3)  # cakanie na bezpecne ukoncenie threadu
            self.simEngine = None

        self.diagram.mode = MODE.MOVE

    def simReset(self):
        """!
        @if English

        @endif

        @if Slovak

        Zastavenie prebiehajucej simulacie a reset vsetkych komponentov.

        @endif
        """
        self.diagram.mode = MODE.MOVE

        # 1. zastavenie simulacie
        if self.simEngine is not None:
            self.simEngine.stopSimulation()
            time.sleep(0.3)  # cakanie na bezpecne ukoncenie threadu
            self.simEngine = None

        # 2. reset vsetkych komponentov, prip. re-inicializacia terminalov
        for comp in self.diagram.componentList:
            comp.sim(SIM_RESET, 0, 0, 0)

    def newDiagramWindow(self):
        '''!
        @if English

        @endif

        @if Slovak

        Funkcia otvorí nové okno pre diagram.

        @endif
        '''
        self.diagram.mode = MODE.MOVE

        self.newWindow = MainPseWindow('')
        self.newWindow.setGeometry(120, 120, 800, 500)
        self.newWindow.show()

    def newDiagram(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        # @todo - v pripade existujuceho diagramu dialog o ulozeni diagramu ...
        # ukoncenie simulacie
        self.simReset()

        # zmazanie vsetkych komponentov
        self.diagram.deleteAll()

        self.fileName = ''
        self.setWindowTitle('Untitled.pse')

    def rotateLeft(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.rotateComponentLeft()

        self.diagram.mode = MODE.MOVE

    def rotateRight(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.rotateComponentRight()
        self.diagram.mode = MODE.MOVE

    def flipHorizontal(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        self.diagram.flipComponentHorizontal()

    def flipVertical(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        self.diagram.flipComponentVertical()

    def delComponent(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE

        for item in self.diagram.selectedItems():
            self.diagram.deleteComponent(item)
        self.diagram.update()

    def move(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE
        print('mode move')

    def frontComponent(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        pass

    def backComponent(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        pass

    def addNet(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.ADD_NEW_NET

    def delNet(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        for net in self.diagram.netList:
            if net.isActive is True:
                self.diagram.deleteNet(net)

    def selNet(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.SELECT_NET

    def addVertex(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.INSERT_VERTEX

    def delVertex(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.DELETE_VERTEX

    def moveVertex(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.MOVE

    def addConnection(self):
        '''!
        @if English

        @endif

        @if Slovak

        @endif
        '''
        self.diagram.mode = MODE.ADD_JUNCTION

    def about(self):
        '''show about dialog'''
        s = "The <b>pse</b> is simple python simulator and block editor<br>" \
            "<br>Project of Research Centre University of Zilina<br>" \
            "Zilina, Slovak Republic<br>" \
            "<b>E-mail</b> [email protected]<br>" \
            "<b>Version</b> 151214_0.11<br>"
        QMessageBox.about(self, "About pse", s)

    def editComponentProperties(self):
        '''Open Component Properties dialog on active component'''
        comp = self.diagram.activeComponent

        if not isinstance(comp, Component):
            LOG.debug('Cannot edit: %s' % comp)
            return

        if comp:
            # vypocet polohy okna pre editovanie vlastnosti komponentu
            # okno sa nachadza v blizkosti polohy komponentu
            winPos = self.view.mapFromScene(
                QPoint(comp.position.x(), comp.position.y())) + self.pos()
            w = CompProperties(comp, winPos, self)
            w.show()

        self.diagram.mode = MODE.MOVE

    def closeEvent(self, event):
        '''!
        @if English

        @endif

        @if Slovak

        Ukoncenie aplikacie.

        Pri ukonceni aplikacie sa zastavi prebiehajuca simulacia.

        @todo - kontrola na neulozeny subor

        @endif
        '''

        reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
                                     QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            # ukoncenie simulacie
            self.simReset()

            # zmazanie vsetkych komponentov a ukoncenie refresovacieho threadu
            self.diagram.deleteAll()
            self.diagram.stopRefresh()
            if self.lib_win:
                self.lib_win.close()  # close liblary
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, event):
        key = event.key()

        if key == Qt.Key_Escape:
            print('>>> Key event - ESC - Cancel action')
            self.diagram.cancelAction()

        elif key == Qt.Key_C:
            print('>>> Key event - C - Copy action')
            self.diagram.copyComponent()

        elif key == Qt.Key_M:
            print('>>> Key event - M - Move ')
            self.move()

        elif key == Qt.Key_N:
            print('>>> Key event - N - Add net ')
            self.addNet()

        elif key == Qt.Key_R:
            print('>>> Key event - R - Rotate right')
            self.diagram.rotateComponentRight()

        elif key == Qt.Key_L:
            print('>>> Key event - L - Rotate left')
            self.diagram.rotateComponentLeft()

        elif key == Qt.Key_Q:
            print('>>> Key event - Q - Component list dump')
            for comp in self.diagram.componentList:
                print(comp)

        elif key == Qt.Key_W:
            print('>>> Key event - W - Net list dump')
            for net in self.diagram.netList:
                print(net)

        elif key == Qt.Key_Delete:
            print('>>> Key event - DEL - Delete')
            for item in self.diagram.selectedItems():
                if isinstance(item, Component):
                    self.diagram.deleteComponent(item)

                elif isinstance(item, Net):
                    self.diagram.deleteNet(item)

        self.diagram.update()

    def init_recent_files(self):
        '''inicialization of File->Recent'''
        for _ in range(MAX_RECENT):
            act = QAction(self, visible=False, triggered=self.__openRecentFile)
            self.ui.recent.addAction(act)
            self.recentFileActs.append(act)
        self._updateRecentFileActions()

    def _updateRecentFileActions(self):
        ''' '''
        settings = QSettings("PSE", 'data')
        recent = settings.value("recent", defaultValue=[])
        numRecentFiles = min(len(recent), MAX_RECENT)

        for i in range(numRecentFiles):
            path = recent[i]
            filename = os.path.basename(path)
            text = "&%d  %s" % (i + 1, filename)
            act = self.recentFileActs[i]
            act.setText(text)
            act.setData(path)
            act.setVisible(True)
            act.setStatusTip('%s' % path)
            icon = QIcon('./icons/ikona_pse_128x128.png')
            act.setIcon(icon)

    def add_to_recent(self, filename):
        '''remember current file to the recent files '''
        settings = QSettings("PSE", 'data')
        recent = settings.value("recent", defaultValue=[])
        try:
            recent.remove(filename)
        except ValueError:
            pass
        recent.insert(0, filename)
        settings.setValue('recent', recent)
        settings.sync()
        self._updateRecentFileActions()

    def __openRecentFile(self):
        '''open choosed diagram from recent files'''
        action = self.sender()
        filename = str(action.data())
        self.loadDiagram(filename)

    def show_libwindow(self):
        '''Show liblary window'''
        if not self.lib_win:
            self.lib_win = Library()
            self.lib_win.setGeometry(20, 20, 400, 500)
        self.lib_win.show()
Exemplo n.º 8
0
    if new_dir == "":
        return
    else:
        if ui.tran_data_file_text.text() == new_dir:
            return
        else:
            ui.tran_data_file_text.setText(new_dir)
            ui.textBrowser.append("发射文件路径 has been changed to: " + new_dir)
            set_tran_data_file(ui)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    dispaly_all(ui)
    ui.tran_address_text.editingFinished.connect(partial(set_tran_address, ui))
    ui.rece_address_text.editingFinished.connect(partial(set_rece_address, ui))
    ui.GNUradio_file_text.editingFinished.connect(
        partial(set_GNUradio_file, ui))
    ui.data_file_text.editingFinished.connect(partial(set_data_file, ui))
    ui.tran_data_file_text.editingFinished.connect(
        partial(set_tran_data_file, ui))
    ui.tran_model_box.currentIndexChanged.connect(partial(set_tran_model, ui))
    ui.tran_kind_box.currentIndexChanged.connect(partial(set_tran_kind, ui))
    ui.rece_kind_box.currentIndexChanged.connect(partial(set_rece_kind, ui))
    ui.f_tran_ad_btn.clicked.connect(partial(find_tran_address, ui))
    ui.f_rece_ad_btn.clicked.connect(partial(find_rece_address, ui))
Exemplo n.º 9
0
    def __init__(self):
        QMainWindow.__init__(self)

        # This is always the same
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
Exemplo n.º 10
0
class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        # This is always the same
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

    def add_file(self):
        """Add files or directories to the list of files/directories"""
        file_dialog = QFileDialog(self)
        if file_dialog.exec_():
            filenames = file_dialog.selectedFiles()
            self.ui.listWidget.addItems(filenames)
            self.ui.encryptButton.setEnabled(True)

    def remove_file(self):
        """Removes selected files (addresses) from the list"""
        listWidget = self.ui.listWidget
        selected = listWidget.selectedItems()
        for item in selected:
            row = listWidget.row(item)
            listWidget.takeItem(row)
            del item
        if listWidget.count() == 0:
            # if list is empty, remove and encrypt buttons disabled
            self.ui.removeButton.setEnabled(False)
            self.ui.encryptButton.setEnabled(False)

    def selection_changed(self):
        """ Triggered when there is a change in selection in the list
            Item selected/deselected in the list.
        """
        listWidget = self.ui.listWidget
        if listWidget.count() > 0:
            self.ui.removeButton.setEnabled(True)
        else:
            self.ui.removeButton.setEnabled(False)

    def encrypt(self):
        """Implementation of UI's "Encrypt" button function"""
        listWidget = self.ui.listWidget
        # open a dialog to choose/create file that will be our encrypted file
        filter = 'Encrypted (*.encrypted)'
        save_file = QFileDialog.getSaveFileName(self,
                                                'Save encrypted file',
                                                filter=filter)[0]
        tempfile = save_file + ".tmp"
        if save_file:
            # Making a tar archive from all files in the list and save tar as
            # chosen by user in file dialog
            with tarfile.open(tempfile, "w") as tar:
                for i in range(listWidget.count()):
                    item = listWidget.item(i).text()
                    tar.add(item, split(item)[1])
            # Getting password(key) for encryption
            pass_dialog = PasswordDlg(self)
            if pass_dialog.exec_():
                password = pass_dialog.password()
                cipher = MyCipher(str(password), save_file)
                if cipher.encrypt():
                    self.message_box("Successful Encryption!")
                    os.remove(tempfile)

    def browse(self):
        self.encrypted_file = QFileDialog.getOpenFileName()[0]
        self.ui.lineEdit.setText(self.encrypted_file)

    def text_changed(self):
        if self.ui.lineEdit.text():
            self.ui.decryptButton.setEnabled(True)
        else:
            self.ui.decryptButton.setEnabled(False)

    def decrypt(self):
        """Implementation of UI's "Decrypt" button function"""
        pass_dialog = PasswordDlg(self)
        infile = self.ui.lineEdit.text()
        if not os.path.isfile(infile):
            self.message_box("File not found!")
            return
        if pass_dialog.exec_():
            password = pass_dialog.password()
            cipher = MyCipher(password, infile)
            outfile = cipher.decrypt()
            if outfile:
                dir, fname = split(outfile)
                prefix = fname.rsplit('.tar', 1)[0]+' '
                outdir = tempfile.mkdtemp(prefix=prefix, dir=dir)
                with tarfile.open(outfile, 'r') as tar:
                    tar.extractall(outdir)
                os.remove(outfile)
                self.message_box("Successful Decryption!")

    def message_box(self, text, type=BOXTYPE.SUCCESS):
        msgBox = QMessageBox()
        msgBox.setText(text)
        if type == BOXTYPE.SUCCESS:
            pixmap = QtGui.QPixmap(":/icon/image/check.png")
        elif type == BOXTYPE.ERROR:
            pixmap = QtGui.QPixmap(":/icon/image/delete.png")
        msgBox.setIconPixmap(pixmap)
        msgBox.exec_()
Exemplo n.º 11
0
class Window(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.canvas.paintEvent = self.on_canvas_paint_event
        self.ui.canvas.mouseReleaseEvent = self.on_canvas_mouse_release_event
        self.ui.canvas.mouseMoveEvent = self.on_canvas_mouse_move_event
        self.ui.scrollArea.resizeEvent = self.on_scroll_area_resize_event

        self.ui.actionZoomIn.triggered.connect(self.on_action_zoom_in)
        self.ui.actionZoomOut.triggered.connect(self.on_action_zoom_out)
        self.ui.actionPoints.triggered.connect(self.on_action_points)
        self.ui.actionPointPoint.triggered.connect(self.on_action_point_point)
        self.ui.actionLineLine.triggered.connect(self.on_action_line_line)
        self.ui.actionLinePoint.triggered.connect(self.on_action_line_point)
        self.ui.actionPointPointLine.triggered.connect(
            self.on_action_point_point_line)
        self.ui.actionLinePointLine.triggered.connect(
            self.on_action_line_point_line)
        self.ui.actionValleyFold.triggered.connect(self.on_action_valley_fold)
        self.ui.actionExecuteFold.triggered.connect(
            self.on_action_execute_fold)

        self.ui.canvas.setMouseTracking(True)

        self.zoom = 1

        points = [
            geo.Point(0, 0),
            geo.Point(0, 1),
            geo.Point(1, 1),
            geo.Point(1, 0)
        ]
        polygon = geo.Polygon(points)
        self.sheet = paper.Sheet(polygon)
        self.highlight = None
        self.selected = []
        self.lines = []
        self.intersections = []
        self.fold = None
        self.update_actions()

    def canvas_size(self):
        return min(self.ui.scrollArea.width(),
                   self.ui.scrollArea.height()) * self.zoom

    def point_to_window(self, point):
        size = self.canvas_size()
        return QtCore.QPoint(MARGIN + point.x * (size - 2 * MARGIN),
                             MARGIN + point.y * (size - 2 * MARGIN))

    def window_to_point(self, point):
        size = self.canvas_size()
        return geo.Point((point.x() - MARGIN) / (size - 2 * MARGIN),
                         (point.y() - MARGIN) / (size - 2 * MARGIN))

    def selection_threshold(self):
        return SELECTION_THRESHOLD / self.canvas_size()

    def find_point_near(self, mouse_point):
        threshold = self.selection_threshold()

        for point in self.sheet.points:
            distance2 = (mouse_point - point).magnitude2()
            if distance2 <= threshold * threshold:
                return point

        for point in self.intersections:
            distance2 = (mouse_point - point).magnitude2()
            if distance2 <= threshold * threshold:
                return point

        return None

    def find_line_near(self, mouse_point):
        found_line = None
        threshold = self.selection_threshold()
        for segment in self.sheet.segments:
            line = geoutil.line.from_segment(segment)
            if geoutil.line.distance_to_point(
                    line, mouse_point
            ) <= threshold and geoutil.segment.is_point_within(
                    segment, mouse_point):
                found_line = line
                break

        if not found_line:
            for line in self.lines:
                if geoutil.line.distance_to_point(line,
                                                  mouse_point) <= threshold:
                    found_line = line
                    break

        return found_line

    def on_canvas_paint_event(self, event):
        painter = QtGui.QPainter(self.ui.canvas)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        def draw_segment(segment):
            draw_points = [
                self.point_to_window(point) for point in segment.points()
            ]
            painter.drawLine(*draw_points)

        def draw_point(point):
            painter.drawEllipse(self.point_to_window(point), POINT_SIZE,
                                POINT_SIZE)

        def draw_line(line):
            min = self.window_to_point(QtCore.QPoint(0, 0))
            max = self.window_to_point(
                QtCore.QPoint(self.ui.canvas.width(), self.ui.canvas.height()))
            if abs(line.normal.x) > abs(line.normal.y):
                minline = geoutil.line.from_point_normal(min, geo.Vector(0, 1))
                maxline = geoutil.line.from_point_normal(
                    max, geo.Vector(0, -1))
            else:
                minline = geoutil.line.from_point_normal(min, geo.Vector(1, 0))
                maxline = geoutil.line.from_point_normal(
                    max, geo.Vector(-1, 0))

            minpoint = geoutil.line.intersect(line, minline)
            maxpoint = geoutil.line.intersect(line, maxline)
            points = [minpoint, maxpoint]
            draw_points = [self.point_to_window(point) for point in points]
            painter.drawLine(*draw_points)

        def draw_polygon(polygon):
            draw_points = [
                self.point_to_window(point) for point in polygon.points
            ]
            painter.drawPolygon(draw_points)

        pen = QtGui.QPen(EDGE_COLOR, LINE_WIDTH, Qt.SolidLine, Qt.SquareCap,
                         Qt.MiterJoin)
        painter.setPen(pen)
        for layer in self.sheet.layers:
            for facet in layer.facets:
                brush = QtGui.QBrush(PAPER_COLORS[facet.parity])
                painter.setBrush(brush)
                draw_polygon(facet.polygon)

        highlight = self.highlight
        if highlight:
            if highlight in self.selected or self.num_selected(
                    type(highlight)) == 2:
                highlight = None

        pen = QtGui.QPen(LINE_COLOR, LINE_WIDTH, Qt.SolidLine, Qt.SquareCap,
                         Qt.MiterJoin)
        painter.setPen(pen)
        for line in self.lines:
            draw_line(line)

        pen = QtGui.QPen(FOLD_COLOR, FOLD_WIDTH, Qt.DashLine, Qt.SquareCap,
                         Qt.MiterJoin)
        painter.setPen(pen)
        if self.fold:
            draw_line(self.fold)
            line = geoutil.line.perpendicular(self.fold, geo.Point(0.5, 0.5))
            point = self.point_to_window(
                geoutil.line.intersect(line, self.fold))
            vec = QtCore.QPoint(self.fold.normal.x * 20,
                                self.fold.normal.y * 20)
            p = geoutil.vector.perpendicular(self.fold.normal)
            perp_vec = QtCore.QPoint(p.x * 5, p.y * 5)
            norm_vec = QtCore.QPoint(self.fold.normal.x * 5,
                                     self.fold.normal.y * 5)
            pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 2, Qt.SolidLine,
                             Qt.SquareCap, Qt.MiterJoin)
            painter.setPen(pen)
            painter.drawLine(point - vec, point + vec)
            painter.drawLine(point + vec, point + vec - norm_vec - perp_vec)
            painter.drawLine(point + vec, point + vec - norm_vec + perp_vec)

        idx = 0
        for selected in self.selected:
            if not isinstance(selected, geo.Line):
                continue
            pen = QtGui.QPen(SELECTED_LINE_COLORS[idx], LINE_WIDTH_SELECTED,
                             Qt.SolidLine, Qt.SquareCap, Qt.MiterJoin)
            painter.setPen(pen)
            draw_line(selected)
            idx += 1

        idx = 0
        painter.setPen(Qt.NoPen)
        for selected in self.selected:
            if not isinstance(selected, geo.Point):
                continue
            brush = QtGui.QBrush(SELECTED_POINT_COLORS[idx])
            painter.setBrush(brush)
            draw_point(selected)
            idx += 1

        if highlight:
            if isinstance(highlight, geo.Line):
                pen = QtGui.QPen(HIGHLIGHT_COLOR, LINE_WIDTH_SELECTED,
                                 Qt.SolidLine, Qt.SquareCap, Qt.MiterJoin)
                painter.setPen(pen)
                draw_line(highlight)

            elif isinstance(highlight, geo.Point):
                brush = QtGui.QBrush(HIGHLIGHT_COLOR)
                painter.setBrush(brush)
                painter.setPen(Qt.NoPen)
                draw_point(highlight)

    def num_selected(self, type):
        count = 0
        for selected in self.selected:
            if isinstance(selected, type):
                count += 1
        return count

    def on_canvas_mouse_release_event(self, event):
        mouse_point = self.window_to_point(event.pos())
        found = False

        if self.fold:
            line = geoutil.line.perpendicular(self.fold, geo.Point(0.5, 0.5))
            point = geoutil.line.intersect(line, self.fold)
            threshold = self.selection_threshold()
            if (mouse_point - point).magnitude2() < threshold * threshold:
                self.fold = geo.Line(-self.fold.normal, -self.fold.offset)
                found = True

        if not found:
            if self.highlight:
                if self.highlight in self.selected:
                    self.selected.remove(self.highlight)
                else:
                    if self.num_selected(type(self.highlight)) < 2:
                        self.selected.append(self.highlight)
                        self.highlight = None
            else:
                self.selected.clear()

        self.ui.canvas.update()
        self.update_actions()

    def on_canvas_mouse_move_event(self, event):
        mouse_point = self.window_to_point(event.pos())
        highlight = self.find_point_near(mouse_point)
        if not highlight:
            highlight = self.find_line_near(mouse_point)

        if highlight != self.highlight:
            self.highlight = highlight
            self.ui.canvas.update()

    def on_scroll_area_resize_event(self, event):
        self.resize_canvas()

    def resize_canvas(self):
        size = self.canvas_size()

        hmax = self.ui.scrollArea.horizontalScrollBar().maximum()
        hvalue = self.ui.scrollArea.horizontalScrollBar().value()
        vmax = self.ui.scrollArea.verticalScrollBar().maximum()
        vvalue = self.ui.scrollArea.verticalScrollBar().value()
        x = hvalue / hmax if hmax else 0.5
        y = vvalue / vmax if vmax else 0.5

        self.ui.canvas.setMinimumSize(QtCore.QSize(size, size))
        self.ui.canvas.setMaximumSize(QtCore.QSize(size, size))

        hmax = self.ui.scrollArea.horizontalScrollBar().maximum()
        vmax = self.ui.scrollArea.verticalScrollBar().maximum()

        self.ui.scrollArea.horizontalScrollBar().setValue(x * hmax)
        self.ui.scrollArea.verticalScrollBar().setValue(y * vmax)

    def update_actions(self):
        self.ui.actionPoints.setEnabled(
            self.num_selected(geo.Point) == 2
            and self.num_selected(geo.Line) == 0)
        self.ui.actionPointPoint.setEnabled(
            self.num_selected(geo.Point) == 2
            and self.num_selected(geo.Line) == 0)
        self.ui.actionLineLine.setEnabled(
            self.num_selected(geo.Point) == 0
            and self.num_selected(geo.Line) == 2)
        self.ui.actionLinePoint.setEnabled(
            self.num_selected(geo.Point) == 1
            and self.num_selected(geo.Line) == 1)
        self.ui.actionPointPointLine.setEnabled(
            self.num_selected(geo.Point) == 2
            and self.num_selected(geo.Line) == 1)
        self.ui.actionLinePointLine.setEnabled(
            self.num_selected(geo.Point) == 1
            and self.num_selected(geo.Line) == 2)
        self.ui.actionValleyFold.setEnabled(
            self.num_selected(geo.Point) == 0
            and self.num_selected(geo.Line) == 1 and not self.fold)
        self.ui.actionExecuteFold.setEnabled(self.fold is not None)

    def add_lines(self, lines):
        for line in lines:
            for segment in self.sheet.segments:
                point = geoutil.segment.intersect_line(segment, line)
                if point:
                    self.intersections.append(point)

            for other_line in self.lines:
                point = geoutil.line.intersect(line, other_line)
                if point:
                    self.intersections.append(point)

        self.lines.extend(lines)
        self.update_actions()
        self.ui.canvas.update()

    def add_line(self, line):
        self.add_lines([line])

    def on_action_zoom_in(self):
        self.zoom *= ZOOM_INCREMENT
        self.resize_canvas()

    def on_action_zoom_out(self):
        self.zoom /= ZOOM_INCREMENT
        self.resize_canvas()

    def on_action_points(self):
        line = geoutil.huzita_justin.O1(self.selected[0], self.selected[1])
        self.selected.clear()
        self.add_line(line)

    def on_action_point_point(self):
        line = geoutil.huzita_justin.O2(self.selected[0], self.selected[1])
        self.selected.clear()
        self.add_line(line)

    def on_action_line_line(self):
        lines = geoutil.huzita_justin.O3(self.selected[0], self.selected[1])
        if lines:
            self.selected.clear()
            self.add_lines(lines)

    def on_action_line_point(self):
        for selected in self.selected:
            if isinstance(selected, geo.Point):
                point = selected
            elif isinstance(selected, geo.Line):
                line = selected

        line = geoutil.huzita_justin.O4(point, line)
        self.selected.clear()
        self.add_line(line)

    def on_action_point_point_line(self):
        points = []
        for selected in self.selected:
            if isinstance(selected, geo.Point):
                points.append(selected)
            elif isinstance(selected, geo.Line):
                line = selected

        lines = geoutil.huzita_justin.O5(points[0], points[1], line)
        if lines:
            self.selected.clear()
            self.add_lines(lines)

    def on_action_line_point_line(self):
        lines = []
        for selected in self.selected:
            if isinstance(selected, geo.Point):
                point = selected
            elif isinstance(selected, geo.Line):
                lines.append(selected)

        line = geoutil.huzita_justin.O7(point, lines[0], lines[1])
        if line:
            self.selected.clear()
            self.add_line(line)

    def on_action_valley_fold(self):
        self.fold = self.selected[0]
        self.lines = []
        self.intersections = []
        self.selected.clear()
        self.highlighted = None
        self.update_actions()
        self.ui.canvas.update()

    def on_action_execute_fold(self):
        self.sheet.fold(self.fold)
        self.fold = None
        self.update_actions()
        self.ui.canvas.update()
Exemplo n.º 12
0
    def __init__(self):
        QMainWindow.__init__(self)

        # This is always the same
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
Exemplo n.º 13
0
class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        # This is always the same
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

    def add_file(self):
        """Add files or directories to the list of files/directories"""
        file_dialog = QFileDialog(self)
        if file_dialog.exec_():
            filenames = file_dialog.selectedFiles()
            self.ui.listWidget.addItems(filenames)
            self.ui.encryptButton.setEnabled(True)

    def remove_file(self):
        """Removes selected files (addresses) from the list"""
        listWidget = self.ui.listWidget
        selected = listWidget.selectedItems()
        for item in selected:
            row = listWidget.row(item)
            listWidget.takeItem(row)
            del item
        if listWidget.count() == 0:
            # if list is empty, remove and encrypt buttons disabled
            self.ui.removeButton.setEnabled(False)
            self.ui.encryptButton.setEnabled(False)

    def selection_changed(self):
        """ Triggered when there is a change in selection in the list
            Item selected/deselected in the list.
        """
        listWidget = self.ui.listWidget
        if listWidget.count() > 0:
            self.ui.removeButton.setEnabled(True)
        else:
            self.ui.removeButton.setEnabled(False)

    def encrypt(self):
        """Implementation of UI's "Encrypt" button function"""
        listWidget = self.ui.listWidget
        # open a dialog to choose/create file that will be our encrypted file
        filter = 'Encrypted (*.encrypted)'
        save_file = QFileDialog.getSaveFileName(self,
                                                'Save encrypted file',
                                                filter=filter)[0]
        tempfile = save_file + ".tmp"
        if save_file:
            # Making a tar archive from all files in the list and save tar as
            # chosen by user in file dialog
            with tarfile.open(tempfile, "w") as tar:
                for i in range(listWidget.count()):
                    item = listWidget.item(i).text()
                    tar.add(item, split(item)[1])
            # Getting password(key) for encryption
            pass_dialog = PasswordDlg(self)
            if pass_dialog.exec_():
                password = pass_dialog.password()
                cipher = MyCipher(str(password), save_file)
                if cipher.encrypt():
                    self.message_box("Successful Encryption!")
                    os.remove(tempfile)

    def browse(self):
        self.encrypted_file = QFileDialog.getOpenFileName()[0]
        self.ui.lineEdit.setText(self.encrypted_file)

    def text_changed(self):
        if self.ui.lineEdit.text():
            self.ui.decryptButton.setEnabled(True)
        else:
            self.ui.decryptButton.setEnabled(False)

    def decrypt(self):
        """Implementation of UI's "Decrypt" button function"""
        pass_dialog = PasswordDlg(self)
        infile = self.ui.lineEdit.text()
        if not os.path.isfile(infile):
            self.message_box("File not found!")
            return
        if pass_dialog.exec_():
            password = pass_dialog.password()
            cipher = MyCipher(password, infile)
            outfile = cipher.decrypt()
            if outfile:
                dir, fname = split(outfile)
                prefix = fname.rsplit('.tar', 1)[0] + ' '
                outdir = tempfile.mkdtemp(prefix=prefix, dir=dir)
                with tarfile.open(outfile, 'r') as tar:
                    tar.extractall(outdir)
                os.remove(outfile)
                self.message_box("Successful Decryption!")

    def message_box(self, text, type=BOXTYPE.SUCCESS):
        msgBox = QMessageBox()
        msgBox.setText(text)
        if type == BOXTYPE.SUCCESS:
            pixmap = QtGui.QPixmap(":/icon/image/check.png")
        elif type == BOXTYPE.ERROR:
            pixmap = QtGui.QPixmap(":/icon/image/delete.png")
        msgBox.setIconPixmap(pixmap)
        msgBox.exec_()
Exemplo n.º 14
0
    def __init__(self, parent=None, document = None):
        """ Initialize MainWindow """
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(':img/note64.png'))
        self._preamble = PREAMBLE
        self.offset = 0
        self.docpath = ''
        self.lastpath = HOME
        self.rmdoc = False
        self.displayed_uid = -1
        self.okular_notes = []

        # Toolbar icons
        self.ui.actionOpen.setIcon(QtGui.QIcon.fromTheme("document-open"))
        self.ui.actionExport.setIcon(QtGui.QIcon.fromTheme("document-save-as"))
        self.ui.actionQuit.setIcon(QtGui.QIcon.fromTheme("application-exit"))

        self.ui.actionPreambleEditor.setIcon(QtGui.QIcon.fromTheme(
                                                        "preferences-other"))

        self.ui.actionAbout.setIcon(QtGui.QIcon.fromTheme("help-about"))

        # Toolbar connections
        self.connect(self.ui.actionOpen, QtCore.SIGNAL("triggered()"),
                     self.slot_gui_open)
        self.connect(self.ui.actionExport, QtCore.SIGNAL("triggered()"),
                     self.slot_export)
        self.connect(self.ui.actionQuit, QtCore.SIGNAL("triggered()"),
                     self.close)

        self.connect(self.ui.actionControls,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.controlsWidget.setVisible)
        self.connect(self.ui.actionAnnotationSource,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.annotationSourceDockWidget.setVisible)
        self.connect(self.ui.actionAnnotation,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.annotationDockWidget.setVisible)
        self.connect(self.ui.controlsWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_controls)
        self.connect(self.ui.annotationDockWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_annotation)
        self.connect(self.ui.annotationSourceDockWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_annotation_source)

        self.connect(self.ui.actionAbout, QtCore.SIGNAL("triggered()"),
                     self.slot_about)

        # Document controls
        if PLATFORM == 'Windows':
            self.ui.previousPageButton.setText('Previous')
            self.ui.nextPageButton.setText('Next')
            font_metrics = QtGui.QFontMetrics(QtGui.QFont())
            size_p = font_metrics.size(QtCore.Qt.TextSingleLine, 'Previous')
            size_n = font_metrics.size(QtCore.Qt.TextSingleLine, 'Next')
            self.ui.previousPageButton.setMinimumWidth(size_p.width() + 10)
            self.ui.nextPageButton.setMinimumWidth(size_n.width() + 10)
        else:
            self.ui.previousPageButton.setIcon(QtGui.QIcon.fromTheme("go-previous"))
            self.ui.nextPageButton.setIcon(QtGui.QIcon.fromTheme("go-next"))
        self.ui.controlsWidget.mouseMoveEvent = self.highlight_buttons

        self.offsetWindow = OffsetWindow(self)
        self.connect(self.ui.offsetCheckBox, QtCore.SIGNAL("stateChanged(int)"),
                     self.offsetWindow.slot_open)

        # Search widget
        self.ui.searchWidget = SearchWidget(self.ui.searchDockWidgetContents)
        self.ui.gridLayout_4.addWidget(self.ui.searchWidget, 0, 0, 1, 1)
        self.ui.searchDockWidget.hide()
        self.ui.searchWidget.hide_trigger.connect(self.ui.searchDockWidget.hide)
        self.ui.searchWidget.change_page_trigger.connect(self.ui.pageSpinBox.setValue)
        #self.ui.searchWidget.show_trigger.connect(self.ui.searchDockWidget.show)

        # PDF viewer widget
        self.ui.scrollArea.setMinimumWidth(0)
        self.ui.documentWidget = DocumentWidget(self.ui.scrollArea)
        self.ui.documentWidget.setObjectName("documentWidget")
        self.ui.scrollArea.setBackgroundRole(QtGui.QPalette.Dark)
        self.ui.scrollArea.setWidget(self.ui.documentWidget.ImgLabel)
        self.connect(self.ui.documentWidget.ImgLabel,
                     QtCore.SIGNAL("dropped"), self.slot_load_dropped)
        self.ui.documentWidget.ImgLabel.change_page_trigger.connect(
                                                self.ui.pageSpinBox.setValue)
        self.ui.documentWidget.ImgLabel.change_scale_trigger.connect(
                                                self.ui.scaleSpinBox.setValue)
        self.ui.documentWidget.ImgLabel.show_search_trigger.connect(
                                                self.slot_show_search_widget)
        self.ui.documentWidget.ImgLabel.hide_search_trigger.connect(
                                                self.ui.searchWidget.hide)

        # Connections for PDF viewer
        self.connect(self.ui.previousPageButton, QtCore.SIGNAL("clicked()"),
                     self.slot_prev_page)
        self.connect(self.ui.nextPageButton, QtCore.SIGNAL("clicked()"),
                     self.slot_next_page)
        self.connect(self.ui.pageSpinBox, QtCore.SIGNAL("valueChanged(int)"),
                     self.ui.documentWidget.change_page)
        self.connect(self.ui.scaleSpinBox, QtCore.SIGNAL("valueChanged(double)"),
                    self.ui.documentWidget.set_scale)
        self.connect(self.ui.scaleComboBox,
                     QtCore.SIGNAL("currentIndexChanged(int)"),
                     self.slot_scale)

        # Scroll Widget for annotation
        self.ui.scrollAreaAnnotation = QtGui.QScrollArea(self.ui.annotationDockWidget)
        self.ui.scrollAreaAnnotation.setWidgetResizable(True)
        self.ui.scrollAreaAnnotation.setObjectName("scrollAreaAnnotation")
        self.ui.gridLayoutAnnotationDock.addWidget(self.ui.scrollAreaAnnotation,
                                                0, 0, 1, 1)

        # Beginning note
        self.current_note = Note(WELCOME, self.preamble)

        # Annotation PNG widget
        self.ui.annotationWidget = AnnotationWidget(self.ui.scrollAreaAnnotation,
                                                 self.current_note.icon)
        self.ui.annotationWidget.setObjectName("annotationWidget")

        self.ui.scrollAreaAnnotation.setBackgroundRole(QtGui.QPalette.Light)
        self.ui.scrollAreaAnnotation.setWidget(self.ui.annotationWidget.ImgLabel)
        self.ui.actionAnnotation.toggle()

        # Connections for Annotation widget
        self.connect(self.ui.compileButton, QtCore.SIGNAL("clicked()"),
                     self.slot_force_compile)

        # Annotation Source Widget
        self.ui.annotationSourceTextEdit.setText(WELCOME)
        self.connect(self.ui.documentWidget.ImgLabel.addNoteAction,
                     QtCore.SIGNAL("triggered()"), self.slot_change_note)
        self.connect(self.ui.documentWidget.ImgLabel.editNoteAction,
                     QtCore.SIGNAL("triggered()"), self.slot_change_note)
        #self.connect(self.ui.documentWidget.ImgLabel.removeNoteAction,
                     #QtCore.SIGNAL("triggered()"), self.slot_remove_note)
        self.ui.documentWidget.ImgLabel.remove_trigger.connect(
                                                    self.slot_remove_note)
        self.ui.documentWidget.ImgLabel.toggle_source_trigger.connect(
                                        self.ui.actionAnnotationSource.toggle)
        self.ui.actionAnnotationSource.toggle()

        # Connections for Annotation Source Widget
        self.timer = QtCore.QTimer()
        self.timer.start(3500)
        self.connect(self.timer, QtCore.SIGNAL("timeout()"),
                     self.slot_compile_annotation)
        self.old_text = ''

        # Preamble editor
        self.preambleEditorWindow = PreambleWindow(self)
        self.connect(self.ui.actionPreambleEditor, QtCore.SIGNAL("triggered()"),
                     self.preambleEditorWindow.slot_open)

        # Status bar
        self.ui.documentWidget.ImgLabel.set_clipboard_trigger.connect(
                                                    self.slot_set_status)

        if document is not None:
            self.load_file(document)
Exemplo n.º 15
0
class MainWindow(QtGui.QMainWindow):
    """ Main Window Class """

    add_windows_trigger = QtCore.pyqtSignal(list)

    def __init__(self, parent=None, document = None):
        """ Initialize MainWindow """
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(':img/note64.png'))
        self._preamble = PREAMBLE
        self.offset = 0
        self.docpath = ''
        self.lastpath = HOME
        self.rmdoc = False
        self.displayed_uid = -1
        self.okular_notes = []

        # Toolbar icons
        self.ui.actionOpen.setIcon(QtGui.QIcon.fromTheme("document-open"))
        self.ui.actionExport.setIcon(QtGui.QIcon.fromTheme("document-save-as"))
        self.ui.actionQuit.setIcon(QtGui.QIcon.fromTheme("application-exit"))

        self.ui.actionPreambleEditor.setIcon(QtGui.QIcon.fromTheme(
                                                        "preferences-other"))

        self.ui.actionAbout.setIcon(QtGui.QIcon.fromTheme("help-about"))

        # Toolbar connections
        self.connect(self.ui.actionOpen, QtCore.SIGNAL("triggered()"),
                     self.slot_gui_open)
        self.connect(self.ui.actionExport, QtCore.SIGNAL("triggered()"),
                     self.slot_export)
        self.connect(self.ui.actionQuit, QtCore.SIGNAL("triggered()"),
                     self.close)

        self.connect(self.ui.actionControls,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.controlsWidget.setVisible)
        self.connect(self.ui.actionAnnotationSource,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.annotationSourceDockWidget.setVisible)
        self.connect(self.ui.actionAnnotation,
                     QtCore.SIGNAL("toggled(bool)"),
                     self.ui.annotationDockWidget.setVisible)
        self.connect(self.ui.controlsWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_controls)
        self.connect(self.ui.annotationDockWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_annotation)
        self.connect(self.ui.annotationSourceDockWidget,
                     QtCore.SIGNAL("visibilityChanged(bool)"),
                     self.slot_hide_annotation_source)

        self.connect(self.ui.actionAbout, QtCore.SIGNAL("triggered()"),
                     self.slot_about)

        # Document controls
        if PLATFORM == 'Windows':
            self.ui.previousPageButton.setText('Previous')
            self.ui.nextPageButton.setText('Next')
            font_metrics = QtGui.QFontMetrics(QtGui.QFont())
            size_p = font_metrics.size(QtCore.Qt.TextSingleLine, 'Previous')
            size_n = font_metrics.size(QtCore.Qt.TextSingleLine, 'Next')
            self.ui.previousPageButton.setMinimumWidth(size_p.width() + 10)
            self.ui.nextPageButton.setMinimumWidth(size_n.width() + 10)
        else:
            self.ui.previousPageButton.setIcon(QtGui.QIcon.fromTheme("go-previous"))
            self.ui.nextPageButton.setIcon(QtGui.QIcon.fromTheme("go-next"))
        self.ui.controlsWidget.mouseMoveEvent = self.highlight_buttons

        self.offsetWindow = OffsetWindow(self)
        self.connect(self.ui.offsetCheckBox, QtCore.SIGNAL("stateChanged(int)"),
                     self.offsetWindow.slot_open)

        # Search widget
        self.ui.searchWidget = SearchWidget(self.ui.searchDockWidgetContents)
        self.ui.gridLayout_4.addWidget(self.ui.searchWidget, 0, 0, 1, 1)
        self.ui.searchDockWidget.hide()
        self.ui.searchWidget.hide_trigger.connect(self.ui.searchDockWidget.hide)
        self.ui.searchWidget.change_page_trigger.connect(self.ui.pageSpinBox.setValue)
        #self.ui.searchWidget.show_trigger.connect(self.ui.searchDockWidget.show)

        # PDF viewer widget
        self.ui.scrollArea.setMinimumWidth(0)
        self.ui.documentWidget = DocumentWidget(self.ui.scrollArea)
        self.ui.documentWidget.setObjectName("documentWidget")
        self.ui.scrollArea.setBackgroundRole(QtGui.QPalette.Dark)
        self.ui.scrollArea.setWidget(self.ui.documentWidget.ImgLabel)
        self.connect(self.ui.documentWidget.ImgLabel,
                     QtCore.SIGNAL("dropped"), self.slot_load_dropped)
        self.ui.documentWidget.ImgLabel.change_page_trigger.connect(
                                                self.ui.pageSpinBox.setValue)
        self.ui.documentWidget.ImgLabel.change_scale_trigger.connect(
                                                self.ui.scaleSpinBox.setValue)
        self.ui.documentWidget.ImgLabel.show_search_trigger.connect(
                                                self.slot_show_search_widget)
        self.ui.documentWidget.ImgLabel.hide_search_trigger.connect(
                                                self.ui.searchWidget.hide)

        # Connections for PDF viewer
        self.connect(self.ui.previousPageButton, QtCore.SIGNAL("clicked()"),
                     self.slot_prev_page)
        self.connect(self.ui.nextPageButton, QtCore.SIGNAL("clicked()"),
                     self.slot_next_page)
        self.connect(self.ui.pageSpinBox, QtCore.SIGNAL("valueChanged(int)"),
                     self.ui.documentWidget.change_page)
        self.connect(self.ui.scaleSpinBox, QtCore.SIGNAL("valueChanged(double)"),
                    self.ui.documentWidget.set_scale)
        self.connect(self.ui.scaleComboBox,
                     QtCore.SIGNAL("currentIndexChanged(int)"),
                     self.slot_scale)

        # Scroll Widget for annotation
        self.ui.scrollAreaAnnotation = QtGui.QScrollArea(self.ui.annotationDockWidget)
        self.ui.scrollAreaAnnotation.setWidgetResizable(True)
        self.ui.scrollAreaAnnotation.setObjectName("scrollAreaAnnotation")
        self.ui.gridLayoutAnnotationDock.addWidget(self.ui.scrollAreaAnnotation,
                                                0, 0, 1, 1)

        # Beginning note
        self.current_note = Note(WELCOME, self.preamble)

        # Annotation PNG widget
        self.ui.annotationWidget = AnnotationWidget(self.ui.scrollAreaAnnotation,
                                                 self.current_note.icon)
        self.ui.annotationWidget.setObjectName("annotationWidget")

        self.ui.scrollAreaAnnotation.setBackgroundRole(QtGui.QPalette.Light)
        self.ui.scrollAreaAnnotation.setWidget(self.ui.annotationWidget.ImgLabel)
        self.ui.actionAnnotation.toggle()

        # Connections for Annotation widget
        self.connect(self.ui.compileButton, QtCore.SIGNAL("clicked()"),
                     self.slot_force_compile)

        # Annotation Source Widget
        self.ui.annotationSourceTextEdit.setText(WELCOME)
        self.connect(self.ui.documentWidget.ImgLabel.addNoteAction,
                     QtCore.SIGNAL("triggered()"), self.slot_change_note)
        self.connect(self.ui.documentWidget.ImgLabel.editNoteAction,
                     QtCore.SIGNAL("triggered()"), self.slot_change_note)
        #self.connect(self.ui.documentWidget.ImgLabel.removeNoteAction,
                     #QtCore.SIGNAL("triggered()"), self.slot_remove_note)
        self.ui.documentWidget.ImgLabel.remove_trigger.connect(
                                                    self.slot_remove_note)
        self.ui.documentWidget.ImgLabel.toggle_source_trigger.connect(
                                        self.ui.actionAnnotationSource.toggle)
        self.ui.actionAnnotationSource.toggle()

        # Connections for Annotation Source Widget
        self.timer = QtCore.QTimer()
        self.timer.start(3500)
        self.connect(self.timer, QtCore.SIGNAL("timeout()"),
                     self.slot_compile_annotation)
        self.old_text = ''

        # Preamble editor
        self.preambleEditorWindow = PreambleWindow(self)
        self.connect(self.ui.actionPreambleEditor, QtCore.SIGNAL("triggered()"),
                     self.preambleEditorWindow.slot_open)

        # Status bar
        self.ui.documentWidget.ImgLabel.set_clipboard_trigger.connect(
                                                    self.slot_set_status)

        if document is not None:
            self.load_file(document)

    @property
    def preamble(self):
        return self._preamble
    @preamble.setter
    def preamble(self, preamble):
        self._preamble = preamble
        self.current_note.preamble = preamble
        self.slot_compile_annotation()

    def highlight_buttons(self, event):
        if self.ui.previousPageButton.underMouse():
            self.ui.previousPageButton.setFlat(False)
        else:
            self.ui.previousPageButton.setFlat(True)

        if self.ui.nextPageButton.underMouse():
            self.ui.nextPageButton.setFlat(False)
        else:
            self.ui.nextPageButton.setFlat(True)

    def slot_load_dropped(self, files):
        if self.docpath == '' or files[0].endswith('.xml'):
            self.load_file(files.pop(0))
        windows = []
        for doc in files:
            win = MainWindow(document=doc)
            windows.append(win)
            win.show()
        self.add_windows_trigger.emit(windows)
        #print files

    def slot_set_status(self, text):
        """ Slot to set statusBar with message. """
        self.statusBar().showMessage('Copied "%s" to clipboard.' % 
                                     unicode(text).strip())
    def slot_about(self):
        about_msg = '''
        <p><center><font size="4"><b>Notorius %s</b></font></center></p>
        <p><b>Author</b>: Carlos da Costa</p>
        <p><b>Code at</b>: <a href="https://github.com/cako/notorius">
                                    https://github.com/cako/notorius<a/></p>
        <p><b>License</b>: <a href="http://www.gnu.org/licenses/gpl-3.0.txt">
                                    GNU General Public License version 3</a></p>
                    ''' % VERSION
        QtGui.QMessageBox.about(self, "About me", about_msg)

    def slot_gui_open(self):
        """ Slot for actionOpen. """
        file_filter = "All supported filetypes (*.pdf *.okular *.zip *.xml);;"
        file_filter +=  "PDF files (*.pdf);;"
        file_filter += "Okular (*.okular);;"
        file_filter += "ZIP archive (*.zip);;"
        file_filter += "XML file (*.xml)"
        filename = unicode(
                   QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                    self.lastpath, file_filter))
        self.lastpath = os.path.dirname(filename)
        self.load_file(filename)


    def load_file(self, filename = None):
        def parse_metadata(root):
            notes = {}
            for page in root.find('pageList').findall('page'):
                pg = int(page.attrib['number'])
                annotlist = page.find('annotationList')
                for annot in annotlist.findall('annotation'):
                    if ( annot.attrib['type'] == "1" and
                                        pg <= self.ui.documentWidget.num_pages ):
                        base = annot.find('base')
                        try:
                            author = base.attrib['author']
                        except KeyError:
                            author = ''
                        try:
                            text = base.attrib['contents']
                        except KeyError:
                            text = ''
                        try:
                            cdate = base.attrib['creationDate']
                        except KeyError:
                            cdate = ''
                        try:
                            mdate = base.attrib['modifyDate']
                        except KeyError:
                            mdate = ''
                        try:
                            preamble = base.attrib['preamble']
                        except KeyError:
                            preamble = PREAMBLE
                        try:
                            uname = base.attrib['uniqueName']
                            # notorius-1-0 becomes 0
                            uid = int(uname.rsplit('-')[-1])
                        except KeyError:
                            try:
                                uid = max(notes.keys())
                            except ValueError:
                                uid = 0

                        boundary = base.find('boundary')
                        x = float(boundary.attrib['l'])
                        y = float(boundary.attrib['t'])
                        size = self.ui.documentWidget.Document.page(
                                                        pg).pageSizeF()
                        pos = QtCore.QPointF(x*size.width(),
                                             y*size.height())
                        note = Note(text, preamble, page = pg, pos = pos,
                                    uid = uid)
                        notes[uid] = note
                        note.cdate = datetime.datetime.strptime(cdate, "%Y-%m-%dT%H:%M:%S")
                        note.mdate = datetime.datetime.strptime(mdate, "%Y-%m-%dT%H:%M:%S")
                        note.update()
                    else:
                        self.okular_notes.append(annot)
            return notes
        loaded = False
        if filename:
            self.ui.nextPageButton.setEnabled(True)
            self.ui.previousPageButton.setEnabled(True)
            self.ui.pageSpinBox.setEnabled(True)
            self.ui.offsetCheckBox.setEnabled(True)
            self.ui.offsetCheckBox.setChecked(False)
            self.ui.scaleSpinBox.setEnabled(True)
            self.ui.scaleComboBox.setEnabled(True)
            #file_dir = os.path.dirname(filename)
            self.okular_notes = []
            if filename.endswith(('.zip', '.okular')):
                self.rmdoc = True
                zipf = zipfile.ZipFile(filename, 'r')
                zipf.extractall(TMPDIR)
                # [ 'filename.pdf', 'content.xml', 'metadata.xml' ]
                # becomes [ 'filename.pdf' ] which then becomes 'filename.pdf'
                # then TMPDIR is added.
                # Important! filename can have .okular extension!
                self.docpath = os.path.join(TMPDIR,
                                            [ fl for fl in zipf.namelist() if (
                                            fl.rsplit('.')[1] != 'xml') ][0])
                # Must insert try statement!
                self.ui.documentWidget.load_document(self.docpath)
                loaded = True
                root = xml.parse(os.path.join(TMPDIR, 'metadata.xml')).getroot()
                notes = parse_metadata(root)
                for aux in ['content.xml', 'metadata.xml']:
                    os.remove(os.path.join(TMPDIR, aux))
                self.ui.documentWidget.ImgLabel.notes = notes
                self.ui.documentWidget.update_image()
                self.setWindowTitle('Notorius - %s' %os.path.basename(filename))
                if self.okular_notes:
                    warning = 'Not loading annotations that are '
                    warning += 'not text notes or are out of range.'
                    QtGui.QMessageBox.warning(self, "Warning", warning)
            elif filename.endswith('.xml'):
                if self.docpath == '':
                    QtGui.QMessageBox.warning(self, "Warning",
                                            'You need to load a PDF first!.')
                    loaded = False
                else:
                    self.rmdoc = False
                    root = xml.parse(filename).getroot()
                    self.ui.documentWidget.ImgLabel.notes = parse_metadata(root)
                    self.ui.documentWidget.update_image()
                    loaded = True
                    self.setWindowTitle(
                        'Notorius - %s + %s' % (os.path.basename(self.docpath),
                                                os.path.basename(filename)))
                    if self.okular_notes:
                        warning = 'Not loading annotations that are '
                        warning += 'not text notes or are out of range.'
                        QtGui.QMessageBox.warning(self, "Warning", warning)
            else:
                if not filename.endswith('.pdf'):
                    print "Treating file as pdf!"
                self.rmdoc = False
                self.docpath = filename
                self.ui.documentWidget.load_document(self.docpath)
                self.setWindowTitle('Notorius - %s' %os.path.basename(filename))
                loaded = True

            if loaded:
                self.ui.pageSpinBox.setValue(1)
                self.ui.pageSpinBox.setMinimum(-self.ui.documentWidget.num_pages + 1)
                self.ui.pageSpinBox.setMaximum(self.ui.documentWidget.num_pages)
                self.ui.scaleComboBox.setCurrentIndex(0)
                self.ui.maxPageLabel.setText("of %d" %
                                          self.ui.documentWidget.num_pages)
                self.ui.actionExport.setEnabled(True)
                self.ui.searchWidget.documentWidget = self.ui.documentWidget
                self.statusBar().showMessage('Opened file %s.' % filename)
        else:
            print 'No file to load!'

    def slot_export(self):
        file_dir = os.path.dirname(self.docpath)
        file_base = os.path.basename(self.docpath)
        filt = QtCore.QString()
        filename = unicode(QtGui.QFileDialog.getSaveFileName(self,
            'Save archive as', file_dir,
            "Okular archive (*.okular);;ZIP archive (*.zip);;XML file (*.xml)",
            filt))
        if filename:
            # Create the content.xml file
            if filt != 'XML file (*.xml)':
                content_path = os.path.join(TMPDIR, 'content.xml')
                root = xml.Element('OkularArchive')
                child_files = xml.SubElement(root, 'Files')
                child_doc = xml.SubElement(child_files, 'DocumentFileName')
                child_doc.text = file_base
                child_meta = xml.SubElement(child_files, 'MetadataFileName')
                child_meta.text = 'metadata.xml'
                xml.ElementTree(root).write(content_path)

            # Create the metadata.xml file
            if filt != 'XML file (*.xml)':
                metadata_path = os.path.join(TMPDIR, 'metadata.xml')
            else:
                metadata_path = filename
            root = xml.Element('documentInfo')
            pagelist = xml.SubElement(root, 'pageList')
            notes = self.ui.documentWidget.ImgLabel.notes
            for note in notes.values():
                try:
                    page = [ pg for pg in pagelist if (
                                int(pg.attrib['number']) == note.page) ][0]
                    annotlist = page.find('annotationList')

                except IndexError:
                    page = xml.SubElement(pagelist, 'page')
                    page.set('number', str(note.page))
                    annotlist = xml.SubElement(page, 'annotationList')

                annot = xml.SubElement(annotlist, 'annotation')
                annot.set('type', '1')

                base = xml.SubElement(annot, 'base')
                base.set('creationDate', note.cdate.isoformat()) #BOGUS DATE
                base.set('uniqueName', 'notorius-%d-%d' % (note.page, note.uid))
                base.set('author', USERNAME)
                base.set('contents', note.text)
                base.set('preamble', note.preamble)
                base.set('modifyDate', note.mdate.isoformat()) #BOGUS DATE
                base.set('color', '#ffff00')

                boundary = xml.SubElement(base, 'boundary')
                size = self.ui.documentWidget.Document.page(note.page).pageSizeF()
                posx = note.pos.x()/size.width()
                posy = note.pos.y()/size.height()
                boundary.set('l', str(posx))
                boundary.set('r', str(posx + 0.03)) # "Empirical values"
                boundary.set('b', str(posy + 0.022))
                boundary.set('t', str(posy))

                window = xml.SubElement(base, 'window')
                window.set('width', '0')
                window.set('flags', '-1')
                window.set('title', '')
                window.set('left', '0')
                window.set('height', '0')
                window.set('summary', 'LaTeXNote')
                window.set('top', '0')

                text = xml.SubElement(annot, 'text')
                text.set('icon', 'None')

            # Write okular notes that are not displayed
            for annot in self.okular_notes:
                pg_n = False
                try:
                    pg_n = annot.find('base').attrib['uniqueName'].split('-')[1]
                except IndexError:
                    # Did not find page, ignore
                    pass
                if pg_n:
                    try:
                        page = [ pg for pg in pagelist if (
                                    pg.attrib['number'] == pg_n) ][0]
                        annotlist = page.find('annotationList')

                    except IndexError:
                        page = xml.SubElement(pagelist, 'page')
                        page.set('number', str(note.page))
                        annotlist = xml.SubElement(page, 'annotationList')
                    annotlist.append(annot)


            xml.ElementTree(root).write(metadata_path)

            # Create the archive
            if ( filt == "ZIP archive (*.zip)" and not
                                                filename.endswith('.zip') ):
                filename += '.zip'
            elif ( filt == "Okular archive (*.okular)" and not
                                                filename.endswith('.okular') ):
                filename += '.okular'
            elif ( filt == 'XML file (*.xml)' and not
                                                filename.endswith('.xml') ):
                filename += '.xml'
            if filt != 'XML file (*.xml)':
                zipf = zipfile.ZipFile(filename, 'w')
                zipf.write(self.docpath, file_base)
                for (path, name) in [(content_path, 'content.xml'),
                                     (metadata_path, 'metadata.xml')]:
                    zipf.write(path, name)
                    os.remove(path)

                zipf.close()
            self.statusBar().showMessage('Exported annotations to file %s.'
                                                                    % filename)

    def slot_change_note(self):
        """
        Slot to add or edit note. Replaces current note display in
        annotationSourceTextEdit and annotationWidget with the new note.
        """
        self.ui.annotationSourceDockWidget.show()
        self.ui.actionAnnotationSource.setChecked(True)
        uid = self.ui.documentWidget.ImgLabel.current_uid
        if (self.displayed_uid != -1 and self.displayed_uid != -2):
            text = unicode(self.ui.annotationSourceTextEdit.toPlainText())
            self.current_note.text = text
        self.current_note = self.ui.documentWidget.ImgLabel.notes[uid]
        self.ui.annotationSourceTextEdit.setText(self.current_note.text)
        self.ui.annotationSourceDockWidget.setWindowTitle('Note %d - Source'
                                                        % self.current_note.uid)
        self.ui.annotationDockWidget.setWindowTitle('Note %d - LaTeX'
                                                        % self.current_note.uid)
        self.slot_force_compile()

    def slot_remove_note(self):
        """
        Removes note along with all its files. If the  current note is being
        replaced, blank annotationSourceTextEdit and annotationWidget.
        """
        uid = self.ui.documentWidget.ImgLabel.closest_id
        #print 'Current note: %d' % self.ui.documentWidget.ImgLabel.current_uid
        self.ui.documentWidget.ImgLabel.notes[uid].remove_files()
        self.ui.documentWidget.ImgLabel.notes[uid].remove_png()
        #print 'Main remove note %d' % uid
        if self.ui.documentWidget.ImgLabel.current_uid == uid:
            self.ui.annotationSourceTextEdit.setText('')
            white_pix = QtGui.QPixmap()
            white_pix.fill()
            self.ui.annotationWidget.ImgLabel.setPixmap(white_pix)
            self.ui.documentWidget.ImgLabel.displayed_uid = -2
            self.ui.documentWidget.ImgLabel.current_uid = -2
            self.ui.annotationSourceDockWidget.setWindowTitle('')
            self.ui.annotationDockWidget.setWindowTitle('')
        del self.ui.documentWidget.ImgLabel.notes[uid]
        self.ui.documentWidget.update_image()

    def slot_hide_controls(self):
        """ Slot to hide controls properly and avoid recursion. """
        if self.ui.controlsWidget.isVisible():
            self.ui.actionControls.setChecked(True)
        if self.ui.annotationDockWidget.isHidden():
            self.ui.actionControls.setChecked(False)

    def slot_hide_annotation(self):
        """ Slot to hide annotation properly and avoid recursion. """
        if self.ui.annotationDockWidget.isVisible():
            self.ui.actionAnnotation.setChecked(True)
        if self.ui.annotationDockWidget.isHidden():
            self.ui.actionAnnotation.setChecked(False)

    def slot_hide_annotation_source(self):
        """ Slot to hide annotation source properly and avoid recursion. """
        if self.ui.annotationSourceDockWidget.isVisible():
            self.ui.actionAnnotationSource.setChecked(True)
        if self.ui.annotationSourceDockWidget.isHidden():
            self.ui.actionAnnotationSource.setChecked(False)

    def slot_prev_page(self):
        """ Slot to go to the previous page. """
        self.ui.pageSpinBox.setValue(self.ui.pageSpinBox.value() - 1)

    def slot_next_page(self):
        """ Slot to go to the next page. """
        self.ui.pageSpinBox.setValue(self.ui.pageSpinBox.value() + 1)

    def slot_scale(self, event):
        """ Slot to change the scale. """
        if event == 0:
            self.ui.scaleSpinBox.setEnabled(True)
            self.ui.documentWidget.set_scale(self.ui.scaleSpinBox.value())
        else:
            self.ui.scaleSpinBox.setEnabled(False)
            self.ui.documentWidget.fit_to_width_or_height(event)

    def slot_force_compile(self):
        """ Slot to force compilation through the compileButton. """
        self.old_text = ''
        self.slot_compile_annotation()

    def slot_compile_annotation(self):
        """
        Slot to compile the current annotation by changing annotationWidget's
        ImgLabel's Pixmap to the updated one.
        """
        text = unicode(self.ui.annotationSourceTextEdit.toPlainText())
        if (self.old_text != text and
            self.ui.documentWidget.ImgLabel.current_uid  != -2):
            self.old_text = text
            self.current_note.remove_png()
            self.current_note.text = text
            self.current_note.update()
            self.displayed_uid = self.current_note.uid
            self.ui.annotationWidget.ImgLabel.setPixmap(
                                            self.current_note.icon)

    def slot_show_search_widget(self):
        self.ui.searchDockWidget.show()
        self.ui.searchWidget.searchLineEdit.selectAll()
        self.ui.searchWidget.searchLineEdit.setFocus()

    def keyPressEvent(self, event):
        if self.docpath != '':
            if (event.matches(QtGui.QKeySequence.Find) or
                                            event.key() == QtCore.Qt.Key_Slash):
                self.slot_show_search_widget()
            elif event.key() == QtCore.Qt.Key_Escape:
                self.ui.searchDockWidget.hide()

    def resizeEvent(self, event):
        """ Slot to adjust widgets when MainWindow is resized. """
        if self.ui.scaleComboBox.currentIndex() == 1:
            self.ui.documentWidget.fit_to_width_or_height(1)
        elif self.ui.scaleComboBox.currentIndex() == 2:
            self.ui.documentWidget.fit_to_width_or_height(2)

    def closeEvent(self, event):
        """
        On close, cleanup files.
        """
        for note in self.ui.documentWidget.ImgLabel.notes.values():
            note.remove_files()
            note.remove_png()
        self.current_note.remove_files()
        self.current_note.remove_png()
        if self.rmdoc:
            os.remove(self.docpath)
        try:
            os.rmdir(TMPDIR)
        except OSError:
            #print 'Directory %s could not be removed. It could be non-empty.' % TMPDIR
            pass