Kandrashin Denis 13 年之前
当前提交
3cf09d65ea
共有 13 个文件被更改,包括 723 次插入0 次删除
  1. 14 0
      source/fb2app.cpp
  2. 12 0
      source/fb2edit.pro
  3. 10 0
      source/fb2edit.qrc
  4. 347 0
      source/fb2main.cpp
  5. 68 0
      source/fb2main.h
  6. 235 0
      source/fb2read.cpp
  7. 37 0
      source/fb2read.h
  8. 二进制
      source/images/copy.png
  9. 二进制
      source/images/cut.png
  10. 二进制
      source/images/new.png
  11. 二进制
      source/images/open.png
  12. 二进制
      source/images/paste.png
  13. 二进制
      source/images/save.png

+ 14 - 0
source/fb2app.cpp

@@ -0,0 +1,14 @@
+#include <QApplication>
+
+#include "fb2main.h"
+
+int main(int argc, char *argv[])
+{
+    Q_INIT_RESOURCE(fb2edit);
+    QApplication app(argc, argv);
+    app.setApplicationName("fb2edit");
+    app.setOrganizationName("LinTest");
+    MainWindow * mainWin = new MainWindow;
+    mainWin->show();
+    return app.exec();
+}

+ 12 - 0
source/fb2edit.pro

@@ -0,0 +1,12 @@
+HEADERS       = \
+    fb2main.h \
+    fb2read.h
+SOURCES       = \
+    fb2app.cpp \
+    fb2main.cpp \
+    fb2read.cpp
+RESOURCES     = \
+    fb2edit.qrc
+
+QT += xml
+

+ 10 - 0
source/fb2edit.qrc

@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>images/copy.png</file>
+    <file>images/cut.png</file>
+    <file>images/new.png</file>
+    <file>images/open.png</file>
+    <file>images/paste.png</file>
+    <file>images/save.png</file>
+</qresource>
+</RCC>

+ 347 - 0
source/fb2main.cpp

