Code covered by the BSD License  

Highlights from
FinMetrics

  • fm(varargin) This source file is subject to version 3 of the GPL license,
  • AssetThis source file is subject to version 3 of the GPL license,
  • AssetUniverseThis source file is subject to version 3 of the GPL license,
  • AxlThis source file is subject to version 3 of the GPL license,
  • CashPositionThis source file is subject to version 3 of the GPL license,
  • CashTransactionThis source file is subject to version 3 of the GPL license,
  • Config This source file is subject to version 3 of the GPL license,
  • ConsoleMenuThis source file is subject to version 3 of the GPL license,
  • ConsoleMenuItemThis source file is subject to version 3 of the GPL license,
  • CurrencyAssetThis source file is subject to version 3 of the GPL license,
  • ExchangeTradedAssetThis source file is subject to version 3 of the GPL license,
  • FinMetricsThis source file is subject to version 3 of the GPL license,
  • PortfolioThis source file is subject to version 3 of the GPL license,
  • PositionThis source file is subject to version 3 of the GPL license,
  • StatisticsThis source file is subject to version 3 of the GPL license,
  • StockPositionThis source file is subject to version 3 of the GPL license,
  • StockTransactionThis source file is subject to version 3 of the GPL license,
  • TextUIThis source file is subject to version 3 of the GPL license,
  • TextUILocaleThis source file is subject to version 3 of the GPL license,
  • TextUIQuestionThis source file is subject to version 3 of the GPL license,
  • TextUIQuestionnaireThis source file is subject to version 3 of the GPL license,
  • TransactionThis source file is subject to version 3 of the GPL license,
  • View all files

FinMetrics

by

 

Open source/open architecture quantitative portfolio management environment.

