Kandrashin Denis 13 gadi atpakaļ
vecāks
revīzija
4abc478f35

+ 65 - 64
fb2edit.pro

@@ -1,64 +1,65 @@
-HEADERS = \
-    source/fb2xml.h \
-    source/fb2xml2.h \
-    source/fb2app.hpp \
-    source/fb2code.hpp \
-    source/fb2head.hpp \
-    source/fb2main.hpp \
-    source/fb2read.hpp \
-    source/fb2temp.hpp \
-    source/fb2tree.hpp \
-    source/fb2view.hpp \
-    source/fb2utils.h \
-    source/fb2save.hpp \
-    source/fb2dlgs.hpp
-
-SOURCES = \
-    source/fb2app.cpp \
-    source/fb2code.cpp \
-    source/fb2head.cpp \
-    source/fb2main.cpp \
-    source/fb2read.cpp \
-    source/fb2save.cpp \
-    source/fb2temp.cpp \
-    source/fb2tree.cpp \
-    source/fb2view.cpp \
-    source/fb2xml.cpp \
-    source/fb2xml2.cpp \
-    source/fb2utils.cpp \
-    source/fb2dlgs.cpp
-
-RESOURCES = \
-    3rdparty/gnome/gnome.qrc \
-    source/res/fb2edit.qrc \
-    source/js/javascript.qrc
-
-TARGET = fb2edit
-
-TRANSLATIONS = source/ts/ru.ts
-
-VERSION = 0.01.1
-
-QT += xml
-QT += webkit
-QT += network
-
-OTHER_FILES += \
-    source/res/style.css \
-    source/res/blank.fb2 \
-    source/js/export.js \
-    source/js/set_cursor.js \
-    source/js/get_status.js \
-    source/js/get_location.js
-
-if (unix) {
-
-    DEFINES += FB2_USE_LIBXML2
-    INCLUDEPATH += /usr/include/libxml2
-    LIBS += -lxml2
-
-}
-
-FORMS += \
-    source/fb2note.ui \
-    source/fb2find.ui
+HEADERS = \
+    source/fb2xml.h \
+    source/fb2xml2.h \
+    source/fb2app.hpp \
+    source/fb2code.hpp \
+    source/fb2head.hpp \
+    source/fb2main.hpp \
+    source/fb2read.hpp \
+    source/fb2temp.hpp \
+    source/fb2tree.hpp \
+    source/fb2view.hpp \
+    source/fb2utils.h \
+    source/fb2save.hpp \
+    source/fb2dlgs.hpp
+
+SOURCES = \
+    source/fb2app.cpp \
+    source/fb2code.cpp \
+    source/fb2head.cpp \
+    source/fb2main.cpp \
+    source/fb2read.cpp \
+    source/fb2save.cpp \
+    source/fb2temp.cpp \
+    source/fb2tree.cpp \
+    source/fb2view.cpp \
+    source/fb2xml.cpp \
+    source/fb2xml2.cpp \
+    source/fb2utils.cpp \
+    source/fb2dlgs.cpp
+
+RESOURCES = \
+    3rdparty/gnome/gnome.qrc \
+    source/res/fb2edit.qrc \
+    source/js/javascript.qrc
+
+TARGET = fb2edit
+
+TRANSLATIONS = source/ts/ru.ts
+
+VERSION = 0.01.1
+
+QT += xml
+QT += webkit
+QT += network
+
+OTHER_FILES += \
+    source/res/style.css \
+    source/res/blank.fb2 \
+    source/js/export.js \
+    source/js/set_cursor.js \
+    source/js/get_status.js \
+    source/js/get_location.js \
+    source/js/insert_title.js
+
+if (unix) {
+
+    DEFINES += FB2_USE_LIBXML2
+    INCLUDEPATH += /usr/include/libxml2
+    LIBS += -lxml2
+
+}
+
+FORMS += \
+    source/fb2note.ui \
+    source/fb2find.ui

+ 52 - 7
source/fb2head.cpp

@@ -4,6 +4,7 @@
 #include <QWebFrame>
 #include <QWebPage>
 #include <QWebView>
+#include <QItemDelegate>
 #include <QTreeView>
 
 #include "fb2view.hpp"