@@ -0,0 +1,347 @@
+#include <QtGui>
+
+#include "fb2main.h"
+#include "fb2read.h"
+
+MainWindow::MainWindow()
+{
+    init();
+    setCurrentFile("");
+}
+
+MainWindow::MainWindow(const QString &fileName)
+{
+    init();
+    loadFile(fileName);
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+    if (maybeSave()) {
+        writeSettings();
+        event->accept();
+    } else {
+        event->ignore();
+    }
+}
+
+void MainWindow::newFile()
+{
+    MainWindow *other = new MainWindow;
+    other->move(x() + 40, y() + 40);
+    other->show();
+}
+
+void MainWindow::open()
+{
+    QString fileName = QFileDialog::getOpenFileName(this);
+    if (!fileName.isEmpty()) {
+        MainWindow *existing = findMainWindow(fileName);
+        if (existing) {
+            existing->show();
+            existing->raise();
+            existing->activateWindow();
+            return;
+        }
+
+        if (isUntitled && textEdit->document()->isEmpty()
+                && !isWindowModified()) {
+            loadFile(fileName);
+        } else {
+            MainWindow *other = new MainWindow(fileName);
+            if (other->isUntitled) {
+                delete other;
+                return;
+            }
+            other->move(x() + 40, y() + 40);
+            other->show();
+        }
+    }
+}
+
+bool MainWindow::save()
+{
+    if (isUntitled) {
+        return saveAs();
+    } else {
+        return saveFile(curFile);
+    }
+}
+
+bool MainWindow::saveAs()
+{
+    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
+                                                    curFile);
+    if (fileName.isEmpty())
+        return false;
+
+    return saveFile(fileName);
+}
+
+void MainWindow::about()
+{
+   QMessageBox::about(this, tr("About SDI"),
+            tr("The <b>SDI</b> example demonstrates how to write single "
+               "document interface applications using Qt."));
+}
+
+void MainWindow::documentWasModified()
+{
+    setWindowModified(true);
+}
+
+void MainWindow::init()
+{
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    isUntitled = true;
+
+    textEdit = new QTextEdit;
+    setCentralWidget(textEdit);
+
+    createActions();
+    createMenus();
+    createToolBars();
+    createStatusBar();
+
+    readSettings();
+
+    connect(textEdit->document(), SIGNAL(contentsChanged()),
+            this, SLOT(documentWasModified()));
+
+    setUnifiedTitleAndToolBarOnMac(true);
+}
+
+void MainWindow::createActions()
+{
+    newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
+    newAct->setShortcuts(QKeySequence::New);
+    newAct->setStatusTip(tr("Create a new file"));
+    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
+
+    openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
+    openAct->setShortcuts(QKeySequence::Open);
+    openAct->setStatusTip(tr("Open an existing file"));
+    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
+
+    saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
+    saveAct->setShortcuts(QKeySequence::Save);
+    saveAct->setStatusTip(tr("Save the document to disk"));
+    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
+
+    saveAsAct = new QAction(tr("Save &As..."), this);
+    saveAsAct->setShortcuts(QKeySequence::SaveAs);
+    saveAsAct->setStatusTip(tr("Save the document under a new name"));
+    connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
+
+    closeAct = new QAction(tr("&Close"), this);
+    closeAct->setShortcut(tr("Ctrl+W"));
+    closeAct->setStatusTip(tr("Close this window"));
+    connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
+
+    exitAct = new QAction(tr("E&xit"), this);
+    exitAct->setShortcuts(QKeySequence::Quit);
+    exitAct->setStatusTip(tr("Exit the application"));
+    connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
+
+    cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
+    cutAct->setShortcuts(QKeySequence::Cut);
+    cutAct->setStatusTip(tr("Cut the current selection's contents to the "
+                            "clipboard"));
+    connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut()));
+
+    copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
+    copyAct->setShortcuts(QKeySequence::Copy);
+    copyAct->setStatusTip(tr("Copy the current selection's contents to the "
+                             "clipboard"));
+    connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy()));
+
+    pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
+    pasteAct->setShortcuts(QKeySequence::Paste);
+    pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
+                              "selection"));
+    connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste()));
+
+    aboutAct = new QAction(tr("&About"), this);
+    aboutAct->setStatusTip(tr("Show the application's About box"));
+    connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+
+    aboutQtAct = new QAction(tr("About &Qt"), this);
+    aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
+    connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+
+
+    cutAct->setEnabled(false);
+    copyAct->setEnabled(false);
+    connect(textEdit, SIGNAL(copyAvailable(bool)),
+            cutAct, SLOT(setEnabled(bool)));
+    connect(textEdit, SIGNAL(copyAvailable(bool)),
+            copyAct, SLOT(setEnabled(bool)));
+}
+
+//! [implicit tr context]
+void MainWindow::createMenus()
+{
+    fileMenu = menuBar()->addMenu(tr("&File"));
+//! [implicit tr context]
+    fileMenu->addAction(newAct);
+    fileMenu->addAction(openAct);
+    fileMenu->addAction(saveAct);
+    fileMenu->addAction(saveAsAct);
+    fileMenu->addSeparator();
+    fileMenu->addAction(closeAct);
+    fileMenu->addAction(exitAct);
+
+    editMenu = menuBar()->addMenu(tr("&Edit"));
+    editMenu->addAction(cutAct);
+    editMenu->addAction(copyAct);
+    editMenu->addAction(pasteAct);
+
+    menuBar()->addSeparator();
+
+    helpMenu = menuBar()->addMenu(tr("&Help"));
+    helpMenu->addAction(aboutAct);
+    helpMenu->addAction(aboutQtAct);
+}
+
+void MainWindow::createToolBars()
+{
+//! [0]
+    fileToolBar = addToolBar(tr("File"));
+    fileToolBar->addAction(newAct);
+    fileToolBar->addAction(openAct);
+//! [0]
+    fileToolBar->addAction(saveAct);
+
+    editToolBar = addToolBar(tr("Edit"));
+    editToolBar->addAction(cutAct);
+    editToolBar->addAction(copyAct);
+    editToolBar->addAction(pasteAct);
+}
+
+void MainWindow::createStatusBar()
+{
+    statusBar()->showMessage(tr("Ready"));
+}
+
+void MainWindow::readSettings()
+{
+    QSettings settings;
+    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
+    QSize size = settings.value("size", QSize(400, 400)).toSize();
+    move(pos);
+    resize(size);
+}
+
+void MainWindow::writeSettings()
+{
+    QSettings settings;
+    settings.setValue("pos", pos());
+    settings.setValue("size", size());
+}
+
+bool MainWindow::maybeSave()
+{
+    if (textEdit->document()->isModified()) {
+	QMessageBox::StandardButton ret;
+        ret = QMessageBox::warning(this, tr("SDI"),
+                     tr("The document has been modified.\n"
+                        "Do you want to save your changes?"),
+                     QMessageBox::Save | QMessageBox::Discard
+		     | QMessageBox::Cancel);
+        if (ret == QMessageBox::Save)
+            return save();
+        else if (ret == QMessageBox::Cancel)
+            return false;
+    }
+    return true;
+}
+
+void MainWindow::loadFile(const QString &fileName)
+{
+
+    QFile file(fileName);
+    if (!file.open(QFile::ReadOnly | QFile::Text)) {
+        QMessageBox::warning(
+            this,
+            tr("fb2edit"),
+            tr("Cannot read file %1:\n%2.")
+                .arg(fileName)
+                .arg(file.errorString())
+        );
+        return;
+    }
+
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+
+    Fb2Reader handler(textEdit);
+    QXmlSimpleReader reader;
+    reader.setContentHandler(&handler);
+    reader.setErrorHandler(&handler);
+
+    QXmlInputSource source(&file);
+    if (reader.parse(source))
+        statusBar()->showMessage(tr("File loaded"), 2000);
+
+    QApplication::restoreOverrideCursor();
+
+    setCurrentFile(fileName);
+    statusBar()->showMessage(tr("File loaded"), 2000);
+}
+
+bool MainWindow::saveFile(const QString &fileName)
+{
+    return false;
+
+    QFile file(fileName);
+    if (!file.open(QFile::WriteOnly | QFile::Text)) {
+        QMessageBox::warning(this, tr("SDI"),
+                             tr("Cannot write file %1:\n%2.")
+                             .arg(fileName)
+                             .arg(file.errorString()));
+        return false;
+    }
+
+    QTextStream out(&file);
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+    out << textEdit->toPlainText();
+    QApplication::restoreOverrideCursor();
+
+    setCurrentFile(fileName);
+    statusBar()->showMessage(tr("File saved"), 2000);
+    return true;
+}
+
+void MainWindow::setCurrentFile(const QString &fileName)
+{
+    static int sequenceNumber = 1;
+
+    isUntitled = fileName.isEmpty();
+    if (isUntitled) {
+        curFile = tr("document%1.txt").arg(sequenceNumber++);
+    } else {
+        curFile = QFileInfo(fileName).canonicalFilePath();
+    }
+
+    textEdit->document()->setModified(false);
+    setWindowModified(false);
+    setWindowFilePath(curFile);
+}
+
+QString MainWindow::strippedName(const QString &fullFileName)
+{
+    return QFileInfo(fullFileName).fileName();
+}
+
+MainWindow *MainWindow::findMainWindow(const QString &fileName)
+{
+    QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
+
+    foreach (QWidget *widget, qApp->topLevelWidgets()) {
+        MainWindow *mainWin = qobject_cast<MainWindow *>(widget);
+        if (mainWin && mainWin->curFile == canonicalFilePath)
+            return mainWin;
+    }
+    return 0;
+}
+

