Ejemplo n.º 1
0
    def set_highlights(self):
        for ix, lbl in enumerate(self.color_lbls):
            if ix == 0 and ix != TextExtractDialog.highlight_ix:
                if state.is_nightmode():
                    lbl.setStyleSheet(""" border: 2px solid grey; """)
                else:
                    lbl.setStyleSheet(""" border: 2px solid grey; """)

            elif ix == TextExtractDialog.highlight_ix:
                if state.is_nightmode():
                    lbl.setStyleSheet(""" border: 2px solid white; """)
                else:
                    lbl.setStyleSheet(""" border: 2px solid #0096dc; """)
            else:
                lbl.setStyleSheet(""" border: 2px solid transparent; """)
    def setup_ui(self):

        self.vbox = QVBoxLayout()
        self.vbox.addSpacing(15)
        icon = utility.misc.qlabel_image(
            "graduation_cap_night.png"
            if state.is_nightmode() else "graduation_cap.png", 50, 50)
        hb_icon = QHBoxLayout()
        hb_icon.addStretch()
        hb_icon.addWidget(icon)
        hb_icon.addStretch()
        self.vbox.addLayout(hb_icon)
        self.vbox.addSpacing(15)
        lbl = QLabel("Open first item in the queue?")
        lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
        lbl.setStyleSheet("font-size: 20px;")
        lbl.setMargin(15)

        cnt = get_read_today_count()
        s = "s" if cnt != 1 else ""
        sub = QLabel(f"Read today: <b>{cnt}</b> page{s}")
        sub.setAlignment(Qt.AlignmentFlag.AlignCenter)
        sub.setStyleSheet("font-size: 15px; color: grey;")

        at = utility.misc.count_cards_added_today()
        s = "s" if at != 1 else ""
        sub_1 = QLabel(f"Added today: <b>{at}</b> card{s}")
        sub_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        sub_1.setStyleSheet("font-size: 15px; color: grey;")

        self.vbox.addWidget(lbl)
        self.vbox.addWidget(sub)
        self.vbox.addWidget(sub_1)
        self.vbox.addSpacing(30)
        self.vbox.addStretch()

        bhb = QHBoxLayout()
        bhb.addStretch(1)

        self.read_btn = QPushButton("Yes")
        self.read_btn.clicked.connect(self.read_clicked)
        bhb.addWidget(self.read_btn)

        self.later_btn = QPushButton("Later")
        self.later_btn.clicked.connect(self.later_clicked)
        bhb.addWidget(self.later_btn)

        self.stop_btn = QPushButton("Enough for today!")
        self.stop_btn.clicked.connect(self.stop_clicked)
        bhb.addWidget(self.stop_btn)

        self.vbox.addLayout(bhb)

        self.setLayout(self.vbox)
        self.show()