@@ -42,13 +43,15 @@ Fb2HeadItem::Fb2HeadItem(QWebElement &element, Fb2HeadItem *parent)
     , m_parent(parent)
 {
     m_name = element.tagName().toLower();
-    QString style = element.attribute("class").toLower();
+    m_id = element.attribute("id");
     if (m_name == "div") {
+        QString style = element.attribute("class").toLower();
         if (!style.isEmpty()) m_name = style;
+        if (style == "annotation") return;
+        if (style == "history") return;
     } else if (m_name == "img") {
         m_text = element.attribute("alt");
     }
-    m_id = element.attribute("id");
     addChildren(element);
 }
 
@@ -109,7 +112,10 @@ QString Fb2HeadItem::value() const
 {
     switch (toKeyword(m_name)) {
         case Auth : {
-            return sub("last-name") + " " + sub("first-name") + " " + sub("middle-name");
+            QString result = sub("last-name");
+            result += " " + sub("first-name");
+            result += " " + sub("middle-name");
+            return result.simplified();
         } break;
         case Cover : {
             QString text;
@@ -122,11 +128,11 @@ QString Fb2HeadItem::value() const
             return text;
         } break;
         case Image : {
-            return m_element.attribute("alt");
+            return m_element.attribute("src");
         } break;
         case Seqn : {
-            QString text = m_element.attribute("fb2:name");
-            QString numb = m_element.attribute("fb2:number");
+            QString text = m_element.attribute("fb2.name");
+            QString numb = m_element.attribute("fb2.number");
             if (numb.isEmpty() || numb == "0") return text;
             return text + ", " + tr("#") + numb;
         } break;
@@ -222,7 +228,7 @@ int Fb2HeadModel::rowCount(const QModelIndex &parent) const
 
 QVariant Fb2HeadModel::data(const QModelIndex &index, int role) const
 {
-    if (role != Qt::DisplayRole) return QVariant();
+    if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
     Fb2HeadItem * i = item(index);
     return i ? i->text(index.column()) : QVariant();
 }
@@ -245,6 +251,27 @@ void Fb2HeadModel::select(const QModelIndex &index)
     m_view.page()->mainFrame()->scrollToAnchor(node->id());
 }
 
+void Fb2HeadItem::setText(const QString &text)
+{
+    m_text = text;
+}
+
+bool Fb2HeadModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (role != Qt::EditRole) return false;
+    Fb2HeadItem * i = item(index);
+    if (!i) return false;
+    i->setText(value.toString());
+    emit dataChanged(index, index);
+}
+
+Qt::ItemFlags Fb2HeadModel::flags(const QModelIndex &index) const
+{
+    if (!index.isValid()) return 0;
+    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+    if (index.column() == 1) flags |= Qt::ItemIsEditable;
+    return flags;
+}
 
 //---------------------------------------------------------------------------
 //  Fb2TreeView
@@ -254,7 +281,11 @@ Fb2HeadView::Fb2HeadView(Fb2WebView &view, QWidget *parent)
     : QTreeView(parent)
     , m_view(view)
 {
+    //setItemDelegate(new QItemDelegate(this));
+    setSelectionBehavior(QAbstractItemView::SelectItems);
+    setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
     connect(&m_view, SIGNAL(loadFinished(bool)), SLOT(updateTree()));
+    connect(this, SIGNAL(activated(QModelIndex)), SLOT(activated(QModelIndex)));
 }
 
 void Fb2HeadView::updateTree()
@@ -264,3 +295,17 @@ void Fb2HeadView::updateTree()
     model->expand(this);
 }
 
+void Fb2HeadView::editCurrent()
+{
+    QModelIndex current = currentIndex();
+    if (!current.isValid()) return;
+    Fb2HeadModel * m = static_cast<Fb2HeadModel*>(model());
+    QModelIndex index = m->index(current.row(), 1, m->parent(current));
+    setCurrentIndex(index);
+    edit(index);
+}
+
+void Fb2HeadView::activated(const QModelIndex &index)
+{
+    if (index.isValid() && index.column() == 1) edit(index);
+}

+ 8 - 0
source/fb2head.hpp

@@ -44,6 +44,8 @@ public:
 
     QString text(int col = 0) const;
 