+ 68 - 0
source/fb2main.h

@@ -0,0 +1,68 @@
+#ifndef FB2MAIN_H
+#define FB2MAIN_H
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QMenu;
+class QTextEdit;
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow();
+    MainWindow(const QString &fileName);
+
+protected:
+    void closeEvent(QCloseEvent *event);
+
+private slots:
+    void newFile();
+    void open();
+    bool save();
+    bool saveAs();
+    void about();
+    void documentWasModified();
+
+private:
+    void init();
+    void createActions();
+    void createMenus();
+    void createToolBars();
+    void createStatusBar();
+    void readSettings();
+    void writeSettings();
+    bool maybeSave();
+    void loadFile(const QString &fileName);
+    bool saveFile(const QString &fileName);
+    void setCurrentFile(const QString &fileName);
+    QString strippedName(const QString &fullFileName);
+    MainWindow *findMainWindow(const QString &fileName);
+
+    QTextEdit *textEdit;
+    QString curFile;
+    bool isUntitled;
+
+    QMenu *fileMenu;
+    QMenu *editMenu;
+    QMenu *helpMenu;
+    QToolBar *fileToolBar;
+    QToolBar *editToolBar;
+    QAction *newAct;
+    QAction *openAct;
+    QAction *saveAct;
+    QAction *saveAsAct;
+    QAction *closeAct;
+    QAction *exitAct;
+    QAction *cutAct;
+    QAction *copyAct;
+    QAction *pasteAct;
+    QAction *aboutAct;
+    QAction *aboutQtAct;
+};
+
+#endif // FB2MAIN_H