Ejemplo n.º 3
0
    def __init__(self, parent):
        QDialog.__init__(
            self, parent,
            Qt.WindowType.WindowSystemMenuHint | Qt.WindowType.WindowTitleHint
            | Qt.WindowType.WindowMaximizeButtonHint
            | Qt.WindowType.WindowCloseButtonHint)

        self.mw = aqt.mw
        self.parent = parent

        if QueuePicker.icons_path is None:
            QueuePicker.icons_path = utility.misc.get_web_folder_path(
            ) + "icons/"
            QueuePicker.vline_icn = QueuePicker.icons_path + (
                'vline-night' if state.is_nightmode() else 'vline')
            QueuePicker.branch_more_icn = QueuePicker.icons_path + (
                'branch-more-night' if state.is_nightmode() else 'branch-more')
            QueuePicker.branch_end_icn = QueuePicker.icons_path + (
                'branch-end-night' if state.is_nightmode() else 'branch-end')
            QueuePicker.branch_closed_icn = QueuePicker.icons_path + (
                'branch-closed-night'
                if state.is_nightmode() else 'branch-closed')
            QueuePicker.branch_open_icn = QueuePicker.icons_path + (
                'branch-open-night' if state.is_nightmode() else 'branch-open')

        try:
            self.dark_mode_used = state.is_nightmode()
        except:
            self.dark_mode_used = False

        self.setup_ui()
        self.setWindowTitle("Queue Manager")
        self.showMaximized()
    def setup_ui(self):
        self.scheduler = QtScheduleComponent(self.note.reminder)

        self.setLayout(QVBoxLayout())

        c_lbl = QLabel(self)
        c_icon   = "calendar_night.png" if state.is_nightmode() else "calendar.png"
        c_pixmap  = QPixmap(utility.misc.get_web_folder_path() + f"icons/{c_icon}").scaled(QSize(35, 35), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        c_lbl.setPixmap(c_pixmap)
        hbox    = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(c_lbl)
        hbox.addStretch()
        self.layout().addSpacing(10)
        self.layout().addLayout(hbox)
        self.layout().addSpacing(16)

        self.layout().addWidget(self.scheduler)
        accept = QPushButton("Save")
        accept.clicked.connect(self.accept)
        hbox = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(accept)
        self.layout().addLayout(hbox)
    def setup_ui(self):
        self.setLayout(QVBoxLayout())

        c_lbl = QLabel(self)
        c_icon   = "hourglass_night.png" if state.is_nightmode() else "hourglass.png"
        c_pixmap  = QPixmap(utility.misc.get_web_folder_path() + f"icons/{c_icon}").scaled(QSize(35, 35), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        c_lbl.setPixmap(c_pixmap)
        hbox    = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(c_lbl)
        hbox.addStretch()
        self.layout().addSpacing(15)
        self.layout().addLayout(hbox)
        self.layout().addSpacing(16)

        header = QLabel("Time is up!")
        header.setAlignment(Qt.AlignmentFlag.AlignCenter)
        header.setStyleSheet("font-size: 20px; font-weight: bold;")
        self.layout().addWidget(header, Qt.AlignmentFlag.AlignCenter)
        self.layout().addSpacing(10)

        read_today_count    = get_read_today_count()
        pages               = "pages" if read_today_count != 1 else "page"
        added_today_count   = utility.misc.count_cards_added_today()
        cards               = "cards" if added_today_count != 1 else "card"

        read_lbl  = QLabel(f"Read <b>{read_today_count}</b> {pages} today")
        read_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
        added_lbl = QLabel(f"Added <b>{added_today_count}</b> {cards} today")
        added_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.layout().addWidget(read_lbl)
        self.layout().addWidget(added_lbl)


        gbox            = QGroupBox("Start a new timer")
        hbox_restart    = QHBoxLayout()
        for m in [5, 10, 15, 25, 30]:
            
            btn = QToolButton()
            btn.setText(str(m))
            btn.clicked.connect(functools.partial(self.set_restart, m))
            hbox_restart.addWidget(btn)

        gbox.setLayout(hbox_restart)
        self.layout().addSpacing(20)
        self.layout().addWidget(gbox)

        accept = QPushButton("Ok")
        accept.clicked.connect(self.accept)
        hbox = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(accept)
        hbox.addStretch()
        self.layout().addSpacing(25)
        self.layout().addLayout(hbox)
        self.layout().addSpacing(5)
        self.layout().setContentsMargins(50,10,50, 10)

        self.setObjectName("elapsed")
        self.setStyleSheet("""
            #elapsed {
                border: 3px outset #2496dc; 
                border-radius: 5px;
            } 
        """)
Ejemplo n.º 6
0
    def setup_ui(self):

        self.vbox_left = QVBoxLayout()
        self.title_hbox = QHBoxLayout()
        l_lbl = QLabel("Queue")
        self.title_hbox.addWidget(l_lbl)
        self.title_hbox.addStretch()
        self.vbox_left.addLayout(self.title_hbox)
        self.t_view_left = QTableWidget()
        self.tabs = QTabWidget()
        self.tags_tab = TagsTab(self)
        self.pdfs_tab = PDFsTab(self)
        self.notes_tab = TextNotesTab(self)
        self.videos_tab = VideosTab(self)
        self.folders_tab = FoldersTab(self)

        self.tabs.currentChanged.connect(self.tabs_changed)
        self.tabs.addTab(self.tags_tab, "Unqueued Notes, By Tag")
        self.tabs.addTab(self.pdfs_tab, "PDFs")
        self.tabs.addTab(self.notes_tab, "Text Notes")
        self.tabs.addTab(self.videos_tab, "Videos")
        self.tabs.addTab(self.folders_tab, "Folders - Import")

        self.t_view_left.setColumnCount(5)
        self.t_view_left.setHorizontalHeaderLabels(
            ["", "Title", "Sched.", "Prio", ""])
        self.t_view_left.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.ResizeMode.ResizeToContents)
        self.t_view_left.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.ResizeMode.Stretch)
        self.t_view_left.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.ResizeMode.ResizeToContents)
        self.t_view_left.horizontalHeader().setSectionResizeMode(
            3, QHeaderView.ResizeMode.ResizeToContents)
        self.t_view_left.horizontalHeader().setSectionResizeMode(
            4, QHeaderView.ResizeMode.ResizeToContents)
        # self.t_view_left.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.ResizeToContents)
        self.t_view_left.setSelectionMode(
            QAbstractItemView.SelectionMode.NoSelection)
        self.t_view_left.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        self.t_view_left.setEditTriggers(
            QAbstractItemView.EditTrigger.NoEditTriggers)
        self.t_view_left.cellDoubleClicked.connect(self.cell_clicked)

        self.t_view_left.setMinimumWidth(470)
        self.vbox_left.addWidget(self.t_view_left)

        # buttons under queue table

        uncheck_icn = "icons/unchecked" + ("_night.png"
                                           if state.is_nightmode() else ".png")
        check_icn = "icons/checked" + ("_night.png"
                                       if state.is_nightmode() else ".png")

        self.check_all_btn = QPushButton("")
        self.check_all_btn.setIcon(
            QIcon(utility.misc.get_web_folder_path() + check_icn))
        self.check_all_btn.clicked.connect(self.check_all_clicked)

        self.uncheck_all_btn = QPushButton("")
        self.uncheck_all_btn.setIcon(
            QIcon(utility.misc.get_web_folder_path() + uncheck_icn))
        self.uncheck_all_btn.clicked.connect(self.uncheck_all_clicked)

        self.unqueue_btn = QPushButton(" Remove Sel.")
        self.unqueue_btn.setDisabled(True)
        self.unqueue_btn.setIcon(QApplication.style().standardIcon(
            QStyle.StandardPixmap.SP_TrashIcon))
        self.unqueue_btn.clicked.connect(self.rem_selected_clicked)

        self.unqueue_all_btn = QPushButton(" Empty... ")
        self.unqueue_all_btn.setIcon(QApplication.style().standardIcon(
            QStyle.StandardPixmap.SP_TrashIcon))
        self.unqueue_all_btn.clicked.connect(self.empty_clicked)

        self.shuffle_queue_btn = QPushButton(" Shuffle... ")
        self.shuffle_queue_btn.clicked.connect(self.shuffle_clicked)

        self.spread_prios_btn = QPushButton(" Spread Priorities... ")
        self.spread_prios_btn.clicked.connect(self.spread_clicked)

        self.random_prios_btn = QPushButton(" Randomize Priorities... ")
        self.random_prios_btn.clicked.connect(self.random_prios_clicked)

        self.tags_btn = QPushButton(" Tag... ")
        self.tags_btn.clicked.connect(self.tag_assign_clicked)

        btn_hbox_l = QHBoxLayout()
        btn_hbox_l.addWidget(self.check_all_btn)
        btn_hbox_l.addWidget(self.uncheck_all_btn)
        btn_hbox_l.addWidget(self.unqueue_btn)
        btn_hbox_l.addWidget(self.unqueue_all_btn)
        btn_hbox_l.addWidget(self.shuffle_queue_btn)
        btn_hbox_l.addWidget(self.spread_prios_btn)
        btn_hbox_l.addWidget(self.random_prios_btn)
        btn_hbox_l.addWidget(self.tags_btn)
        btn_hbox_l.addStretch()

        self.vbox_left.addLayout(btn_hbox_l)
        self.vbox = QVBoxLayout()

        self.hbox = QHBoxLayout()
        self.hbox.addLayout(self.vbox_left)
        self.hbox.addWidget(self.tabs)

        self.vbox.addLayout(self.hbox)

        bottom_box = QHBoxLayout()
        bottom_box.addStretch(1)
        self.reject_btn = QPushButton("Close")
        self.reject_btn.clicked.connect(self.parent.reject)
        bottom_box.addWidget(self.reject_btn)
        self.vbox.addSpacing(10)
        self.vbox.addLayout(bottom_box)

        self.setLayout(self.vbox)
        # self.resize(770, 480)

        styles = """
            QTableWidget::item:hover {
                background-color: #2496dc;
                color: white;
            }
        """
        if self.parent.dark_mode_used:
            styles += """
                QTabBar {
                background: #222;
                color: #666;
                border-radius: 0;
                border: 2px solid #222;
                }
                 QTabWidget::pane {
                border-color: black;
                color: #666;
                border-radius: 0;
                border: 2px solid #222;
                }
                QTabBar::tab:top {
                margin: 1px 1px 0 0;
                padding: 4px 8px;
                border-bottom: 3px solid transparent;
                }

                QTabBar::tab:selected {
                color: white;
                border: 0;
                }

                QTabBar::tab:top:hover {
                border-bottom: 3px solid #444;
                }
                QTabBar::tab:top:selected {
                border-bottom: 3px solid #1086e2;
                }

                QTabBar::tab:hover,
                QTabBar::tab:focus { }

                QComboBox {
                    background-color: #222;
                    color: lightgrey;
                }
            """
        self.setStyleSheet(styles)
