def accept(self):
     """
     Public slot handling the acceptance of the dialog.
     """
     if (not self.__addFolder and self.addressEdit.text().isEmpty()) or \
        self.nameEdit.text().isEmpty():
         QDialog.accept(self)
         return
     
     idx = self.currentIndex()
     if not idx.isValid():
         idx = self.__bookmarksManager.bookmarksModel().index(0, 0)
     parent = self.__bookmarksManager.bookmarksModel().node(idx)
     
     if self.__addFolder:
         type_ = BookmarkNode.Folder
     else:
         type_ = BookmarkNode.Bookmark
     bookmark = BookmarkNode(type_)
     bookmark.title = self.nameEdit.text()
     if not self.__addFolder:
         bookmark.url = self.addressEdit.text()
     
     self.__bookmarksManager.addBookmark(parent, bookmark)
     self.__addedNode = bookmark
     
     QDialog.accept(self)
Example #2
0
    def __readBookmarkNode(self, node):
        """
        Private method to read and parse a bookmark subtree.
        
        @param node reference to the node to attach to (BookmarkNode)
        """
        if not self.isStartElement() and self.name() != "bookmark":
            return

        bookmark = BookmarkNode(BookmarkNode.Bookmark, node)
        bookmark.url = self.attributes().value("href").toString()

        while not self.atEnd():
            self.readNext()
            if self.isEndElement():
                break

            if self.isStartElement():
                if self.name() == "title":
                    self.__readTitle(bookmark)
                elif self.name() == "desc":
                    self.__readDescription(bookmark)
                else:
                    self.__skipUnknownElement()

        if bookmark.title.isEmpty():
            bookmark.title = QCoreApplication.translate("XbelReader", "Unknown title")
Example #3
0
    def __newFolder(self):
        """
        Private slot to add a new bookmarks folder.
        """
        currentIndex = self.bookmarksTree.currentIndex()
        idx = QModelIndex(currentIndex)
        sourceIndex = self.__proxyModel.mapToSource(idx)
        sourceNode = self.__bookmarksModel.node(sourceIndex)
        row = -1  # append new folder as the last item per default

        if sourceNode is not None and sourceNode.type() != BookmarkNode.Folder:
            # If the selected item is not a folder, add a new folder to the
            # parent folder, but directly below the selected item.
            idx = idx.parent()
            row = currentIndex.row() + 1

        if not idx.isValid():
            # Select bookmarks menu as default.
            idx = self.__proxyModel.index(1, 0)

        idx = self.__proxyModel.mapToSource(idx)
        parent = self.__bookmarksModel.node(idx)
        node = BookmarkNode(BookmarkNode.Folder)
        node.title = self.trUtf8("New Folder")
        self.__bookmarksManager.addBookmark(parent, node, row)
