Esempio n. 1
0
class QuickOrderViewWidget(SubFrame):
    def __init__(self, parent):
        super(QuickOrderViewWidget, self).__init__("Quick view", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self.table_view = QTableView(self)
        self.table_view.setModel(self._table_model)
        self.layout().addWidget(self.table_view)

        self._table_model.setHorizontalHeaderLabels(
            ['Part Nr.', 'Description'])

        self.table_view.verticalHeader().hide()
        headers_view = self.table_view.horizontalHeader()
        headers_view.setResizeMode(0, QHeaderView.ResizeToContents)
        headers_view.setResizeMode(1, QHeaderView.Stretch)

    def selected_order(self, cur, prev):
        if cur.isValid():
            order_id = cur.model().index(cur.row(), 0).data(Qt.UserRole)

            self._table_model.removeRows(0, self._table_model.rowCount())
            row = 0
            for label, description in dao.order_dao.load_quick_view(order_id):
                self._table_model.appendRow(
                    [QStandardItem(label),
                     QStandardItem(description)])
Esempio n. 2
0
class WeekViewWidget(SubFrame):
    def __init__(self, parent):
        super(WeekViewWidget, self).__init__("Week", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self._table_model.setHorizontalHeaderLabels(
            [_("# Ord."), _("Customer")])

        self.table_view = LeftRightTableView(self)
        self.table_view.setModel(self._table_model)
        self.table_view.verticalHeader().hide()
        self.table_view.setAlternatingRowColors(True)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.table_view.horizontalHeader().setResizeMode(
            0, QHeaderView.ResizeToContents)
        self.table_view.horizontalHeader().setStretchLastSection(True)

        self.preorder_brush = QBrush(QColor(255, 255, 128))
        self.completed_order_brush = QBrush(QColor(128, 255, 128))

        self.layout().addWidget(self.table_view)

    def _set_last_row(self, data, role):
        for i in range(self._table_model.columnCount()):
            self._table_model.setData(
                self._table_model.index(self._table_model.rowCount() - 1, i),
                data, role)

    def set_data(self, data, base_date):
        self.set_title(date_to_dm(base_date))
        self._table_model.removeRows(0, self._table_model.rowCount())

        current_ndx = 0
        for d in data:
            order, customer_name = d

            number = order.preorder_label
            if order.accounting_label:
                number = order.accounting_label

            self._table_model.appendRow(
                [QStandardItem(str(number)),
                 QStandardItem(customer_name)])
            self._table_model.setData(self._table_model.index(current_ndx, 0),
                                      order.order_id, Qt.UserRole)

            if order.state == OrderStatusType.order_completed:
                self._set_last_row(self.completed_order_brush,
                                   Qt.BackgroundRole)
            elif order.state == OrderStatusType.preorder_definition:
                self._set_last_row(self.preorder_brush, Qt.BackgroundRole)

            current_ndx += 1
        # Not the slightest idea why this works
        # and not resizeColumnsToContents
        for i in range(self._table_model.columnCount()):
            self.table_view.resizeColumnToContents(i)
Esempio n. 3
0
    def _createCompleterModel(self, completionPrefix):
        """
        Creates a QStandardModel that holds the suggestion from the completion
        models for the QCompleter

        :param completionPrefix:
        """
        # build the completion model
        cc_model = QStandardItemModel()
        cptSuggestion = 0
        displayedTexts = []
        self.__tooltips.clear()
        for model in self._models:
            for s in model.suggestions:
                # skip redundant completion
                if s.display != completionPrefix and \
                        not s.display in displayedTexts:
                    displayedTexts.append(s.display)
                    items = []
                    item = QStandardItem()
                    items.append(item)
                    item.setData(s.display, Qt.DisplayRole)
                    if s.description is not None:
                        self.__tooltips[s.display] = s.description
                    if s.decoration is not None:
                        item.setData(QIcon(s.decoration), Qt.DecorationRole)
                    cc_model.appendRow(items)
                    cptSuggestion += 1
            # do we need to use more completion model?
            if cptSuggestion >= self.minSuggestions:
                break  # enough suggestions
        return cc_model, cptSuggestion
    def _on_level_selected_changed(self, index):
        level_name = self.mClassList.itemData(index)
        level = self.levels_dict[level_name]
        model = QStandardItemModel()
        for verb in level.verbs_list:
            item = QStandardItem(verb.base_verbal)
            item.setData(verb.base_verbal)
            model.appendRow(item)

        self.mVerbsList.setModel(model)
Esempio n. 5
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.mainwindow = Ui_MainWindow()
        self.mainwindow.setupUi(self)

        it1 = Category(title='it1')
        it2 = Page('it2', 'This is it2\'s content')
        it3 = Page('it3', 'This is it3\'s content')
        it1.setChild(it1.rowCount(), it2)
        it1.setChild(it1.rowCount(), it3)
        model = QStandardItemModel()
        model.appendRow(it1)
        tv = self.mainwindow.treeView
        tv.setModel(model)
        tv.setRootIsDecorated(True)
        tv.setSelectionMode(QAbstractItemView.SingleSelection)
        tv.setSelectionBehavior(QAbstractItemView.SelectItems)
        tv.clicked.connect(self.printData)
Esempio n. 6
0
    def testOperators(self):
        model = QStandardItemModel()
        for i in range(100):
            model.appendRow(QStandardItem("Item: %d"%i))

        first = model.index(0, 0)
        second = model.index(10, 0)
        third = model.index(20, 0)
        fourth = model.index(30, 0)

        sel = QItemSelection(first, second)
        sel2 = QItemSelection()
        sel2.select(third, fourth)

        sel3 = sel + sel2 #check operator +
        self.assertEqual(len(sel3), 2)
        sel4 = sel
        sel4 += sel2 #check operator +=
        self.assertEqual(len(sel4), 2)
        self.assertEqual(sel4, sel3)
Esempio n. 7
0
    def testOperators(self):
        model = QStandardItemModel()
        for i in range(100):
            model.appendRow(QStandardItem("Item: %d" % i))

        first = model.index(0, 0)
        second = model.index(10, 0)
        third = model.index(20, 0)
        fourth = model.index(30, 0)

        sel = QItemSelection(first, second)
        sel2 = QItemSelection()
        sel2.select(third, fourth)

        sel3 = sel + sel2  # check operator +
        self.assertEqual(len(sel3), 2)
        sel4 = sel
        sel4 += sel2  # check operator +=
        self.assertEqual(len(sel4), 2)
        self.assertEqual(sel4, sel3)
Esempio n. 8
0
class LibraryListView(QListView):
    def __init__(self, strategy):
        QListView.__init__(self)

        self.item_strat = strategy

        self.itemmodel = QStandardItemModel()
        self.proxymodel = QSortFilterProxyModel()
        self.proxymodel.setSourceModel(self.itemmodel)
        self.proxymodel.setDynamicSortFilter(True)
        self.setModel(self.proxymodel)
        self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)

    def add(self, obj):
        item = self.item_strat.get_item(obj)
        self.itemmodel.appendRow(item)
        return item

    def filter(self, field, value):
        self.proxymodel.setFilterRole(field)
        self.proxymodel.setFilterFixedString(value)
Esempio n. 9
0
class LibraryListView(QListView):
    def __init__(self, strategy):
        QListView.__init__(self)
        self.ctrl = None
        self.item_strat = strategy

        self.itemmodel = QStandardItemModel()
        self.proxymodel = LuneSortFilterProxyModel()
        self.proxymodel.setSourceModel(self.itemmodel)
        self.setModel(self.proxymodel)
        self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.proxymodel.setSortCaseSensitivity(QtCore.Qt.CaseSensitivity.CaseInsensitive)
        self.proxymodel.sort(0)

    def add(self, obj):
        item = self.item_strat.get_item(obj)
        self.itemmodel.appendRow(item)
        if self.ctrl:
            self.ctrl.update()

        return item

    def remove(self, obj):
        index = self.model().sourceModel().indexFromItem(obj.item)
        self.model().sourceModel().removeRow(index.row())

    def filter(self, field, value):
        self.proxymodel.setFilterRole(field)
        self.proxymodel.setFilterFixedString(value)
        if self.ctrl:
            self.ctrl.update()

    def sort(self, sort):
        self.ctrl.set_sort(sort)

    def set_ctrl(self, ctrl):
        self.ctrl = ctrl
Esempio n. 10
0
    def makeTopLayout(self):
        """Make a QHBoxLayout containing clickable buttons like 'Pause', and filters ('errors', 'warnings'...)"""
        top = QtGui.QHBoxLayout()
        top.setAlignment( Qt.AlignLeft )

        btn = QtGui.QPushButton("Pause")
        btn.setCheckable(True)
        btn.pressed.connect( self.toggle_paused )
        top.addWidget( btn )

        btn = QtGui.QPushButton("Run")
        btn.pressed.connect( self.run_yaml )
        top.addWidget( btn )

        btn = QtGui.QPushButton("Stop")
        btn.pressed.connect( self.stop_yaml )
        top.addWidget( btn )

        top.addWidget( QtGui.QLabel("Filters:") )
        
        model = QStandardItemModel()
        combo = QtGui.QComboBox()
        combo.setModel(model)
        self.filter_model = model

        ix = 0
        for label,str in config.FILTERS:
            item = QStandardItem(label)
            model.appendRow(item)
            combo.setItemData(ix, str)
            ix += 1

        combo.currentIndexChanged.connect( lambda ix, combo=combo : self.filter_combo_changed(ix, combo) )
        top.addWidget(combo)
        
        return top
Esempio n. 11
0
class window(QMainWindow):

    """Main window."""

    def __init__(self, parent=None):
        """Initialize the parent class of this instance."""
        super(window, self).__init__(parent)
        app.aboutToQuit.connect(self.myExitHandler)

        self.style_sheet = self.styleSheet('style')
        # app.setStyle(QStyleFactory.create('Macintosh'))
        #app.setStyleSheet(self.style_sheet)
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0,0,0,0)

        app.setOrganizationName("Eivind Arvesen")
        app.setOrganizationDomain("https://github.com/eivind88/raskolnikov")
        app.setApplicationName("Raskolnikov")
        app.setApplicationVersion("0.0.1")
        settings = QSettings()

        self.data_location = QDesktopServices.DataLocation
        self.temp_location = QDesktopServices.TempLocation
        self.cache_location = QDesktopServices.CacheLocation

        self.startpage = "https://duckduckgo.com/"
        self.new_tab_behavior = "insert"

        global bookmarks

        global saved_tabs
        print "Currently saved_tabs:\n", saved_tabs

        global menubar
        menubar = QMenuBar()

        # Initialize a statusbar for the window
        self.statusbar = self.statusBar()
        self.statusbar.setFont(QFont("Helvetica Neue", 11, QFont.Normal))
        self.statusbar.setStyleSheet(self.style_sheet)
        self.statusbar.setMinimumHeight(15)

        self.pbar = QProgressBar()
        self.pbar.setMaximumWidth(100)
        self.statusbar.addPermanentWidget(self.pbar)

        self.statusbar.hide()

        self.setMinimumSize(504, 235)
        # self.setWindowModified(True)
        # app.alert(self, 0)
        self.setWindowTitle("Raskolnikov")
        # toolbar = self.addToolBar('Toolbar')
        # toolbar.addAction(exitAction)
        # self.setUnifiedTitleAndToolBarOnMac(True)
        self.setWindowIcon(QIcon(""))

        # Create input widgets
        self.bbutton = QPushButton(u"<")
        self.fbutton = QPushButton(u">")
        self.hbutton = QPushButton(u"⌂")
        self.edit = QLineEdit("")
        self.edit.setFont(QFont("Helvetica Neue", 12, QFont.Normal))
        self.edit.setPlaceholderText("Enter URL")
        # self.edit.setMinimumSize(400, 24)
        self.rbutton = QPushButton(u"↻")
        self.dbutton = QPushButton(u"☆")
        self.tbutton = QPushButton(u"⁐")
        # ↆ ⇧ √ ⌘ ⏎ ⏏ ⚠ ✓ ✕ ✖ ✗ ✘ ::: ❤ ☮ ☢ ☠ ✔ ☑ ♥ ✉ ☣ ☤ ✘ ☒ ♡ ツ ☼ ☁ ❅ ✎
        self.nbutton = QPushButton(u"+")
        self.nbutton.setObjectName("NewTab")
        self.nbutton.setMinimumSize(35, 30)
        self.nbutton.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)

        self.edit.setTextMargins(2, 1, 2, 0)

        # create a horizontal layout for the input
        input_layout = QHBoxLayout()
        input_layout.setSpacing(4)
        input_layout.setContentsMargins(0, 0, 0, 0)

        # add the input widgets to the input layout
        input_layout.addWidget(self.bbutton)
        input_layout.addWidget(self.fbutton)
        input_layout.addWidget(self.hbutton)
        input_layout.addWidget(self.edit)
        input_layout.addWidget(self.rbutton)
        input_layout.addWidget(self.dbutton)
        input_layout.addWidget(self.tbutton)

        # create a widget to hold the input layout
        self.input_widget = QFrame()
        self.input_widget.setObjectName("InputWidget")
        self.input_widget.setStyleSheet(self.style_sheet)

        # set the layout of the widget
        self.input_widget.setLayout(input_layout)
        self.input_widget.setVisible(True)

        # CREATE BOOKMARK-LINE HERE
        self.bookmarks_layout = QHBoxLayout()
        self.bookmarks_layout.setSpacing(0)
        self.bookmarks_layout.setContentsMargins(0, 0, 0, 0)

        for i in bookmarks:
            link = QToolButton()
            link.setDefaultAction(QAction(unicode(i), link))
            link.setObjectName(unicode(i))
            link.setFont(QFont("Helvetica Neue", 11, QFont.Normal))
            link.clicked.connect(self.handleBookmarks)

            self.bookmarks_layout.addWidget(link)

        self.bookmarks_widget = QFrame()
        self.bookmarks_widget.setObjectName("BookmarkWidget")
        self.bookmarks_widget.setStyleSheet(self.style_sheet)
        self.bookmarks_widget.setLayout(self.bookmarks_layout)

        if not bookmarks:
            self.bookmarks_widget.hide()

        # Task list
        self.tasklist = QStandardItemModel()
        #parentItem = self.tasklist.invisibleRootItem()
        #self.tasklist.header().hide()
        self.tasklist.setHorizontalHeaderItem(0, QStandardItem('Tasks'))
        parentItem = QStandardItem("Parent")
        self.tasklist.appendRow(parentItem)
        for i in range(4):
            item = QStandardItem("Item %d" % i)
            parentItem.appendRow(item)
            #parentItem = item

        #self.list.activated[str].connect(self.handleBookmarks)
        #self.list.view().setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)

        # create tabs
        self.tabs = QTabWidget()
        self.tabs.setDocumentMode(True)
        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(True)
        self.tabs.tabBar().hide()
        self.tabs.setFont(QFont("Helvetica Neue", 11, QFont.Normal))
        self.tabs.setCornerWidget(self.nbutton)
        self.tabs.cornerWidget().setObjectName("CornerWidget")
        self.tabs.cornerWidget().setMinimumSize(10, 24)
        self.tabs.cornerWidget().setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)

        if saved_tabs:
            for tab in saved_tabs['tabs']:
                tasklist = QTreeView()
                tasklist.hide()
                tasklist.setObjectName('taskList')
                tasklist.setMinimumWidth(100)
                tasklist.setMaximumWidth(250)

                new_tab = QWebView()
                new_tab.setObjectName('webView')

                inspector = QWebInspector(self)
                inspector.setObjectName('webInspector')
                inspector.hide()

                page_layout = QVBoxLayout()
                page_layout.setSpacing(0)
                page_layout.setContentsMargins(0, 0, 0, 0)
                page_layout.addWidget(new_tab)
                page_layout.addWidget(inspector)
                page_widget = QFrame()
                page_widget.setObjectName('pageWidget')
                page_widget.setLayout(page_layout)

                complete_tab_layout = QHBoxLayout()
                complete_tab_layout.setSpacing(0)
                complete_tab_layout.setContentsMargins(0, 0, 0, 0)
                complete_tab_layout.addWidget(tasklist)
                complete_tab_layout.addWidget(page_widget)
                complete_tab_widget = QFrame()
                complete_tab_widget.setLayout(complete_tab_layout)

                #for page in tab['history']:
                #    new_tab.load(QUrl(page['url']))
                #print tab['current_history']
                #for item in new_tab.history().items():
                #    print item
                #new_tab.history().goToItem(new_tab.history().itemAt(tab['current_history']))
                new_tab.load(QUrl(tab['history'][tab['current_history']]['url']))
                tab['current_history']
                self.tabs.setUpdatesEnabled(False)
                if self.new_tab_behavior == "insert":
                    self.tabs.insertTab(self.tabs.currentIndex()+1, complete_tab_widget,
                                        unicode(new_tab.title()))
                elif self.new_tab_behavior == "append":
                    self.tabs.appendTab(complete_tab_widget, unicode(new_tab.title()))
                self.tabs.setUpdatesEnabled(True)
                new_tab.titleChanged.connect(self.change_tab)
                new_tab.urlChanged.connect(self.change_tab)
                new_tab.loadStarted.connect(self.load_start)
                new_tab.loadFinished.connect(self.load_finish)
                new_tab.loadProgress.connect(self.pbar.setValue)
                new_tab.page().linkHovered.connect(self.linkHover)
                inspector.setPage(new_tab.page())

            for index, tab in enumerate(saved_tabs['tabs']):
                self.tabs.setTabText(index, tab['history'][tab['current_history']]['title'])

            self.tabs.setCurrentIndex(saved_tabs['current_tab'])
        else:
            self.new_tab()

        tabs_layout = QVBoxLayout()
        tabs_layout.setSpacing(0)
        tabs_layout.setContentsMargins(0, 0, 0, 0)
        tabs_layout.addWidget(self.tabs)

        self.tabs_widget = QFrame()
        self.tabs_widget.setObjectName("TabLine")
        self.tabs_widget.setStyleSheet(self.style_sheet)
        self.tabs_widget.setLayout(tabs_layout)
        self.tabs_widget.setVisible(True)

        # Webkit settings
        gsettings = self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).settings().globalSettings()
        # Basic settings
        gsettings.setAttribute(QWebSettings.AutoLoadImages, True)
        gsettings.setAttribute(QWebSettings.JavascriptEnabled, True)
        gsettings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False)
        gsettings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False)
        gsettings.setAttribute(QWebSettings.PluginsEnabled, False) # Flash isn't stable at present
        gsettings.setAttribute(QWebSettings.JavaEnabled, False) # Java applet's aren't supported by PySide
        gsettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
        gsettings.setAttribute(QWebSettings.AcceleratedCompositingEnabled,
            True)
        # Performace settings
        gsettings.setAttribute(QWebSettings.DnsPrefetchEnabled, True)
        gsettings.setAttribute(QWebSettings.AcceleratedCompositingEnabled, True)
        gsettings.setAttribute(QWebSettings.DnsPrefetchEnabled, True)
        # Other settings
        gsettings.setAttribute(QWebSettings.PrivateBrowsingEnabled, False)

        # Create a vertical layout and add widgets
        vlayout = QVBoxLayout()
        vlayout.setSpacing(0)
        vlayout.setContentsMargins(0, 0, 0, 0)
        # toolbar.addWidget(self.input_widget)
        vlayout.addWidget(self.input_widget)
        vlayout.addWidget(self.bookmarks_widget)
        vlayout.addWidget(self.tabs_widget)

        # create a widget to hold the vertical layout
        wrapper_widget = QWidget()
        wrapper_widget.setLayout(vlayout)
        self.setCentralWidget(wrapper_widget)

        self.bbutton.clicked.connect(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).back)
        self.fbutton.clicked.connect(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).forward)
        self.hbutton.clicked.connect(self.goHome)
        self.edit.returnPressed.connect(self.set_url)
        # Add button signal to "go" slot
        self.rbutton.clicked.connect(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).reload)
        self.dbutton.clicked.connect(self.bookmark)
        self.tbutton.clicked.connect(self.toggleTaskBar)
        self.nbutton.clicked.connect(self.new_tab)
        self.tabs.tabCloseRequested.connect(self.tabs.removeTab)
        self.tabs.currentChanged.connect(self.change_tab)

        widgets = (input_layout.itemAt(i).widget() for i in range(
            input_layout.count()))
        for widget in widgets:
            if isinstance(widget, QPushButton):
                widget.setFixedSize(33, 21)
                widget.setFont(QFont("Helvetica Neue", 12, QFont.Normal))
                widget.pressed.connect(self.press_button)
                widget.released.connect(self.release_button)

        # make a ctrl+q quit
        sequence = QKeySequence(Qt.CTRL + Qt.Key_Q)
        QShortcut(sequence, self, SLOT("close()"))

        # make an accelerator to toggle fullscreen
        sequence = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_F)
        QShortcut(sequence, self, self.toggle_fullscreen)

        # make an accelerator to toggle input visibility
        sequence = QKeySequence(Qt.CTRL + Qt.ALT + Qt.Key_L)
        QShortcut(sequence, self, self.toggle_input)

        # make an accelerator to focus adress-bar
        sequence = QKeySequence(Qt.CTRL + Qt.Key_L)
        QShortcut(sequence, self, self.focus_adress)

        # make an accelerator to reload page
        sequence = QKeySequence(Qt.CTRL + Qt.Key_R)
        QShortcut(sequence, self, self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).reload)

        # make an accelerator to create new tab
        sequence = QKeySequence(Qt.CTRL + Qt.Key_T)
        QShortcut(sequence, self, self.new_tab)

        # make an accelerator to close tab
        sequence = QKeySequence(Qt.CTRL + Qt.Key_W)
        QShortcut(sequence, self, self.close_tab)

        # make an accelerator to navigate tabs
        sequence = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Left)
        QShortcut(sequence, self, self.previous_tab)
        sequence = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Right)
        QShortcut(sequence, self, self.next_tab)

        # make an accelerator to toggle inspector
        sequence = QKeySequence(Qt.CTRL + Qt.ALT + Qt.Key_U)
        QShortcut(sequence, self, self.handleShowInspector)

        # make an accelerator to toggle bookmark
        sequence = QKeySequence(Qt.CTRL + Qt.Key_D)
        QShortcut(sequence, self, self.bookmark)

        # make an accelerator to toggle task/project-list
        sequence = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_L)
        QShortcut(sequence, self, self.toggleTaskBar)

        # finally set the attribute need to rotate
        # try:
        #     self.setAttribute(Qt.WA_Maemo5AutoOrientation, True)
        # except:
        #     print "not maemo"

        self.statusbar.show()

    def press_button(self):
        """On button press. Connected."""
        self.sender().setStyleSheet('background-color: rgba(228, 228, 228)')

    def release_button(self):
        """On button release. Connected."""
        self.sender().setStyleSheet('background-color: rgba(252, 252, 252)')

    def goHome(self):
        """Go to startpage."""
        self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).setUrl(QUrl(self.startpage))

    def handleShowInspector(self):
        """Toggle web inspector."""
        self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebInspector, unicode('webInspector')).setShown(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebInspector, unicode('webInspector')).isHidden())

    def toggleTaskBar(self):
        """Toggle task bar."""
        if self.tabs.currentWidget().findChild(QTreeView, unicode('taskList')).isHidden():
            self.tabs.currentWidget().findChild(QTreeView, unicode('taskList')).setModel(self.tasklist)
        self.tabs.currentWidget().findChild(QTreeView, unicode('taskList')).setShown(self.tabs.currentWidget().findChild(QTreeView, unicode('taskList')).isHidden())
        #self.tasklist.setShown(self.tasklist.isHidden())

    def focus_adress(self):
        """Focus adress bar."""
        self.edit.selectAll()
        self.edit.setFocus()

    def toggle_input(self):
        """Toggle input visibility."""
        if self.input_widget.isVisible():
            visible = False
        else:
            visible = True
        self.input_widget.setVisible(visible)

    def toggle_fullscreen(self):
        """Toggle fullscreen."""
        if self.isFullScreen():
            self.showNormal()
        else:
            self.showFullScreen()
        self.change_tab()

    def linkHover(self, l):
        """Show link adress in status bar on mouse hover."""
        self.statusbar.showMessage(l)

    def new_tab(self):
        """Open new tab."""
        tasklist = QTreeView()
        tasklist.hide()
        tasklist.setObjectName('taskList')
        tasklist.setMinimumWidth(100)
        tasklist.setMaximumWidth(250)

        new_tab = QWebView()
        new_tab.setObjectName('webView')

        inspector = QWebInspector(self)
        inspector.setObjectName('webInspector')
        inspector.hide()

        page_layout = QVBoxLayout()
        page_layout.setSpacing(0)
        page_layout.setContentsMargins(0, 0, 0, 0)
        page_layout.addWidget(new_tab)
        page_layout.addWidget(inspector)
        page_widget = QFrame()
        page_widget.setObjectName('pageWidget')
        page_widget.setLayout(page_layout)

        complete_tab_layout = QHBoxLayout()
        complete_tab_layout.setSpacing(0)
        complete_tab_layout.setContentsMargins(0, 0, 0, 0)
        complete_tab_layout.addWidget(tasklist)
        complete_tab_layout.addWidget(page_widget)
        complete_tab_widget = QFrame()
        complete_tab_widget.setLayout(complete_tab_layout)

        new_tab.load(QUrl(self.startpage))
        self.tabs.setUpdatesEnabled(False)
        if self.new_tab_behavior == "insert":
            self.tabs.insertTab(self.tabs.currentIndex()+1, complete_tab_widget,
                                    unicode(new_tab.title()))
        elif self.new_tab_behavior == "append":
            self.tabs.appendTab(complete_tab_widget, unicode(new_tab.title()))
        self.tabs.setCurrentWidget(complete_tab_widget)
        self.tabs.setTabText(self.tabs.currentIndex(),
                             unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).title()))
        self.tabs.setUpdatesEnabled(True)
        # tab.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        # tab.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
        new_tab.titleChanged.connect(self.change_tab)
        new_tab.urlChanged.connect(self.change_tab)
        new_tab.loadStarted.connect(self.load_start)
        new_tab.loadFinished.connect(self.load_finish)
        new_tab.loadProgress.connect(self.pbar.setValue)
        new_tab.page().linkHovered.connect(self.linkHover)
        inspector.setPage(new_tab.page())

    def change_tab(self):
        """Change active tab."""
        if self.tabs.count() <= 1:
            self.tabs.tabBar().hide()
        else:
            self.tabs.tabBar().show()

        try:
            self.edit.setText(str(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded()))
            self.tabs.setTabText(self.tabs.currentIndex(),
                                 unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).title()))
            self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).setFocus()
        except Exception:
            self.tabs.tabBar().hide()
            self.new_tab()

        #print (self.tabs.widget(self.tabs.currentIndex()).size().width()-10), self.tabs.count()
        self.tabs_widget.setStyleSheet(self.style_sheet +
                                       "QTabBar::tab { width:" + str(
                                        (self.tabs.widget(
                                            self.tabs.currentIndex()
                                            ).size().width()-26-self.tabs.count()*2)/self.tabs.count()
                                        ) + "px; }")

    def previous_tab(self):
        """Previous tab."""
        try:
            if self.tabs.currentIndex() > 0:
                self.tabs.setCurrentIndex(self.tabs.currentIndex()-1)
            else:
                self.tabs.setCurrentIndex(self.tabs.count()-1)

            self.change_tab()
        except Exception:
            pass

    def next_tab(self):
        """Next tab."""
        try:
            if self.tabs.currentIndex() < self.tabs.count()-1:
                self.tabs.setCurrentIndex(self.tabs.currentIndex()+1)
            else:
                self.tabs.setCurrentIndex(0)

            self.change_tab()
        except Exception: #, e
            pass

    def close_tab(self):
        """Close tab."""
        self.tabs.removeTab(self.tabs.currentIndex())

    def close(self):
        """Close app."""
        Qapplication.quit()

    def set_url(self):
        """Set url."""
        url = self.edit.text()
        # does the url start with http://?
        if "." not in url:
            url = "http://www.google.com/search?q="+url
        elif not url.startswith("http://"):
            url = "http://" + url
        qurl = QUrl(url)
        self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).load(qurl)
        self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).setFocus()

    def load_start(self):
        """Update view values, called upon started page load."""
        self.rbutton.setText(u"╳")
        self.rbutton.clicked.connect(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).stop)
        self.pbar.show()

    def load_finish(self):
        """Update view values, called upon finished page load."""
        if (self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).history().canGoBack()):
            self.bbutton.setEnabled(True)
        else:
            self.bbutton.setEnabled(False)
        if (self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).history().canGoForward()):
            self.fbutton.setEnabled(True)
        else:
            self.fbutton.setEnabled(False)

        self.rbutton.setText(u"↻")
        self.rbutton.clicked.connect(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).reload)
        self.pbar.hide()

        global bookmarks
        if unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded()) in bookmarks:
            self.dbutton.setText(u"★")
        else:
            self.dbutton.setText(u"☆")

        if not self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebInspector, unicode('webInspector')).isHidden():
            self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebInspector, unicode('webInspector')).hide()
            self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebInspector, unicode('webInspector')).show()

    def bookmark(self):
        """Toggle bookmark."""
        global bookmarks
        if not self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded() in bookmarks:
            bookmarks.append(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded())
            pickle.dump(bookmarks, open(bookFile, "wb"))
            link = QToolButton()
            link.setDefaultAction(QAction(unicode(unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded())), link))
            link.setObjectName(unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded()))
            link.setFont(QFont("Helvetica Neue", 11, QFont.Normal))
            link.clicked.connect(self.handleBookmarks)
            self.bookmarks_layout.addWidget(link)

            if self.bookmarks_widget.isHidden():
                self.bookmarks_widget.show()

            self.dbutton.setText(u"★")

        else:
            bookmarks.remove(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded())
            pickle.dump(bookmarks, open(bookFile, "wb"))
            link = self.bookmarks_widget.findChild(QToolButton, unicode(self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).url().toEncoded()))
            self.bookmarks_layout.removeWidget(link)
            link.deleteLater()
            link = None

            if not bookmarks:
                self.bookmarks_widget.hide()

            self.dbutton.setText(u"☆")

    def handleBookmarks(self):

        self.gotoLink(self.sender().objectName())
        #self.gotoLink(unicode())

    def gotoLink(self, url):

        self.tabs.currentWidget().findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).load(QUrl(url))

    def styleSheet(self, style_sheet):
        """Load stylesheet."""
        try:
            with open(os.path.join
                      (basedir, 'assets', 'style.qss'), 'r') as file:
                return file.read()
        except Exception:
            # print e
            return ''

    def resizeEvent(self, evt=None):
        """Called on window resize."""
        self.change_tab()

    def myExitHandler(self):
        """Exiting."""
        pass
        global tabFile

    # {current_tab: 1, tabs:[0: {current_history:3, history:[{title, url}]]}
        pb = {'current_tab': self.tabs.currentIndex()}
        pb['tabs'] = list()
        for tab in range(self.tabs.count()):
            pb['tabs'].append(dict(current_history=self.tabs.widget(
                tab).findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).history().currentItemIndex(), history=list(dict(
                    title=item.title(), url=item.url()
                    ) for item in self.tabs.widget(tab).findChild(QFrame, unicode('pageWidget')).findChild(QWebView, unicode('webView')).history().items())))

        # print pb
        pickle.dump(pb, open(tabFile, "wb"))