Ejemplo n.º 7
0
    def fill_table(self):
        self.table.clear()
        self.table.setRowCount(len(self.notes))

        due_dates = sorted(self.notes.keys())
        c_total = 0
        ix = -1
        today_stmp = datetime.today().strftime("%Y-%m-%d")

        while ix < len(due_dates) - 1:

            ix += 1
            due_date = due_dates[ix]
            dt = utility.date.dt_from_date_only_stamp(due_date)

            # only regard next n days
            if (dt.date() - datetime.now().date()).days > self.table_boundary:
                break

            pretty = utility.date.dt_from_date_only_stamp(due_date).strftime(
                "%a, %d %b, %Y")

            sub = QTableWidget()
            sub.setFocusPolicy(Qt.FocusPolicy.NoFocus)
            sub.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
            sub.setRowCount(len(self.notes[due_date]))
            sub.setColumnCount(3)
            sub.horizontalHeader().setVisible(False)
            sub.verticalHeader().setVisible(False)
            sub.horizontalHeader().setSectionResizeMode(
                0, QHeaderView.ResizeMode.ResizeToContents)
            sub.horizontalHeader().setSectionResizeMode(
                1, QHeaderView.ResizeMode.Stretch)
            sub.horizontalHeader().setSectionResizeMode(
                2, QHeaderView.ResizeMode.Stretch)

            item = QTableWidgetItem(pretty)
            item.setTextAlignment(Qt.AlignmentFlag.AlignTop)
            self.table.setItem(ix, 0, item)
            if ix == 0 and today_stmp == due_date:
                self.table.item(ix, 0).setForeground(
                    Qt.blue if not state.is_nightmode() else Qt.cyan)
                self.table.item(ix, 0).setText("Today")
            elif (datetime.today().date() +
                  timedelta(days=1)).strftime("%Y-%m-%d") == due_date:
                self.table.item(ix, 0).setText(f"{pretty}\n(Tomorrow)")
            due = ""
            types = ""
            c_total += len(self.notes[due_date])
            for ix_2, note in enumerate(self.notes[due_date]):
                if note.schedule_type() != "td":
                    next_rem = note.reminder
                    while True:
                        next_rem = utility.date.get_next_reminder(next_rem)
                        due = utility.date.dt_from_stamp(
                            next_rem.split("|")[1])

                        if (due.date() - datetime.now().date()
                            ).days <= self.table_boundary:
                            due_stamp = due.strftime("%Y-%m-%d")
                            copied = copy.copy(note)
                            copied.reminder = next_rem
                            if due_stamp in self.notes:
                                if not note.id in [
                                        n.id for n in self.notes[due_stamp]
                                ]:
                                    self.notes[due_stamp].append(copied)
                            else:
                                self.notes[due_stamp] = [copied]
                                self.table.setRowCount(len(self.notes))
                                due_dates = sorted(self.notes.keys())
                        else:
                            break

                if note.id in self.prios:
                    prio = self.prios[note.id]
                else:
                    prio = "-"

                prio_lbl = QLabel(str(prio))
                prio_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
                if prio != "-":
                    prio_lbl.setStyleSheet(
                        f"background: {utility.misc.prio_color(prio)}; color: white;"
                    )

                title_lbl = QLabel(note.get_title())
                title_lbl.setStyleSheet("padding-left: 5px;")

                sched_lbl = QLabel(utility.date.schedule_verbose(
                    note.reminder))
                sched_lbl.setStyleSheet("padding-left: 5px;")

                sub.setCellWidget(ix_2, 0, prio_lbl)
                sub.setCellWidget(ix_2, 1, title_lbl)
                sub.setCellWidget(ix_2, 2, sched_lbl)

            sub.setColumnWidth(2, 300)
            sub.resizeRowsToContents()
            sub.setMaximumHeight(sub.verticalHeader().length() + 5)

            self.table.setCellWidget(ix, 1, sub)
            # self.table.item(ix, 0).setFlags(Qt.ItemIsEnabled)
        self.table.resizeRowsToContents()
        if c_total > 0:
            self.avg_lbl.setText(
                f"Avg. {round(c_total/ self.table_boundary, 1)} notes / day")
        else:
            self.avg_lbl.setText("")
