Exemple #1
0
class VirtualKeyboard(QWidget):
    def __init__(self, parent=None):
        super(VirtualKeyboard, self).__init__(parent)

        self.globalLayout = QVBoxLayout(self)
        self.keysLayout = QGridLayout()
        self.buttonLayout = QHBoxLayout()
        self.dictOfButtons = {}
        self.setStyleSheet("QWidget {"
                           "background-color: rgb(118, 118, 118);"
                           "color: rgb(240, 240, 240);"
                           "}"
                           ""
                           "QLabel{"
                           "color: rgb(240, 240, 240);"
                           "}"
                           "QPushButton{"
                           "background-color: rgb(42, 42, 42);"
                           "color: rgb(255, 255, 255);"
                           "border-style: solid;"
                           "border-color: black;"
                           "border-width: 5px;"
                           "border-radius: 10px;"
                           "font: 63 20pt 'Ubuntu';"
                           "}")
        self.keyListByLines = [
            ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', u'ß',
             '?'],  # comment this line if you dont want numbers
            ['q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', u'ü', '+'],
            ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', u'ö', u'ä', '#'],
            ['y', 'x', 'c', 'v', 'b', 'n', 'm', '_', '-', '/', '.', ':'],
        ]
        self.inputString = ""
        self.state = InputState.LOWER

        self.stateButton = QPushButton()
        self.stateButton.setText('Shift')
        self.backButton = QPushButton()
        self.backButton.setText(self.tr('Delete'))
        self.backButton.setFocusPolicy(Qt.NoFocus)
        self.okButton = QPushButton()
        self.okButton.setText('OK')
        self.okButton.setFocusPolicy(Qt.NoFocus)
        self.cancelButton = QPushButton()
        self.cancelButton.setText(self.tr("Abort"))
        self.cancelButton.setFocusPolicy(Qt.NoFocus)
        self.spaceButton = SpaceKeyButton(" ")
        self.spaceButton.setText(self.tr("Space"))
        self.dictOfButtons.update({"keyButton ": self.spaceButton})
        self.connect(self.spaceButton, SIGNAL("sigKeyButtonClicked"),
                     self.addInputByKey)

        self.inputLine = QLineEdit()

        self.inputLine.setFont(font)

        for lineIndex, line in enumerate(self.keyListByLines):
            for keyIndex, key in enumerate(line):
                buttonName = "keyButton" + key.capitalize()
                self.dictOfButtons.update({buttonName: KeyButton(key)})
                self.keysLayout.addWidget(self.getButtonByKey(key),
                                          self.keyListByLines.index(line),
                                          line.index(key))
                self.getButtonByKey(key).setText(key)
                self.connect(self.getButtonByKey(key),
                             SIGNAL("sigKeyButtonClicked"), self.addInputByKey)
                self.keysLayout.setColumnMinimumWidth(keyIndex, 50)
            self.keysLayout.setRowMinimumHeight(lineIndex, 50)

        self.connect(self.stateButton, SIGNAL("clicked()"), self.switchState)
        self.connect(self.backButton, SIGNAL("clicked()"), self.backspace)
        self.connect(self.okButton, SIGNAL("clicked()"), self.emitInputString)
        self.connect(self.cancelButton, SIGNAL("clicked()"), self.emitCancel)

        self.buttonLayout.addWidget(self.cancelButton)
        self.buttonLayout.addWidget(self.backButton)
        self.buttonLayout.addWidget(self.stateButton)
        self.buttonLayout.addWidget(self.okButton)

        self.globalLayout.addWidget(self.inputLine)
        self.globalLayout.addLayout(self.keysLayout)
        self.globalLayout.addWidget(self.spaceButton)

        self.globalLayout.addLayout(self.buttonLayout)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

    def getButtonByKey(self, key):
        dictKey = "keyButton" + key.capitalize()
        return self.dictOfButtons[dictKey]

    def getLineForButtonByKey(self, key):
        return [key in keyList for keyList in self.keyListByLines].index(True)

    def switchState(self):
        self.state = not self.state
        #print("State", self.state)
        if self.state == InputState.LOWER:
            for line in self.keyListByLines:
                for key in line:
                    self.getButtonByKey(key).setText(key.lower())
                    self.stateButton.clearFocus()
        if self.state == InputState.CAPITAL:
            for line in self.keyListByLines:
                for key in line:
                    self.getButtonByKey(key).setText(key.capitalize())

    def addInputByKey(self, key):
        self.inputString += (key.lower(), key.capitalize())[self.state]
        self.inputLine.setText(self.inputString)

    def backspace(self):
        self.inputLine.backspace()
        self.inputString = self.inputString[:-1]

    def emitInputString(self):
        self.emit(SIGNAL("sigInputString"), self.inputLine.text())

    def emitCancel(self):
        self.emit(SIGNAL("sigInputString"), "")

    def clearContent(self):
        self.inputLine.setText("")
        self.inputString = ""

    def sizeHint(self):
        return QSize(480, 272)