Esempio n. 12
0
class FindOrderDialog(QDialog):
    def __init__(self,parent):
        global dao
        super(FindOrderDialog,self).__init__(parent)

        title = _("Find order")
        self.setWindowTitle(title)
        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title,self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Search")))
        self.search_criteria = QLineEdit()
        self.search_criteria.setObjectName("search_criteria")
        hlayout.addWidget(self.search_criteria)
        top_layout.addLayout(hlayout)



        self.search_results_view = QTableView()

        self.headers_view = QHeaderView(Qt.Orientation.Horizontal)
        self.header_model = make_header_model([_("Preorder Nr"),_("Order Nr"),_("Customer Nr"),_("Customer"),_("Order Part")])
        self.headers_view.setModel(self.header_model) # qt's doc : The view does *not* take ownership (bt there's something with the selecion mode

        self.search_results_model = QStandardItemModel()
        self.search_results_view.setModel(self.search_results_model)

        self.search_results_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.search_results_view.setHorizontalHeader(self.headers_view)
        self.search_results_view.verticalHeader().hide()
        # self.search_results_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(3, QHeaderView.Stretch)
        self.search_results_view.horizontalHeader().setResizeMode(4, QHeaderView.Stretch)

        self.search_results_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton( QDialogButtonBox.Ok)
        self.buttons.button(QDialogButtonBox.Ok).setObjectName("go_search")

        top_layout.addWidget(self.search_results_view)
        top_layout.setStretch(2,1000)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.search_results_view.activated.connect(self.row_activated)
        self.search_criteria.returnPressed.connect(self.search_criteria_submitted)

        self.setMinimumSize(800,640)

    def find_by_text(self,text):
        text = text.strip()

        try:
            too_many_results, res = dao.order_part_dao.find_ids_by_text(text.strip())

            if too_many_results:
                showWarningBox(_("Too many results"),_("The query you've given brought back too many results. Only a part of them is displayed. Consider refining your query"),object_name="too_many_results")

            return dao.order_part_dao.find_by_ids(res)

        except DataException as de:

            if de.code == DataException.CRITERIA_IS_EMPTY:
                showErrorBox(_("Error in the filter !"),
                             _("The filter can't be empty"),object_name="filter_is_empty")
            elif de.code == DataException.CRITERIA_IS_TOO_SHORT:
                showErrorBox(_("Error in the filter !"),
                             _("The filter is too short"),object_name="filter_is_too_short")
            elif de.code == DataException.CRITERIA_IS_TOO_LONG:
                showErrorBox(_("Error in the filter !"),
                             _("The filter is too long"),object_name="filter_is_too_long")

            return []
        


        # order_part_match = []
        # matches = []
        # super_matches = []

        # import re
        # re_order_part_identifier = re.compile("^([0-9]+)([A-Z]+)$")
        # re_label_identifier = re.compile("^[0-9]+$")

        # if re_order_part_identifier.match(text.upper()):
        #     # Look for an exact (and unique) match on the order part full identifier
        #     p = dao.order_part_dao.find_by_full_id(text.upper())
        #     if p:
        #         # Mimick SQLAlchemy's KeyTuples
        #         # FIXME It seems that I use something that's internal to SQLA
        #         # Search SQLA's doc for KeyedTuple to find about collections.namedtuple()

        #         from sqlalchemy.util._collections import KeyedTuple

        #         kt = KeyedTuple([p.order_id, p.order.preorder_label, p.order.accounting_label, p.order.customer_order_name, p.order.customer.fullname, p.order.creation_date, p.description, p.order_part_id, p.label],
        #                         labels=['order_id','preorder_label','accounting_label','customer_order_name','fullname','creation_date','description','order_part_id','label'])

        #         order_part_match = [ kt ]

        # if re_label_identifier.match(text):
        #     for r in dao.order_dao.find_by_labels(int(text)):
        #         super_matches.append(r)

        # for r in dao.order_dao.find_by_customer_name(text):
        #     # mainlog.debug('customer name match on {}'.format(text))
        #     matches.append(r)

        # for r in dao.order_dao.find_by_customer_order_name(text):
        #     # mainlog.debug('customer name match on {}'.format(text))
        #     matches.append(r)

        # for r in dao.order_part_dao.find_by_description(text):
        #     matches.append(r)

        # # Finally we order the matches to bring the most relevant
        # # first. The "most relevant" is really a business order.

        # return order_part_match + super_matches + \
        #     sorted(matches, lambda a,b: - cmp(a.order_id,b.order_id))


    def _search_results_to_array(self,search_results):
        array = []
        
        for res in search_results:
            # mainlog.debug("_search_results_to_array {}".format(res.creation_date))

            i = QStandardItem(res.preorder_part_label)
            row = [i,
                   QStandardItem(res.accounting_part_label),
                   QStandardItem(res.customer_order_name),
                   QStandardItem(res.fullname)]

            if 'order_part_id' in res.__dict__:
                # It's an order part

                i.setData( res.order_part_id, Qt.UserRole)
                i.setData( 'order_part', Qt.UserRole+1)
                row.append( QStandardItem(res.description))
            else:
                # It's an order

                i.setData( res.order_id, Qt.UserRole)
                i.setData( 'order', Qt.UserRole+1)
                row.append( QStandardItem())

            array.append(row)

        return array


    def load_search_results(self,text=None):
        global dao

        if text is None:
            text = self.search_criteria.text()

        db_results = self.find_by_text(text)
        array = self._search_results_to_array(db_results)

        self.search_results_model.removeRows(0,self.search_results_model.rowCount())
        for row in array:
            self.search_results_model.appendRow(row)
        mainlog.debug("Loaded model : {}".format(self.search_results_model.rowCount()))
        self.search_results_view.resizeColumnsToContents()

        if self.search_results_model.rowCount() > 0:
            self.search_results_view.setCurrentIndex(self.search_results_model.index(0,0))
            self.search_results_view.setFocus(Qt.OtherFocusReason)

        if self.search_results_model.rowCount() == 1:
            self.accept()


    def selected_item(self):
        mainlog.debug("FindOrder.selected_item")
        ndx = self.search_results_view.currentIndex()
        if ndx.isValid():
            ndx = self.search_results_view.model().index( ndx.row(), 0)

            item = ndx.data(Qt.UserRole)
            item_type = ndx.data(Qt.UserRole+1)

            if item_type == 'order':
                mainlog.debug("FindOrder.selected_item order_id={}".format(item))
                return dao.order_dao.find_by_id(item)
            elif item_type == 'order_part':
                mainlog.debug("FindOrder.selected_item order_part_id={}".format(item))
                return dao.order_part_dao.find_by_id(item)
            else:
                mainlog.error("Unsupported item type {}".format(item_type))
        else:
            mainlog.error("Invalid index")
            return None

    @Slot()
    def accept(self):
        # mainlog.debug("accept")
        # self.load_search_results()
        # mainlog.debug("accept - done")
        return super(FindOrderDialog,self).accept()

    @Slot()
    def reject(self):
        return super(FindOrderDialog,self).reject()

    @Slot()
    def search_criteria_submitted(self):
        mainlog.debug("search_criteria_submitted")
        self.load_search_results()

    @Slot(QModelIndex)
    def row_activated(self,ndx):
        mainlog.debug("row_activated")
        self.accept()

    def keyPressEvent(self,event):

        # The goal here is to make sure the accept signal is called only
        # if the user clicks on the "OK" button /with the mouse/ and,
        # not with the keyboard

        if event.key() in (Qt.Key_Enter, Qt.Key_Return):
            return
        else:
            super(FindOrderDialog,self).keyPressEvent(event)