+ 235 - 0
source/fb2read.cpp

@@ -0,0 +1,235 @@
+#include <QtGui>
+#include <QTextEdit>
+
+#include "fb2read.h"
+
+Fb2Reader::Fb2Reader(QTextEdit * editor)
+    : m_editor(editor)
+    , m_cursor(editor->textCursor())
+    , m_section(None)
+{
+    m_cursor.beginEditBlock();
+    editor->clear();
+    m_cursor.movePosition(QTextCursor::Start);
+}
+
+Fb2Reader::~Fb2Reader()
+{
+    m_cursor.endEditBlock();
+}
+
+bool Fb2Reader::startElement(const QString & /* namespaceURI */,
+                               const QString & /* localName */,
+                               const QString &qName,
+                               const QXmlAttributes &attributes)
+{
+    const QString name = qName.toLower();
+
+    switch (m_tags.count()) {
+        case 0: {
+            if (name != "fictionbook") {
+                m_error = QObject::tr("The file is not an FB2 file.");
+                return false;
+            };
+        } break;
+        case 1: {
+            if (name == "body") {
+                m_section = Body;
+            } else if (name == "description") {
+                m_section = Descr;
+            } else if (name == "binary") {
+                m_section = Bynary;
+            } else {
+                m_section = None;
+            }
+        } break;
+        default: {
+            if (name == "p") m_cursor.insertBlock();
+        } break;
+    }
+
+    m_text.clear();
+
+    m_tags << name;
+
+    return true;
+}
+
+bool Fb2Reader::endElement(const QString & /* namespaceURI */,
+                             const QString & /* localName */,
+                             const QString &qName)
+{
+    const QString name = qName.toLower();
+    int index = m_tags.lastIndexOf(name);
+    int count = m_tags.count();
+    for (int i = index; i < count; i++) m_tags.removeLast();
+    if (m_tags.count() < 2) m_section = None;
+
+    return true;
+}
+
+bool Fb2Reader::characters(const QString &str)
+{
+    switch (m_section) {
+        case Body: {
+            m_cursor.insertText(str);
+        } break;
+        default: {
+            m_text += str;
+        }
+    }
+    return true;
+}
+
+bool Fb2Reader::fatalError(const QXmlParseException &exception)
+{
+    QMessageBox::information(
+        m_editor->window(),
+        QObject::tr("fb2edit"),
+        QObject::tr("Parse error at line %1, column %2:\n%3")
+            .arg(exception.lineNumber())
+            .arg(exception.columnNumber())
+            .arg(exception.message())
+        );
+    return false;
+}
+
+QString Fb2Reader::errorString() const
+{
+    return m_error;
+}
+
+/*
+
+//! [2]
+    QTextCursor cursor(editor->textCursor());
+    cursor.movePosition(QTextCursor::Start);
+//! [2] //! [3]
+    QTextFrame *topFrame = cursor.currentFrame();
+    QTextFrameFormat topFrameFormat = topFrame->frameFormat();
+    topFrameFormat.setPadding(16);
+    topFrame->setFrameFormat(topFrameFormat);
+
+    QTextCharFormat textFormat;
+    QTextCharFormat boldFormat;
+    boldFormat.setFontWeight(QFont::Bold);
+
+    QTextFrameFormat referenceFrameFormat;
+    referenceFrameFormat.setBorder(1);
+    referenceFrameFormat.setPadding(8);
+    referenceFrameFormat.setPosition(QTextFrameFormat::FloatRight);
+    referenceFrameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 40));
+    cursor.insertFrame(referenceFrameFormat);
+
+    cursor.insertText("A company", boldFormat);
+    cursor.insertBlock();
+    cursor.insertText("321 City Street");
+    cursor.insertBlock();
+    cursor.insertText("Industry Park");
+    cursor.insertBlock();
+    cursor.insertText("Another country");
+//! [3]
+
+//! [4]
+    cursor.setPosition(topFrame->lastPosition());
+
+    cursor.insertText(name, textFormat);
+    QString line;
+    foreach (line, address.split("\n")) {
+        cursor.insertBlock();
+        cursor.insertText(line);
+    }
+//! [4] //! [5]
+    cursor.insertBlock();
+    cursor.insertBlock();
+
+    QDate date = QDate::currentDate();
+    cursor.insertText(tr("Date: %1").arg(date.toString("d MMMM yyyy")),
+                      textFormat);
+    cursor.insertBlock();
+
+    QTextFrameFormat bodyFrameFormat;
+    bodyFrameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
+    cursor.insertFrame(bodyFrameFormat);
+//! [5]
+
+//! [6]
+    cursor.insertText(tr("I would like to place an order for the following "
+                         "items:"), textFormat);
+    cursor.insertBlock();
+//! [6] //! [7]
+    cursor.insertBlock();
+//! [7]
+
+//! [8]
+    QTextTableFormat orderTableFormat;
+    orderTableFormat.setAlignment(Qt::AlignHCenter);
+    QTextTable *orderTable = cursor.insertTable(1, 2, orderTableFormat);
+
+    QTextFrameFormat orderFrameFormat = cursor.currentFrame()->frameFormat();
+    orderFrameFormat.setBorder(1);
+    cursor.currentFrame()->setFrameFormat(orderFrameFormat);
+//! [8]
+
+//! [9]
+    cursor = orderTable->cellAt(0, 0).firstCursorPosition();
+    cursor.insertText(tr("Product"), boldFormat);
+    cursor = orderTable->cellAt(0, 1).firstCursorPosition();
+    cursor.insertText(tr("Quantity"), boldFormat);
+//! [9]
+
+//! [10]
+    for (int i = 0; i < orderItems.count(); ++i) {
+        QPair<QString,int> item = orderItems[i];
+        int row = orderTable->rows();
+
+        orderTable->insertRows(row, 1);
+        cursor = orderTable->cellAt(row, 0).firstCursorPosition();
+        cursor.insertText(item.first, textFormat);
+        cursor = orderTable->cellAt(row, 1).firstCursorPosition();
+        cursor.insertText(QString("%1").arg(item.second), textFormat);
+    }
+//! [10]
+
+//! [11]
+    cursor.setPosition(topFrame->lastPosition());
+
+    cursor.insertBlock();
+//! [11] //! [12]
+    cursor.insertText(tr("Please update my records to take account of the "
+                         "following privacy information:"));
+    cursor.insertBlock();
+//! [12]
+
+//! [13]
+    QTextTable *offersTable = cursor.insertTable(2, 2);
+
+    cursor = offersTable->cellAt(0, 1).firstCursorPosition();
+    cursor.insertText(tr("I want to receive more information about your "
+                         "company's products and special offers."), textFormat);
+    cursor = offersTable->cellAt(1, 1).firstCursorPosition();
+    cursor.insertText(tr("I do not want to receive any promotional information "
+                         "from your company."), textFormat);
+
+    if (sendOffers)
+        cursor = offersTable->cellAt(0, 0).firstCursorPosition();
+    else
+        cursor = offersTable->cellAt(1, 0).firstCursorPosition();
+
+    cursor.insertText("X", boldFormat);
+//! [13]
+
+//! [14]
+    cursor.setPosition(topFrame->lastPosition());
+    cursor.insertBlock();
+    cursor.insertText(tr("Sincerely,"), textFormat);
+    cursor.insertBlock();
+    cursor.insertBlock();
+    cursor.insertBlock();
+    cursor.insertText(name);
+
+    printAction->setEnabled(true);
+}
+//! [14]
+
+*/

+ 37 - 0
source/fb2read.h

@@ -0,0 +1,37 @@
+#ifndef FB2READ_H
+#define FB2READ_H
+
+#include <QXmlDefaultHandler>
+#include <QTextCursor>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+class QTextEdit;
+QT_END_NAMESPACE
+
+class Fb2Reader : public QXmlDefaultHandler
+{
+public:
+    enum DocumentSection {
+        None   = 0x0000,
+        Body   = 0x0001,
+        Descr  = 0x0002,
+        Bynary = 0x0003,
+    };
+    Fb2Reader(QTextEdit * editor);
+    virtual ~Fb2Reader();
+    bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes);
+    bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
+    bool characters(const QString &str);
+    bool fatalError(const QXmlParseException &exception);
+    QString errorString() const;
+private:
+    QTextEdit * m_editor;
+    QTextCursor m_cursor;
+    QString m_text;
+    QString m_error;
+    QStringList m_tags;
+    DocumentSection m_section;
+};
+
+#endif // FB2READ_H

二进制
source/images/copy.png


二进制
source/images/cut.png


二进制
source/images/new.png


二进制
source/images/open.png


二进制
source/images/paste.png


二进制
source/images/save.png