Example #1
0
    def __init__(self):
        super(LogDialog, self).__init__()
        self.ui = Ui_LogDialog()
        self.ui.setupUi(self)
        self.layout().setMargin(0)

        self.dataDir = os.path.dirname(__file__)

        self.setupJinjaEnv()

        self.ui.fromDateEdit.setDate(QDate.currentDate().addDays(-7))
        self.ui.toDateEdit.setDate(QDate.currentDate())
        self.ui.dueDateEdit.setDate(QDate.currentDate())

        self.ui.webView.settings().setDefaultTextEncoding("utf-8")
        self.ui.webView.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)

        for obj, signal in [
                (self.ui.fromDateEdit, "dateChanged(QDate)"),
                (self.ui.toDateEdit, "dateChanged(QDate)"),
                (self.ui.dueDateEdit, "dateChanged(QDate)"),
                (self.ui.projectLineEdit, "textChanged(QString)"),
                (self.ui.queryListWidget, "itemSelectionChanged()"),
            ]:
            QObject.connect(obj, SIGNAL(signal), self.updateView)

        QObject.connect(self.ui.queryListWidget, SIGNAL("itemSelectionChanged()"), self.updateFilterWidgets)

        QObject.connect(self.ui.webView, SIGNAL("linkClicked(const QUrl&)"), self.dispatch)

        self.updateFilterWidgets()
        self.updateView()
