www.gusucode.com > rmidemos工具箱matlab源码程序 > rmidemos/slvnvdemo_customlinktype.m

    %% Implement RMI Extension for Support of Custom Document Type
% Requirements Management Interface (RMI) provides tools for creating and
% reviewing links between model-based design elements and requirements
% documents. RMI provides built-in support for many document types.
% Additionally, you can implement custom link-type extensions to enable
% linking to other document types. 
% This example illustrates implementation of RMI extension for linking with
% Microsoft PowerPoint presentations. 

% Copyright 2014-2015 The MathWorks, Inc.

%% Files to Use with This Example
% For the purposes of this example tutorial, we will link objects in the
% <matlab:open_system('slvnvdemo_powerwindowController')
% slvnvdemo_powerwindowController.slx> model with slides in the
% <matlab:rmidemo_callback('doc','powerwin_reqs\powerwindowController.pptx') powerwindowController.pptx> PowerPoint presentation.
% Because of possible user permission limitations, and to avoid the risk of
% unintentionally modifying installed files, it is recommended that you
% create your own copies of both the 
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/slvnvdemo_powerwindowController.slx'],'./slvnvdemo_powerwindowController_copy.slx') model>.
% and the
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/powerwindowController.pptx'],'./powerwindowController_copy.pptx') document>.
% Consider making both files
% <matlab:fileattrib(fullfile(pwd,'powerwindowController_copy.pptx'),'+w');fileattrib(fullfile(pwd,'slvnvdemo_powerwindowController_copy.slx'),'+w');
% writeable>, and configure RMI settings to store
% traceability data in a separate |.req| file (see the *Storage* tab in the
% <matlab:rmi_settings_dlg Settings dialog>).

rmipref('StoreDataExternally', true); % use "external" (.req) storage
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/powerwindowController.pptx'], './powerwindowController_copy.pptx');
fileattrib(fullfile(pwd, 'powerwindowController_copy.pptx'),'+w'); % make user copy writable
copyfile([rmidemoroot,'/slvnvdemo_powerwindowController.slx'], './slvnvdemo_powerwindowController_copy.slx');
fileattrib(fullfile(pwd, 'slvnvdemo_powerwindowController_copy.slx'),'+w'); % make user copy writable
open_system('slvnvdemo_powerwindowController_copy');

%% Installed Link Type Definition Files
% Depending on the application you use for your custom-type documents,
% you can implement basic support, including link creation
% via the *Link Editor* dialog box and link navigation via context menu shortcuts,
% or you may choose to implement a more feature-rich support with selection
% linking via context menu shortcuts, consistency checking, etc.
%
% In this tutorial we will create a Custom Link Type definition from
% scratch. To find out more about the Custom Link Type extension API, please
% refer to the included
% <matlab:edit([matlabroot,'/toolbox/slrequirements/linktype_examples/linktype_TEMPLATE.m'])
% linktype_TEMPLATE>, or review the actual linktype definition files used
% by the released product. For an example, refer to the minimal 
% <matlab:edit([matlabroot,'/toolbox/slrequirements/linktype_examples/linktype_rmi_text.m'])
% Text File link type> or the more advanced 
% <matlab:edit([matlabroot,'/toolbox/slrequirements/linktype_examples/linktype_rmi_excel.m'])
% Microsoft Excel Workbook link type>. 

%% Create and Register a Stubbed Link Type File
% Copy and paste the following code into the MATLAB Editor and save the
% script as |slvnvdemo_pp_linkype.m| anywhere on MATLAB path. 
%
%   function linkType = rmidemo_pp_linktype
%       linkType = ReqMgr.LinkType;
%       linkType.Registration = mfilename;
%       linkType.Version = '';  % not used
%       %
%       % Label describing this link type
%       linkType.Label = 'Microsoft Power Point';
%       %
%       % File information
%       linkType.IsFile = 1;
%       linkType.Extensions = {'.ppt', '.pptx'};
%       %
%       % Location delimiters
%       linkType.LocDelimiters = '#';
%       %
%       % Supported methods
%       linkType.NavigateFcn = @NavigateFcn;
%   end
%   
%   function NavigateFcn(filePath,locationStr)
%       if isempty(locationStr)
%           disp(['Navigating to "' filePath '"']);
%       else
%           disp(['Navigating to "' locationStr '" in "' filePath '"']);
%       end
%   end
%
% Alternatively,
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step1.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click here to install this script>.
%
% Next,
% <matlab:rmi('register','rmidemo_pp_linktype') register your new link type with RMI>.
%
% This instructs RMI to recognize the filename extensions |.ppt| and |.pptx| as
% supported files and to use the methods defined here for RMI functionality.

rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step1.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('register', 'rmidemo_pp_linktype')


%% Create the First Link
% 
% * Right-click the background of the
% <matlab:open_system('slvnvdemo_powerwindowController_copy')
% slvnvdemo_powerwindowController_copy> example model and expand the 
% *Requirements Traceability* submenu
% * Click *Open Link Editor* to bring up the 
% <matlab:rmi('edit','slvnvdemo_powerwindowController_copy'); Link Editor
% dialog>
% * Click *New* to create a new link
% * Expand the *Document Type* drop-down
% list. *Microsoft Power Point* appears at the bottom
% * Use the *Browse* button to locate
% <matlab:uiopen('powerwindowController_copy.pptx') your copy of the
% example document>
% * Enter a *Description* label, like _Example Presentation_
% * Click *OK* to save the new link and close the dialog
%
% <<customlinktype_linkeditor.png>>
% 
% Right-click the Simulink diagram background again and expand the *Requirements
% Traceability* submenu. Notice the new navigation shortcut at the top of
% the submenu. When you 
% <matlab:rmi('view','slvnvdemo_powerwindowController_copy',1) click this new shortcut>,
% MATLAB displays the message in a command window, according to the stubbed
% implementation of
% <matlab:edit('rmidemo_pp_linktype.m') rmidemo_pp_linktype>.
%
% <<customlinktype_firstlink.png>>

firstReq = rmi('createempty');
firstReq.reqsys = 'rmidemo_pp_linktype';
firstReq.doc = 'powerwindowController_copy.pptx';
firstReq.description = 'Example presentation';
rmi('set', 'slvnvdemo_powerwindowController_copy', firstReq);
rmi('view','slvnvdemo_powerwindowController_copy', 1);

%% Implement Navigation to the Document
% You can now provide a functional implementation for the
% |NavigateFcn| in |rmidemo_pp_linktype.m|. Implementation of this and all
% other methods requires detailed knowledge of the APIs available in the
% application that manages the requirements documents. For this Microsoft
% PowerPoint example we use COM API. We use the |actxserver| command
% in MATLAB to create a connection with the PowerPoint application.
% Then, we use calls like |Application.Presentations.Open(FILENAME)| to
% manipulate the PowerPoint application via the |rmidemo_pp_linktype| methods.
% See Microsoft's 
% <matlab:web('http://msdn.microsoft.com/en-us/library/office/ff743835(v=office.15).aspx')
% Developer Reference pages> for information on which
% PowerPoint Objects and Methods are available via COM API.
%  
% Copy and paste the following code to replace the existing |NavigateFcn()|
% stub in |rmidemo_pp_linktype.m|.  Make sure to copy the new helper
% functions as well.
%
%   function NavigateFcn(filePath, locationStr)
%       if isempty(loctionStr)
%           disp(['Navigating to "' filePath '"']);
%       else
%           disp(['Navigating to "' locationStr '" in "' filePath '"']);
%       end
%       hDoc = openFile(filePath);
%       if isempty(hDoc)
%           disp(['Failed to open ' filePath]);
%       else
%           % try to bring the window forward
%           [~, fileName, ext] = fileparts(filePath);
%           reqmgt('winFocus', [fileName ext]); % locate by window title match
%       end
%   end
%  
%   function hDoc = openFile(fileName)
%       disp(['Checking for ' fileName]);
%       hApp = getApplication();
%       hDoc = findOpenDoc(hApp, fileName);
%       if isempty(hDoc)
%           try
%               hDoc = hApp.Presentations.Open(fileName);
%           catch
%               hDoc = [];
%           end
%       end
%   end
%   
%   function hApp = getApplication()
%       try
%           % try to connecto to already running application
%           hApp = actxGetRunningServer('powerpoint.application');
%       catch
%           % start-up PowerPoint and connect to it
%           hApp = actxserver('powerpoint.application');
%       end
%   end
%   
%   function hDoc = findOpenDoc(hApp, fileName)
%       hDoc = [];
%       hDocs = hApp.Presentations;
%       for i = 1:hDocs.Count
%           if strcmp(hDocs.Item(i).FullName, fileName)
%               hDoc = hDocs.Item(i);
%               return;
%           end
%       end
%   end
%
% Alternatively, 
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step2.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install>.
%
% Retry navigation from the block diagram. The Microsoft PowerPoint
% application should start and display the correct document.
%
% <<customlinktype_docopen.png>>

rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step2.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('view','slvnvdemo_powerwindowController_copy', 1);

%% Implement Navigation to a Given Slide Number
% Suppose we want to link 
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table')
% Driver Input Truth Table> to the corresponding slide number 5 in the
% PowerPoint presentation.
%
% * Right-click the block, expand the *Requirements Traceability* submenu, and
% <matlab:rmi('edit','slvnvdemo_powerwindowController_copy/Truth%20Table');
% open the Link Editor dialog>
% * Specify the document type and filename as before
% * Enter _Driver input_ into the *Description* field
% * Enter _5_ into the *Location/Identifier* input field 
% * Click *OK* to save the new link
%
% <<customlinktype_driverinput.png>>
%
% If you navigate this link from the Simulink diagram, the document will
% open as before, but it will not scroll down to 5th slide. You need to
% extend the implementation of |NavigateFcn()| in |rmidemo_pp_linktype.m|
% to allow navigation to particular slide.
% Copy and paste the following implementation, including
% the helper |goToSlide()| method.
%
%   function NavigateFcn(filePath, locationStr)
%       if isempty(locationStr)
%           disp(['Navigating to "' filePath '"']);
%       else
%           disp(['Navigating to "' locationStr '" in "' filePath '"']);
%       end
%       hDoc = openFile(filePath);
%       if isempty(hDoc)
%           disp(['Failed to open ' filePath]);
%       else
%           if ~isempty(locationStr)
%               switch(locationStr(1))
%                   case '#'
%                       slideNum = str2num(locationStr(2:end)); %#ok<ST2NM>
%                       goToSlide(hDoc, slideNum);
%                   otherwise
%                       warning('Invalid location specifier: %s', locationStr);
%               end
%           end
%           % try to bring the window forward
%           [~, fileName, ext] = fileparts(filePath);
%           reqmgt('winFocus', [fileName ext]); % locate by window title match
%       end
%   end
%   
%   function goToSlide(hDoc, slideNum)
%       disp(['Opening slide #' num2str(slideNum)]);
%       hDoc.Slides.Item(slideNum).Select;
%   end
%
% Alternatively, 
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step3.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install>.
%
% Retry navigation from the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table')
% Driver Input Truth Table block>. 
%
% <<customlinktype_drivershortcut.png>>
% 
% PowerPoint presentation window should scroll down to 5th slide.
%
% <<customlinktype_drivernavigate.png>>

secondReq = rmi('createempty');
secondReq.reqsys = 'rmidemo_pp_linktype';
secondReq.doc = 'powerwindowController_copy.pptx';
secondReq.description = 'Driver input';
secondReq.id = '#5';
rmi('set', 'slvnvdemo_powerwindowController_copy/Truth Table', secondReq);
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step3.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('view','slvnvdemo_powerwindowController_copy/Truth Table', 1);

%% Implement Navigation to a Given Slide ID
% Linking to a stored slide number can be problematic: links may
% get stale when you modify the document. For example, duplicate the first
% slide in our presentation:
%
% <<customlinktype_duplicateslide.png>>
% 
% Now all the other slides shift down by one. Navigation from the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table')
% Driver Input Truth Table block> will bring up the wrong slide. We need to  
% use a different location type, other than |Page/Item number|. 
% To do this we modify the |LocDelimiters| list in
% |rmidemo_pp_linktype.m| file to become:
% 
%    % Location delimiters
%    linkType.LocDelimiters = '#@';
%
% We also need to further extend the |NavigateFcn| implementation by
% adding another |case|:
%
%            case '@' 
%                goToItem(hDoc, locationStr(2:end));
%
% Finally, we add implementation for the |goToItem()| method:
%
%   function goToItem(hDoc, itemIdStr)
%       disp(['Opening item ID ' itemIdStr]);
%       itemId = str2num(itemIdStr); %#ok<ST2NM>
%       hDoc.Slides.FindBySlideID(itemId).Select;
%   end
% 
% You can insert these changes manually, or 
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step4.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install>. You also need to 
% <matlab:rmi('unregister','rmidemo_pp_linktype') unregister> and 
% <matlab:rmi('register','rmidemo_pp_linktype') re-register> the linktype
% for these changes to go into effect.