+    void setText(const QString &text);
+
     const QString & id() const {
         return m_id;
     }
@@ -86,12 +88,14 @@ public:
     void expand(QTreeView *view);
 
 public:
+    virtual Qt::ItemFlags flags(const QModelIndex &index) const;
     virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
     virtual QModelIndex parent(const QModelIndex &child) const;
     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
     virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+    virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
 
 protected:
     Fb2HeadItem * item(const QModelIndex &index) const;
@@ -109,8 +113,12 @@ public:
     explicit Fb2HeadView(Fb2WebView &view, QWidget *parent = 0);
 
 public slots:
+    void editCurrent();
     void updateTree();
 
+private slots:
+    void activated(const QModelIndex &index);
+
 private:
     Fb2WebView & m_view;
 };

+ 7 - 0
source/fb2main.cpp

@@ -296,6 +296,10 @@ void Fb2MainWindow::createActions()
     act->setShortcuts(QKeySequence::New);
     menu->addAction(act);
 
+    actionModify = act = new QAction(FB2::icon("list-add"), tr("&Modify"), this);
+    act->setPriority(QAction::LowPriority);
+    menu->addAction(act);
+
     actionDelete = act = new QAction(FB2::icon("list-remove"), tr("&Delete"), this);
     act->setPriority(QAction::LowPriority);
     act->setShortcuts(QKeySequence::Delete);
@@ -676,6 +680,7 @@ void Fb2MainWindow::viewText()
     connect(actionImage, SIGNAL(triggered()), textEdit, SLOT(insertImage()));
     connect(actionNote, SIGNAL(triggered()), textEdit, SLOT(insertNote()));
     connect(actionLink, SIGNAL(triggered()), textEdit, SLOT(insertLink()));
+    connect(actionTtile, SIGNAL(triggered()), textEdit, SLOT(insertTitle()));
 
     connect(actionZoomIn, SIGNAL(triggered()), textEdit, SLOT(zoomIn()));
     connect(actionZoomOut, SIGNAL(triggered()), textEdit, SLOT(zoomOut()));
@@ -723,6 +728,7 @@ void Fb2MainWindow::viewHead()
     if (!headTree) {
         headTree = new Fb2HeadView(*textEdit, this);
         headTree->header()->setDefaultSectionSize(200);
+        connect(actionModify, SIGNAL(triggered()), headTree, SLOT(editCurrent()));
     }
 
     this->setFocus();
@@ -754,6 +760,7 @@ void Fb2MainWindow::viewHead()
     QToolBar *tool = toolEdit = addToolBar(tr("Edit"));
     tool->addSeparator();
     tool->addAction(actionInsert);
+    tool->addAction(actionModify);
     tool->addAction(actionDelete);
     tool->setMovable(false);
 }

+ 1 - 0
source/fb2main.hpp

@@ -104,6 +104,7 @@ private:
         *actionFind,
         *actionReplace,
         *actionInsert,
+        *actionModify,
         *actionDelete,
         *actionImage,
         *actionNote,

+ 1 - 0
source/fb2read.cpp

@@ -285,6 +285,7 @@ Fb2ReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &nam
     , m_style(style)
 {
     Init(atts);
+    if (name == "empty-line") writer().writeCharacters(QChar(160));
 }
 
 void Fb2ReadHandler::TextHandler::Init(const QXmlAttributes &atts)

+ 2 - 8
source/fb2tree.cpp

@@ -207,7 +207,7 @@ void Fb2TreeModel::selectText(const QModelIndex &index)
     m_view.setFocus();
 }
 
-QModelIndex Fb2TreeModel::index(const QString &location, QModelIndex current) const
+QModelIndex Fb2TreeModel::index(const QString &location) const
 {
     QModelIndex index;
     Fb2TreeItem * parent = m_root;
@@ -220,12 +220,6 @@ QModelIndex Fb2TreeModel::index(const QString &location, QModelIndex current) co
         Fb2TreeItem * child = parent->content(*this, key, index);
         parent = child;
     }
-
-    while (current.isValid()) {
-        if (current == index) return QModelIndex();
-        current = this->parent(current);
-    }
-
     return index;
 }
 
