QCad源码分析 第六章

讲解文档视图场景的创建过程:

参考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();
        }
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值