Ejemplo n.º 8
0
    def setup_ui(self):

        self.vbox_left = QVBoxLayout()
        r_lbl = QLabel("Tags")
        r_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.vbox_left.addWidget(r_lbl)
        self.vbox_left.setAlignment(r_lbl, Qt.AlignmentFlag.AlignTop)

        if state.is_nightmode():
            self.tag_fg = get_config_value("styles.night.tagForegroundColor")
            self.tag_bg = get_config_value("styles.night.tagBackgroundColor")
        else:
            self.tag_fg = get_config_value("styles.tagForegroundColor")
            self.tag_bg = get_config_value("styles.tagBackgroundColor")

        self.tag_tree = QTreeWidget()
        self.tag_tree.setColumnCount(1)
        self.tag_tree.setHeaderHidden(True)
        self.tag_tree.setMaximumWidth(370)
        self.tag_icon = QIcon(QueuePicker.icons_path + "icon-tag-24.png")

        self.tag_tree.setStyleSheet(f"""
        QTreeWidget::item:hover,QTreeWidget::item:hover:selected {{
            border:none;
            border-radius:5px;
            font-weight: bold;
            background-color: {self.tag_bg};
            color: {self.tag_fg};
        }}
        QTreeWidget::branch:has-siblings:!adjoins-item {{
            border-image: url({QueuePicker.vline_icn}.png) 0;
        }}
        QTreeWidget::branch:has-siblings:adjoins-item {{
            border-image: url({QueuePicker.branch_more_icn}.png) 0;
        }}
        QTreeWidget::branch:!has-children:!has-siblings:adjoins-item {{
            border-image: url({QueuePicker.branch_end_icn}.png) 0;
        }}
        QTreeWidget::branch:has-children:!has-siblings:closed,
        QTreeWidget::branch:closed:has-children:has-siblings {{
                border-image: none;
                image: url({QueuePicker.branch_closed_icn}.png);
        }}
        QTreeWidget::branch:open:has-children:!has-siblings,
        QTreeWidget::branch:open:has-children:has-siblings  {{
                border-image: none;
                image: url({QueuePicker.branch_open_icn}.png);
        }}
        """)
        self.vbox_left.addWidget(self.tag_tree)
        self.tag_displayed = None

        self.vbox_right = QVBoxLayout()
        self.lbl = QLabel("Notes, unqueued.")
        self.tag_lbl = QLabel("")
        hbox_top = QHBoxLayout()
        hbox_top.addWidget(self.lbl)
        hbox_top.addWidget(self.tag_lbl)
        hbox_top.addStretch()
        self.list = NoteList(self)
        self.vbox_right.addLayout(hbox_top)
        self.vbox_right.addWidget(self.list)
        self.enqueue_all_btn = QPushButton("+ Enqueue All...")
        self.enqueue_all_btn.clicked.connect(self.enqueue_all)
        self.empty_and_enqueue_all_btn = QPushButton(
            "+ Empty Queue and Enqueue All...")
        self.empty_and_enqueue_all_btn.clicked.connect(
            self.empty_queue_and_enqueue_all)

        btn_hbox = QHBoxLayout()
        btn_hbox.addWidget(self.enqueue_all_btn)
        btn_hbox.addWidget(self.empty_and_enqueue_all_btn)
        btn_hbox.addStretch()
        self.vbox_right.addLayout(btn_hbox)

        self.tag_tree.itemClicked.connect(self.tree_item_clicked)
        hbox = QHBoxLayout()
        hbox.addLayout(self.vbox_left)
        hbox.addLayout(self.vbox_right)
        self.setLayout(hbox)
        self.setStyleSheet("""
            QTreeWidget::item {
                padding: 0;
                margin: 0;
            }
        """)