rmi('unregister', 'rmidemo_pp_linktype');
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step4.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('register', 'rmidemo_pp_linktype');

%% Linking and Navigation to Slide ID
% Now that our linktype supports _Named Item_ location identifiers, do the
% following:
% 
% * <matlab:rmi('edit','slvnvdemo_powerwindowController_copy/Truth%20Table');
% Re-open the Link Editor dialog> for the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table')
% Driver Input Truth Table block>
% * Select _Named Item_ from the *Location (Type/Identifier)* drop-down list
% * Enter _260_ into the *Location* input field
% * Click *OK* to save the modified link
%
% "260" is a persistent ID for the _Driver Input_ slide (more on this below).
%
% <<customlinktype_linktoid.png>>
%
% Now, after this change, navigation from the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table')
% Driver Input Truth Table block>
% will bring up the correct slide, even after its order number changes. 
%
% Unfortunately, one cannot see slide IDs in the PowerPoint application UI.
% To find out the ID for the 5th slide, you can use the COM API:
%
%  >> hApp = actxGetRunningServer('powerpoint.application');
%  >> hDoc = hApp.ActivePresentation;
%  >> hDoc.Slides.Item(5).SlideID  
%  ans =
%     260
%
% More user-friendly solutions to this problem are covered in the sections
% below.

betterLink = rmi('createempty');
betterLink.reqsys = 'rmidemo_pp_linktype';
betterLink.doc = 'powerwindowController_copy.pptx';
betterLink.description = 'Driver input - better link';
betterLink.id = '@260';
rmi('set', 'slvnvdemo_powerwindowController_copy/Truth Table', betterLink);
rmi('view','slvnvdemo_powerwindowController_copy/Truth Table', 1);

%% Enable Linking Via a Document Index Selection
% As shown above, we can create persistent links that do not become stale
% after slides in linked presentation are re-ordered, but you do not
% have easy access to persistent _SlideID_ values in PowerPoint.
% One possible solution is to select a desired slide in the
% Document Index tab of the Link Editor dialog. The content of the Document
% Index tab is controlled by the |ContentsFcn()| method in the linktype definition
% file. We can provide implementation for this method, such that the
% persistent _SlideID_ value is stored by RMI when creating a link,
% insetead of the volatile _SlideNumber_ value.
%
% In the |rmidemo_pp_linktype.m|, add the |ContentsFcn()| declaration to
% the list of supported methods:
%
%      % Supported methods
%      linkType.NavigateFcn = @NavigateFcn;
%      linkType.ContentsFcn = @ContentsFcn;
%
% Next, provide the implementation for |ContentsFcn()|:
%
%   function [labels, depths, locations] = ContentsFcn(filePath)
%       hDoc = openFile(filePath);
%       slidecount = hDoc.Slides.Count;
%       if slidecount == 0
%           labels = {'no slides in presentation!'};
%           locations = {''};
%           depths = 0;
%       else
%           labels = cell(slidecount,1);
%           locations = cell(slidecount,1);
%           depths = zeros(slidecount,1);
%       end
%       for k = 1:slidecount    
%           try
%               txt = hDoc.Slides.Item(k).Shapes.Item(1).TextFrame.TextRange.Text;
%               txt(txt < 32) = ' ';  % avoid control characters in labels
%           catch  
%               txt = '[slide with no title]';
%           end
%           labels{k} = strtrim(txt);
%           locations{k} = ['@' num2str(hDoc.Slides.Item(k).SlideID)];
%       end
%       reqmgt('winFocus', 'Link Editor'); % try to keep the dialog on top
%   end
%
% Alternatively,
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step5.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install>. You also need to 
% <matlab:rmi('unregister','rmidemo_pp_linktype') unregister> and 
% <matlab:rmi('register','rmidemo_pp_linktype') re-register> the linktype
% for these changes to go into effect.
%
% As you can see, the |ContentsFcn()| methods returns three arrays: 
%
% * |labels| to use for Document Index list items and navigation shortcuts 
% * |depths| to indicate the hierarchical relationship of listed items (unused in this example)
% * |locations| to use for stored unique IDs
% 
% The |ContentsFcn()| implementation relies on the following PowerPoint API
% call to populate _location_ values:
% 
%   hDoc.Slides.Item(k).SlideID
%
% This ensures persistent
% navigation information even after slide order changes.
% Note that we use _@_ as a prefix for |locations| values, to indicate that
% the number that follows stores the _Named Item_ location value instead of
% slide (page) number location value.