Esempio n. 13
0
class ConsoleWidget(QMainWindow):
    def __init__(self):
        super(ConsoleWidget, self).__init__()
        self.setWindowTitle('1c query')

        self._connection = None

        self._home = os.path.expanduser('~/%s' % QApplication.applicationName())
        if not os.path.isdir(self._home):
            os.mkdir(self._home)

        self.queryToolBar = self.addToolBar('Query')
        self.queryAction = self.queryToolBar.addAction('Run', self.executeQuery)
        self.queryAction.setDisabled(True)

        uri_history = list()
        path = os.path.join(self._home, 'uri_history.txt')
        if os.path.isfile(path):
            uri_history = open(path, 'r').read().split('\n')

        self.connectionToolBar = self.addToolBar('Connection')
        self.connectionUriCombo = QComboBox(self)
        self.connectionUriCombo.setEditable(True)
        if not uri_history:
            self.connectionUriCombo.addItem('File="";usr="";pwd="";')
            self.connectionUriCombo.addItem('Srvr="{host}";Ref="{ref}";Usr="******";Pwd="{password}";')
        else:
            self.connectionUriCombo.addItems(uri_history)
            self.connectionUriCombo.setCurrentIndex(len(uri_history) - 1)
        self.connectionUriCombo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
        self.connectionToolBar.addWidget(self.connectionUriCombo)

        self.onesVersionCombo = QComboBox(self)
        self.onesVersionCombo.addItems(['8.3', '8.2', '8.1', '8.0'])
        self.onesVersionCombo.setCurrentIndex(0)
        self.connectionToolBar.addWidget(self.onesVersionCombo)
        self.connectAction = self.connectionToolBar.addAction('Connect', self.connectOneS)
        self.disconnectAction = self.connectionToolBar.addAction('Disconnect', self.disconnectOneS)
        self.disconnectAction.setDisabled(True)

        self.logEdit = QPlainTextEdit(self)
        self.logDock = QDockWidget('Log', self)
        self.logDock.setWidget(self.logEdit)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logDock, Qt.Horizontal)

        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)

        self.sqlEdit = QTextEdit(self)
        self.sqlEdit.setLineWrapMode(QTextEdit.NoWrap)

        path = os.path.join(self._home, 'last-sql.txt')
        if os.path.isfile(path):
            sql = open(path, 'r').read()
            self.sqlEdit.setText(sql)

        self.model = QStandardItemModel(self)
        self.tableView = QTableView(self)
        self.tableView.setModel(self.model)

        self.splitter.addWidget(self.sqlEdit)
        self.splitter.addWidget(self.tableView)
        self.splitter.setStretchFactor(0, 3)
        self.splitter.setStretchFactor(1, 2)

    def query(self, sql):
        if not self._connection:
            self.logEdit.appendPlainText('No connection')
            return None

        try:
            query = self._connection.NewObject('Query', sql)
            result = query.Execute()
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return None

        return result

    def refresh(self, result):
        self.model.clear()

        columns = list()
        result_columns = result.Columns
        for index in range(result_columns.Count()):
            name = result_columns.Get(index).Name
            columns.append(name)

        self.model.setColumnCount(len(columns))
        for section, name in enumerate(columns):
            self.model.setHeaderData(section, Qt.Horizontal, name)

        select = result.Choose()
        self.logEdit.appendPlainText('Selected %d records' % select.Count())
        while select.Next():
            items = list()
            for index in range(len(columns)):
                value = select.Get(index)

                item = QStandardItem('')
                if isinstance(value, bool):
                    item.setText(value and 'Yes' or 'No')

                elif isinstance(value, (int, str)):
                    item.setText(str(value))

                elif isinstance(value, datetime.datetime):
                    item.setText(value.strftime('%Y.%m.%d %H:%M:%S'))

                else:
                    item.setText(str(value))
                items.append(item)

            self.model.appendRow(items)

    @Slot()
    def executeQuery(self):
        sql = self.sqlEdit.toPlainText()
        result = self.query(sql)
        if result:
            path = os.path.join(self._home, 'last-sql.txt')
            open(path, 'w').write(sql)
            self.refresh(result)

    @Slot()
    def connectOneS(self):
        uri = self.connectionUriCombo.currentText().strip()
        if not uri:
            self.logEdit.appendPlainText('Need a connection string')
            return

        version = self.onesVersionCombo.currentText()
        comName = "V%s.COMConnector" % str(version).replace('.', '')

        pythoncom.CoInitialize()
        try:
            obj = win32com.client.Dispatch(comName)
            self._connection = obj.Connect(uri)
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return

        self.connectAction.setDisabled(True)
        self.disconnectAction.setEnabled(True)
        self.queryAction.setEnabled(True)

        uri_history = list()
        for i in range(self.connectionUriCombo.count()):
            uri_history.append(self.connectionUriCombo.itemText(i))

        if uri not in uri_history:
            self.connectionUriCombo.clearEditText()
            self.connectionUriCombo.addItem(uri)
            self.connectionUriCombo.setCurrentIndex(len(uri_history))
            uri_history.append(uri)
            path = os.path.join(self._home, 'uri_history.txt')
            open(path, 'w').write('\n'.join(uri_history))

    @Slot()
    def disconnectOneS(self):
        pythoncom.CoUninitialize()
        self._connection = None
        self.connectAction.setEnabled(True)
        self.disconnectAction.setDisabled(True)
        self.queryAction.setDisabled(True)