@@ -279,7 +273,7 @@ void Fb2TreeView::selectTree()
     QWebFrame * frame = model->view().page()->mainFrame();
     static const QString javascript = FB2::read(":/js/get_location.js");
     QString location = frame->evaluateJavaScript(javascript).toString();
-    QModelIndex index = model->index(location, currentIndex());
+    QModelIndex index = model->index(location);
     if (!index.isValid()) return;
 
     disconnect(this, SIGNAL(activated(QModelIndex)), this, SLOT(activated(QModelIndex)));

+ 1 - 1
source/fb2tree.hpp

@@ -73,7 +73,7 @@ class Fb2TreeModel: public QAbstractItemModel
 public:
     explicit Fb2TreeModel(Fb2WebView &view, QObject *parent = 0);
     virtual ~Fb2TreeModel();
-    QModelIndex index(const QString &location, QModelIndex current) const;
+    QModelIndex index(const QString &location) const;
     Fb2WebView & view() { return m_view; }
     void selectText(const QModelIndex &index);
 

+ 6 - 0
source/fb2view.cpp

@@ -344,3 +344,9 @@ void Fb2WebView::loadFinished()
 {
     selectText(this, "var element=$('div.body').get(0);if(element===undefined)element=document.body");
 }
+
+void Fb2WebView::insertTitle()
+{
+    static const QString javascript = FB2::read(":/js/insert_title.js");
+    page()->mainFrame()->evaluateJavaScript(javascript);
+}

+ 1 - 0
source/fb2view.hpp

@@ -97,6 +97,7 @@ public slots:
     void insertImage();
     void insertNote();
     void insertLink();
+    void insertTitle();
     void zoomIn();
     void zoomOut();
     void zoomReset();

+ 34 - 0
source/js/insert_title.js

@@ -0,0 +1,34 @@
+var insert = function(parent) {
+    var child = document.createElement('DIV');
+    child.setAttribute("class", 'title');
+    child.innerText = "title";
+    parent.insertAdjacentElement("afterBegin",child);
+    return child;
+}
+
+var section = function(parent) {
+    if (parent.nodeName !== 'DIV') return 0;
+    var attr = parent.getAttribute('CLASS').toLowerCase();
+    if (attr === 'section') return 1;
+    return 0;
+}
+
+var exists = function(parent) {
+    var child = parent.firstChild;
+    if (child === undefined) return 0;
+    if (child.nodeName !== 'DIV') return 0;
+    if (child.getAttribute('CLASS').toLowerCase() !== 'title') return 0;
+    return 1;
+}
+
+var parent = document.getSelection().baseNode;
+
+while (parent.nodeName !== 'BODY') {
+  if (parent.nodeName === 'DIV') {
+      if (!section(parent)) break;
+      if (exists(parent)) break;
+      insert(parent);
+      break;
+  }
+  parent = parent.parentNode;
+}

+ 1 - 0
source/js/javascript.qrc

@@ -5,5 +5,6 @@
         <file>get_status.js</file>
         <file>get_location.js</file>
         <file>set_cursor.js</file>
+        <file>insert_title.js</file>
     </qresource>
 </RCC>

BIN
source/ts/ru.qm


+ 5 - 5
source/ts/ru.ts

@@ -406,23 +406,23 @@
     </message>
     <message>
         <source>&amp;Body</source>
-        <translation>&amp;Тело &lt;body&gt;</translation>
+        <translation>Тело &lt;body&gt;</translation>
     </message>
     <message>
         <source>Zoom original</source>
-        <translation type="unfinished"></translation>
+        <translation></translation>
     </message>
     <message>
         <source>&amp;Section</source>
-        <translation>&amp;Секция &lt;section&gt;</translation>
+        <translation>Секция &lt;section&gt;</translation>
     </message>
     <message>
         <source>&amp;Title</source>
-        <translation>&amp;Заголовок &lt;title&gt;</translation>
+        <translation>Заголовок &lt;title&gt;</translation>
     </message>
     <message>
         <source>&amp;Author</source>
-        <translation>&amp;Автор &lt;author&gt;</translation>
+        <translation>Автор &lt;author&gt;</translation>
     </message>
     <message>
         <source>&amp;Annotation</source>