Browse Source

Add self-closed tags into XML2::HtmlReader

Kandrashin Denis 13 years ago
parent
commit
82a57efb66
7 changed files with 73 additions and 8 deletions
  1. 5 3
      source/fb2main.cpp
  2. 2 1
      source/fb2main.h
  3. 0 1
      source/fb2save.cpp
  4. 25 0
      source/fb2view.cpp
  5. 2 0
      source/fb2view.h
  6. 8 1
      source/fb2xml.cpp
  7. 31 2
      source/fb2xml2.cpp

+ 5 - 3
source/fb2main.cpp

@@ -329,7 +329,7 @@ void Fb2MainWindow::createActions()
 
     menu = menuBar()->addMenu(tr("&Insert", "Main menu"));
 
-    act = new QAction(icon("insert-image"), tr("&Image"), this);
+    actionImage = act = new QAction(icon("insert-image"), tr("&Image"), this);
     menu->addAction(act);
 
     act = new QAction(icon("insert-link"), tr("&Link"), this);
@@ -388,7 +388,7 @@ void Fb2MainWindow::createActions()
 
     act = new QAction(tr("&XML"), this);
     act->setCheckable(true);
-    connect(act, SIGNAL(triggered()), this, SLOT(viewQsci()));
+    connect(act, SIGNAL(triggered()), this, SLOT(viewCode()));
     viewGroup->addAction(act);
     menu->addAction(act);
     tool->addAction(act);
@@ -646,7 +646,7 @@ void Fb2MainWindow::checkScintillaUndo()
     actionRedo->setEnabled(codeEdit->isRedoAvailable());
 }
 
-void Fb2MainWindow::viewQsci()
+void Fb2MainWindow::viewCode()
 {
     if (centralWidget() == codeEdit) return;
     QString xml;
@@ -731,6 +731,8 @@ void Fb2MainWindow::viewText()
     connect(actionTextSub, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleSubscript), SIGNAL(triggered()));
     connect(actionTextSup, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleSuperscript), SIGNAL(triggered()));
 
+    connect(actionImage, SIGNAL(triggered()), textEdit, SLOT(insertImage()));
+
     connect(actionZoomIn, SIGNAL(triggered()), textEdit, SLOT(zoomIn()));
     connect(actionZoomOut, SIGNAL(triggered()), textEdit, SLOT(zoomOut()));
     connect(actionZoomOrig, SIGNAL(triggered()), textEdit, SLOT(zoomOrig()));

+ 2 - 1
source/fb2main.h

@@ -46,7 +46,7 @@ private slots:
     void treeDestroyed();
     void logDestroyed();
     void logShowed();
-    void viewQsci();
+    void viewCode();
     void viewText();
     void viewHead();
     void viewTree();
@@ -110,6 +110,7 @@ private:
         *actionReplace,
         *actionInsert,
         *actionDelete,
+        *actionImage,
         *actionTextBold,
         *actionTextItalic,
         *actionTextStrike,

+ 0 - 1
source/fb2save.cpp