rmi('unregister', 'rmidemo_pp_linktype');
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step5.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('register', 'rmidemo_pp_linktype');

%% Using Document Index Tab
% Now that our PowerPoint link type supports a functional Document Index
% tab, we can use it to populate input fields in the primary tab:
%
% * Right-click the 
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table1')
% Truth Table block connected to passenger inputs>
% * Expand the *Requirements Traceability* submenu
% * <matlab:rmi('edit','slvnvdemo_powerwindowController_copy/Truth%20Table1');
% Open the *Link Editor* dialog> 
% * As done before, click *New* for a new link entry
% * Specify _Microsoft PowerPoint_ as the *Document type*
% * Specify _powerwindowController_copy.pptx_ as the *Document*
% * Leave the *Description* input
% * Instead of specifying *Location* manually, switch to the *Document
% Index* tab, locate the line that corresponds to Passenger Inputs slide,
% and double-click the line
% * Notice that the remaining input fields are automatically filled with the
% correct information
% * Click *OK* to save the new link
%
% <<customlinktype_docindex.png>>
%
% <<customlinktype_location.png>>
%
% Navigate the link via the new shortcut at the top of the *Requirements
% Traceability* context submenu for the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/Truth%20Table1')
% Truth Table1 block>. This link should work correctly even after slides
% are shifted or re-ordered.

indexLink = rmi('createempty');
indexLink.reqsys = 'rmidemo_pp_linktype';
indexLink.doc = 'powerwindowController_copy.pptx';
indexLink.description = 'Passenger input - linked via Index tab';
indexLink.id = '@259';
rmi('set', 'slvnvdemo_powerwindowController_copy/Truth Table1', indexLink);
rmi('view','slvnvdemo_powerwindowController_copy/Truth Table1', 1);

%% Enable Linking to the Current Slide in PowerPoint
% An even better way to support robust persistent links is via Selection
% Linking Shortcuts. The RMI API allows you to defind a the
% |SelectionLinkFcn()| function
% for linking with the current object in the current document.
% In the next step of our tutorial, you will automate linking to the current
% slide in the currently open PowerPoint presentation.
%
% In the top section of |rmidemo_pp_linktype.m|, add the following declarations:
%
%      % For selection-based linking:
%      linkType.SelectionLinkLabel = 'Link to Slide in PowerPoint';
%      linkType.SelectionLinkFcn = @SelectionLinkFcn; 
%
% Next, copy and paste the following implementation for
% |SelectionLinkFcn()|, including the |getCurrentDoc()| helper method:
%
%   function reqstruct = SelectionLinkFcn(objH, varargin)
%       reqstruct=[];
%       hDoc = getCurrentDoc();
%       if isempty(hDoc)
%           errordlg('PowerPoint presentation is not open', 'Linking Failed');
%           return;
%       end
%       %
%       % PPT file we are linking with:
%       docName = hDoc.Name;   % or should we use .FullName ??
%       %
%       % PPT slide we are linking with:
%       currentSlide = hDoc.Application.ActiveWindow.Selection.Slide;
%       [objName, objType] = rmi.objname(objH);
%       disp(['Linking ' objName ' (' objType ') to ' currentSlide.Name ' in ' docName]);
%       %
%       % Add a new requirement
%       reqstruct = rmi('createempty');
%       reqstruct.reqsys = mfilename;
%       reqstruct.doc = docName;
%       reqstruct.id = sprintf('@%d', currentSlide.SlideId);    
%       %
%       % Label for navigation shortcut
%       try
%           txt = currentSlide.Shapes.Item(1).TextFrame.TextRange.Text;
%           txt(txt < 32) = ' ';  % avoid control characters in labels
%       catch
%           txt = '[slide with no title]';
%       end
%       if length(txt) > 40
%           reqstruct.description = [txt(1:40) '...'];
%       else
%           reqstruct.description = txt;
%       end
%   end
%   
%   function hDoc = getCurrentDoc()
%       hDoc = [];
%       try
%           % try to connecto to already running application
%           hApp = actxGetRunningServer('powerpoint.application');
%           hDoc = hApp.ActivePresentation;
%       catch
%           return;  % PowerPoint is not running
%       end
%   end
%
% Or,
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step6.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install this script>. Again, you will 
% need to <matlab:rmi('unregister','rmidemo_pp_linktype') unregister> and 
% <matlab:rmi('register','rmidemo_pp_linktype') re-register> the linktype
% for these changes to go into effect.