Example #4
0
    def __readFolder(self, node):
        """
        Private method to read and parse a folder subtree.
        
        @param node reference to the node to attach to (BookmarkNode)
        """
        if not self.isStartElement() and self.name() != "folder":
            return

        folder = BookmarkNode(BookmarkNode.Folder, node)
        folder.expanded = self.attributes().value("folded") == "no"

        while not self.atEnd():
            self.readNext()
            if self.isEndElement():
                break

            if self.isStartElement():
                if self.name() == "title":
                    self.__readTitle(folder)
                elif self.name() == "desc":
                    self.__readDescription(folder)
                elif self.name() == "folder":
                    self.__readFolder(folder)
                elif self.name() == "bookmark":
                    self.__readBookmarkNode(folder)
                elif self.name() == "separator":
                    self.__readSeparator(folder)
                else:
                    self.__skipUnknownElement()
 def dropMimeData(self, data, action, row, column, parent):
     """
     Public method to accept the mime data of a drop action.
     
     @param data reference to the mime data (QMimeData)
     @param action drop action requested (Qt.DropAction)
     @param row row number (integer)
     @param column column number (integer)
     @param parent index of the parent node (QModelIndex)
     @return flag indicating successful acceptance of the data (boolean)
     """
     if action == Qt.IgnoreAction:
         return True
     
     if column > 0:
         return False
     
     parentNode = self.node(parent)
     
     if not data.hasFormat(self.MIMETYPE):
         if not data.hasUrls():
             return False
         
         node = BookmarkNode(BookmarkNode.Bookmark, parentNode)
         node.url = QString.fromUtf8(data.urls()[0].toEncoded())
         
         if data.hasText():
             node.title = data.text()
         else:
             node.title = node.url
         
         self.__bookmarksManager.addBookmark(parentNode, node, row)
         return True
     
     ba = data.data(self.MIMETYPE)
     stream = QDataStream(ba, QIODevice.ReadOnly)
     if stream.atEnd():
         return False
     
     undoStack = self.__bookmarksManager.undoRedoStack()
     undoStack.beginMacro("Move Bookmarks")
     
     while not stream.atEnd():
         encodedData = QByteArray()
         stream >> encodedData
         buffer = QBuffer(encodedData)
         buffer.open(QIODevice.ReadOnly)
         
         reader = XbelReader()
         rootNode = reader.read(buffer)
         for bookmarkNode in rootNode.children():
             rootNode.remove(bookmarkNode)
             row = max(0, row)
             self.__bookmarksManager.addBookmark(parentNode, bookmarkNode, row)
             self.__endMacro = True
     
     return True
 def __convertFromOldBookmarks(self):
     """
     Private method to convert the old bookmarks into the new ones.
     """
     bmNames = Preferences.Prefs.settings.value('Bookmarks/Names')
     bmFiles = Preferences.Prefs.settings.value('Bookmarks/Files')
     
     if bmNames.isValid() and bmFiles.isValid():
         bmNames = bmNames.toStringList()
         bmFiles = bmFiles.toStringList()
         if len(bmNames) == len(bmFiles):
             convertedRootNode = BookmarkNode(BookmarkNode.Folder)
             convertedRootNode.title = self.trUtf8("Converted %1")\
                 .arg(QDate.currentDate().toString(Qt.SystemLocaleShortDate))
             for i in range(len(bmNames)):
                 node = BookmarkNode(BookmarkNode.Bookmark, convertedRootNode)
                 node.title = bmNames[i]
                 url = QUrl(bmFiles[i])
                 if url.scheme().isEmpty():
                     url.setScheme("file")
                 node.url = url.toString()
             self.addBookmark(self.menu(), convertedRootNode)
             
             Preferences.Prefs.settings.remove('Bookmarks')