Ejemplo n.º 9
0
    def __init__(self,
                 parent,
                 note_id=None,
                 add_only=False,
                 read_note_id=None,
                 tag_prefill=None,
                 source_prefill=None,
                 text_prefill=None,
                 title_prefill=None,
                 prio_prefill=None,
                 author_prefill=None,
                 url_prefill=None,
                 prefill_with_opened_note=False):

        QDialog.__init__(
            self, parent,
            Qt.WindowType.WindowSystemMenuHint | Qt.WindowType.WindowTitleHint
            | Qt.WindowType.WindowCloseButtonHint
            | Qt.WindowType.WindowMaximizeButtonHint
            | Qt.WindowType.WindowMinimizeButtonHint)

        self.mw = aqt.mw
        self.parent = parent

        self.note_id = note_id
        self.note = None
        self.add_only = add_only
        self.read_note_id = read_note_id
        self.tag_prefill = tag_prefill
        self.source_prefill = source_prefill
        self.text_prefill = text_prefill
        self.title_prefill = title_prefill
        self.prio_prefill = prio_prefill
        self.dark_mode_used = state.is_nightmode()

        open_note = Reader.current_note
        if prefill_with_opened_note and open_note is not None:
            self.tag_prefill = open_note.tags
            self.prio_prefill = open_note.priority

            #showInfo(self.prio_prefill)
            if self.prio_prefill == 0.0:
                self.prio_prefill = get_last_priority(open_note.id)

        # self.screen_h       = QApplication.desktop().screenGeometry().height()
        self.screen_h = QGuiApplication.screens()[0].size().height()

        if self.note_id is not None:
            self.note = get_note(note_id)
            if not self.note:
                return

        # fill meta data
        if self.note:
            self.author = self.note.author
            self.url = self.note.url
        else:
            self.author = author_prefill
            self.url = url_prefill

        #self.mw.setupDialogGC(self)
        #self.setWindowModality(Qt.WindowModal)
        #self.setAttribute(Qt.WA_DeleteOnClose)
        self.setup_ui()
    def __init__(self,
                 include_anki_tags=True,
                 only_tags=False,
                 knowledge_tree=False,
                 sort="a-z"):
        super().__init__()

        self.include_anki_tags = include_anki_tags
        self.only_tags = only_tags
        self.knowledge_tree = knowledge_tree
        self.sort = sort

        self.map = get_all_tags_as_hierarchy(
            include_anki_tags=include_anki_tags, sort=self.sort)

        # only show selected notes
        self.nids_anki_whitelist = None
        self.nids_siac_whitelist = None

        # load icon paths/icons
        web_path = get_web_folder_path()
        icons_path = web_path + "icons/"

        self.tag_icon = QIcon(icons_path + "icon-tag-24.png")
        self.pdfsiac_icon = QIcon(icons_path + "icon-pdf-24.png")
        self.ytsiac_icon = QIcon(icons_path + "icon-yt-24.png")
        self.mdsiac_icon = QIcon(icons_path + "icon-markdown-24.png")
        self.cards_icon = QIcon(icons_path + "icon-cards-24.png")

        config = mw.addonManager.getConfig(__name__)
        if state.is_nightmode():
            tag_bg = config["styles.night.tagBackgroundColor"]
            tag_fg = config["styles.night.tagForegroundColor"]
        else:
            tag_bg = config["styles.tagBackgroundColor"]
            tag_fg = config["styles.tagForegroundColor"]

        self.recursive_build_tree(self.map)
        self.setSizePolicy(QSizePolicy.Policy.Expanding,
                           QSizePolicy.Policy.Expanding)
        self.setMinimumHeight(150)
        self.setMinimumWidth(220)

        if self.knowledge_tree:
            self.setSelectionMode(QAbstractItemView.ExtendedSelection)
            self.setColumnCount(2)
            self.setHeaderLabels(["Item", "Deck"])
            self.setHeaderHidden(False)
            self.setColumnWidth(0, 300)
            self.setColumnWidth(1, 80)

            self.itemExpanded.connect(self.item_expanded)
        else:
            self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
            self.setColumnCount(1)
            self.setHeaderHidden(True)

        vline_icn = icons_path + ('vline-night'
                                  if state.is_nightmode() else 'vline')
        branch_more_icn = icons_path + (
            'branch-more-night' if state.is_nightmode() else 'branch-more')
        branch_end_icn = icons_path + ('branch-end-night' if
                                       state.is_nightmode() else 'branch-end')
        branch_closed_icn = icons_path + (
            'branch-closed-night' if state.is_nightmode() else 'branch-closed')
        branch_open_icn = icons_path + (
            'branch-open-night' if state.is_nightmode() else 'branch-open')

        stylesheet = f"""
            QTreeWidget::branch:has-siblings:!adjoins-item {{
                border-image: url({vline_icn}.png) 0;
            }}
            QTreeWidget::branch:has-siblings:adjoins-item {{
                border-image: url({branch_more_icn}.png) 0;
            }}
            QTreeWidget::branch:!has-children:!has-siblings:adjoins-item {{
                border-image: url({branch_end_icn}.png) 0;
            }}
            QTreeWidget::branch:has-children:!has-siblings:closed,
            QTreeWidget::branch:closed:has-children:has-siblings {{
                    border-image: none;
                    image: url({branch_closed_icn}.png);
            }}
            QTreeWidget::branch:open:has-children:!has-siblings,
            QTreeWidget::branch:open:has-children:has-siblings  {{
                    border-image: none;
                    image: url({branch_open_icn}.png);
            }}
        """

        # add cool hover effect with user-defined tag colour when used in note editor
        if not self.knowledge_tree:
            stylesheet += f"""
                QTreeWidget::item:hover,QTreeWidget::item:hover:selected,QTreeWidget::item:selected {{
                    border:none;
                    border-radius:5px;
                    font-weight: bold;
                    background-color: {tag_bg};
                    color: {tag_fg};
                }}
            """

        self.setStyleSheet(stylesheet)
    def setup_ui(self):

        shortcut = get_config_value_or_default("pdf.shortcuts.later",
                                               "CTRL+Shift+Y")
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(30, 20, 30, 10)

        header = QLabel(f"Postpone ({shortcut})")
        header.setAlignment(Qt.AlignmentFlag.AlignCenter)
        header.setStyleSheet("font-size: 15px; font-weight: bold;")
        self.layout.addSpacing(5)
        self.layout.addWidget(header)
        self.layout.addSpacing(10)

        self.later_rb = QRadioButton("Later Today")
        self.tomorrow_rb = QRadioButton("")
        self.days_rb = QRadioButton("")
        self.group = QButtonGroup()
        for ix, b in enumerate([self.later_rb, self.tomorrow_rb,
                                self.days_rb]):
            self.group.addButton(b, ix)

        c_lbl = QLabel(self)
        a_lbl = QLabel(self)
        c_icon = "clock_night.png" if state.is_nightmode() else "clock.png"
        a_icon = "rarrow_night.png" if state.is_nightmode() else "rarrow.png"
        c_pixmap = QPixmap(utility.misc.get_web_folder_path() +
                           f"icons/{c_icon}")
        c_lbl.setPixmap(c_pixmap)
        a_pixmap = QPixmap(utility.misc.get_web_folder_path() +
                           f"icons/{a_icon}")
        a_lbl.setPixmap(a_pixmap)
        hbox = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(c_lbl)
        hbox.addWidget(a_lbl)
        hbox.addStretch()
        self.layout.addSpacing(10)
        self.layout.addLayout(hbox)
        self.layout.addSpacing(20)

        self.layout.addWidget(self.later_rb)

        icon = "calendar_night" if state.is_nightmode() else "calendar"
        pmap = QPixmap(utility.misc.get_web_folder_path() +
                       f"icons/{icon}").scaled(QSize(13,
                                                     13), Qt.KeepAspectRatio,
                                               Qt.SmoothTransformation)

        # Tomorrow radio button + label
        t_hb = QHBoxLayout()
        t_hb.addWidget(self.tomorrow_rb)
        t_icn = ClickableQLabel()
        t_icn.setPixmap(pmap)
        t_icn.clicked.connect(self.toggle_tomorrow_rb)
        t_hb.addWidget(t_icn)
        t_lbl = ClickableQLabel("Tomorrow")
        t_lbl.clicked.connect(self.toggle_tomorrow_rb)
        t_hb.addWidget(t_lbl)
        t_hb.addStretch()
        self.layout.addLayout(t_hb)

        # In ... days radio button + label
        d_hb = QHBoxLayout()
        d_lbl = ClickableQLabel("In ")
        d_lbl.clicked.connect(self.toggle_days_rb)
        d_hb.addWidget(self.days_rb)
        d_icn = ClickableQLabel()
        d_icn.setPixmap(pmap)
        d_icn.clicked.connect(self.toggle_days_rb)
        d_hb.addWidget(d_icn)
        d_hb.addWidget(d_lbl)
        self.days_inp = QDoubleSpinBox()
        self.days_inp.setSingleStep(1)
        self.days_inp.setValue(3)
        self.days_inp.setMinimum(1)
        self.days_inp.setMaximum(10000)
        self.days_inp.setDecimals(0)
        self.days_inp.setSuffix(" day(s)")
        d_hb.addWidget(self.days_inp)
        d_hb.addStretch()
        self.layout.addLayout(d_hb)

        self.later_rb.setChecked(True)

        self.accept_btn = QPushButton("Postpone")
        self.accept_btn.clicked.connect(self.on_accept)
        self.reject_btn = QPushButton("Cancel")
        self.reject_btn.clicked.connect(self.reject)

        self.hbox = QHBoxLayout()
        self.hbox.addStretch()
        self.hbox.addWidget(self.accept_btn)
        self.hbox.addWidget(self.reject_btn)
        self.hbox.addStretch()

        self.layout.addSpacing(30)
        self.layout.addLayout(self.hbox)
        self.layout.addSpacing(10)
        self.layout.setAlignment(Qt.AlignmentFlag.AlignHCenter)
        self.setLayout(self.layout)
        self.setMinimumWidth(300)

        self.setObjectName("postpone")
        self.setStyleSheet("""
            #postpone {
                border: 3px outset #2496dc; 
                border-radius: 5px;
            } 
        """)