rmi('unregister', 'rmidemo_pp_linktype');
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step6.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('register', 'rmidemo_pp_linktype');

%% Use the Selection Linking Shortcut
% The *Requirements Traceability* section of the context menus will now
% display a new shortcut for linking with the current slide in PowerPoint. 
%
% * In your copy of the PowerPoint presentation example, open a slide 6
% which deals with
% _end positions_ of window movement (make it the active slide)
% * In the Simulink diagram, right-click the 
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/endstop')
% endstop input>
% * Expand the *Requirements Traceability* context submenu
% * Click on *Link to Slide in PowerPoint*
%
% <<customlinktype_selectionlink.png>>
%
% RMI will automaticlly create a link to the _SlideID_ that corresponds to
% the current location in the active presentation.
% RMI will try to use the header text of the target slide as a label for
% the new link. 
%
% * Close the PowerPoint application
% * Right-click the
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/endstop')
% input> again to re-display the context menu
% * Click the new link to navigate it
%
% The PowerPoint application should open to the correct slide.
%
% <<customlinktype_selectionnavigate.png>>
%

selectionLink = rmi('createempty');
selectionLink.reqsys = 'rmidemo_pp_linktype';
selectionLink.doc = 'powerwindowController_copy.pptx';
selectionLink.description = 'Endstop signal - selection link';
selectionLink.id = '@261';
rmi('set', 'slvnvdemo_powerwindowController_copy/endstop', selectionLink);
rmi('view','slvnvdemo_powerwindowController_copy/endstop', 1);

%% Selection-based Bidirectional Linking Support
% As a final steop of this tutorial you will extend the |SelectionLinkFcn()|
% function to optionally insert a hyperlink in the current slide, for
% navigation from PowerPoint to the linked object in Simulink.
%
% In the |rmidemo_pp_linktype.m| script, modify the header of |SelectionLinkFcn()|
% to look like this:
%
%   function reqstruct = SelectionLinkFcn(objH, make2way, varargin)
%
% Then add the following code at the bottom of |SelectionLinkFcn()|:
%
%   if make2way
%       % Insert a Simulink RMI icon with navigation hyperlink: 
%       slPicture = [matlabroot '\toolbox\shared\reqmgt\icons\mwlink.bmp'];
%       currentSlide.Shapes.AddPicture(slPicture, 'msoTrue', 'msoTrue', 20, 20);
%       myNewShape = currentSlide.Shapes.Item(currentSlide.Shapes.Count);
%       myNewShape.ActionSettings.Item(1).Hyperlink.Address = rmi.getURL(objH);
%       myNewShape.ActionSettings.Item(1).Hyperlink.ScreenTip = ['Linked from ' objName ' (' objType ')'];
%   end
%
% Or,
% <matlab:copyfile([matlabroot,'/toolbox/slvnv/rmidemos/powerwin_reqs/rmidemo_pp_linktype_step7.m'],'./rmidemo_pp_linktype.m');fileattrib('./rmidemo_pp_linktype.m','+w');
% click to install this script>. Be sure to 
% <matlab:rmi('unregister','rmidemo_pp_linktype') unregister> and 
% <matlab:rmi('register','rmidemo_pp_linktype') re-register> the linktype.

rmi('unregister', 'rmidemo_pp_linktype');
rmidemoroot = [matlabroot,'/toolbox/slvnv/rmidemos'];
copyfile([rmidemoroot,'/powerwin_reqs/rmidemo_pp_linktype_step7.m'], './rmidemo_pp_linktype.m');
fileattrib('./rmidemo_pp_linktype.m','+w');
rmi('register', 'rmidemo_pp_linktype');