Example #2
0
class LogDialog(QDialog):
    def __init__(self):
        super(LogDialog, self).__init__()
        self.ui = Ui_LogDialog()
        self.ui.setupUi(self)
        self.layout().setMargin(0)

        self.dataDir = os.path.dirname(__file__)

        self.setupJinjaEnv()

        self.ui.fromDateEdit.setDate(QDate.currentDate().addDays(-7))
        self.ui.toDateEdit.setDate(QDate.currentDate())
        self.ui.dueDateEdit.setDate(QDate.currentDate())

        self.ui.webView.settings().setDefaultTextEncoding("utf-8")
        self.ui.webView.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)

        for obj, signal in [
                (self.ui.fromDateEdit, "dateChanged(QDate)"),
                (self.ui.toDateEdit, "dateChanged(QDate)"),
                (self.ui.dueDateEdit, "dateChanged(QDate)"),
                (self.ui.projectLineEdit, "textChanged(QString)"),
                (self.ui.queryListWidget, "itemSelectionChanged()"),
            ]:
            QObject.connect(obj, SIGNAL(signal), self.updateView)

        QObject.connect(self.ui.queryListWidget, SIGNAL("itemSelectionChanged()"), self.updateFilterWidgets)

        QObject.connect(self.ui.webView, SIGNAL("linkClicked(const QUrl&)"), self.dispatch)

        self.updateFilterWidgets()
        self.updateView()

    def setupJinjaEnv(self):
        self.jinjaEnv = Environment()
        self.jinjaEnv.filters["dueDateCssClass"] = dueDateCssClass
        self.jinjaEnv.filters["formatDate"] = formatDate
        self.jinjaEnv.filters["formatDueDate"] = formatDueDate

        tmplDir = os.path.join(self.dataDir, "templates")
        self.jinjaEnv.loader = FileSystemLoader(tmplDir)

    def updateFilterWidgets(self):
        queryType = self.ui.queryListWidget.currentRow()
        self.ui.dueWidget.setVisible(queryType == QUERY_DUE)
        self.ui.doneWidget.setVisible(queryType == QUERY_DONE)

    def updateView(self):
        filters = []
        queryType = self.ui.queryListWidget.currentRow()

        # Project
        wantedProject = self.ui.projectLineEdit.text()
        if not wantedProject.isEmpty():
            filters.append(
                IN(
                    Task.q.project,
                    Select(Project.q.id, LIKE(Project.q.name, "%" + unicode(wantedProject) + "%"))
                ))

        # Status
        statusFilters = []
        if queryType == QUERY_DONE:
            minDate = datetimeFromQDate(self.ui.fromDateEdit.date())
            maxDate = datetimeFromQDate(self.ui.toDateEdit.date())
            if maxDate < minDate:
                minDate, maxDate = maxDate, minDate

            maxDate += timedelta(1)
            doneFilter = AND( \
                Task.q.status == "done", \
                Task.q.doneDate >= minDate, \
                Task.q.doneDate < maxDate \
                )
            statusFilters.append(doneFilter)
        else:
            statusFilters.append(Task.q.status == "new")
            statusFilters.append(Task.q.status == "started")

        filters.append(OR(*statusFilters))

        # Due date
        if queryType == QUERY_DUE:
            dueDate = datetimeFromQDate(self.ui.dueDateEdit.date()) + timedelta(1)
            filters.append(Task.q.dueDate < dueDate)

        tasks = Task.select(AND(*filters))

        lst = []
        class Item(object):
            __slots__ = ["task", "grp1", "grp2"]
        for task in tasks:
            item = Item()
            item.task = task
            if queryType == QUERY_DUE:
                item.grp1 = task.dueDate.date()
                item.grp2 = task.project.name
            elif queryType == QUERY_PROJECT:
                item.grp1 = task.project.name
                item.grp2 = ""
            elif queryType == QUERY_DONE:
                item.grp1 = task.doneDate.date()
                item.grp2 = task.project.name
            else:
                raise Exception()
            lst.append(item)

        if queryType == QUERY_DUE:
            fmt1 = formatDate
        elif queryType == QUERY_PROJECT:
            fmt1 = lambda x: x
        elif queryType == QUERY_DONE:
            fmt1 = formatDate
        else:
            raise Exception()

        tmpl = self.jinjaEnv.get_template("index.html")
        html = tmpl.render(lst=lst, fmt1=fmt1)
        baseUrl = QUrl.fromLocalFile(os.path.join(self.dataDir, "static/"))
        self.ui.webView.setHtml(html, baseUrl)
        self.ui.webView.page().mainFrame().addToJavaScriptWindowObject("qtWindow", self)

    def updateViewAndKeepPosition(self):
        frame = self.ui.webView.page().currentFrame()
        pos = frame.scrollPosition()
        self.updateView()
        frame.setScrollPosition(pos)

    def dispatch(self, url):
        if url.scheme() != "y":
            QDesktopServices.openUrl(url)
            return
        path = unicode(url.path())
        tokens = path.split("/")
        methodName = "do_" + tokens[0]
        if hasattr(self, methodName):
            getattr(self, methodName)(*tokens[1:])
        else:
            print "Unknown method", methodName

    def editTask(self, taskId):
        task = Task.get(taskId)
        dlg = AddTaskDialog(task, self)
        if dlg.exec_() == QDialog.Accepted:
            self.updateViewAndKeepPosition()

    def removeTask(self, taskId):
        Task.delete(taskId)
        self.updateViewAndKeepPosition()

    @pyqtSlot(int, str)
    def setTaskStatus(self, taskId, status):
        task = Task.get(taskId)
        status = unicode(status)
        task.status = status
        if status == "done":
            task.doneDate = datetime.now()

    @pyqtSlot(int, str)
    def showTaskPopup(self, taskId, buttonId):
        frame = self.ui.webView.page().mainFrame()
        element = frame.findFirstElement(buttonId)
        assert element
        rect = element.geometry()
        topLeft = self.ui.webView.mapToGlobal(rect.topLeft() - frame.scrollPosition())

        menu = QMenu()
        edit = menu.addAction(self.tr("Edit"))
        rmMenu = menu.addMenu(self.tr("Remove"))
        remove = rmMenu.addAction(self.tr("Do It"))
        menuHeight = menu.sizeHint().height()
        screenHeight = QApplication.desktop().screenGeometry(self).height()

        if topLeft.y() + menuHeight < screenHeight:
            pos = QPoint(topLeft.x(), topLeft.y() + rect.height())
        else:
            pos = QPoint(topLeft.x(), topLeft.y() - menuHeight)

        action = menu.exec_(pos)

        if action == edit:
            self.editTask(taskId)
        elif action == remove:
            self.removeTask(taskId)