Exemple #2
0
class VirtualKeyboard(QWidget):

    def __init__(self, parent=None):
        super(VirtualKeyboard, self).__init__(parent)

        self.globalLayout = QVBoxLayout(self)
        self.keysLayout = QGridLayout()
        self.buttonLayout = QHBoxLayout()
        self.dictOfButtons = {}
        self.setStyleSheet("QWidget {"
                           "background-color: rgb(118, 118, 118);"
                           "color: rgb(240, 240, 240);"
                           "}"
                           ""
                           "QLabel{"
                           "color: rgb(240, 240, 240);"
                           "}"
                           "QPushButton{"
                           "background-color: rgb(42, 42, 42);"
                           "color: rgb(255, 255, 255);"
                           "border-style: solid;"
                           "border-color: black;"
                           "border-width: 5px;"
                           "border-radius: 10px;"
                           "font: 63 20pt 'Ubuntu';"
                           "}")
        self.keyListByLines = [
                    ['1','2','3','4','5','6','7','8','9','0',u'ß','?'],    # comment this line if you dont want numbers
                    ['q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', u'ü','+'],
                    ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', u'ö', u'ä','#' ],
                    ['y', 'x', 'c', 'v', 'b', 'n', 'm', '_', '-', '/', '.',':'],
                ]
        self.inputString = ""
        self.state = InputState.LOWER

        self.stateButton = QPushButton()
        self.stateButton.setText('Shift')
        self.backButton = QPushButton()
        self.backButton.setText(self.tr('Delete'))
        self.backButton.setFocusPolicy(Qt.NoFocus)
        self.okButton = QPushButton()
        self.okButton.setText('OK')
        self.okButton.setFocusPolicy(Qt.NoFocus)
        self.cancelButton = QPushButton()
        self.cancelButton.setText(self.tr("Abort"))
        self.cancelButton.setFocusPolicy(Qt.NoFocus)
        self.spaceButton = SpaceKeyButton(" ")
        self.spaceButton.setText(self.tr("Space"))
        self.dictOfButtons.update({"keyButton " : self.spaceButton})
        self.connect(self.spaceButton, SIGNAL("sigKeyButtonClicked"), self.addInputByKey)

        self.inputLine = QLineEdit()

        self.inputLine.setFont(font)


        for lineIndex, line in enumerate(self.keyListByLines):
            for keyIndex, key in enumerate(line):
                buttonName = "keyButton" + key.capitalize()
                self.dictOfButtons.update({buttonName : KeyButton(key)})
                self.keysLayout.addWidget(self.getButtonByKey(key), self.keyListByLines.index(line), line.index(key))
                self.getButtonByKey(key).setText(key)
                self.connect(self.getButtonByKey(key), SIGNAL("sigKeyButtonClicked"), self.addInputByKey)
                self.keysLayout.setColumnMinimumWidth(keyIndex, 50)
            self.keysLayout.setRowMinimumHeight(lineIndex, 50)

        self.connect(self.stateButton, SIGNAL("clicked()"), self.switchState)
        self.connect(self.backButton, SIGNAL("clicked()"), self.backspace)
        self.connect(self.okButton, SIGNAL("clicked()"), self.emitInputString)
        self.connect(self.cancelButton, SIGNAL("clicked()"), self.emitCancel)

        self.buttonLayout.addWidget(self.cancelButton)
        self.buttonLayout.addWidget(self.backButton)
        self.buttonLayout.addWidget(self.stateButton)
        self.buttonLayout.addWidget(self.okButton)

        self.globalLayout.addWidget(self.inputLine)
        self.globalLayout.addLayout(self.keysLayout)
        # construct a small horizontal layout, to assure that space-bare is in the middle of the keyboard...
        tmpLayout = QHBoxLayout()
        space = QSpacerItem(0,0)
        tmpLayout.addSpacerItem(space)
        tmpLayout.addWidget(self.spaceButton)
        tmpLayout.addSpacerItem(space)
        self.globalLayout.addLayout(tmpLayout)
        # self.globalLayout.addWidget(self.spaceButton)   # replaced with layout (tmpLayout)

        self.globalLayout.addLayout(self.buttonLayout)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))


    def getButtonByKey(self, key):
        dictKey = "keyButton" + key.capitalize()
        return self.dictOfButtons[dictKey]

    def getLineForButtonByKey(self, key):
        return [key in keyList for keyList in self.keyListByLines].index(True)

    def switchState(self):
        self.state = not self.state
        #print("State", self.state)
        if self.state == InputState.LOWER:
            for line in self.keyListByLines:
                for key in line:
                    self.getButtonByKey(key).setText(key.lower())
                    self.stateButton.clearFocus()
        if self.state == InputState.CAPITAL:
            for line in self.keyListByLines:
                for key in line:
                    self.getButtonByKey(key).setText(key.capitalize())

    def addInputByKey(self, key):
        self.inputString += (key.lower(), key.capitalize())[self.state]
        self.inputLine.setText(self.inputString)

    def backspace(self):
        self.inputLine.backspace()
        self.inputString = self.inputString[:-1]

    def emitInputString(self):
        self.emit(SIGNAL("sigInputString"), self.inputLine.text())

    def emitCancel(self):
        self.emit(SIGNAL("sigInputString"), "")

    def clearContent(self):
        self.inputLine.setText("")
        self.inputString = ""

    def sizeHint(self):
        return QSize(480,272)
