讲解文档视图场景的创建过程:
参考NewFile.js文件
NewFile.createMdiChild = function (fileName, nameFilter, uiFile, graphicsSceneClass) {
//判断文件是否是打开
var isOpen = !isNull(fileName);
//文件过滤
if (isNull(nameFilter)) {
nameFilter = "";
}
if (isOpen && !isUrl(fileName)) {
if (!isNull(AutoSave) && !new QFileInfo(fileName).baseName().startsWith("~")) {
if (!AutoSave.recover(fileName)) {
// canceled file recovering:
return undefined;
}
}
}
//获取主窗口
var appWin = EAction.getMainWindow();
//获取取主mdi
var mdiArea = appWin.centralWidget();
if (isOpen) {
appWin.handleUserMessage(qsTr("Opening drawing:") + " " + fileName + "...");
}
// create document:
//创建存储
var storage = new RMemoryStorage();
//创建空间索引
var spatialIndex = createSpatialIndex();
//创建文档
var document = new RDocument(storage, spatialIndex);
//创建一个文档接口
var documentInterface = new RDocumentInterface(document);
if (isOpen) {
//appWin.setProgressText(qsTr("Loading..."));
var errorCode;
if (isUrl(fileName)) {
errorCode = documentInterface.importUrl(new QUrl(fileName), nameFilter);
document.setFileName("");
document.setModified(true);
}
else {
errorCode = documentInterface.importFile(fileName, nameFilter);
}
if (errorCode !== RDocumentInterface.IoErrorNoError) {
var dialog = new QMessageBox(
QMessageBox.Warning,
qsTr("Import Error"),
"",
QMessageBox.OK
);
var path = fileName.elidedText(dialog.font, 500);
var text = qsTr("Cannot open file") + "\n\n'%1'.\n\n".arg(path);
switch (errorCode) {
case RDocumentInterface.IoErrorNoImporterFound:
text += qsTr("No suitable Importer found. "
+ "Please check file format and extension.");
break;
case RDocumentInterface.IoErrorNotFound:
text += qsTr("File not found.");
break;
case RDocumentInterface.IoErrorPermission:
text += qsTr("Please check your access rights, "
+ "the file format and file extension.");
break;
case RDocumentInterface.IoErrorGeneralImportError:
text += qsTr("Import failed.");
break;
case RDocumentInterface.IoErrorZeroSize:
text += qsTr("File is empty.");
break;
}
dialog.text = text;
appWin.handleUserWarning(text);
dialog.exec();
dialog.destroy();
EAction.activateMainWindow();
RSettings.removeRecentFile(fileName);
return undefined;
}
else {
appWin.handleUserMessage(qsTr("Drawing loaded successfully:") + " " + fileName);
}
if (document.getFileVersion().length!==0) {
appWin.handleUserMessage(qsTr("Format:") + " " + document.getFileVersion());
}
RSettings.removeRecentFile(fileName);
RSettings.addRecentFile(fileName);
}
if (!isOpen) {
//新建文档
// color of layer 0 defaults to black if background color is bright:
var bgColor = RSettings.getColor("GraphicsViewColors/BackgroundColor", new RColor("black"));
if (bgColor.lightness()>200) {
var layer0 = document.queryLayer("0");
layer0.setColor(new RColor("black"));
var op = new RModifyObjectOperation(layer0, false);
documentInterface.applyOperation(op);
document.setModified(false);
}
}
var uiFileName = undefined;
// get viewport template from drawing settings
if (isOpen) {
uiFileName = document.getVariable("Viewport/ViewportList.data");
}
if (!isOpen || isNull(uiFileName)) {
//如果没有ui文件,则使用ViewportList.data
uiFileName = RSettings.getStringValue("Viewport/ViewportList.data", "00_Single.ui");
}
//创建子mdi
var mdiChild = new RMdiChildQt();
//设置子mdi图标
mdiChild.windowIcon = new QIcon(autoPath("scripts/qcad_icon.png"));
//设置子mdi文档接口
mdiChild.setDocumentInterface(documentInterface);
var flags = new Qt.WindowFlags(Qt.FramelessWindowHint);
mdiChild.setWindowFlags(flags);
//向主mdi中添加子mdi
mdiArea.addSubWindow(mdiChild);
mdiChild.updatesEnabled = false;
// load ui file and set the MDI content widget:
//qDebug("initMdiChild");
//创建视图
ViewportWidget.initMdiChild(mdiChild, uiFileName);
// fix Qt bug in which Qt icon is shown at the top left if tab bar is off:
mdiChild.showMaximized();
var viewports = ViewportWidget.getViewports(mdiChild, documentInterface);
mdiChild.viewports = viewports;
//视图绑定场景和文档
ViewportWidget.initializeViewports(viewports, uiFile, graphicsSceneClass);
NewFile.updateTitle(mdiChild);
NewFile.setupDefaultAction(documentInterface);
ViewportWidget.initEventHandler(viewports);
RGuiAction.triggerGroupDefaults();
mdiChild.closeRequested.connect(NewFile, "closeRequested");
mdiChild.modifiedStatusChanged.connect(NewFile, "updateTitle");
appWin.resumedTab.connect(NewFile, "updateTitle");
// make sure the MDI widget is maximized before performing an auto zoom:
// Qt 5 / Unity bug workaround:
// breaks Ubuntu Unity menu on start:
if (RS.getSystemId()!=="linux" || !RSettings.isQt(5) || appWin.property("starting")!==true) {
appWin.disable();
}
for (var i=0; i<5; i++) {
QCoreApplication.processEvents();
}
if (!appWin.enabled) {
appWin.enable();
}
//qDebug("subWindowActivated");
appWin.subWindowActivated(mdiChild);
//qDebug("updateViewports");
if (!isDeleted(mdiChild)) {
mdiChild.updatesEnabled = true;
ViewportWidget.updateViewports(viewports);
}
var k, action;
if (isOpen) {
// trigger post open actions (actions configured by the user to be
// run whenever a file is opened, for example to show a font
// replacement dialog, etc):
for (k=0; k<NewFile.postOpenActions.length; k++) {
if (!isNull(NewFile.postOpenActions[k])) {
action = RGuiAction.getByScriptFile(NewFile.postOpenActions[k]);
if (!isNull(action)) {
action.slotTrigger();
}
}
}
}
else {
// trigger post new action (e.g. to load template file):
for (k=0; k<NewFile.postNewActions.length; k++) {
if (!isNull(NewFile.postNewActions[k])) {
include(NewFile.postNewActions[k]);
if (isFunction(initNewFile)) {
initNewFile(mdiChild);
}
action = RGuiAction.getByScriptFile(NewFile.postNewActions[k]);
if (!isNull(action)) {
action.slotTrigger();
}
}
}
}
if (!isNull(mdiChild) && !isDeleted(mdiChild)) {
mdiChild.setFocus();
}
return mdiChild;
};
下面的代码用于创建视图:
//初始化视图
ViewportWidget.initMdiChild = function (mdiChild, uiFileName) {
//创建一个视口
var w = WidgetFactory.createWidget("", ViewportWidget.templateDir + QDir.separator + uiFileName, mdiChild);
//设置视口标题
w.setWindowTitle("");
//设置一个视口
mdiChild.setWidget(w);
};
下面的代码用于获取视图:
ViewportWidget.getViewports = function(widget, documentInterface) {
var vpWidget;
var c = 0;
var vps = [];
do {
//拼视口名称
var vpName = sprintf("Viewport%02d", c);
//查找视口
vpWidget = widget.findChild(vpName);
//如果视口是null,则返回
if (isNull(vpWidget)) {
break;
}
//如果视口不是null,就把视口的名称,
var viewport = new ViewportWidget(c, vpWidget, documentInterface);
vps.push(viewport);
++c;
} while (!isNull(vpWidget));
return vps;
};
下面的代码用于关联视图、场景、文档接口:
ViewportWidget.initializeViewports = function(viewports, uiFile, graphicsSceneClass) {
for ( var i = 0; i < viewports.length; ++i) {
var vp = viewports[i];
//真正的调用视口创建时场景
vp.init(uiFile, graphicsSceneClass);
}
};
ViewportWidget.prototype.init = function(uiFile, graphicsSceneClass) {
// delete placeholder children if there are any (clear out parent window):
var chs = this.vpWidget.children();
for (var i = 0; i < chs.length; ++i) {
var ch = chs[i];
ch.destroy();
}
if (isNull(uiFile)) {
uiFile = "scripts/Widgets/ViewportWidget/ViewportWidgetQt.ui";
}
// use ViewportWidgetQt.ui or
var vpw = WidgetFactory.createWidget("", uiFile, this.vpWidget);
var layout = new QVBoxLayout();
layout.addWidget(vpw, 0, Qt.AlignTop | Qt.AlignLeft);
layout.setStretch(0, 1);
layout.setContentsMargins(0,0,0,0);
if (!isNull(this.vpWidget.layout())) {
// destroy existing layout manager
this.vpWidget.layout().destroy();
}
this.vpWidget.setLayout(layout);
// clear style sheet
this.vpWidget.styleSheet = "";
this.graphicsView = this.vpWidget.findChild("GraphicsView");
if (isNull(this.graphicsView)) {
qWarning("graphics view not found");
return;
}
this.graphicsView.setViewportNumber(this.vpNumber);
if (isFunction(this.graphicsView.setFocusFrameWidget)) {
this.graphicsView.setFocusFrameWidget(this.vpWidget);
}
this.graphicsView.setAntialiasing(RSettings.getBoolValue("GraphicsView/Antialiasing", false));
// create custom graphics scene (e.g. OpenGL, ...):
var scene = undefined;
if (!isNull(graphicsSceneClass)) {
if (!isNull(global[graphicsSceneClass])) {
scene = new global[graphicsSceneClass](this.documentInterface);
}
}
if (isNull(scene)) {
//场景绑定文档接口
scene = new RGraphicsSceneQt(this.documentInterface);
}
if (RSettings.getBoolValue("GraphicsView/AutoSwitchLinetypes", false)===true) {
scene.setScreenBasedLinetypes(true);
}
//设置场景
this.graphicsView.setScene(scene);
if (typeof(DefaultNavigation)!=="undefined") {
var navigationAction = new DefaultNavigation(this.vpWidget);
this.graphicsView.setNavigationAction(navigationAction);
}
//视图中添加正交网格
var grid = new ROrthoGrid(this.graphicsView.getRGraphicsView());
this.graphicsView.setGrid(grid);
this.graphicsView.setFocus();
this.hsb = this.vpWidget.findChild("HorizontalScrollBar");
if (!isNull(this.hsb)) {
this.hsb.singleStep = 50;
}
this.vsb = this.vpWidget.findChild("VerticalScrollBar");
if (!isNull(this.vsb)) {
this.vsb.singleStep = 50;
}
if (RSettings.getBoolValue("GraphicsView/ShowScrollBars", true)===false) {
var infoLabel = this.vpWidget.findChild("InfoLabel");
infoLabel.hide();
if (!isNull(this.hsb)) {
this.hsb.hide();
}
if (!isNull(this.vsb)) {
this.vsb.hide();
}
}
if (RSettings.getBoolValue("GraphicsView/ShowRulers", true)) {
//显示尺子
//水平尺子
this.hruler = this.vpWidget.findChild("HorizontalRuler");
if (!isNull(this.hruler)) {
this.hruler.setGraphicsView(this.graphicsView);
this.documentInterface.addCoordinateListener(this.hruler);
}
//垂直尺子
this.vruler = this.vpWidget.findChild("VerticalRuler");
if (!isNull(this.vruler)) {
this.vruler.setGraphicsView(this.graphicsView);
this.documentInterface.addCoordinateListener(this.vruler);
}
} else {
var hruler = this.vpWidget.findChild("HorizontalRuler");
if (!isNull(hruler)) {
//隐藏尺子
hruler.hide();
}
var vruler = this.vpWidget.findChild("VerticalRuler");
if (!isNull(vruler)) {
//隐藏尺子
vruler.hide();
}
var cf = this.vpWidget.findChild("cornerFrame");
if (!isNull(cf)) {
//??
cf.hide();
}
}
};