Esempio n. 14
0
class List(QMainWindow):
    """All Notes dialog"""

    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.closed = False
        self.sort_order = None
        self._init_interface()
        self.app.data_changed.connect(self._reload_data)
        self._init_notebooks()
        self._init_tags()
        self._init_notes()

    def _init_interface(self):
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())
        self.setWindowTitle(self.tr("Everpad / All Notes"))
        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    def _init_notebooks(self):
        self._current_notebook = None
        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(self.notebook_context_menu)

    def _init_tags(self):
        self._current_tag = None
        self.tagsModel = QStandardItemModel()
        self.ui.tagsList.setModel(self.tagsModel)
        self.ui.tagsList.selection.connect(self.tag_selection_changed)
        self.ui.tagsList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tagsList.customContextMenuRequested.connect(self.tag_context_menu)

    def _init_notes(self):
        self._current_note = None
        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.selection.connect(self.note_selection_changed)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(self.sort_order_updated)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.tagsList.clearSelection()
            self.notebook_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def tag_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.notebooksList.clearSelection()
            self.tag_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def note_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.note_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        super(List, self).showEvent(*args, **kwargs)
        self._reload_data()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def note_selected(self, index):
        self._current_note = index

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0

        self._current_notebook = notebook_id
        self._current_tag = SELECT_NONE

        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array([], signature='i')

        if hasattr(item, 'stack'):  # stack selected, retrieve all underlying notebooks
            notebook_filter = []
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    notebook_filter.append(notebook.id)

        notes = self.app.provider.find_notes(
            '', notebook_filter, dbus.Array([], signature='i'),
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64

        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    def tag_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            tag_id = item.tag.id
        else:
            tag_id = 0

        self._current_notebook = SELECT_NONE
        self._current_tag = tag_id

        tag_filter = [tag_id] if tag_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '', dbus.Array([], signature='i'), tag_filter,
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self, oldStack=''):
        name, status, stack = self._notebook_new_name(self.tr('Create new notebook'), '', oldStack)
        if status:
            notebook_struct = self.app.provider.create_notebook(name, stack)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status, stack = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name, notebook.stack
        )
        if status:
            notebook.name = name
            notebook.stack = stack
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr("Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def rename_stack(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        stack = item.stack
        name, status = self._stack_new_name(
            self.tr('Rename stack'), stack,
        )
        if status:
            # loop notebooks and update stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    notebook.stack = name
                    self.app.provider.update_notebook(notebook.struct)

            self.app.send_notify(self.tr('Stack "%s" renamed!') % name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_stack(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a stack"),
            self.tr("Are you sure want to delete this stack? Notebooks and notes are preserved."),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            # loop notebooks and remove stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    print "Clearing one notebook from its stack."
                    notebook.stack = ''
                    self.app.provider.update_notebook(notebook.struct)

            self._reload_notebooks_list()

    @Slot()
    def remove_tag(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a tag"),
            self.tr("Are you sure want to delete this tag and untag all notes tagged with it?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.tagsList.currentIndex()
            item = self.tagsModel.itemFromIndex(index)
            self.app.provider.delete_tag(item.tag.id)
            self.app.send_notify(self.tr('Tag "%s" deleted!') % item.tag.name)
            self._reload_tags_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') % item.note.title,
            QMessageBox.Yes | QMessageBox.No
        )
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
        if hasattr(item, 'stack'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_stack)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_stack)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def tag_context_menu(self, pos):
        index = self.ui.tagsList.currentIndex()
        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            menu = QMenu(self.ui.tagsList)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_tag)
            menu.exec_(self.ui.tagsList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'), self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_data(self):
        self._reload_notebooks_list(self._current_notebook)
        self._reload_tags_list(self._current_tag)
        self._mark_note_selected(self._current_note)

    def _reload_notebooks_list(self, select_notebook_id=None):
        # TODO could enable selecting an already selected stack
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Notes'))
        self.notebooksModel.appendRow(root)
        selected_item = root

        stacks = {}
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)

            if(notebook.stack == ''):
                root.appendRow(item)
            else:
                if(notebook.stack not in stacks.keys()):
                    stack = QStandardItem(QIcon.fromTheme('user-home'), notebook.stack)
                    stack.stack = notebook.stack
                    root.appendRow(stack)
                    stacks[notebook.stack] = stack

                stacks[notebook.stack].appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()

        if selected_item and not select_notebook_id == SELECT_NONE:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude='', oldStack=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name, self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self, title, self.tr('Enter notebook name:'), text=exclude)
        while name in names and status:
            message = self.tr('Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        if status:
            stack, status = QInputDialog.getText(self, title, self.tr('Enter stack name (empty for no stack):'), text=oldStack)
        else:
            stack = oldStack
        return name, status, stack

    def _stack_new_name(self, title, value=''):
        name, status = QInputDialog.getText(self, title, self.tr('Enter stack name:'), text=value)
        return name, status

    def _reload_tags_list(self, select_tag_id=None):
        # TODO nested tags
        self.tagsModel.clear()
        tagRoot = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Tags'))
        self.tagsModel.appendRow(tagRoot)
        selected_item = tagRoot

        for tag_struct in self.app.provider.list_tags():
            tag = Tag.from_tuple(tag_struct)
            count = self.app.provider.get_tag_notes_count(tag.id)
            item = QTagItem(tag, count)
            tagRoot.appendRow(item)

            if select_tag_id and tag.id == select_tag_id:
                selected_item = item

        self.ui.tagsList.expandAll()
        if selected_item and not select_tag_id == SELECT_NONE:
            index = self.tagsModel.indexFromItem(selected_item)
            self.ui.tagsList.setCurrentIndex(index)
            self.tag_selected(index)

    def _mark_note_selected(self, index):
        if index:
            self.ui.notesList.setCurrentIndex(index)
Esempio n. 15
0
class List(QDialog):
    """All Notes dialog"""
    def __init__(self, app, *args, **kwargs):
        QDialog.__init__(self, *args, **kwargs)
        self.app = app
        self.closed = False
        self.sort_order = None
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())

        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(
            self.notebook_context_menu)

        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(
            self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(
            self.sort_order_updated)

        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.notebook_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        QDialog.showEvent(self, *args, **kwargs)
        self._reload_notebooks_list()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0
        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array(
            [], signature='i')
        notes = self.app.provider.find_notes(
            '',
            notebook_filter,
            dbus.Array([], signature='i'),
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self):
        name, status = self._notebook_new_name(self.tr('Create new notebook'))
        if status:
            notebook_struct = self.app.provider.create_notebook(name)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(
                self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status = self._notebook_new_name(
            self.tr('Rename notebook'),
            notebook.name,
        )
        if status:
            notebook.name = name
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(
                self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr(
                "Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(
                self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') %
            item.note.title, QMessageBox.Yes | QMessageBox.No)
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(
                self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'),
                       self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                       self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_notebooks_list(self, select_notebook_id=None):
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'),
                             self.tr('All Notes'))
        self.notebooksModel.appendRow(root)

        selected_item = root
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)
            root.appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()
        if selected_item:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name,
                    self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter notebook name:'),
                                            text=exclude)
        while name in names and status:
            message = self.tr(
                'Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        return name, status
Esempio n. 16
0
class TemplateSelectDialog(QDialog):
    def refresh_templates_list(self):

        documents = documents_service.all_templates()

        self.model.removeRows(0, self.model.rowCount())

        if documents:
            for doc in sorted(list(documents), key=lambda d: d.filename):
                self._add_one_document(doc.filename, doc.template_document_id,
                                       doc.file_size, doc.description)

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

        self.setWindowTitle(_("Select a template"))

        self.template_id = []

        self.model = QStandardItemModel()
        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.verticalHeader().setVisible(False)
        self.view.horizontalHeader().setVisible(False)
        self.view.setMinimumSize(500, 200)
        self.view.setShowGrid(True)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)

        l = QVBoxLayout()

        l.addWidget(QLabel(_("Please select one or more template.")))
        self.view.doubleClicked.connect(self._doubleClicked)

        l.addWidget(QLabel(u"<h3>{}</h3>".format(_("Documents Templates"))))
        l.addWidget(self.view)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        l.addWidget(self.buttons)

        self.setLayout(l)

    def _add_one_document(self, file_name, doc_id, file_size, description):
        """ Adds a document to the list
        """

        # file_name is either an absolute path or just a file name
        # If it is an absolute path, then the file is expected
        # to exist locally (at it absolute path location of course).
        # If not, then the file is expected to be a remote file
        # and shall be downloaded before opening.

        mainlog.debug(u"{} {} {} {}".format(file_name, doc_id, file_size,
                                            description))
        short_name = file_name
        if os.path.isabs(file_name):
            short_name = os.path.basename(file_name)
            if not os.path.isfile(file_name):
                raise Exception(u"The file {} doesn't exist".format(file_name))

        items = [QStandardItem(short_name)]
        items.append(QStandardItem(description))

        self.model.appendRow(items)
        self.model.setData(self.model.index(self.model.rowCount() - 1, 0),
                           doc_id, Qt.UserRole + 1)

        self.view.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.view.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
        self.view.resizeRowsToContents()

    @Slot()
    def accept(self):
        selected_rows = self.view.selectionModel().selectedRows()
        if selected_rows:
            self.template_id = []
            for row in selected_rows:
                ndx_row = row.row()
                self.template_id.append(
                    self.model.data(self.model.index(ndx_row, 0),
                                    Qt.UserRole + 1))
        else:
            self.template_id = []
        return super(TemplateSelectDialog, self).accept()

    @Slot()
    def reject(self):
        return super(TemplateSelectDialog, self).reject()

    @Slot(QModelIndex)
    def _doubleClicked(self, ndx):
        self.accept()
Esempio n. 17
0
class List(QMainWindow):
    """All Notes dialog"""
    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.closed = False
        self.sort_order = None
        self._init_interface()
        self.app.data_changed.connect(self._reload_data)
        self._init_notebooks()
        self._init_tags()
        self._init_notes()

    def _init_interface(self):
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())
        self.setWindowTitle(self.tr("Everpad / All Notes"))
        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(
            QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    def _init_notebooks(self):
        self._current_notebook = None
        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(
            self.notebook_context_menu)

    def _init_tags(self):
        self._current_tag = None
        self.tagsModel = QStandardItemModel()
        self.ui.tagsList.setModel(self.tagsModel)
        self.ui.tagsList.selection.connect(self.tag_selection_changed)
        self.ui.tagsList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tagsList.customContextMenuRequested.connect(
            self.tag_context_menu)

    def _init_notes(self):
        self._current_note = None
        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.selection.connect(self.note_selection_changed)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(
            self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(
            self.sort_order_updated)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.tagsList.clearSelection()
            self.notebook_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def tag_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.notebooksList.clearSelection()
            self.tag_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def note_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.note_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        super(List, self).showEvent(*args, **kwargs)
        self._reload_data()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def note_selected(self, index):
        self._current_note = index

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0

        self._current_notebook = notebook_id
        self._current_tag = SELECT_NONE

        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array(
            [], signature='i')

        if hasattr(
                item,
                'stack'):  # stack selected, retrieve all underlying notebooks
            notebook_filter = []
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    notebook_filter.append(notebook.id)

        notes = self.app.provider.find_notes(
            '',
            notebook_filter,
            dbus.Array([], signature='i'),
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64

        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    def tag_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            tag_id = item.tag.id
        else:
            tag_id = 0

        self._current_notebook = SELECT_NONE
        self._current_tag = tag_id

        tag_filter = [tag_id] if tag_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '',
            dbus.Array([], signature='i'),
            tag_filter,
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self, oldStack=''):
        name, status, stack = self._notebook_new_name(
            self.tr('Create new notebook'), '', oldStack)
        if status:
            notebook_struct = self.app.provider.create_notebook(name, stack)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(
                self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status, stack = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name, notebook.stack)
        if status:
            notebook.name = name
            notebook.stack = stack
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(
                self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr(
                "Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(
                self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def rename_stack(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        stack = item.stack
        name, status = self._stack_new_name(
            self.tr('Rename stack'),
            stack,
        )
        if status:
            # loop notebooks and update stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    notebook.stack = name
                    self.app.provider.update_notebook(notebook.struct)

            self.app.send_notify(self.tr('Stack "%s" renamed!') % name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_stack(self):
        msg = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a stack"),
            self.
            tr("Are you sure want to delete this stack? Notebooks and notes are preserved."
               ), QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            # loop notebooks and remove stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    print "Clearing one notebook from its stack."
                    notebook.stack = ''
                    self.app.provider.update_notebook(notebook.struct)

            self._reload_notebooks_list()

    @Slot()
    def remove_tag(self):
        msg = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a tag"),
            self.
            tr("Are you sure want to delete this tag and untag all notes tagged with it?"
               ), QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.tagsList.currentIndex()
            item = self.tagsModel.itemFromIndex(index)
            self.app.provider.delete_tag(item.tag.id)
            self.app.send_notify(self.tr('Tag "%s" deleted!') % item.tag.name)
            self._reload_tags_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') %
            item.note.title, QMessageBox.Yes | QMessageBox.No)
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(
                self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
        if hasattr(item, 'stack'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_stack)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_stack)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def tag_context_menu(self, pos):
        index = self.ui.tagsList.currentIndex()
        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            menu = QMenu(self.ui.tagsList)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_tag)
            menu.exec_(self.ui.tagsList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'),
                       self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                       self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_data(self):
        self._reload_notebooks_list(self._current_notebook)
        self._reload_tags_list(self._current_tag)
        self._mark_note_selected(self._current_note)

    def _reload_notebooks_list(self, select_notebook_id=None):
        # TODO could enable selecting an already selected stack
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'),
                             self.tr('All Notes'))
        self.notebooksModel.appendRow(root)
        selected_item = root

        stacks = {}
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)

            if (notebook.stack == ''):
                root.appendRow(item)
            else:
                if (notebook.stack not in stacks.keys()):
                    stack = QStandardItem(QIcon.fromTheme('user-home'),
                                          notebook.stack)
                    stack.stack = notebook.stack
                    root.appendRow(stack)
                    stacks[notebook.stack] = stack

                stacks[notebook.stack].appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()

        if selected_item and not select_notebook_id == SELECT_NONE:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude='', oldStack=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name,
                    self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter notebook name:'),
                                            text=exclude)
        while name in names and status:
            message = self.tr(
                'Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        if status:
            stack, status = QInputDialog.getText(
                self,
                title,
                self.tr('Enter stack name (empty for no stack):'),
                text=oldStack)
        else:
            stack = oldStack
        return name, status, stack

    def _stack_new_name(self, title, value=''):
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter stack name:'),
                                            text=value)
        return name, status

    def _reload_tags_list(self, select_tag_id=None):
        # TODO nested tags
        self.tagsModel.clear()
        tagRoot = QStandardItem(QIcon.fromTheme('user-home'),
                                self.tr('All Tags'))
        self.tagsModel.appendRow(tagRoot)
        selected_item = tagRoot

        for tag_struct in self.app.provider.list_tags():
            tag = Tag.from_tuple(tag_struct)
            count = self.app.provider.get_tag_notes_count(tag.id)
            item = QTagItem(tag, count)
            tagRoot.appendRow(item)

            if select_tag_id and tag.id == select_tag_id:
                selected_item = item

        self.ui.tagsList.expandAll()
        if selected_item and not select_tag_id == SELECT_NONE:
            index = self.tagsModel.indexFromItem(selected_item)
            self.ui.tagsList.setCurrentIndex(index)
            self.tag_selected(index)

    def _mark_note_selected(self, index):
        if index:
            self.ui.notesList.setCurrentIndex(index)
Esempio n. 18
0
class BrowserWindow(QMainWindow):

    MO_ROLE = Qt.UserRole+1

    def __init__(self, conn):
        super(BrowserWindow, self).__init__()
        self._conn = conn
        self._resolver = AsyncResolver()
        self._resolver.object_resolved.connect(self._data_resolved)
        self._resolver.start()
        self._init_models()
        self._init_gui()
        self._init_data()
        self._init_connections()

    def __del__(self):
        self._resolver.stop_work()
        self._resolver.terminate()

    def _init_models(self):
        self._hierarchy_model = QStandardItemModel()
        self._hierarchy_model.setColumnCount(2)
        self._hierarchy_model.setHorizontalHeaderLabels(['class', 'dn'])
        self._details_model = QStandardItemModel()
        self._details_model.setColumnCount(2)
        self._details_model.setHorizontalHeaderLabels(['Property', 'Value'])

    def _init_gui(self):
        self._widget = QSplitter(self, Qt.Horizontal)
        self._hierarchy_view = QTreeView(self._widget)
        self._details_view = QTableView(self._widget)

        self._widget.addWidget(self._hierarchy_view)
        self._widget.addWidget(self._details_view)
        self._widget.setStretchFactor(0, 2)
        self._widget.setStretchFactor(1, 1)
        self.setCentralWidget(self._widget)

        self._hierarchy_view.setModel(self._hierarchy_model)
        self._details_view.setModel(self._details_model)

        self._hierarchy_view.expanded.connect(self._mo_item_expand)

    def _init_data(self):
        item = self._row_for_mo(self._conn.resolve_dn(''))
        self._hierarchy_model.insertRow(0, item)

    def _init_connections(self):
        self.connect(self._resolver,
                        SIGNAL('object_resolved(QVariant)'),
                     self,
                        SLOT('_data_resolved(QVariant)'))
        self._hierarchy_view.activated.connect(self._item_activated)
        #self.connect(self._hierarchy_view.selectionModel(),
        #                SIGNAL('currentChanged(QModelIndex,QModelIndex)'),
        #             self,
        #                SLOT('_current_changed(QModelIndex, QModelIndex)'))
        self.connect(self._hierarchy_view.selectionModel(),
                        SIGNAL('activated(QModelIndex)'),
                     self,
                        SLOT('_item_activated(QModelIndex)'))


    def _row_for_mo(self, mo):
        row = [QStandardItem(mo.ucs_class), QStandardItem(mo.dn)]
        for item in row:
            item.setEditable(False)
        row[0].appendColumn([QStandardItem('Loading...')])
        row[0].setData(mo, self.MO_ROLE)
        return row

    def _add_mo_in_tree(self, mo, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            item = self._get_item_for_dn(self._parent_dn(mo.dn))
        if item:
            item.appendColumn([self._row_for_mo(mo)[0]])
        self.auto_width()

    def _add_mos_in_tree(self, mos, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            if not mos:
                return
            item = self._get_item_for_dn(self._parent_dn(mos[0].dn))
        while item.columnCount():
            item.removeColumn(0)
        items = map(self._row_for_mo, mos)
        if items:
            for x in xrange(len(items[0])):
                item.appendColumn([row[x] for row in items])
        self.auto_width()

    @staticmethod
    def _parent_dn(dn):
        parent_dn, _, rn = dn.rpartition('/')
        return parent_dn

    def _get_item_for_dn(self, dn):
        parent_dn = dn
        items = self._hierarchy_model.findItems(parent_dn, column=1)
        if items:
            return self._hierarchy_model.item(items[0].row())
        return None

    @QtCore.Slot('_data_resolved(QVariant)')
    def _data_resolved(self, datav):
        print 'Data resolved: ', datav
        index, data = datav
        if isinstance(data, UcsmObject):
            self._add_mo_in_tree(data, index=index)
        else:
            self._add_mos_in_tree(data, index=index)

    @QtCore.Slot('_current_changed(QModelIndex,QModelIndex)')
    def _current_changed(self, curr, prev):
        self._item_activated(curr)

    @QtCore.Slot('_item_activated(QModelIndex)')
    def _item_activated(self, index):
        print 'Activated: %s data %s' % (index, index.data(self.MO_ROLE))
        if index.sibling(0, 0).isValid():
            index = index.sibling(0, 0)
            data = index.data(self.MO_ROLE)
            self.set_detail_object(data)

    def _mo_item_expand(self, index):
        obj = index.data(self.MO_ROLE)
        print 'Expanded object: %s' % obj
        try:
            self._resolver.add_task(lambda: (index,
                                        self._conn.resolve_children(obj.dn)))
        except (KeyError, AttributeError):
            QtGui.QMessageBox.critical(0, 'Error', 'Object does not have dn')

    def auto_width(self):
        for view in [self._hierarchy_view, self._details_view]:
            for col in xrange(view.model().columnCount()):
                view.resizeColumnToContents(col)

    def set_detail_object(self, object):
        self._details_model.removeRows(0, self._details_model.rowCount())
        for k, v in object.attributes.iteritems():
            row = [QStandardItem(k), QStandardItem(v)]
            for item in row:
                item.setEditable(False)
            self._details_model.appendRow(row)
        self.auto_width()
Esempio n. 19
0
class List(QDialog):
    """All Notes dialog"""

    def __init__(self, app, *args, **kwargs):
        QDialog.__init__(self, *args, **kwargs)
        self.app = app
        self.closed = False
        self.sort_order = None
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())

        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(self.notebook_context_menu)

        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(self.sort_order_updated)

        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.notebook_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        QDialog.showEvent(self, *args, **kwargs)
        self._reload_notebooks_list()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0
        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '', notebook_filter, dbus.Array([], signature='i'),
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self):
        name, status = self._notebook_new_name(self.tr('Create new notebook'))
        if status:
            notebook_struct = self.app.provider.create_notebook(name)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name,
        )
        if status:
            notebook.name = name
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr("Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') % item.note.title,
            QMessageBox.Yes | QMessageBox.No
        )
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'), self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_notebooks_list(self, select_notebook_id=None):
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Notes'))
        self.notebooksModel.appendRow(root)

        selected_item = root
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)
            root.appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()
        if selected_item:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name, self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self, title, self.tr('Enter notebook name:'), text=exclude)
        while name in names and status:
            message = self.tr('Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        return name, status
Esempio n. 20
0
class ReprintDeliverySlipDialog(QDialog):
    def __init__(self, parent, dao):
        super(ReprintDeliverySlipDialog, self).__init__(parent)
        self.dao = dao

        title = _("Print a delivery slip")
        self.setWindowTitle(title)
        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, None)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Slip number")))
        self.slip_number = QLineEdit()
        hlayout.addWidget(self.slip_number)
        hlayout.addStretch()

        self.search_results_view = QTableView()
        self.search_results_model = QStandardItemModel()
        self.search_results_model.setHorizontalHeaderLabels(
            [_("Slip Nr"), _("Date"),
             _("Customer"), _("Order")])

        self.search_results_view.setModel(self.search_results_model)
        # self.search_results_view.setHorizontalHeader(self.headers_view)
        self.search_results_view.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.search_results_view.horizontalHeader().setResizeMode(
            1, QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(
            2, QHeaderView.Stretch)
        self.search_results_view.verticalHeader().hide()

        self.slip_part_view = DeliverySlipViewWidget(self)

        hlayout_results = QHBoxLayout()
        hlayout_results.addWidget(self.search_results_view)
        hlayout_results.addWidget(self.slip_part_view)

        self.search_results_model.removeRows(
            0, self.search_results_model.rowCount())
        delivery_slips = self.dao.delivery_slip_part_dao.find_recent()
        for slip in delivery_slips:
            self.search_results_model.appendRow([
                QStandardItem(str(slip[0])),
                QStandardItem(date_to_dmy(slip[1])),
                QStandardItem(slip[2]),
                QStandardItem(slip[3])
            ])

        top_layout.addWidget(self.title_widget)
        top_layout.addLayout(hlayout)
        top_layout.addLayout(hlayout_results)
        top_layout.addWidget(self.buttons)
        top_layout.setStretch(2, 100)
        self.setLayout(top_layout)

        self.search_results_view.setSelectionBehavior(
            QAbstractItemView.SelectRows)
        self.search_results_view.setSelectionMode(
            QAbstractItemView.SingleSelection)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.search_results_view.activated.connect(self.row_activated)
        self.search_results_view.selectionModel().currentRowChanged.connect(
            self.row_selected)

    @Slot(QModelIndex, QModelIndex)
    def row_selected(self, cur_ndx, prev_ndx):
        slip_id = cur_ndx.model().index(cur_ndx.row(), 0).data()
        self.slip_number.setText(str(slip_id))
        self.slip_part_view.set_delivery_slip_parts(
            dao.delivery_slip_part_dao.load_slip_parts_frozen(slip_id))

    @Slot(QModelIndex)
    def row_activated(self, ndx):
        slip_id = ndx.model().index(ndx.row(), 0).data()
        self.slip_number.setText(str(slip_id))
        self.accept()

    @Slot()
    def accept(self):
        try:
            try:
                slip_id = int(self.slip_number.text())
            except ValueError as e:
                makeErrorBox(
                    _("The delivery slip number {} is not valid").format(
                        self.slip_number.text())).exec_()
                return

            if self.dao.delivery_slip_part_dao.id_exists(slip_id):
                print_delivery_slip(self.dao, slip_id)
            else:
                makeErrorBox(
                    _("The delivery slip {} doesn't exist").format(
                        slip_id)).exec_()
                return
        except Exception as e:
            mainlog.exception(e)
            msgBox = makeErrorBox(_("Something wrong happened while printing"))
            msgBox.exec_()

        return super(ReprintDeliverySlipDialog, self).accept()

    @Slot()
    def reject(self):
        return super(ReprintDeliverySlipDialog, self).reject()