@@ -200,7 +200,6 @@ Fb2SaveHandler::ImageHandler::ImageHandler(BodyHandler *parent, const QString &n
 {
     QString href = Value(atts, "src");
     QString file = m_writer.getFile(href);
-    if (file.isEmpty()) return;
     file.prepend('#');
     m_writer.writeAttribute("l:href", file);
     m_writer.writeEndElement();

+ 25 - 0
source/fb2view.cpp

@@ -5,6 +5,7 @@
 
 #include <QAction>
 #include <QtDebug>
+#include <QFileDialog>
 #include <QNetworkRequest>
 #include <QToolTip>
 #include <QWebElement>
@@ -225,3 +226,27 @@ bool Fb2WebView::SupChecked()
     return pageAction(QWebPage::ToggleSuperscript)->isChecked();
 }
 
+void Fb2WebView::insertImage()
+{
+    QString filters;
+    filters += tr("Common Graphics (*.png *.jpg *.jpeg *.gif);;");
+    filters += tr("Portable Network Graphics (PNG) (*.png);;");
+    filters += tr("JPEG (*.jpg *.jpeg);;");
+    filters += tr("Graphics Interchange Format (*.gif);;");
+    filters += tr("All Files (*)");
+
+    QString fn = QFileDialog::getOpenFileName(this, tr("Open image..."), QString(), filters);
+    if (fn.isEmpty()) return;
+    if (!QFile::exists(fn)) return;
+
+    QUrl url = QUrl::fromLocalFile(fn);
+    execCommand("insertImage", url.toString());
+}
+
+void Fb2WebView::execCommand(const QString &cmd, const QString &arg)
+{
+    QWebFrame *frame = page()->mainFrame();
+    QString js = QString("document.execCommand(\"%1\", false, \"%2\")").arg(cmd).arg(arg);
+    frame->evaluateJavaScript(js);
+}
+

+ 2 - 0
source/fb2view.h

@@ -82,6 +82,7 @@ public slots:
     void data(QString name, QByteArray data);
     void html(QString name, QString html);
     void linkHovered(const QString &link, const QString &title, const QString &textContent);
+    void insertImage();
     void zoomIn();
     void zoomOut();
     void zoomOrig();
@@ -90,6 +91,7 @@ private slots:
     void fixContents();
 
 private:
+    void execCommand(const QString &cmd, const QString &arg);
     QTemporaryFile * file(const QString &name);
     QWebElement doc();
 

+ 8 - 1
source/fb2xml.cpp

@@ -19,7 +19,14 @@ QString Fb2XmlHandler::NodeHandler::Value(const QXmlAttributes &attributes, cons
 bool Fb2XmlHandler::NodeHandler::doStart(const QString &name, const QXmlAttributes &attributes)
 {
     if (m_handler) return m_handler->doStart(name, attributes);
-    m_handler = NewTag(name, attributes); if (m_handler) return true;
+    m_handler = NewTag(name, attributes);
+    if (m_handler) {
+        if (m_handler->m_closed) {
+            delete m_handler;
+            m_handler = NULL;
+        }
+        return true;
+    }
     m_handler = new NodeHandler(name);
     return true;
 }

+ 31 - 2
source/fb2xml2.cpp

@@ -21,7 +21,10 @@ private:
     HtmlReader* reader;
 };
 
-class HtmlReaderPrivate {
+class HtmlReaderPrivate
+{
+private:
+    class ClosedTag : public QList<QString> { public: ClosedTag(); };
 public:
     ~HtmlReaderPrivate(void) {}
 private:
@@ -55,6 +58,7 @@ private:
     QXmlDeclHandler*    declhandler;
 
     xmlParserCtxt* context;
+    QList<QString> closed;
 
     friend class HtmlReaderLocator;
 };
@@ -65,6 +69,26 @@ HtmlReaderPrivate::HtmlReaderPrivate(HtmlReader* reader)
     this->locator.reset(new HtmlReaderLocator(reader));
 }
 
+HtmlReaderPrivate::ClosedTag::ClosedTag()
+{
+    *this << "area";
+    *this << "base";
+    *this << "br";
+    *this << "col";
+    *this << "command";
+    *this << "embed";
+    *this << "hr";
+    *this << "img";
+    *this << "input";
+    *this << "keygen";
+    *this << "link";
+    *this << "meta";
+    *this << "param";
+    *this << "source";
+    *this << "track";
+    *this << "wbr";
+}
+
 QString HtmlReaderPrivate::C2S(const xmlChar* text, int size)
 {
     return QString::fromLocal8Bit(reinterpret_cast<const char*>(text), size);
@@ -127,8 +151,13 @@ void HtmlReaderPrivate::startElement(void* c, const xmlChar* name, const xmlChar
                 i += 2;
             }
         }
+        static ClosedTag closed;
         QString qName = C2S(name);
-        r->contenthandler->startElement("", local(qName), qName, a);
+        QString localName = local(qName);
+        r->contenthandler->startElement("", localName, qName, a);
+        if (closed.indexOf(qName.toLower()) != -1) {
+            r->contenthandler->endElement("", localName, qName);
+        }
     }
 }