Exemple #3
0
class NotesMainWindow(QMainWindow):
    """The view class"""
    def __init__(self, parent=None):
        super().__init__(parent)

        # Load saved application settings
        self.recentNotes = []

        self.numberOfTabs = 0  # keep track of the total number of tabs in the window
        self.currentPage = None
        self.__mediator = MITM.Mediator.Mediator(
        )  # the mediator object. intermediary btwn view and model

        # create a timer
        timer = QTimer(self)
        # dialogs: saved to avoid eating memory by constant cre- and re- creation
        self.findDialog = None
        self.renameDialog = None
        self.helpAboutDialog = HelpAboutDialog(self)
        self.helpHelpDialog = HelpHelpDialog(self)
        self.recentFilesListWidget = QListWidget

        # create menus first
        self.fileMenu = self.menuBar().addMenu("File")
        self.recentNotesMenu = self.fileMenu.addMenu("Open Recent")
        self.editMenu = self.menuBar().addMenu("Edit")
        self.syncMenu = self.menuBar().addMenu("Sync")
        self.helpMenu = self.menuBar().addMenu("Help")

        # region Actions
        # create the menu actions
        # first the file menu actions
        fileNewAct = self.createAction(self,
                                       "&New",
                                       shortcut=QKeySequence.New,
                                       tooltip="Create a new note",
                                       enabled=True,
                                       slot=self.onNewClick)
        fileOpenRecentNotesAct = self.createAction(self,
                                                   "&Open Recent Note",
                                                   tooltip="open recent notes",
                                                   enabled=True,
                                                   slot=self.onOpenRecentNotes)
        fileQuitAct = self.createAction(self,
                                        "&Exit",
                                        shortcut=QKeySequence.Quit,
                                        tooltip="Exit the application",
                                        enabled=True,
                                        slot=self.close)

        # recent files menu actions
        self.recentFilesMenuAct = self.createAction(self.recentNotesMenu,
                                                    "File 1")

        # edit menu actions
        editInsertAct = self.createAction(self,
                                          "Ins&ert...",
                                          shortcut="Ctrl+I",
                                          tooltip="Insert a media file",
                                          enabled=True)
        editPreferencesAct = self.createAction(
            self,
            "&Preferences",
            shortcut="Ctrl+Shift+P",
            tooltip="Set application preferences",
            enabled=True)
        editFindAct = self.createAction(self,
                                        "&Find",
                                        shortcut=QKeySequence.Find,
                                        tooltip="Find a text string",
                                        slot=self.onFind)
        editUndoAct = self.createAction(
            self,
            "&Undo",
            shortcut=QKeySequence.Undo,
            tooltip="Roll back changes to document",
            slot=self.onUndo)
        editRedoAct = self.createAction(self,
                                        "&Redo",
                                        shortcut=QKeySequence.Redo,
                                        tooltip="Repeat the last action",
                                        slot=self.onRedo)
        editRenameAct = self.createAction(self,
                                          "&Rename...",
                                          shortcut="Ctrl+Shift+R",
                                          tooltip="Rename current note",
                                          slot=self.onRenameNote)

        # sync menu actions
        synCloudAcctAct = self.createAction(self,
                                            "Cloud &Account",
                                            shortcut="Alt+A",
                                            tooltip="Sync with cloud accounts",
                                            enabled=True)

        # help menu actions
        helpHelpAct = self.createAction(self,
                                        "Help",
                                        shortcut=QKeySequence.HelpContents,
                                        tooltip="Display help",
                                        enabled=True,
                                        slot=self.onHelpHelp)
        helpAboutAct = self.createAction(self,
                                         "A&bout",
                                         shortcut="Ctrl+Shift+B",
                                         tooltip="About application",
                                         enabled=True,
                                         slot=self.onHelpAbout)

        boldTextAction = self.createAction(self,
                                           "B",
                                           shortcut="Ctrl+B",
                                           tooltip="Bold text")
        italicsTextAction = self.createAction(self,
                                              "<i>I</i>",
                                              shortcut="Ctrl+I",
                                              tooltip="Italics text")
        # endregion

        # add actions to corresponding menu
        self.addActions_(
            self.fileMenu,
            (fileNewAct, fileOpenRecentNotesAct, fileQuitAct))  # to file menu
        self.addActions_(self.editMenu,
                         (editRenameAct, editUndoAct, editRedoAct, editFindAct,
                          editInsertAct, editPreferencesAct))  # to edit menu
        self.addActions_(self.helpMenu,
                         (helpHelpAct, helpAboutAct))  # to help menu
        self.addActions_(self.recentNotesMenu, (self.recentFilesMenuAct, ))
        # create tool bar and add relevant actions
        allToolBar = self.addToolBar(
            "All Tools"
        )  # tool bar that contains all tool;not separated into file/edit/*
        self.addActions_(allToolBar,
                         (fileNewAct, synCloudAcctAct, editInsertAct,
                          editFindAct, editUndoAct, editRedoAct))

        fontDetailsToolBar = self.addToolBar("Font Details")
        self.fontTypeComboBox = QFontComboBox(
            fontDetailsToolBar)  # get font list present on the user system
        self.fontSizeSpinBox = QSpinBox(fontDetailsToolBar)  # size of the font
        self.fontSizeSpinBox.setMinimum(7)
        self.fontSizeSpinBox.setValue(12)
        self.textBoldButton = QPushButton("B")
        self.addNewNoteButton = QPushButton("+")
        self.textItalicsButton = QPushButton("I")
        maskLabel = QLabel(
            fontDetailsToolBar)  # TODO: experimental, to be removed
        pixmap = QPixmap("Asset/guit.png")  # TODO: experimental, remove
        maskLabel.setPixmap(pixmap.mask())  # TODO: experimental, remove
        self.addWidgetToToolBar(fontDetailsToolBar,
                                (self.fontTypeComboBox, self.fontSizeSpinBox,
                                 self.textBoldButton, self.textItalicsButton))
        # self.addActions_(fontDetailsToolBar, (boldTextAction, italicsTextAction))

        # create a QTabWidget
        self.tabWidget = QTabWidget(self)
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setTabPosition(QTabWidget.South)
        # self.setTabPosition(Qt.BottomDockWidgetArea, QTabWidget.South)  # TODO: not working yet. Handled
        self.tabWidgetTabBar = self.tabWidget.tabBar()
        self.tabWidget.setCornerWidget(self.addNewNoteButton,
                                       Qt.TopRightCorner)

        # create pages  # TODO:     let an event handler handle this job: HANDLED
        self.onWindowStartOpenNote()
        # self.page1 = View.TabbedPage.TabbedPage(self, Note("First", "/path"))
        # # add the pages to the tab Widget
        # self.tabWidget.addTab(self.page1, "Note 1 ")
        # self.currentPage = self.tabWidget.currentWidget()
        self.setCurrentPage()
        #        print("count() returned: ", self.tabWidget.count())

        # create "+" bar:  TODO: find a better way to create a plus tab: DONE
        # self.plusTabIndex = self.tabWidgetTabBar.insertTab(self.tabWidget.count() + 1,
        #                                         "+")  # this tab bears the "+" sign that indicates 'create new tab'
        # self.plusTabWidget = self.tabWidget.widget(self.plusTabIndex)  # get a reference to the plus tab widget

        # create Dock widget that holds find dialog
        # self.dockWidget = QDockWidget(self)
        # self.dockWidget.setAllowedAreas(Qt.TopDockWidgetArea)
        # self.dockWidget.setFeatures(QDockWidget.DockWidgetClosable|QDockWidget.DockWidgetMovable)
        # self.dockWidget.setWidget(FindDialog.FindDialog(self.currentPage, self))
        # self.dockWidget.hide()

        # do window namings and other stuffs
        self.statusbar = QStatusBar(self)
        self.statusbar.setSizeGripEnabled(False)
        self.setStatusBar(self.statusbar)
        self.setCentralWidget(self.tabWidget)
        self.setWindowTitle("Notes")

        # region Signal And Slot Bindings
        self.tabWidget.currentChanged.connect(self.setCurrentPage)
        # self.currentPage.firstTime.connect(self.openPageOnFirstNavigation)
        self.tabWidget.currentChanged.connect(
            self.notifyMediatorOfCurrentPageChange)
        # fileNewAct.triggered.connect(self.onNewClick)
        # fileQuitAct.triggered.connect(self.close)
        self.tabWidget.tabCloseRequested.connect(
            self.confirmTabCloseAndCloseTab)
        # self.tabWidget.tabCloseRequested.connect(self.holla)
        self.fontTypeComboBox.currentFontChanged.connect(self.changeFont)
        self.fontSizeSpinBox.valueChanged.connect(self.changeFontSize)
        self.textBoldButton.clicked.connect(self.toggleTextBold)
        self.textItalicsButton.clicked.connect(self.toggleTextItalics)
        timer.timeout.connect(self.onSaveClick)
        timer.timeout.connect(self.timed)
        self.addNewNoteButton.clicked.connect(self.onNewClick)
        self.currentPage.cursorPositionChanged.connect(
            self.reportCurrentCursor)
        self.recentNotesMenu.aboutToShow.connect(self.updateRecentNotesMenu)
        # editUndoAct.triggered.connect(self.currentPage.undo)
        # editRedoAct.triggered.connect(self.currentPage.redo)
        # endregion

        self.readSettings()
        # QTimer.singleShot(5000, self.onSaveClick)
        # Start the timer
        timer.start(1500000)
        # Application settings

    # region Methods
    def updateRecentNotesMenu(self):
        """Repopulate the recent files menu"""
        self.recentNotesMenu.clear()
        for note in self.recentNotes:
            if os.path.exists(self.mediator.returnNotePath(note)):
                noteName, ext = os.path.basename(note).split(".")
                act = self.createAction(
                    self.recentNotesMenu, noteName, slot=self.loadNotes
                )  #TODO: incomplete update loadNotes() to receive the noteName
                self.addActions_(self.recentNotesMenu, (act, ))

    def onOpenRecentNotes(self):
        """"""

    def reportCurrentCursor(self):
        print("###### cursor position has changed now #####")  # TODO: remove
        print("current font is: ", self.currentPage.currentFont().family())
        self.fontTypeComboBox.setCurrentFont(self.currentPage.currentFont())
        self.fontSizeSpinBox.setValue(
            self.currentPage.currentFont().pointSize())

    def onRecentNotes(self):
        self.recentFilesListWidget.show()

    def toggleTextItalics(self):
        self.currentPage.setFontItalic(not self.currentPage.fontItalic())
        self.currentPage.setFocus()
        # if not self.textItalicsButton.isChecked():
        #     self.textItalicsButton.setChecked(True)
        #     self.currentPage.setFontItalic(True)
        #     self.currentPage.setFocus()
        #     return
        # self.textItalicsButton.setChecked(False)
        # self.currentPage.setFontItalic(False)
        # self.currentPage.setFontItalic(checked)
        # self.currentPage.setFontItalic(not self.currentPage.fontItalic)

    def keyPressEvent(self, event: QKeyEvent):
        if event.modifiers() and Qt.ControlModifier:
            handled = False
        if event.key() == Qt.Key_B:
            self.toggleTextBold()  # bolden text
            handled = True
        elif event.key() == Qt.Key_I:
            self.toggleTextItalics()  # italicise text
            handled = True
            print("Ctrl+I")

        if handled:
            event.accept()
            return
        else:
            QTextEdit.keyPressEvent(self.currentPage, event)

    def toggleTextBold(self):
        self.currentPage.setFontWeight(
            QFont.Normal
            if self.currentPage.fontWeight() > QFont.Normal else QFont.Bold)
        # if not self.textBoldButton.isChecked():
        #     # self.textBoldButton.setChecked(True)
        #     self.currentPage.setFontWeight(QFont.Bold)
        #     self.currentPage.setFocus()
        #     return
        # # self.textBoldButton.setChecked(False)
        # self.currentPage.setFontWeight(QFont.Normal)
        self.currentPage.setFocus()
        # self.currentPage.setFontWeight(QFont.Bold) if checked else \
        #                                     self.currentPage.setFontWeight(QFont.Normal)
        # self.currentPage.setFocus()

    def changeFontSize(self, value: float):
        self.currentPage.setFontPointSize(value)
        self.currentPage.setFocus()

    def changeFont(self, font: QFont):
        self.currentPage.setCurrentFont(font)
        self.currentPage.setFocus()

    def addWidgetToToolBar(self, toolBar: QToolBar, widgets: tuple):
        for widget in widgets:
            toolBar.addWidget(widget)

    def holla(self, index):
        """Debugging Method. To be removed in release code"""
        print("<<<<**** Hey! holla! Removing: .... ", index)

    def timed(self):
        """Debugging Method. To be removed in release code"""
        print("\n$$$$> Called by timer")

    # region Methods

    def onWindowStartOpenNote(self):
        for note_file in self.findNotesInCurrentDirectory(
                applicationDirectory):  # find all the notes in the app dir
            self.createNoteObjectFromNoteFile(
                note_file)  # create note objs from the files
        self.createAndLoadNotes()

    def createNoteObjectFromNoteFile(self, note_file: str):
        self.mediator.createNote(notePath=note_file)

    def createAndLoadNotes(
            self):  # Trent Harmon: When a man loves a woman....song request
        if len(self.mediator.notesCollection) > 0:
            self.loadNotes()
        else:  # couldn't find a note obj
            self.createOnlyOneNote()

    def loadNotes(self):
        """Creates a TabbedPage for each note found in notes collection
            Without reading the contents of the associated note file found
            In note path"""
        note = self.sender().getData() if self.sender() is QAction else None
        if note:
            pageIndex = self.createNotePage(note)
            self.tabWidget.setCurrentIndex(pageIndex)

        for note in self.mediator.NotesCollection:
            self.createNotePage(note)
            # self.mediator.setCurrentlyDisplayedNote(note)

    def createNotePage(self, note):
        page = View.TabbedPage.TabbedPage(self, note)
        pageIndex = self.tabWidget.addTab(page, note.NoteName)
        page.page_number = pageIndex
        return pageIndex

    def createOnlyOneNote(self):
        page1 = View.TabbedPage.TabbedPage(self, Note("First", "/path"))
        # add the pages to the tab Widget
        self.tabWidget.addTab(page1, "Note 1 ")

    def openPageOnFirstNavigation(self):
        """Reads the content of the file on first nav.
            Implements something like lazy loading
            Implementation is whack. 
            Implementation Path:
                onWindowStart -> createNoteObjectFromNoteFile -> createAndLoadNotes ->
                loadNotes -> openPageOnFirstNavigation
            TODO: make a better lazy loading implementatiion"""
        # TODO: make a better lazy loading implementatiion
        print("\n<<<<<I also work\n")
        self.mediator.setCurrentlyDisplayedNote(self.currentPage.getNote())
        try:
            contents = self.mediator.openCurrentNote()
            self.currentPage.setHtml(contents)
            self.currentPage.moveCursor(
                QTextCursor.End, QTextCursor.MoveAnchor
            )  # move the cursor to the end of the document
            self.currentPageIsNowDirty(False)
        except IOError as e:
            logging.error("Note is not on filesystem yet: {}".format(e))

    def currentPageIsNowDirty(self, bool_: bool = False):
        self.currentPage.dirty = False

    @property
    def mediator(self):
        return self.__mediator

    @mediator.setter
    def mediator(self, newMediator):
        if isinstance(newMediator, MITM.Mediator.Mediator):
            self.__mediator = newMediator
        else:
            raise TypeError("newMediator must be of type Mediator")

    def writeSettings(self) -> None:
        settings = QSettings()
        settings.setValue("mainWindow/pos", self.pos())
        settings.setValue("mainWindow/size", self.size())
        settings.setValue("mainWindow/state", self.windowState())
        openedNotes = [note.NotePath for note in self.mediator.NotesCollection]
        settings.setValue("list of opened notes", openedNotes)
        fontAttrList = self.fontTypeComboBox.currentFont().toString()
        print("/////////>>>>  ", fontAttrList)
        settings.setValue("mainWindow/font", fontAttrList)
        settings.setValue("mainWindow/fontSize", self.fontSizeSpinBox.value())

    def readSettings(self):
        settings = QSettings()
        self.resize(settings.value("mainWindow/size", QSize(800, 600)))
        pos = settings.value("mainWindow/pos", QPoint(0, 0))
        listOfOpenedNotes = settings.value("list of opened notes")
        print("Opened notes:", listOfOpenedNotes)
        fontDetails = settings.value("mainWindow/font",
                                     "Architext, -1, -1, False")
        fontSize = settings.value("mainWindow/fontSize", 12)
        family, _, _, fontWeight, italics, *_ = fontDetails.split(",")
        font = QFont(family, int(fontSize), int(fontWeight), bool(italics))
        self.fontTypeComboBox.setCurrentFont(font)
        self.fontSizeSpinBox.setValue(int(fontSize))
        self.textItalicsButton.click() if font.italic(
        ) else self.textItalicsButton.clearFocus(
        )  #TODO: code smell, review later
        self.textBoldButton.click() if font.bold(
        ) else self.textBoldButton.clearFocus(
        )  #TODO: code smell, review later
        self.move(pos)
        self.restoreState(settings.value("mainWindow/state"))

    def setCurrentPage(self):
        """Updates the self.currentPage variable"""
        self.currentPage = self.tabWidget.currentWidget()
        self.currentPage.I_becameCurrentPage()
        print(":::::::::  New current page set: ",
              self.currentPage.getNote().NoteName)  # TODO: remove

    def notifyMediatorOfCurrentPageChange(self):
        self.mediator.setCurrentlyDisplayedNote(self.currentPage.getNote())

    def onNewClick(self):
        """Create a new area to write new note"""
        tabCount = self.tabWidget.count() + 1
        noteObject = self.mediator.createNote(tabCount)
        page = View.TabbedPage.TabbedPage(self, note=noteObject)
        newPageIndex = self.tabWidget.addTab(
            page,
            "Note {}".format(tabCount))  # add the page to the parent tabWidget
        page.page_number = newPageIndex  # assign a number to the page
        self.numberOfTabs = self.tabWidget.count()
        # self.tabWidgetTabBar.moveTab(self.plusTabIndex,
        #             self.numberOfTabs)  # move the "+" tab to the end TODO: update the index of the plus tab widget
        self.moveToTab(newPageIndex)
        self.currentPage.setFocus()

    def moveToTab(self, newPageIndex: int):
        self.tabWidgetTabBar.setCurrentIndex(
            newPageIndex)  # switch to the just created page

    def onSaveClick(self, pages: list = []):
        """This method gets the text from the current page;
                Passes the text along with the attached Note object to the mediator to save
        """
        if len(pages) == 0:  # pages is a list of note pages to be saved
            pages.append(self.currentPage)

        for page in pages:
            if page.dirty:
                rich_text = page.toHtml(
                )  # get the text from the current document
                # note = self.currentPage.getNote()  # get the Note object attached to this page
                try:
                    self.mediator.saveNote(rich_text, page.getNote(
                    ))  # give the text document to the mediator
                    self.currentPageIsNowDirty(False)
                except IOError as error:
                    QMessageBox(self, "File Save Error",
                                "Could not save the file", "Ok")
                    assert isinstance(
                        error, IOError
                    )  # pycharm suggested this, I don't think it's needed here
                    print("Error", "IOError occurred", error)
                    logging.log(1, "IOError occurred", error)
                except NoNoteException as error:
                    # QMessageBox.critical(self, "File Save Error", "Could not save the file: {}".format(error),
                    #             "Ok")  # TODO:Not sure this will work yet. Handled
                    print("Error", "IOError occurred: No Note", error)
                    logging.log(1, error)
            else:
                print("\n-----> No changes made to code")

    def onRenameNote(self):
        """Rename a Note"""
        # TODO : create a rename dialog window later
        renameDialog = RenameDialog(self)
        if renameDialog.exec_():
            newName = renameDialog.getNewName()
            try:
                self.mediator.renameNote(newName)
                self.tabWidget.setTabText(self.currentPage.page_number,
                                          newName)
            except Exception as e:  # TODO: what error exactly
                print("Error renaming this file:   ",
                      e)  # TODO: do better, inform  the user of the problem
                raise e

    def onUndo(self):
        """Connect to QTextEdit undo slot. A work around for inability to connect a QAction to
           QTextEdit undo slot.
        """
        self.currentPage.undo()

    def onRedo(self):
        """Connect to QTextEdit undo slot. A work around for inability to connect a QAction to
            QTextEdit undo slot.
         """
        self.currentPage.redo()
        # cus = CustomSignal()
        # cus.redoTriggered.connect(QTextEdit.redo)

    def onFind(self):  # TODO: song request Paul I.K. Dairo: Mo wa dupe
        textSelected = self.currentPage.getDocumentCursor().selectedText()
        print("Text Selected is:  ", textSelected)
        self.findDialog = FindDialog.FindDialog(self.currentPage, self,
                                                textSelected)
        self.findDialog.show()
        # self.dockWidget.show()

    def onHelpAbout(self):
        self.helpAboutDialog.show()

    def onHelpHelp(self):
        self.helpHelpDialog.show()

    def closeEvent(self, event: QEvent):
        # TODO: raise a dialog that prompts the user to accept the closing of the application
        """
        :type event: QEvent
        """
        numberOfPages = self.tabWidget.count()
        widgetList = [
            self.tabWidget.widget(widget) for widget in range(numberOfPages)
        ]
        # self.onSaveClick(widgetList)  # save notes first
        self.writeSettings()
        event.accept()

    def confirmTabCloseAndCloseTab(self, index):
        pageToRemove = self.tabWidget.widget(index)
        if pageToRemove.dirty and isinstance(pageToRemove,
                                             View.TabbedPage.TabbedPage):
            print("Tab Close requested")
            dialog = QMessageBox.warning(self, "Confirm",
                                         "Do you want to close the tab?", "Ok",
                                         "Cancel", "", 1)
            if dialog != 0:
                return
        self.tabWidget.removeTab(pageToRemove.page_number)
        self.recentNotes.append(pageToRemove.getNote())

    @staticmethod
    def addActions_(parent, actions: tuple) -> None:
        for action in actions:
            parent.addAction(action)

    @staticmethod
    def createAction(parent: QObject,
                     text: str,
                     icon: object = None,
                     shortcut: str = None,
                     tooltip: str = None,
                     enabled: bool = False,
                     signal: str = "triggered",
                     slot: object = None) -> object:
        action = QAction(parent)
        action.setText(text)
        if icon:
            action.setIcon(
                QIcon(icon))  # icon is expected as a string argument
        if shortcut:
            action.setShortcut(shortcut)
        if tooltip:
            action.setToolTip(tooltip)
        if enabled:
            action.setEnabled(enabled)

        if slot and signal == "triggered":
            action.pyqtConfigure(triggered=slot)

        return action

    @staticmethod
    def findNotesInCurrentDirectory(directory: str):
        if os.path.exists(directory):
            for path, dirs, files in os.walk(directory):
                for file in files:
                    if file.endswith(".dn"):
                        fullPath = os.path.join(directory, path, file)
                        yield os.path.normpath(os.path.abspath(fullPath))

    def __str__(self):
        print("I am a note window with id {}".format(self.winId()))

    def __repr__(self):
        print(r"I am a note")