%% Creating Bidirectional Links
% Your PowerPoint link type now allows automated insertion of Simulink
% navigation controls into linked slides, when you use *Link to Slide in
% PowerPoint* shortcut in the context menu for Simulink objects. To activate this
% feature, enable the *Modify destination for bidirectional linking* checkbox
% in the *Selection Linking* tab of the <matlab:rmi_settings_dlg RMI Settings dialog>.
% 
% To try this out, let us repeat the selection linking procedure for the 
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/obstacle')
% obstacle signal input>, to associate it with the corresponding slide in
% the example presentation. 
%
% * Scroll to slide 7 in the PowerPoint presentation (make it the active slide)
% * Right-click the  
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController_copy/obstacle')
% obstacle input>
% * Expand the *Requirements Traceability* context submenu
% * Click *Link to Slide in PowerPoint*
% 
% You should now see a new RMI icon inserted at the top-left corner of the
% slide.
%
% <<customlinktype_selectiontwoway.png>>
%
% You can open the *Edit Hyperlink* dialog in PowerPoint to confirm that there
% is a MATLAB URL associated with the new icon. It is recommended that you do
% not edit this URL manually.  
% 
% To see the hyperlink in action, switch PowerPoint application into the
% presentation mode and click the MATLAB icon. 
% The Simulink diagram will pop up with the correct input highlighted.
%
% <<customlinktype_selectiontosl.png>>

origTwoWayPref = rmipref('BiDirectionalLinking', true);

%% Where to Go from Here
% As opposed to linking to a Slide as a whole, you may want to modify the
% |SelectionLinkFcn()| implementation to link to a specific text or picture
% in the slide. Refer to Microsoft's 
% <matlab:web('http://msdn.microsoft.com/en-us/library/office/ff743835(v=office.15).aspx')
% Developer Reference pages> for information on how to adjust the anchoring
% and appearance of Simulink navigation controls. For example, instead of
% inserting an icon with a hyperlink, you may want to attach a hyperlink to
% the selected text on the current slide.
% 
% If you need to link to a _Search text_ pattern, irrespective of which
% slide includes the stored text, you can extend the declaration of
% supported location types to include the _?_ character:
%
%    linkType.LocDelimiters = '#@?';
%
% You should then provide an additional |case| for |switch(locationStr(1))|
% in the |NavigateFcn()| method. The corresponding |findText()| helper
% queries the PowerPoint Presentation object for all _TextFrame_ items
% in all _Slides_ and selects the item with tje matching text.
%
% The RMI link type template supports other methods, depending on your needs.
% For example, to have your custom links covered by Requirements
% Traceability Consistency Checking, consider implementing the following
% methods:
%
% * |IsValidDocFcn()|
% * |IsValidIdFcn()|
% * |IsValidDescFcn()|
%
% To adjust the way your links are displayed in generated reports, you can
% use:
%
% * |CreateURLFcn()|
% * |UrlLabelFcn()|
% * |DocDateFcn()|
% * |DetailsFcn()|
% * |HtmlViewFcn()|
%
% If your application is not file-based, but uses a proprietary database
% to store requirements documents, you must mark the link type as
% "not a file":
%
%   linkType.IsFile = 0;
%
% and provide a specialized implementation for |BrowseFcn()|. This is the
% function that gets called when you click the *Browse* button in the
% <matlab:rmi('edit','slvnvdemo_powerwindowController_copy'); Link Editor
% dialog>
%
% Finally, you may want to _synchronize_ links stored in Simulink with
% your external Requirements Management application, so that traceability
% data can be reported, analized, and modified in that application's
% environment. See the
% <matlab:showdemo('slvnvdemo_customsync') custom type synchronization example>
% where we demonstrate synchronization functionality with Microsoft Excel
% workbook.


%% Cleanup
% For this example to work as intended when you run it again, please
% discard all the changes and remove the example linktype registration:

rmipref('BiDirectionalLinking', origTwoWayPref);

try hApp = actxGetRunningServer('powerpoint.application'); hApp.Quit ; catch ; end;
docFile = 'powerwindowController_copy.pptx';
if exist(docFile, 'file') == 2 ; delete(docFile) ; end;

try close_system('slvnvdemo_powerwindowController_copy', 0); catch ; end; 
modelFile = 'slvnvdemo_powerwindowController_copy.slx';
if exist(modelFile, 'file') == 4 ; delete(modelFile) ; end;

reqFilePath = 'slvnvdemo_powerwindowController_copy.req'; 
if exist(reqFilePath, 'file') == 2 ; delete(reqFilePath) ; end;

try rmi('unregister', 'rmidemo_pp_linktype') ; catch ; end;
if exist('rmidemo_pp_linktype.m', 'file') == 2 ; delete('rmidemo_pp_linktype.m') ; end;

clear('hApp', 'rmidemoroot', 'firstReq', 'secondReq', 'betterLink', 'indexLink');
clear('selectionLink', 'docFile', 'modelFile', 'reqFilePath', 'origTwoWayPref');

displayEndOfDemoMessage(mfilename)