ConsoleMenu
classdef ConsoleMenu < handle
% This source file is subject to version 3 of the GPL license, 
% that is bundled with this package in the file LICENSE, and is 
% available online at http://www.gnu.org/licenses/gpl.txt
%
% This source file can be linked to GPL-incompatible facilities, 
% produced or made available by MathWorks, Inc.
    
    properties (GetAccess = public, SetAccess = private)
        Title;
        AppData;
        Items;
        Parent;       
        % The Select element determines whether this particular menu layer 
        % allows the selection of multiple items - or a single item. The default is 'One'. 
        Select = 'One';
        % PreSelectCallback and PostSelectCallback may be defined to point
        % to the function handler to be executed prior selection is made
        % or after.
        PreSelectCallback;
        PostSelectCallback;
    end
    
    methods
        function  CMobj = ConsoleMenu(Title, AppData, Props)
            CMobj.Title = Title;
            CMobj.AppData = AppData;
            
            if (nargin == 3)                               
                for t=1:size(Props,2) / 2,
                    CMobj.(Props{t*2-1}) = Props{t*2};                    
                end
            end
        end
        
        function ret = DeleteItem(CMobj, id)
            ret = false;
            if ((id < 1) || (id > size(CMobj.Items,1)))                
                return;
            end
            
            CMobj.Items(id) = [];
            ret = true;
        end
        
        function InsertItem(CMobj, item, pos)
            if (size(CMobj.Items,1) == 0 )
                CMobj.Items = { item };
            else
                switch upper(pos)
                    case 'BGN'
                        CMobj.Items = [ { item }; CMobj.Items ];
                    case 'END'
                        CMobj.Items = [ CMobj.Items; { item } ];
                    otherwise
                        CMobj.Items = [ CMobj.Items(1:pos-1,1); { item }; CMobj.Items(pos:end,1)];
                end                                                   
            end            
        end
        
        function ret = SetItemProperty(CMobj, itemTag, itemProperty, value)
            ret = false;
            menuItem = CMobj.GetItemByTag(itemTag);
            
            if ~isempty(menuItem)
                    menuItem.(itemProperty) = value;
                    ret = true;
            end
        end
        
        function ret = Pick(CMobj)
            % When it's needed, multiple item selection can be implemented
            % here based on CMobj.Select property.
            
            while ( true)     
            clc;
            
            if (isa(CMobj.PreSelectCallback, 'function_handle'))
                CMobj.PreSelectCallback();
            end
            
            menuPath = FM.ConsoleMenu.traceMenuPath(CMobj, CMobj.Title);            
            fprintf('\n%s\n\n',menuPath);
            
            for t=1:size(CMobj.Items,1),
                if (CMobj.Items{t}.Separator)
                    fprintf('\n');
                end
                if (CMobj.Items{t}.Enabled)
                    if (CMobj.Items{t}.Checked)
                        fprintf ('\t%d.\t\t%s [*]\n', t, CMobj.Items{t}.Label);
                    else
                        fprintf ('\t%d.\t\t%s\n', t, CMobj.Items{t}.Label);
                    end
                else
                    fprintf ('\t..\t\t%s\n', CMobj.Items{t}.Label);
                end
            end    
                                   
                sel = input('\n(Press "q" to quit, "k" for keyboard mode)\n\nPLEASE ENTER A CHOICE: ', 's');
                          
                switch upper(sel)                    
                    case 'Q'
                        ret = 0;
                        return;
                    case 'K'
                        CMobj.AppData.KeyboardMode();
                    otherwise
                            % Check if input is a hotkey sequence
                            if regexp(sel, '^!')
                                hotkey = regexprep(sel, '!', '');
                                rootMenuObj = CMobj.GetRootMenu();
                                hotkeyCallback = rootMenuObj.findCallbackByHotkey(hotkey);                                                
                                
                                if (isa(hotkeyCallback, 'function_handle'))
                                    hotkeyCallback();
                                end
                                
                                continue;
                            end
                            
                            if (isa(CMobj.PostSelectCallback, 'function_handle'))
                                CMobj.PostSelectCallback(sel);
                            end

                            if (str2num(sel))
                                sel = str2num(sel);                            
                                if ((sel < 1) || sel > size(CMobj.Items,1))
                                    continue;
                                elseif ~(CMobj.Items{sel}.Enabled)
                                    continue;                                
                                end
                                if (strcmp(class(CMobj.Items{sel}.Callback), 'FM.ConsoleMenu'))
                                    subMenu = CMobj.Items{sel}.Callback;
                                        ret = subMenu.Pick;
                                        % If a sub-menu returns a negative
                                        % code, terminate execution of the
                                        % current menu and return the code.
                                        if (ret < 0)
                                            return;                                    
                                        end
                                elseif (isa(CMobj.Items{sel}.Callback, 'function_handle'))                                    
                                    ret = CMobj.Items{sel}.Callback(sel);
                                    % If selection callback returns a
                                    % negative value, end the menu and
                                    % return the code.
                                    if (ret ~= 0)
                                        return;
                                    else
                                        continue;
                                    end
                                end
                            else
                                continue;
                            end                    
                end
                
            end
        end
        
        function ret = GetItemByTag(CMobj, itemTag)
            ret = {};
            for t=1:size(CMobj.Items,1),
                if (strcmp(CMobj.Items{t}.Tag,itemTag))
                    ret = CMobj.Items{t};
                    return;
                end
            end    
        end

        function rootMenu = GetRootMenu(cmObj)
            if ~isempty(cmObj.Parent)                                                
                rootMenu = cmObj.Parent.GetRootMenu();
            else
                rootMenu = cmObj;
                return;
            end
        end                
    end
    
    methods (Access = private)
        function callback = findCallbackByHotkey(cmObj, hotkey)
            callback = NaN;

            % Check items of the menu
            for i=1:size(cmObj.Items,1)                          
                if (strcmpi(hotkey, cmObj.Items{i}.Hotkey) && strcmpi(cmObj.Items{i}.Enabled, 'true'))
                    callback = cmObj.Items{i}.Callback;
                    return;
                elseif isa(cmObj.Items{i}.Callback, 'FM.ConsoleMenu')
                     callback = cmObj.Items{i}.Callback.findCallbackByHotkey(hotkey);
                     if (isa(callback, 'function_handle'))
                         return
                     end
                end            
            end            
        end        
    end
    
    methods (Access = private, Static)
        function menuPath = traceMenuPath(cmObj, menuPath)
            if ~isempty(cmObj.Parent)                                
                menuPath = [ cmObj.Parent.Title, ' > ', menuPath ];
                FM.ConsoleMenu.traceMenuPath(cmObj.Parent, menuPath);
            else
                return;
            end
        end        
    end
end

Contact us