目录
1 问题描述 2
2 需求分析 3
2.1 数据需求 3
2.2 功能需求 3
2.3 非功能需求 3
3 概要设计 4
3.1抽象数据类型 4
3.2 总体设计 8
3.3 功能模块设计 8
3.4 用户界面设计 9
4 详细设计及系统实现 9
4.1 存储结构 9
4.2 核心算法 9
4.3 各功能实现 10
5 系统调试分析 28
6 课程设计总结 35
参考文献 36
1.3 设计内容
1)系统名称:仿Word文档编辑器
2)实现功能:
从word文件中读取文章:系统能够打开word文件并将其内容加载到编辑区,同时保证每行最多不超过80个字符。系统将统计英文字母数、空格数以及整篇文章的总字数,并能对文章进行编辑(增加、删除、查找、替换)。
查找功能:用户可以查找指定字符在文章中出现的次数和位置等信息。
删除功能:系统提供删除某一子串的功能,前提是该子串存在。删除后系统将自动将后面的字符前移。
保存文件:用户能够将修改后的文件保存到指定位置。
新建文件:用户可以新建空白文件,并在编辑区进行文本编辑。
替换功能:系统实现了replace功能,可以用字符串str2替换文件中出现的字符串str1,实现方式不使用内置库函数。
表格编辑:用户可以在文件中插入自定义表格,并能对表格进行编辑。
文字格式调整:用户可以修改文字字体、字号,改变文本颜色,还可以对一行或一段文字进行加粗操作。
图片插入:用户可以在文章中插入图片,并能调整图片大小和旋转图片。
文字转换:用户可以选中指定内容,进行中英文转换(转表头)。
导出多种格式:系统支持导出文件为pdf、xml、TXT等多种格式。
2 需求分析
2.1 数据需求
文章内容:存储整篇文章的文本内容,包括英文字母、空格、中文等字符。
表格数据:存储插入的自定义表格的内容。
图片数据:存储插入的图片文件以及相关信息。
在MyWord类中实现fileNew、fileOpen、fileSave、fileSaveAs、filePrint、filePrintPreview等功能,实现导出pdf、xml、TXT等格式。
/*MyChild中实现基础功能*/
void MyChild::newFile()
{
static int sequenceNumber = 1;
isUntitled = true;
curFile = tr("文档 %1").arg(sequenceNumber++);
setWindowTitle(curFile);
}
bool MyChild::loadFile(const QString &fileName)
{
if (!fileName.isEmpty()) {
QFileInfo fileInfo(fileName);
QString fileExt = fileInfo.suffix().toLower();
if (!QFile::exists(fileName))
return false;
if (fileExt == "txt") {
// Load .txt files using QTextDocument
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text))
return false;
QTextCodec *utf8Codec = QTextCodec::codecForName("UTF-8");
QTextStream in(&file);
in.setCodec(utf8Codec); // Set the codec to UTF-8
QString str = in.readAll();
QTextDocument doc;
doc.setPlainText(str);
// Wrap lines to a maximum of 80 characters
QTextCursor cursor(&doc);
cursor.beginEditBlock();
QTextBlock block = doc.begin();
while (block.isValid()) {
QString blockText = block.text();
if (blockText.length() > 80) {
QStringList lines;
for (int i = 0; i < blockText.length(); i += 80) {
lines.append(blockText.mid(i, 80));
}
blockText = lines.join("\n");
cursor.setPosition(block.position());
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
cursor.insertText(blockText);
}
block = block.next();
}
cursor.endEditBlock();
setPlainText(doc.toPlainText());
} else if (fileExt == "doc" || fileExt == "docx") {
// Load .doc and .docx files using QAxObject (Word Application)
QAxObject word("Word.Application");
word.setProperty("Visible", false);
QAxObject* documents = word.querySubObject("Documents");
QAxObject* document = documents->querySubObject("Open(const QString&)", fileName);
QString text = document->dynamicCall("Content()").toString();
document->dynamicCall("Close()");
word.dynamicCall("Quit()");
QTextDocument doc;
doc.setPlainText(text);
// Wrap lines to a maximum of 80 characters
QTextCursor cursor(&doc);
cursor.beginEditBlock();
QTextBlock block = doc.begin();
while (block.isValid()) {
QString blockText = block.text();
if (blockText.length() > 80) {
QStringList lines;
for (int i = 0; i < blockText.length(); i += 80) {
lines.append(blockText.mid(i, 80));
}
blockText = lines.join("\n");
cursor.setPosition(block.position());
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
cursor.insertText(blockText);
}
block = block.next();
}
cursor.endEditBlock();
setPlainText(doc.toPlainText());
}
setCurrentFile(fileName);
connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified()));
return true;
}
return false;
}
bool MyChild::maybeSave()
{
if (!document()->isModified())
return true;
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("Myself Qt Word"),tr("文档'%1'已被修改,保存吗?").arg(userFriendlyCurrentFile()),QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
return true;
}
bool MyChild::save()
{
if (isUntitled) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool MyChild::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("另存为"),curFile,tr("HTML 文档 (*.htm *.html);;所有文件 (*.*)"));
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
bool MyChild::saveFile(QString fileName)
{
if (!(fileName.endsWith(".htm", Qt::CaseInsensitive) || fileName.endsWith(".html", Qt::CaseInsensitive))) {
fileName += ".html"; // 默认保存为 HTML 文档
}
QTextDocumentWriter writer(fileName);
bool success = writer.write(this->document());
if (success)
setCurrentFile(fileName);
return success;
}