class BookmarksManager(QObject):
    """
    Class implementing the bookmarks manager.
    
    @signal entryAdded emitted after a bookmark node has been added
    @signal entryRemoved emitted after a bookmark
        node has been removed
    @signal entryChanged emitted after a bookmark node has been changed
    """
    def __init__(self, parent = None):
        """
        Constructor
        
        @param parent reference to the parent object (QObject)
        """
        QObject.__init__(self, parent)
        
        self.__loaded = False
        self.__saveTimer = AutoSaver(self, self.save)
        self.__bookmarkRootNode = None
        self.__toolbar = None
        self.__menu = None
        self.__bookmarksModel = None
        self.__commands = QUndoStack()
        
        self.connect(self, SIGNAL("entryAdded"), 
                     self.__saveTimer.changeOccurred)
        self.connect(self, SIGNAL("entryRemoved"), 
                     self.__saveTimer.changeOccurred)
        self.connect(self, SIGNAL("entryChanged"), 
                     self.__saveTimer.changeOccurred)
    
    def close(self):
        """
        Public method to close the bookmark manager.
        """
        self.__saveTimer.saveIfNeccessary()
    
    def undoRedoStack(self):
        """
        Public method to get a reference to the undo stack.
        
        @return reference to the undo stack (QUndoStack)
        """
        return self.__commands
    
    def changeExpanded(self):
        """
        Public method to handle a change of the expanded state.
        """
        self.__saveTimer.changeOccurred()
    
    def load(self):
        """
        Public method to load the bookmarks.
        """
        if self.__loaded:
            return
        
        self.__loaded = True
        
        bookmarkFile = os.path.join(Utilities.getConfigDir(), "browser", "bookmarks.xbel")
        if not QFile.exists(bookmarkFile):
            ba = QByteArray(DefaultBookmarks)
            bookmarkFile = QBuffer(ba)
            bookmarkFile.open(QIODevice.ReadOnly)
        
        reader = XbelReader()
        self.__bookmarkRootNode = reader.read(bookmarkFile)
        if reader.error() != QXmlStreamReader.NoError:
            KQMessageBox.warning(None,
                self.trUtf8("Loading Bookmarks"),
                self.trUtf8("""Error when loading bookmarks on line %1, column %2:\n"""
                            """%3""")\
                    .arg(reader.lineNumber())\
                    .arg(reader.columnNumber())\
                    .arg(reader.errorString()))
        
        others = []
        for index in range(len(self.__bookmarkRootNode.children()) - 1, -1, -1):
            node = self.__bookmarkRootNode.children()[index]
            if node.type() == BookmarkNode.Folder:
                if (node.title == self.trUtf8("Toolbar Bookmarks") or \
                    node.title == BOOKMARKBAR) and \
                   self.__toolbar is None:
                    node.title = self.trUtf8(BOOKMARKBAR)
                    self.__toolbar = node
                
                if (node.title == self.trUtf8("Menu") or \
                    node.title == BOOKMARKMENU) and \
                   self.__menu is None:
                    node.title = self.trUtf8(BOOKMARKMENU)
                    self.__menu = node
            else:
                others.append(node)
            self.__bookmarkRootNode.remove(node)
            
        if len(self.__bookmarkRootNode.children()) > 0:
            raise RuntimeError("Error loading bookmarks.")
        
        if self.__toolbar is None:
            self.__toolbar = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
            self.__toolbar.title = self.trUtf8(BOOKMARKBAR)
        else:
            self.__bookmarkRootNode.add(self.__toolbar)
        
        if self.__menu is None:
            self.__menu = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
            self.__menu.title = self.trUtf8(BOOKMARKMENU)
        else:
            self.__bookmarkRootNode.add(self.__menu)
        
        for node in others:
            self.__menu.add(node)
        
        self.__convertFromOldBookmarks()
    
    def save(self):
        """
        Public method to save the bookmarks.
        """
        if not self.__loaded:
            return
        
        writer = XbelWriter()
        bookmarkFile = os.path.join(Utilities.getConfigDir(), "browser", "bookmarks.xbel")
        
        # save root folder titles in English (i.e. not localized)
        self.__menu.title = BOOKMARKMENU
        self.__toolbar.title = BOOKMARKBAR
        if not writer.write(bookmarkFile, self.__bookmarkRootNode):
            KQMessageBox.warning(None,
                self.trUtf8("Saving Bookmarks"),
                self.trUtf8("""Error saving bookmarks to <b>%1</b>.""").arg(bookmarkFile))
        
        # restore localized titles
        self.__menu.title = self.trUtf8(BOOKMARKMENU)
        self.__toolbar.title = self.trUtf8(BOOKMARKBAR)
    
    def addBookmark(self, parent, node, row = -1):
        """
        Public method to add a bookmark.
        
        @param parent reference to the node to add to (BookmarkNode)
        @param node reference to the node to add (BookmarkNode)
        @param row row number (integer)
        """
        if not self.__loaded:
            return
        
        command = InsertBookmarksCommand(self, parent, node, row)
        self.__commands.push(command)
    
    def removeBookmark(self, node):
        """
        Public method to remove a bookmark.
        
        @param node reference to the node to be removed (BookmarkNode)
        """
        if not self.__loaded:
            return
        
        parent = node.parent()
        row = parent.children().index(node)
        command = RemoveBookmarksCommand(self, parent, row)
        self.__commands.push(command)
    
    def setTitle(self, node, newTitle):
        """
        Public method to set the title of a bookmark.
        
        @param node reference to the node to be changed (BookmarkNode)
        @param newTitle title to be set (QString)
        """
        if not self.__loaded:
            return
        
        command = ChangeBookmarkCommand(self, node, newTitle, True)
        self.__commands.push(command)
    
    def setUrl(self, node, newUrl):
        """
        Public method to set the URL of a bookmark.
        
        @param node reference to the node to be changed (BookmarkNode)
        @param newUrl URL to be set (QString)
        """
        if not self.__loaded:
            return
        
        command = ChangeBookmarkCommand(self, node, newUrl, False)
        self.__commands.push(command)
    
    def bookmarks(self):
        """
        Public method to get a reference to the root bookmark node.
        
        @return reference to the root bookmark node (BookmarkNode)
        """
        if not self.__loaded:
            self.load()
        
        return self.__bookmarkRootNode
    
    def menu(self):
        """
        Public method to get a reference to the bookmarks menu node.
        
        @return reference to the bookmarks menu node (BookmarkNode)
        """
        if not self.__loaded:
            self.load()
        
        return self.__menu
    
    def toolbar(self):
        """
        Public method to get a reference to the bookmarks toolbar node.
        
        @return reference to the bookmarks toolbar node (BookmarkNode)
        """
        if not self.__loaded:
            self.load()
        
        return self.__toolbar
    
    def bookmarksModel(self):
        """
        Public method to get a reference to the bookmarks model.
        
        @return reference to the bookmarks model (BookmarksModel)
        """
        if self.__bookmarksModel is None:
            self.__bookmarksModel = BookmarksModel(self, self)
        return self.__bookmarksModel
    
    def importBookmarks(self):
        """
        Public method to import bookmarks.
        """
        supportedFormats = QStringList() \
            << self.trUtf8("XBEL bookmarks").append(" (*.xbel *.xml)") \
            << self.trUtf8("HTML Netscape bookmarks").append(" (*.html *.htm)")
        
        fileName = KQFileDialog.getOpenFileName(\
            None,
            self.trUtf8("Import Bookmarks"),
            QString(),
            supportedFormats.join(";;"),
            None)
        if fileName.isEmpty():
            return
        
        reader = XbelReader()
        importRootNode = None
        if fileName.endsWith(".html"):
            inFile = QFile(fileName)
            inFile.open(QIODevice.ReadOnly)
            if inFile.openMode == QIODevice.NotOpen:
                KQMessageBox.warning(None,
                    self.trUtf8("Import Bookmarks"),
                    self.trUtf8("""Error opening bookmarks file <b>%1</b>.""")\
                        .arg(fileName))
                return
            
            webpage = QWebPage()
            webpage.mainFrame().setHtml(QString(inFile.readAll()))
            result = webpage.mainFrame().evaluateJavaScript(extract_js).toByteArray()
            buffer_ = QBuffer(result)
            buffer_.open(QIODevice.ReadOnly)
            importRootNode = reader.read(buffer_)
        else:
            importRootNode = reader.read(fileName)
        
        if reader.error() != QXmlStreamReader.NoError:
            KQMessageBox.warning(None,
                self.trUtf8("Import Bookmarks"),
                self.trUtf8("""Error when importing bookmarks on line %1, column %2:\n"""
                            """%3""")\
                    .arg(reader.lineNumber())\
                    .arg(reader.columnNumber())\
                    .arg(reader.errorString()))
            return
        
        importRootNode.setType(BookmarkNode.Folder)
        importRootNode.title = self.trUtf8("Imported %1")\
            .arg(QDate.currentDate().toString(Qt.SystemLocaleShortDate))
        self.addBookmark(self.menu(), importRootNode)
    
    def exportBookmarks(self):
        """
        Public method to export the bookmarks.
        """
        fileName = KQFileDialog.getSaveFileName(\
            None,
            self.trUtf8("Export Bookmarks"),
            "eric4_bookmarks.xbel",
            self.trUtf8("XBEL bookmarks").append(" (*.xbel *.xml)"))
        if fileName.isEmpty():
            return
        
        writer = XbelWriter()
        if not writer.write(fileName, self.__bookmarkRootNode):
            KQMessageBox.critical(None,
                self.trUtf8("Exporting Bookmarks"),
                self.trUtf8("""Error exporting bookmarks to <b>%1</b>.""")\
                    .arg(fileName))
    
    def __convertFromOldBookmarks(self):
        """
        Private method to convert the old bookmarks into the new ones.
        """
        bmNames = Preferences.Prefs.settings.value('Bookmarks/Names')
        bmFiles = Preferences.Prefs.settings.value('Bookmarks/Files')
        
        if bmNames.isValid() and bmFiles.isValid():
            bmNames = bmNames.toStringList()
            bmFiles = bmFiles.toStringList()
            if len(bmNames) == len(bmFiles):
                convertedRootNode = BookmarkNode(BookmarkNode.Folder)
                convertedRootNode.title = self.trUtf8("Converted %1")\
                    .arg(QDate.currentDate().toString(Qt.SystemLocaleShortDate))
                for i in range(len(bmNames)):
                    node = BookmarkNode(BookmarkNode.Bookmark, convertedRootNode)
                    node.title = bmNames[i]
                    url = QUrl(bmFiles[i])
                    if url.scheme().isEmpty():
                        url.setScheme("file")
                    node.url = url.toString()
                self.addBookmark(self.menu(), convertedRootNode)
                
                Preferences.Prefs.settings.remove('Bookmarks')
 def load(self):
     """
     Public method to load the bookmarks.
     """
     if self.__loaded:
         return
     
     self.__loaded = True
     
     bookmarkFile = os.path.join(Utilities.getConfigDir(), "browser", "bookmarks.xbel")
     if not QFile.exists(bookmarkFile):
         ba = QByteArray(DefaultBookmarks)
         bookmarkFile = QBuffer(ba)
         bookmarkFile.open(QIODevice.ReadOnly)
     
     reader = XbelReader()
     self.__bookmarkRootNode = reader.read(bookmarkFile)
     if reader.error() != QXmlStreamReader.NoError:
         KQMessageBox.warning(None,
             self.trUtf8("Loading Bookmarks"),
             self.trUtf8("""Error when loading bookmarks on line %1, column %2:\n"""
                         """%3""")\
                 .arg(reader.lineNumber())\
                 .arg(reader.columnNumber())\
                 .arg(reader.errorString()))
     
     others = []
     for index in range(len(self.__bookmarkRootNode.children()) - 1, -1, -1):
         node = self.__bookmarkRootNode.children()[index]
         if node.type() == BookmarkNode.Folder:
             if (node.title == self.trUtf8("Toolbar Bookmarks") or \
                 node.title == BOOKMARKBAR) and \
                self.__toolbar is None:
                 node.title = self.trUtf8(BOOKMARKBAR)
                 self.__toolbar = node
             
             if (node.title == self.trUtf8("Menu") or \
                 node.title == BOOKMARKMENU) and \
                self.__menu is None:
                 node.title = self.trUtf8(BOOKMARKMENU)
                 self.__menu = node
         else:
             others.append(node)
         self.__bookmarkRootNode.remove(node)
         
     if len(self.__bookmarkRootNode.children()) > 0:
         raise RuntimeError("Error loading bookmarks.")
     
     if self.__toolbar is None:
         self.__toolbar = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
         self.__toolbar.title = self.trUtf8(BOOKMARKBAR)
     else:
         self.__bookmarkRootNode.add(self.__toolbar)
     
     if self.__menu is None:
         self.__menu = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
         self.__menu.title = self.trUtf8(BOOKMARKMENU)
     else:
         self.__bookmarkRootNode.add(self.__menu)
     
     for node in others:
         self.__menu.add(node)
     
     self.__convertFromOldBookmarks()