From e46a302e1cf79f3e6cfaf1340550c9462af90c3a Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 00:45:46 -0500 Subject: [PATCH 01/34] First POC --- toolbox/core/bst_progress.m | 302 +++++++++++++++++++----------------- 1 file changed, 156 insertions(+), 146 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 88208b159f..79b6a10c78 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -79,12 +79,8 @@ end return; end -% Get progress bar -if ~isempty(GlobalData) && ~isempty(GlobalData.Program) && isfield(GlobalData.Program, 'ProgressBar') && ~isempty(GlobalData.Program.ProgressBar) - pBar = GlobalData.Program.ProgressBar; -else - pBar = []; -end + +pBar = []; % Get Brainstorm GUI context jBstFrame = bst_get('BstFrame'); if isempty(jBstFrame) @@ -92,69 +88,7 @@ end % Default window size -if isempty(pBar) || strcmpi(commandName, 'removeimage') || (strcmpi(commandName, 'stop') && pBar.isImage) - DefaultSize = java_scaled('dimension', 350, 130); -end - -% If progress bar was not created yet : create it -if isempty(pBar) - % If action=isvisible: no need to create the progress bar - if strcmpi(commandName, 'isvisible') - pBar = 0; - return - end - % Create a JDialog, if possible dependent of the main Brainstorm JFrame - pBar.jWindow = java_create('javax.swing.JDialog'); - % Set icon - try - pBar.jWindow.setIconImage(IconLoader.ICON_APP.getImage()); - catch - % Old matlab... just ignore... - end - % Set as always-on-top / non-focusable - pBar.jWindow.setAlwaysOnTop(1); - pBar.jWindow.setFocusable(0); - pBar.jWindow.setFocusableWindowState(0); - % Non-modal - pBar.jWindow.setModal(0); - - % Closing callback -% if bst_iscompiled() - pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); -% else -% pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.DO_NOTHING_ON_CLOSE); -% java_setcb(pBar.jWindow, 'WindowClosingCallback', @(h,ev)CloseCallback); -% end - - % Configure window - pBar.jWindow.setPreferredSize(DefaultSize); - % Main panel - pBar.jPanel = java_create('javax.swing.JPanel'); - pBar.jPanel.setLayout(java_create('java.awt.GridBagLayout')); - - % Create objects - pBar.isImage = 0; - pBar.jImage = java_create('javax.swing.JLabel'); - pBar.jLabel = java_create('javax.swing.JLabel', 'Ljava.lang.String;', '...'); - pBar.jLabel.setFont(bst_get('Font')); - pBar.jProgressBar = java_create('javax.swing.JProgressBar', 'II', 0, 99); - % Update constraints - UpdateConstraints(0); - - % Add the main Panel - pBar.jWindow.getContentPane.add(pBar.jPanel); - pBar.jWindow.pack(); - % Set window size and location - %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); - jLoc = jBstFrame.getLocation(); - jSize = jBstFrame.getSize(); - pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2), ... - jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; - pBar.jWindow.setLocation(pos(1), pos(2)); - pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', []); - % Save progress bar - GlobalData.Program.ProgressBar = pBar; -end +DefaultSize = java_scaled('dimension', 350, 130); % Linux: need to print something on the command window (don't know why...) if strcmpi(commandName, 'stop') && ismember(computer('arch'), {'glnx86', 'glnxa64'}) @@ -166,6 +100,39 @@ pause(0.05); end +% % Get the name of the function that is calling bst_progress +stacks = dbstack(1); +caller_name = stacks(1).name; +if ~isempty(GlobalData.Program.ProgressBar) + progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); +else + progress_list = {}; +end +ix = find(strcmp(progress_list, caller_name), 1); + +if isempty(ix) + % Default window size + DefaultSize = java_scaled('dimension', 350, 130); + + % Create progress bar + pBar = createProgressBar(DefaultSize, caller_name, length(progress_list)); + + % Save progress bar + GlobalData.Program.ProgressBar{end+1} = pBar; + ix = length(GlobalData.Program.ProgressBar); +else + if ix < length(progress_list) + for iBar = (ix+1):length(progress_list) + java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); + end + + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); + end + + pBar = GlobalData.Program.ProgressBar{ix}; +end + + %% ===== SWITCH BETWEEN COMMANDS ===== switch (lower(commandName)) @@ -189,10 +156,10 @@ % Set initial value to start pBar.jProgressBar.setValue(0); % Update values in GlobalData - GlobalData.Program.ProgressBar.Values.Minimum = 0; - GlobalData.Program.ProgressBar.Values.Maximum = 100; - GlobalData.Program.ProgressBar.Values.Value = 0; - GlobalData.Program.ProgressBar.Values.LastVal = 0; + GlobalData.Program.ProgressBar{ix}.Values.Minimum = 0; + GlobalData.Program.ProgressBar{ix}.Values.Maximum = 100; + GlobalData.Program.ProgressBar{ix}.Values.Value = 0; + GlobalData.Program.ProgressBar{ix}.Values.LastVal = 0; % Call: bst_progress(''start'', title, msg, start, stop) elseif ((nargin == 5) && ischar(varargin{2}) && ischar(varargin{3}) && isnumeric(varargin{4}) && isnumeric(varargin{5})) @@ -218,10 +185,10 @@ pBar.jProgressBar.setMaximum(valStop); pBar.jProgressBar.setValue(valStart); % Update values in GlobalData - GlobalData.Program.ProgressBar.Values.Minimum = valStart; - GlobalData.Program.ProgressBar.Values.Maximum = valStop; - GlobalData.Program.ProgressBar.Values.Value = valStart; - GlobalData.Program.ProgressBar.Values.LastVal = valStart; + GlobalData.Program.ProgressBar{ix}.Values.Minimum = valStart; + GlobalData.Program.ProgressBar{ix}.Values.Maximum = valStop; + GlobalData.Program.ProgressBar{ix}.Values.Value = valStart; + GlobalData.Program.ProgressBar{ix}.Values.LastVal = valStart; else error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); end @@ -239,23 +206,8 @@ % ==== STOP ==== case 'stop' % Remove the "always on top" status - java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 0); - java_call(pBar.jWindow, 'setFocusable', 'Z', 1); - java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 1); - % Hide window - java_call(pBar.jWindow, 'setVisible', 'Z', 0); - % Restore cursor - jBstFrame.setCursor([]); - % Remove image - if pBar.isImage - GlobalData.Program.ProgressBar.isImage = 0; - pBar.jImage.setIcon([]); - java_setcb(pBar.jImage, 'MouseClickedCallback', []); - UpdateConstraints(0); - pBar.jWindow.setPreferredSize(DefaultSize); - pBar.jWindow.pack(); - end - + java_call(pBar.jWindow, 'dispose'); + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); % ==== INCREMENT ==== case 'inc' % Parse arguments @@ -265,18 +217,18 @@ error('Usage : bst_progress(''inc'', valInc)'); end % Get current value - minValue = GlobalData.Program.ProgressBar.Values.Minimum; - maxValue = GlobalData.Program.ProgressBar.Values.Maximum; - curValue = GlobalData.Program.ProgressBar.Values.Value; + minValue = GlobalData.Program.ProgressBar{ix}.Values.Minimum; + maxValue = GlobalData.Program.ProgressBar{ix}.Values.Maximum; + curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; newVal = min(curValue + valInc + minValue, maxValue); % Plot the incremented progress if it moves at least 1% of the bar range - if (abs(newVal - GlobalData.Program.ProgressBar.Values.LastVal) / (maxValue - minValue)) > 1/100 + if (abs(newVal - GlobalData.Program.ProgressBar{ix}.Values.LastVal) / (maxValue - minValue)) > 1/100 % Get the incremented progress bar position pBar.jProgressBar.setValue(newVal); % Update value in GlobalData - GlobalData.Program.ProgressBar.Values.LastVal = newVal; + GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; end - GlobalData.Program.ProgressBar.Values.Value = newVal; + GlobalData.Program.ProgressBar{ix}.Values.Value = newVal; % ==== SET POSITION ==== case 'set' @@ -287,20 +239,20 @@ error('Usage : bst_progress(''set'', pos)'); end % Get current value - curValue = GlobalData.Program.ProgressBar.Values.Value; + curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; % Plot the position if it changes if (curValue ~= newVal) - newVal = min(newVal, GlobalData.Program.ProgressBar.Values.Maximum); + newVal = min(newVal, GlobalData.Program.ProgressBar{ix}.Values.Maximum); pBar.jProgressBar.setValue(newVal); % Update value in GlobalData - GlobalData.Program.ProgressBar.Values.Value = newVal; - GlobalData.Program.ProgressBar.Values.LastVal = newVal; + GlobalData.Program.ProgressBar{ix}.Values.Value = newVal; + GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; end % ==== GET POSITION ==== case 'get' % Get the incremented progress bar position - pBar = GlobalData.Program.ProgressBar.Values.Value; + pBar = GlobalData.Program.ProgressBar{ix}.Values.Value; % ==== SET TEXT ==== case 'text' @@ -352,7 +304,7 @@ end % Image in label pBar.jImage.setIcon(javax.swing.ImageIcon(imagefile)); - GlobalData.Program.ProgressBar.isImage = 1; + GlobalData.Program.ProgressBar{ix}.isImage = 1; % Extend size of the frame UpdateConstraints(1); pBar.jWindow.setPreferredSize([]); @@ -366,7 +318,7 @@ % ==== REMOVE IMAGE ==== case 'removeimage' % Remove image - GlobalData.Program.ProgressBar.isImage = 0; + GlobalData.Program.ProgressBar{ix}.isImage = 0; pBar.jImage.setIcon([]); java_setcb(pBar.jImage, 'MouseClickedCallback', []); UpdateConstraints(0); @@ -384,9 +336,9 @@ pBarParams.Title = pBar.jWindow.getTitle().toCharArray'; pBarParams.Msg = pBar.jLabel.getText().toCharArray'; pBarParams.isIndeterminate = pBar.jProgressBar.isIndeterminate(); - pBarParams.Value = GlobalData.Program.ProgressBar.Values.Value; - pBarParams.Min = GlobalData.Program.ProgressBar.Values.Minimum; - pBarParams.Max = GlobalData.Program.ProgressBar.Values.Maximum; + pBarParams.Value = GlobalData.Program.ProgressBar{ix}.Values.Value; + pBarParams.Min = GlobalData.Program.ProgressBar{ix}.Values.Minimum; + pBarParams.Max = GlobalData.Program.ProgressBar{ix}.Values.Maximum; pBar = pBarParams; % ==== SET BAR PARAMETERS ==== @@ -409,42 +361,6 @@ error('Unknown command: %s', commandName); end -%% ===== ADD COMPONENTS ===== - function UpdateConstraints(isImage) - import java.awt.GridBagConstraints; - import java.awt.Insets; - % Remove all components - pBar.jPanel.removeAll(); - % Generic constraints - c = GridBagConstraints(); - c.fill = GridBagConstraints.BOTH; - c.gridx = 1; - c.weightx = 1; - % IMAGE - c.gridy = 1; - c.weighty = isImage; - c.insets = Insets(0,0,0,0); - pBar.jPanel.add(pBar.jImage, c); - % TEXT - c.gridy = 2; - c.weighty = ~isImage; - c.insets = Insets(5,12,5,12); - pBar.jPanel.add(pBar.jLabel, c); - % PROGRESS BAR - c.gridy = 3; - c.weighty = 0; - c.insets = Insets(0,12,9,12); - pBar.jPanel.add(pBar.jProgressBar, c); -% % CANCEL BUTTON -% c.gridy = 4; -% c.weighty = 0; -% c.insets = Insets(0,12,9,12); -% c.weightx = 0; -% pBar.jPanel.add(pBar.jButtonCancel, c); - end - - - % %% ===== CLOSE CALLBACK ===== % function CloseCallback() % % Hide progress bar @@ -512,4 +428,98 @@ function UpdateConstraints(isImage) end +function pBar = createProgressBar(DefaultSize, caller_name, n_progress) + % JAVA imports + import org.brainstorm.icon.*; + import java.awt.Dimension; + + % Get Brainstorm GUI context + jBstFrame = bst_get('BstFrame'); + + % Create a JDialog, if possible dependent of the main Brainstorm JFrame + pBar.jWindow = java_create('javax.swing.JDialog'); + % Set icon + try + pBar.jWindow.setIconImage(IconLoader.ICON_APP.getImage()); + catch + % Old matlab... just ignore... + end + % Set as always-on-top / non-focusable + pBar.jWindow.setAlwaysOnTop(1); + pBar.jWindow.setFocusable(0); + pBar.jWindow.setFocusableWindowState(0); + % Non-modal + pBar.jWindow.setModal(0); + + % Closing callback +% if bst_iscompiled() + pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); +% else +% pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.DO_NOTHING_ON_CLOSE); +% java_setcb(pBar.jWindow, 'WindowClosingCallback', @(h,ev)CloseCallback); +% end + + % Configure window + pBar.jWindow.setPreferredSize(DefaultSize); + % Main panel + pBar.jPanel = java_create('javax.swing.JPanel'); + pBar.jPanel.setLayout(java_create('java.awt.GridBagLayout')); + + % Create objects + pBar.isImage = 0; + pBar.jImage = java_create('javax.swing.JLabel'); + pBar.jLabel = java_create('javax.swing.JLabel', 'Ljava.lang.String;', '...'); + pBar.jLabel.setFont(bst_get('Font')); + pBar.jProgressBar = java_create('javax.swing.JProgressBar', 'II', 0, 99); + % Update constraints + UpdateConstraints(0); + + % Add the main Panel + pBar.jWindow.getContentPane.add(pBar.jPanel); + pBar.jWindow.pack(); + % Set window size and location + %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); + jLoc = jBstFrame.getLocation(); + jSize = jBstFrame.getSize(); + pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... + jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; + pBar.jWindow.setLocation(pos(1), pos(2)); + pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); + + %% ===== ADD COMPONENTS ===== + function UpdateConstraints(isImage) + import java.awt.GridBagConstraints; + import java.awt.Insets; + % Remove all components + pBar.jPanel.removeAll(); + % Generic constraints + c = GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 1; + c.weightx = 1; + % IMAGE + c.gridy = 1; + c.weighty = isImage; + c.insets = Insets(0,0,0,0); + pBar.jPanel.add(pBar.jImage, c); + % TEXT + c.gridy = 2; + c.weighty = ~isImage; + c.insets = Insets(5,12,5,12); + pBar.jPanel.add(pBar.jLabel, c); + % PROGRESS BAR + c.gridy = 3; + c.weighty = 0; + c.insets = Insets(0,12,9,12); + pBar.jPanel.add(pBar.jProgressBar, c); +% % CANCEL BUTTON +% c.gridy = 4; +% c.weighty = 0; +% c.insets = Insets(0,12,9,12); +% c.weightx = 0; +% pBar.jPanel.add(pBar.jButtonCancel, c); + end + +end + From 428480c6b88815a826b9c31015da99f717fd2e03 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:03:55 -0500 Subject: [PATCH 02/34] avoid having hanging bar --- toolbox/core/bst_progress.m | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 79b6a10c78..e33b46b55d 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -111,6 +111,19 @@ ix = find(strcmp(progress_list, caller_name), 1); if isempty(ix) + + % We find the first progress bar, that is a parent of the caller + ix = find(cellfun(@(x) any(strcmp({stacks.name},x)), progress_list)); + + if isempty(ix) + ix = 0; + end + + for iBar = (ix+1):length(progress_list) + java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); + end + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); + % Default window size DefaultSize = java_scaled('dimension', 350, 130); From ea2906325e210eee6e24803244eaa1f72ed13107 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:09:29 -0500 Subject: [PATCH 03/34] minor fixes --- toolbox/core/bst_progress.m | 126 ++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index e33b46b55d..429f71bd3e 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -437,68 +437,6 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end - -end - - -function pBar = createProgressBar(DefaultSize, caller_name, n_progress) - % JAVA imports - import org.brainstorm.icon.*; - import java.awt.Dimension; - - % Get Brainstorm GUI context - jBstFrame = bst_get('BstFrame'); - - % Create a JDialog, if possible dependent of the main Brainstorm JFrame - pBar.jWindow = java_create('javax.swing.JDialog'); - % Set icon - try - pBar.jWindow.setIconImage(IconLoader.ICON_APP.getImage()); - catch - % Old matlab... just ignore... - end - % Set as always-on-top / non-focusable - pBar.jWindow.setAlwaysOnTop(1); - pBar.jWindow.setFocusable(0); - pBar.jWindow.setFocusableWindowState(0); - % Non-modal - pBar.jWindow.setModal(0); - - % Closing callback -% if bst_iscompiled() - pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); -% else -% pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.DO_NOTHING_ON_CLOSE); -% java_setcb(pBar.jWindow, 'WindowClosingCallback', @(h,ev)CloseCallback); -% end - - % Configure window - pBar.jWindow.setPreferredSize(DefaultSize); - % Main panel - pBar.jPanel = java_create('javax.swing.JPanel'); - pBar.jPanel.setLayout(java_create('java.awt.GridBagLayout')); - - % Create objects - pBar.isImage = 0; - pBar.jImage = java_create('javax.swing.JLabel'); - pBar.jLabel = java_create('javax.swing.JLabel', 'Ljava.lang.String;', '...'); - pBar.jLabel.setFont(bst_get('Font')); - pBar.jProgressBar = java_create('javax.swing.JProgressBar', 'II', 0, 99); - % Update constraints - UpdateConstraints(0); - - % Add the main Panel - pBar.jWindow.getContentPane.add(pBar.jPanel); - pBar.jWindow.pack(); - % Set window size and location - %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); - jLoc = jBstFrame.getLocation(); - jSize = jBstFrame.getSize(); - pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... - jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; - pBar.jWindow.setLocation(pos(1), pos(2)); - pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); - %% ===== ADD COMPONENTS ===== function UpdateConstraints(isImage) import java.awt.GridBagConstraints; @@ -533,6 +471,70 @@ function UpdateConstraints(isImage) % pBar.jPanel.add(pBar.jButtonCancel, c); end + function pBar = createProgressBar(DefaultSize, caller_name, n_progress) + % JAVA imports + import org.brainstorm.icon.*; + import java.awt.Dimension; + + % Get Brainstorm GUI context + jBstFrame = bst_get('BstFrame'); + + % Create a JDialog, if possible dependent of the main Brainstorm JFrame + pBar.jWindow = java_create('javax.swing.JDialog'); + % Set icon + try + pBar.jWindow.setIconImage(IconLoader.ICON_APP.getImage()); + catch + % Old matlab... just ignore... + end + % Set as always-on-top / non-focusable + pBar.jWindow.setAlwaysOnTop(1); + pBar.jWindow.setFocusable(0); + pBar.jWindow.setFocusableWindowState(0); + % Non-modal + pBar.jWindow.setModal(0); + + % Closing callback + % if bst_iscompiled() + pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); + % else + % pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.DO_NOTHING_ON_CLOSE); + % java_setcb(pBar.jWindow, 'WindowClosingCallback', @(h,ev)CloseCallback); + % end + + % Configure window + pBar.jWindow.setPreferredSize(DefaultSize); + % Main panel + pBar.jPanel = java_create('javax.swing.JPanel'); + pBar.jPanel.setLayout(java_create('java.awt.GridBagLayout')); + + % Create objects + pBar.isImage = 0; + pBar.jImage = java_create('javax.swing.JLabel'); + pBar.jLabel = java_create('javax.swing.JLabel', 'Ljava.lang.String;', '...'); + pBar.jLabel.setFont(bst_get('Font')); + pBar.jProgressBar = java_create('javax.swing.JProgressBar', 'II', 0, 99); + % Update constraints + %UpdateConstraints(0); + + % Add the main Panel + pBar.jWindow.getContentPane.add(pBar.jPanel); + pBar.jWindow.pack(); + % Set window size and location + %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); + jLoc = jBstFrame.getLocation(); + jSize = jBstFrame.getSize(); + pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... + jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; + pBar.jWindow.setLocation(pos(1), pos(2)); + pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); + + + end + end + + + From f8661a4fdb85f7c65d0d4a1a93884b1ea389b891 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:12:58 -0500 Subject: [PATCH 04/34] pass pBar to update constraint to avoid issue --- toolbox/core/bst_progress.m | 74 +++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 429f71bd3e..ba610102e1 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -319,7 +319,7 @@ pBar.jImage.setIcon(javax.swing.ImageIcon(imagefile)); GlobalData.Program.ProgressBar{ix}.isImage = 1; % Extend size of the frame - UpdateConstraints(1); + UpdateConstraints(pBar, 1); pBar.jWindow.setPreferredSize([]); pBar.jWindow.pack(); @@ -334,7 +334,7 @@ GlobalData.Program.ProgressBar{ix}.isImage = 0; pBar.jImage.setIcon([]); java_setcb(pBar.jImage, 'MouseClickedCallback', []); - UpdateConstraints(0); + UpdateConstraints(pBar,0); pBar.jWindow.setPreferredSize(DefaultSize); pBar.jWindow.pack(); @@ -437,39 +437,7 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end - %% ===== ADD COMPONENTS ===== - function UpdateConstraints(isImage) - import java.awt.GridBagConstraints; - import java.awt.Insets; - % Remove all components - pBar.jPanel.removeAll(); - % Generic constraints - c = GridBagConstraints(); - c.fill = GridBagConstraints.BOTH; - c.gridx = 1; - c.weightx = 1; - % IMAGE - c.gridy = 1; - c.weighty = isImage; - c.insets = Insets(0,0,0,0); - pBar.jPanel.add(pBar.jImage, c); - % TEXT - c.gridy = 2; - c.weighty = ~isImage; - c.insets = Insets(5,12,5,12); - pBar.jPanel.add(pBar.jLabel, c); - % PROGRESS BAR - c.gridy = 3; - c.weighty = 0; - c.insets = Insets(0,12,9,12); - pBar.jPanel.add(pBar.jProgressBar, c); -% % CANCEL BUTTON -% c.gridy = 4; -% c.weighty = 0; -% c.insets = Insets(0,12,9,12); -% c.weightx = 0; -% pBar.jPanel.add(pBar.jButtonCancel, c); - end + function pBar = createProgressBar(DefaultSize, caller_name, n_progress) % JAVA imports @@ -515,7 +483,7 @@ function UpdateConstraints(isImage) pBar.jLabel.setFont(bst_get('Font')); pBar.jProgressBar = java_create('javax.swing.JProgressBar', 'II', 0, 99); % Update constraints - %UpdateConstraints(0); + UpdateConstraints(pBar,0); % Add the main Panel pBar.jWindow.getContentPane.add(pBar.jPanel); @@ -532,6 +500,40 @@ function UpdateConstraints(isImage) end + %% ===== ADD COMPONENTS ===== + function UpdateConstraints(pBar, isImage) + import java.awt.GridBagConstraints; + import java.awt.Insets; + % Remove all components + pBar.jPanel.removeAll(); + % Generic constraints + c = GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 1; + c.weightx = 1; + % IMAGE + c.gridy = 1; + c.weighty = isImage; + c.insets = Insets(0,0,0,0); + pBar.jPanel.add(pBar.jImage, c); + % TEXT + c.gridy = 2; + c.weighty = ~isImage; + c.insets = Insets(5,12,5,12); + pBar.jPanel.add(pBar.jLabel, c); + % PROGRESS BAR + c.gridy = 3; + c.weighty = 0; + c.insets = Insets(0,12,9,12); + pBar.jPanel.add(pBar.jProgressBar, c); +% % CANCEL BUTTON +% c.gridy = 4; +% c.weighty = 0; +% c.insets = Insets(0,12,9,12); +% c.weightx = 0; +% pBar.jPanel.add(pBar.jButtonCancel, c); + end + end From cacd7f689a9d32cee4b42435f1800a836a2ac096 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:14:58 -0500 Subject: [PATCH 05/34] fix offset --- toolbox/core/bst_progress.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index ba610102e1..0e132fd95d 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -128,7 +128,7 @@ DefaultSize = java_scaled('dimension', 350, 130); % Create progress bar - pBar = createProgressBar(DefaultSize, caller_name, length(progress_list)); + pBar = createProgressBar(DefaultSize, caller_name, ix); % Save progress bar GlobalData.Program.ProgressBar{end+1} = pBar; From 4265dba4bb99c0f239beb05c8e509995d4307b5a Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:26:26 -0500 Subject: [PATCH 06/34] Restore 'restore cursor' --- toolbox/core/bst_progress.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 0e132fd95d..06331e7240 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -218,9 +218,11 @@ % ==== STOP ==== case 'stop' - % Remove the "always on top" status + % Close the window java_call(pBar.jWindow, 'dispose'); - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); + % Restore cursor + jBstFrame.setCursor([]); % ==== INCREMENT ==== case 'inc' % Parse arguments From ecd484e81ecc24fa1f53879120798932afe4de44 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:28:39 -0500 Subject: [PATCH 07/34] Add comment --- toolbox/core/bst_progress.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 06331e7240..d4c3a4316d 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -119,15 +119,14 @@ ix = 0; end + % Close all progress bar that are not a parent of the caller for iBar = (ix+1):length(progress_list) java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); end GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); - % Default window size + % Create a new progress bar for the caller DefaultSize = java_scaled('dimension', 350, 130); - - % Create progress bar pBar = createProgressBar(DefaultSize, caller_name, ix); % Save progress bar From e023ef5823633d6a104762a6acee1e9db7064811 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:32:19 -0500 Subject: [PATCH 08/34] save filename save filename --- toolbox/core/bst_progress.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index d4c3a4316d..6c1ba3143a 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -102,7 +102,7 @@ % % Get the name of the function that is calling bst_progress stacks = dbstack(1); -caller_name = stacks(1).name; +caller_name = sprintf('%s/%s', stacks(1).file, stacks(1).name); if ~isempty(GlobalData.Program.ProgressBar) progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); else @@ -113,7 +113,11 @@ if isempty(ix) % We find the first progress bar, that is a parent of the caller - ix = find(cellfun(@(x) any(strcmp({stacks.name},x)), progress_list)); + for i = 1:length(stacks) + stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); + end + + ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list)); if isempty(ix) ix = 0; From a101eb8c7e8ff16820ab72d677f14b03d3c92c15 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 01:48:04 -0500 Subject: [PATCH 09/34] Add reminder to fix this --- toolbox/gui/java_getfile.m | 1 + 1 file changed, 1 insertion(+) diff --git a/toolbox/gui/java_getfile.m b/toolbox/gui/java_getfile.m index 097e2f3c8e..8112d15fb7 100644 --- a/toolbox/gui/java_getfile.m +++ b/toolbox/gui/java_getfile.m @@ -94,6 +94,7 @@ end % If a progress bar is displayed : hide it while displaying the file selector +% To check pBar = GlobalData.Program.ProgressBar; if ~isempty(pBar) && isfield(pBar, 'jWindow') && java_call(pBar.jWindow, 'isVisible') pBarHidden = 1; From 6977f49777ff85bddaa98246c9ca164626cefa09 Mon Sep 17 00:00:00 2001 From: Edouard Date: Sun, 8 Mar 2026 23:56:23 -0400 Subject: [PATCH 10/34] fix find --- toolbox/core/bst_progress.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 6c1ba3143a..8023eb48b9 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -117,7 +117,7 @@ stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); end - ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list)); + ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list),1,'last'); if isempty(ix) ix = 0; From 08a9cfc756e7d58c7100993904c9d28ecdc0b6d4 Mon Sep 17 00:00:00 2001 From: Edouard Date: Mon, 9 Mar 2026 17:01:05 -0400 Subject: [PATCH 11/34] fix java_getfile (not tested) --- toolbox/gui/java_getfile.m | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/toolbox/gui/java_getfile.m b/toolbox/gui/java_getfile.m index 8112d15fb7..4e1f30f592 100644 --- a/toolbox/gui/java_getfile.m +++ b/toolbox/gui/java_getfile.m @@ -95,13 +95,22 @@ % If a progress bar is displayed : hide it while displaying the file selector % To check -pBar = GlobalData.Program.ProgressBar; -if ~isempty(pBar) && isfield(pBar, 'jWindow') && java_call(pBar.jWindow, 'isVisible') - pBarHidden = 1; - bst_progress('hide'); -else - pBarHidden = 0; +pBars = GlobalData.Program.ProgressBar; +pBarHidden = false(1, length(pBars)); +for iBar = 1:length(pBars) + + if isfield(pBars{iBar}, 'jWindow') && java_call(pBars{iBar}.jWindow, 'isVisible') + % Remove the "always on top" status + java_call(pBars{iBar}.jWindow, 'setAlwaysOnTop', 'Z', 0); + java_call(pBars{iBar}.jWindow, 'setFocusable', 'Z', 1); + java_call(pBars{iBar}.jWindow, 'setFocusableWindowState', 'Z', 1); + % Hide window + java_call(pBars{iBar}.jWindow, 'setVisible', 'Z', 0); + pBarHidden(iBar) = true; + end end +jBstFrame = bst_get('BstFrame'); +jBstFrame.setCursor([]); %% ===== HIDE MODAL WINDOWS ===== @@ -248,11 +257,22 @@ end end % Restore progress bar -if pBarHidden - bst_progress('show'); -end +if any(pBarHidden) + for iBar = 1:length(pBarHidden) + if ~pBarHidden(iBar) + continue; + end + % Set as "always on top" + java_call(pBars{iBar}.jWindow, 'setAlwaysOnTop', 'Z', 1); + java_call(pBars{iBar}.jWindow, 'setFocusable', 'Z', 0); + java_call(pBars{iBar}.jWindow, 'setFocusableWindowState', 'Z', 0); + % Show window + java_call(pBars{iBar}.jWindow, 'setVisible', 'Z', 1); + end + jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); +end %% ===== CALLBACK FUNCTION ===== function FileSelectorAction(h, ev) From 52ee8daf088b2a76e2f39c54fc03bf3c5700d3a4 Mon Sep 17 00:00:00 2001 From: Edouard Date: Mon, 9 Mar 2026 20:37:16 -0400 Subject: [PATCH 12/34] fix when cmd is entered from the command window (no stack) --- toolbox/core/bst_progress.m | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 8023eb48b9..d4514257ea 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -102,7 +102,16 @@ % % Get the name of the function that is calling bst_progress stacks = dbstack(1); -caller_name = sprintf('%s/%s', stacks(1).file, stacks(1).name); +if isempty(stacks) + stacks = struct('name_file', 'cmd_windows'); +else + % We find the first progress bar, that is a parent of the caller + for i = 1:length(stacks) + stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); + end +end +caller_name = stacks(1).name_file; + if ~isempty(GlobalData.Program.ProgressBar) progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); else @@ -111,12 +120,6 @@ ix = find(strcmp(progress_list, caller_name), 1); if isempty(ix) - - % We find the first progress bar, that is a parent of the caller - for i = 1:length(stacks) - stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); - end - ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list),1,'last'); if isempty(ix) From 0ac1f406732332d5889a704ab50a64c4bf5e66f8 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 07:48:04 -0400 Subject: [PATCH 13/34] refactor + only open progress bar for start action --- toolbox/core/bst_progress.m | 133 +++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 56 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index d4514257ea..6bb45c871f 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -100,58 +100,7 @@ pause(0.05); end -% % Get the name of the function that is calling bst_progress -stacks = dbstack(1); -if isempty(stacks) - stacks = struct('name_file', 'cmd_windows'); -else - % We find the first progress bar, that is a parent of the caller - for i = 1:length(stacks) - stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); - end -end -caller_name = stacks(1).name_file; - -if ~isempty(GlobalData.Program.ProgressBar) - progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); -else - progress_list = {}; -end -ix = find(strcmp(progress_list, caller_name), 1); - -if isempty(ix) - ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list),1,'last'); - - if isempty(ix) - ix = 0; - end - - % Close all progress bar that are not a parent of the caller - for iBar = (ix+1):length(progress_list) - java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); - end - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); - - % Create a new progress bar for the caller - DefaultSize = java_scaled('dimension', 350, 130); - pBar = createProgressBar(DefaultSize, caller_name, ix); - - % Save progress bar - GlobalData.Program.ProgressBar{end+1} = pBar; - ix = length(GlobalData.Program.ProgressBar); -else - if ix < length(progress_list) - for iBar = (ix+1):length(progress_list) - java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); - end - - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); - end - - pBar = GlobalData.Program.ProgressBar{ix}; -end - - +[pBar, ix] = getProgressBar(commandName); %% ===== SWITCH BETWEEN COMMANDS ===== switch (lower(commandName)) @@ -224,11 +173,16 @@ % ==== STOP ==== case 'stop' + % Restore cursor + jBstFrame.setCursor([]); + % Close the window + if isempty(pBar) + return + end + java_call(pBar.jWindow, 'dispose'); GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); - % Restore cursor - jBstFrame.setCursor([]); % ==== INCREMENT ==== case 'inc' % Parse arguments @@ -288,8 +242,11 @@ % ==== IS VISIBLE ==== case 'isvisible' - pBar = pBar.jWindow.isVisible(); - + if isempty(pBar) + pBar = 0 ; + else + pBar = pBar.jWindow.isVisible(); + end % ==== SHOW ==== case 'show' % Set as "always on top" @@ -445,7 +402,71 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end + + function [pBar, ix] = getProgressBar(action) + pBar = []; + + if ~strcmpi(action, 'start') + ix = length(GlobalData.Program.ProgressBar); + + if ~isempty(GlobalData.Program.ProgressBar) + pBar = GlobalData.Program.ProgressBar{end}; + end + return + end + % % Get the name of the function that is calling bst_progress + stacks = dbstack(2); + if isempty(stacks) + stacks = struct('name_file', 'cmd_windows'); + else + % We find the first progress bar, that is a parent of the caller + for i = 1:length(stacks) + stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); + end + end + caller_name = stacks(1).name_file; + + if ~isempty(GlobalData.Program.ProgressBar) + progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); + else + progress_list = {}; + end + ix = find(strcmp(progress_list, caller_name), 1); + + if isempty(ix) + ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list),1,'last'); + + if isempty(ix) + ix = 0; + end + + % Close all progress bar that are not a parent of the caller + for iBar = (ix+1):length(progress_list) + java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); + end + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); + + % Create a new progress bar for the caller + DefaultSize = java_scaled('dimension', 350, 130); + pBar = createProgressBar(DefaultSize, caller_name, ix); + + % Save progress bar + GlobalData.Program.ProgressBar{end+1} = pBar; + ix = length(GlobalData.Program.ProgressBar); + else + if ix < length(progress_list) + for iBar = (ix+1):length(progress_list) + java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); + end + + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); + end + + pBar = GlobalData.Program.ProgressBar{ix}; + end + + end function pBar = createProgressBar(DefaultSize, caller_name, n_progress) % JAVA imports From 43c7d073074ff85262ce00a97c240f3cd2237631 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 07:52:41 -0400 Subject: [PATCH 14/34] wip: add todo --- toolbox/core/bst_progress.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 6bb45c871f..c9c2ad14f0 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -180,9 +180,8 @@ if isempty(pBar) return end - java_call(pBar.jWindow, 'dispose'); - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix-1); % ==== INCREMENT ==== case 'inc' % Parse arguments @@ -407,6 +406,7 @@ pBar = []; if ~strcmpi(action, 'start') + % for action such as hide and stop we dont want the last ix. ix = length(GlobalData.Program.ProgressBar); if ~isempty(GlobalData.Program.ProgressBar) From 26bbfe705badfff1608d78b4450ca00e5d2de62d Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 12:02:08 -0400 Subject: [PATCH 15/34] improve logic of the code --- toolbox/core/bst_progress.m | 81 ++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index c9c2ad14f0..3e1acc34f9 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -100,12 +100,20 @@ pause(0.05); end -[pBar, ix] = getProgressBar(commandName); +% Retrieve the progress bar +[caller_name, stacklist] = getCallerName(); +[pBar, ix] = getProgressBar(caller_name, stacklist); %% ===== SWITCH BETWEEN COMMANDS ===== switch (lower(commandName)) % ==== START ==== case 'start' + + % Create a new progress bar + ix = ix + 1; + pBar = createProgressBar(DefaultSize, caller_name, ix); + GlobalData.Program.ProgressBar{ix} = pBar; + % Set as "always on top" java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); java_call(pBar.jWindow, 'setFocusable', 'Z', 0); @@ -181,7 +189,7 @@ return end java_call(pBar.jWindow, 'dispose'); - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix-1); + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); % ==== INCREMENT ==== case 'inc' % Parse arguments @@ -401,21 +409,8 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end - - function [pBar, ix] = getProgressBar(action) - pBar = []; - - if ~strcmpi(action, 'start') - % for action such as hide and stop we dont want the last ix. - ix = length(GlobalData.Program.ProgressBar); - - if ~isempty(GlobalData.Program.ProgressBar) - pBar = GlobalData.Program.ProgressBar{end}; - end - return - end - - % % Get the name of the function that is calling bst_progress + function [caller_name, stacklist] = getCallerName() + % Get the name of the function that is calling bst_progress stacks = dbstack(2); if isempty(stacks) stacks = struct('name_file', 'cmd_windows'); @@ -426,46 +421,38 @@ end end caller_name = stacks(1).name_file; - - if ~isempty(GlobalData.Program.ProgressBar) - progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); - else - progress_list = {}; + stacklist = {stacks.name_file}; + end + + function [pBar, ix] = getProgressBar(caller_name, stacklist) + pBar = []; + ix = 0; + + if isempty(GlobalData.Program.ProgressBar) + return; end + + progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); + ix = find(strcmp(progress_list, caller_name), 1); if isempty(ix) - ix = find(cellfun(@(x) any(strcmp({stacks.name_file},x)), progress_list),1,'last'); + ix = find(cellfun(@(x) any(strcmp(stacklist,x)), progress_list),1,'last'); if isempty(ix) ix = 0; end - - % Close all progress bar that are not a parent of the caller - for iBar = (ix+1):length(progress_list) - java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); - end - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); - - % Create a new progress bar for the caller - DefaultSize = java_scaled('dimension', 350, 130); - pBar = createProgressBar(DefaultSize, caller_name, ix); - - % Save progress bar - GlobalData.Program.ProgressBar{end+1} = pBar; - ix = length(GlobalData.Program.ProgressBar); - else - if ix < length(progress_list) - for iBar = (ix+1):length(progress_list) - java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); - end - - GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); - end - - pBar = GlobalData.Program.ProgressBar{ix}; end + % Close all progress bar that are not a parent of the caller + for iBar = (ix+1):length(progress_list) + java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); + end + GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:ix); + + if ~isempty(GlobalData.Program.ProgressBar) + pBar = GlobalData.Program.ProgressBar{end}; + end end function pBar = createProgressBar(DefaultSize, caller_name, n_progress) From 8c300ee080bab13611735280deace8c16322528a Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 12:15:58 -0400 Subject: [PATCH 16/34] refactor checks --- toolbox/core/bst_progress.m | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 3e1acc34f9..7553f3c50e 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -104,6 +104,10 @@ [caller_name, stacklist] = getCallerName(); [pBar, ix] = getProgressBar(caller_name, stacklist); +if isempty(pBar) && ~strcmpi(commandName, 'start') + return +end + %% ===== SWITCH BETWEEN COMMANDS ===== switch (lower(commandName)) % ==== START ==== @@ -184,10 +188,6 @@ % Restore cursor jBstFrame.setCursor([]); - % Close the window - if isempty(pBar) - return - end java_call(pBar.jWindow, 'dispose'); GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); % ==== INCREMENT ==== @@ -249,11 +249,7 @@ % ==== IS VISIBLE ==== case 'isvisible' - if isempty(pBar) - pBar = 0 ; - else - pBar = pBar.jWindow.isVisible(); - end + pBar = pBar.jWindow.isVisible(); % ==== SHOW ==== case 'show' % Set as "always on top" From 678bc73d432792300df0604fad7beb1a8a7a2597 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 12:17:32 -0400 Subject: [PATCH 17/34] restore cursor --- toolbox/core/bst_progress.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 7553f3c50e..dec62f42c0 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -105,6 +105,8 @@ [pBar, ix] = getProgressBar(caller_name, stacklist); if isempty(pBar) && ~strcmpi(commandName, 'start') + % Restore cursor + jBstFrame.setCursor([]); return end From f7d8030658541fb15637cf51f098c89182bad0e8 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 12:20:11 -0400 Subject: [PATCH 18/34] bugfix; isvisible require a bool --- toolbox/core/bst_progress.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index dec62f42c0..5cc9214cac 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -107,6 +107,11 @@ if isempty(pBar) && ~strcmpi(commandName, 'start') % Restore cursor jBstFrame.setCursor([]); + + if strcmpi(commandName, 'isvisible') + pBar = 0; + end + return end From 35189317c5bf511ebf710923203786fa61752e0a Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 13:35:19 -0400 Subject: [PATCH 19/34] view leadfield: close progress bar after loading --- toolbox/gui/view_leadfield_sensitivity.m | 1 + 1 file changed, 1 insertion(+) diff --git a/toolbox/gui/view_leadfield_sensitivity.m b/toolbox/gui/view_leadfield_sensitivity.m index 1ba2eaac9f..1eacc77e8f 100644 --- a/toolbox/gui/view_leadfield_sensitivity.m +++ b/toolbox/gui/view_leadfield_sensitivity.m @@ -81,6 +81,7 @@ sSubject = bst_get('Subject', sStudy.BrainStormSubject); MriFile = sSubject.Anatomy(sSubject.iAnatomy).FileName; sMri = in_mri_bst(MriFile); +bst_progress('stop'); % ===== CREATE FIGURE ===== is3D = 0; From b3e846ff95b214241a87476bf919e65e212a6025 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 13:37:15 -0400 Subject: [PATCH 20/34] view leadfield: remove unnecessary progress bar --- toolbox/gui/view_leadfield_sensitivity.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/toolbox/gui/view_leadfield_sensitivity.m b/toolbox/gui/view_leadfield_sensitivity.m index 1eacc77e8f..bf589b8c42 100644 --- a/toolbox/gui/view_leadfield_sensitivity.m +++ b/toolbox/gui/view_leadfield_sensitivity.m @@ -81,7 +81,7 @@ sSubject = bst_get('Subject', sStudy.BrainStormSubject); MriFile = sSubject.Anatomy(sSubject.iAnatomy).FileName; sMri = in_mri_bst(MriFile); -bst_progress('stop'); +bst_progress('hide'); % ===== CREATE FIGURE ===== is3D = 0; @@ -353,7 +353,7 @@ function ComputeMriInterp() %% ===== UPDATE LEADFIELD ===== function UpdateLeadfield() % Compute sensitivity - bst_progress('start', 'View leadfields', 'Computing sensitivity...'); + % Sum all the channels if (iChannel == 0) if isNirs @@ -461,8 +461,7 @@ function UpdateLeadfield() if is3D UpdateMarkers(); end - % Close progress bar - bst_progress('stop'); + end From 932d54d596ce932d5846f032c15d3a5d7ce5c799 Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 10 Mar 2026 23:53:46 -0400 Subject: [PATCH 21/34] Better early return cosmetic changes minor changes --- toolbox/core/bst_progress.m | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 5cc9214cac..5ea4d883c5 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -43,6 +43,7 @@ % =============================================================================@ % % Authors: Francois Tadel, 2008-2013 +% Edouard Delaire, 2026 % JAVA imports import org.brainstorm.icon.*; @@ -58,8 +59,6 @@ error('Usage : bst_progress(commandName, parameters)'); end - -%% ===== GET OR CREATE PROGRESS BAR ===== % Do nothing in case of server mode if ~isempty(GlobalData) && ~isempty(GlobalData.Program) && isfield(GlobalData.Program, 'GuiLevel') && (GlobalData.Program.GuiLevel == -1) if ismember(lower(commandName), {'pos','isvisible'}) @@ -80,16 +79,6 @@ return; end -pBar = []; -% Get Brainstorm GUI context -jBstFrame = bst_get('BstFrame'); -if isempty(jBstFrame) - return -end - -% Default window size -DefaultSize = java_scaled('dimension', 350, 130); - % Linux: need to print something on the command window (don't know why...) if strcmpi(commandName, 'stop') && ismember(computer('arch'), {'glnx86', 'glnxa64'}) drawnow(); @@ -104,14 +93,19 @@ [caller_name, stacklist] = getCallerName(); [pBar, ix] = getProgressBar(caller_name, stacklist); -if isempty(pBar) && ~strcmpi(commandName, 'start') - % Restore cursor - jBstFrame.setCursor([]); - - if strcmpi(commandName, 'isvisible') - pBar = 0; +% Get Brainstorm GUI context +jBstFrame = bst_get('BstFrame'); +DefaultSize = java_scaled('dimension', 350, 130); + +if isempty(jBstFrame) || (isempty(pBar) && ~strcmpi(commandName, 'start')) + if ~isempty(jBstFrame) + % Restore cursor + jBstFrame.setCursor([]); end + if ismember(lower(commandName), {'pos','isvisible'}) + pBar = 0; + end return end @@ -431,13 +425,12 @@ pBar = []; ix = 0; - if isempty(GlobalData.Program.ProgressBar) + if isempty(GlobalData) || isempty(GlobalData.Program.ProgressBar) return; end progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); - - ix = find(strcmp(progress_list, caller_name), 1); + ix = find(strcmp(progress_list, caller_name), 1); if isempty(ix) ix = find(cellfun(@(x) any(strcmp(stacklist,x)), progress_list),1,'last'); From 2a446c458a594b5aa908927127259bcd2e86544e Mon Sep 17 00:00:00 2001 From: Edouard Date: Wed, 11 Mar 2026 02:41:37 -0400 Subject: [PATCH 22/34] Allow progress bar, even if brainstorm is not running --- toolbox/core/bst_progress.m | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 5ea4d883c5..0ed3463b9c 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -67,6 +67,8 @@ pBar = []; end return; +elseif isempty(GlobalData) + GlobalData = db_template('globaldata'); end % If running in NOGUI mode: just display the message in the command window if ~bst_get('isGUI') @@ -95,13 +97,14 @@ % Get Brainstorm GUI context jBstFrame = bst_get('BstFrame'); +if isempty(jBstFrame) + jBstFrame = struct('setCursor', @(x)nan ); +end DefaultSize = java_scaled('dimension', 350, 130); -if isempty(jBstFrame) || (isempty(pBar) && ~strcmpi(commandName, 'start')) - if ~isempty(jBstFrame) - % Restore cursor - jBstFrame.setCursor([]); - end +if isempty(pBar) && ~strcmpi(commandName, 'start') + % Restore cursor + jBstFrame.setCursor([]); if ismember(lower(commandName), {'pos','isvisible'}) pBar = 0; @@ -113,7 +116,6 @@ switch (lower(commandName)) % ==== START ==== case 'start' - % Create a new progress bar ix = ix + 1; pBar = createProgressBar(DefaultSize, caller_name, ix); @@ -456,9 +458,6 @@ import org.brainstorm.icon.*; import java.awt.Dimension; - % Get Brainstorm GUI context - jBstFrame = bst_get('BstFrame'); - % Create a JDialog, if possible dependent of the main Brainstorm JFrame pBar.jWindow = java_create('javax.swing.JDialog'); % Set icon @@ -502,14 +501,17 @@ pBar.jWindow.pack(); % Set window size and location %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); - jLoc = jBstFrame.getLocation(); - jSize = jBstFrame.getSize(); - pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... - jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; + + if isstruct(jBstFrame) + pos = [0, 0]; + else + jLoc = jBstFrame.getLocation(); + jSize = jBstFrame.getSize(); + pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... + jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; + end pBar.jWindow.setLocation(pos(1), pos(2)); - pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); - - + pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); end %% ===== ADD COMPONENTS ===== From 7ac05a2676f6953265f275e6bd2fc8a8391b54dc Mon Sep 17 00:00:00 2001 From: Edouard Date: Wed, 11 Mar 2026 14:42:53 -0400 Subject: [PATCH 23/34] multiple progress bar from the same function --- toolbox/core/bst_progress.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 0ed3463b9c..a68478748e 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -432,7 +432,7 @@ end progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); - ix = find(strcmp(progress_list, caller_name), 1); + ix = find(strcmp(progress_list, caller_name), 1, 'last'); if isempty(ix) ix = find(cellfun(@(x) any(strcmp(stacklist,x)), progress_list),1,'last'); @@ -507,9 +507,10 @@ else jLoc = jBstFrame.getLocation(); jSize = jBstFrame.getSize(); - pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) + n_progress * jSize.getWidth() , ... + pos = [jLoc.getX() + ((jSize.getWidth() - DefaultSize.getWidth()) / 2) , ... jLoc.getY() + ((jSize.getHeight() - DefaultSize.getHeight()) / 2)]; end + pos(1) = pos(1) + n_progress * (10+DefaultSize.getWidth()); pBar.jWindow.setLocation(pos(1), pos(2)); pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); end From fdc73361237ce262aa375c624bf5f9c0ce321ea9 Mon Sep 17 00:00:00 2001 From: Edouard Date: Wed, 11 Mar 2026 15:05:41 -0400 Subject: [PATCH 24/34] db_template: avoid opening a second bar --- toolbox/db/db_set_template.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolbox/db/db_set_template.m b/toolbox/db/db_set_template.m index 6a5bfd16c5..c2b4942592 100644 --- a/toolbox/db/db_set_template.m +++ b/toolbox/db/db_set_template.m @@ -117,7 +117,7 @@ function db_set_template( iSubject, sTemplate, isInteractive ) error(['Invalid template directory : "' strrep(templateDir, '\', '\\') '".']); end % Progress bar -bst_progress('start', 'Import template', 'Copying template files...'); +bst_progress('text', 'Copying template files...'); % Remove all the files of the previous default anatomy file_delete(bst_fullfile(targetDir, '*.bin'), 1); file_delete(bst_fullfile(targetDir, '*.bak'), 1); From 97a4a156a09160145e30359b21236753d6c356f5 Mon Sep 17 00:00:00 2001 From: Edouard Date: Mon, 23 Mar 2026 18:14:56 -0400 Subject: [PATCH 25/34] [wip] separate each call to its function --- toolbox/core/bst_progress.m | 208 ++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 103 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 38b478e500..2118c0bf85 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -122,71 +122,9 @@ pBar = createProgressBar(DefaultSize, caller_name, ix); GlobalData.Program.ProgressBar{ix} = pBar; - % Set as "always on top" - java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); - java_call(pBar.jWindow, 'setFocusable', 'Z', 0); - java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); - % Call: bst_progress(''start'', title, msg) - if (nargin == 3) && ischar(varargin{3}) && ischar(varargin{2}) - % Get window title and comment - wndTitle = varargin{2}; - msg = varargin{3}; - % Set Progress bar in inderminate mode - pBar.jProgressBar.setIndeterminate(1); - pBar.jProgressBar.setStringPainted(0); - % Set progress bar bounds - pBar.jProgressBar.setMinimum(0); - pBar.jProgressBar.setMaximum(100); - % Set initial value to start - pBar.jProgressBar.setValue(0); - % Update values in GlobalData - GlobalData.Program.ProgressBar{ix}.Values.Minimum = 0; - GlobalData.Program.ProgressBar{ix}.Values.Maximum = 100; - GlobalData.Program.ProgressBar{ix}.Values.Value = 0; - GlobalData.Program.ProgressBar{ix}.Values.LastVal = 0; - - % Call: bst_progress(''start'', title, msg, start, stop) - elseif ((nargin == 5) && ischar(varargin{2}) && ischar(varargin{3}) && isnumeric(varargin{4}) && isnumeric(varargin{5})) - % Get window title and comment - wndTitle = varargin{2}; - msg = varargin{3}; - % Set Progress bar in derminate mode - pBar.jProgressBar.setIndeterminate(0); - pBar.jProgressBar.setStringPainted(1); - % Get progress bar bounds - valStart = varargin{4}; - valStop = varargin{5}; - % Test bounds - if ( (valStart >= valStop) || (valStop <= 0) ) - % Set indeterminate bounds - pBar.jProgressBar.setIndeterminate(1); - pBar.jProgressBar.setStringPainted(0); - valStart = 0; - valStop = 100; - end - % Set progress bar bounds - pBar.jProgressBar.setMinimum(valStart); - pBar.jProgressBar.setMaximum(valStop); - pBar.jProgressBar.setValue(valStart); - % Update values in GlobalData - GlobalData.Program.ProgressBar{ix}.Values.Minimum = valStart; - GlobalData.Program.ProgressBar{ix}.Values.Maximum = valStop; - GlobalData.Program.ProgressBar{ix}.Values.Value = valStart; - GlobalData.Program.ProgressBar{ix}.Values.LastVal = valStart; - else - error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); - end - % Set window title - pBar.jWindow.setTitle(wndTitle); - % Set window comment (central label) - pBar.jLabel.setText(msg); - % Show window - java_call(pBar.jWindow, 'setVisible', 'Z', 1); - % Repaing window - pBar.jWindow.getContentPane().repaint(); - % Set watch cursor - jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); + pBar = start(pBar, varargin{2:end}); + % ==== STOP ==== case 'stop' % Restore cursor @@ -218,22 +156,7 @@ % ==== SET POSITION ==== case 'set' - % Parse arguments - if ((nargin == 2) && isnumeric(varargin{2})) - newVal = varargin{2}; - else - error('Usage : bst_progress(''set'', pos)'); - end - % Get current value - curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; - % Plot the position if it changes - if (curValue ~= newVal) - newVal = min(newVal, GlobalData.Program.ProgressBar{ix}.Values.Maximum); - pBar.jProgressBar.setValue(newVal); - % Update value in GlobalData - GlobalData.Program.ProgressBar{ix}.Values.Value = newVal; - GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; - end + pBar = set (pBar, varargin{2:end}); % ==== GET POSITION ==== case 'get' @@ -341,10 +264,10 @@ end % (Re)start bar if pBarParams.isIndeterminate - bst_progress('start', pBarParams.Title, pBarParams.Msg); + pBar = start(pBar, pBarParams.Title, pBarParams.Msg); else - bst_progress('start', pBarParams.Title, pBarParams.Msg, pBarParams.Min, pBarParams.Max); - bst_progress('set', pBarParams.Value); + pBar = start(pBar, pBarParams.Title, pBarParams.Msg, pBarParams.Min, pBarParams.Max); + pBar = set (pBar, pBarParams.Value); end % ==== SET PLUGIN LOGO ==== @@ -368,7 +291,7 @@ end % Start progress bar if needed if ~pBar.jWindow.isVisible() - bst_progress('Start', ['Plugin: ' PlugDesc.Name], ''); + pBar = start(pBar, ['Plugin: ' PlugDesc.Name], ''); end % Set logo file if ~isempty(PlugDesc.LogoFile) @@ -389,6 +312,7 @@ error('Unknown command: %s', commandName); end + % %% ===== CLOSE CALLBACK ===== % function CloseCallback() % % Hide progress bar @@ -452,7 +376,71 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end + + +function pBar = start(pBar, wndTitle, msg, valStart, valStop) + % JAVA imports + import org.brainstorm.icon.*; + % Set as "always on top" + java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); + java_call(pBar.jWindow, 'setFocusable', 'Z', 0); + java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); + % Call: bst_progress(''start'', title, msg) + if (nargin == 3) && ischar(wndTitle) && ischar(msg) + % Set Progress bar in inderminate mode + pBar.jProgressBar.setIndeterminate(1); + pBar.jProgressBar.setStringPainted(0); + % Set progress bar bounds + pBar.jProgressBar.setMinimum(0); + pBar.jProgressBar.setMaximum(100); + % Set initial value to start + pBar.jProgressBar.setValue(0); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = 0; + GlobalData.Program.ProgressBar{end}.Values.Maximum = 100; + GlobalData.Program.ProgressBar{end}.Values.Value = 0; + GlobalData.Program.ProgressBar{end}.Values.LastVal = 0; + + % Call: bst_progress(''start'', title, msg, start, stop) + elseif ((nargin == 5) && ischar(wndTitle) && ischar(msg) && isnumeric(valStart) && isnumeric(valStop)) + % Set Progress bar in derminate mode + pBar.jProgressBar.setIndeterminate(0); + pBar.jProgressBar.setStringPainted(1); + + % Test bounds + if ( (valStart >= valStop) || (valStop <= 0) ) + % Set indeterminate bounds + pBar.jProgressBar.setIndeterminate(1); + pBar.jProgressBar.setStringPainted(0); + valStart = 0; + valStop = 100; + end + % Set progress bar bounds + pBar.jProgressBar.setMinimum(valStart); + pBar.jProgressBar.setMaximum(valStop); + pBar.jProgressBar.setValue(valStart); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = valStart; + GlobalData.Program.ProgressBar{end}.Values.Maximum = valStop; + GlobalData.Program.ProgressBar{end}.Values.Value = valStart; + GlobalData.Program.ProgressBar{end}.Values.LastVal = valStart; + else + error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); + end + % Set window title + pBar.jWindow.setTitle(wndTitle); + % Set window comment (central label) + pBar.jLabel.setText(msg); + % Show window + java_call(pBar.jWindow, 'setVisible', 'Z', 1); + % Repaing window + pBar.jWindow.getContentPane().repaint(); + % Set watch cursor + jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); + +end function [caller_name, stacklist] = getCallerName() + % Get the name of the function that is calling bst_progress stacks = dbstack(2); if isempty(stacks) @@ -467,14 +455,33 @@ stacklist = {stacks.name_file}; end + function pBar = set (pBar, newVal) + % Parse arguments + if ~((nargin == 2) && isnumeric(varargin{2})) + error('Usage : bst_progress(''set'', pos)'); + end + + % Get current value + curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; + % Plot the position if it changes + if (curValue ~= newVal) + newVal = min(newVal, GlobalData.Program.ProgressBar{ix}.Values.Maximum); + pBar.jProgressBar.setValue(newVal); + % Update value in GlobalData + GlobalData.Program.ProgressBar{ix}.Values.Value = newVal; + GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; + end + end + function [pBar, ix] = getProgressBar(caller_name, stacklist) + pBar = []; ix = 0; - + if isempty(GlobalData) || isempty(GlobalData.Program.ProgressBar) return; end - + progress_list = cellfun(@(x) x.Values.Caller, GlobalData.Program.ProgressBar, 'UniformOutput',false); ix = find(strcmp(progress_list, caller_name), 1, 'last'); @@ -485,7 +492,7 @@ ix = 0; end end - + % Close all progress bar that are not a parent of the caller for iBar = (ix+1):length(progress_list) java_call(GlobalData.Program.ProgressBar{iBar}.jWindow, 'dispose'); @@ -496,8 +503,9 @@ pBar = GlobalData.Program.ProgressBar{end}; end end - + function pBar = createProgressBar(DefaultSize, caller_name, n_progress) + % JAVA imports import org.brainstorm.icon.*; import java.awt.Dimension; @@ -545,7 +553,7 @@ pBar.jWindow.pack(); % Set window size and location %pBar.jWindow.setLocationRelativeTo(pBar.jWindow.getParent()); - + if isstruct(jBstFrame) pos = [0, 0]; else @@ -558,7 +566,7 @@ pBar.jWindow.setLocation(pos(1), pos(2)); pBar.Values = struct('Minimum', [], 'Maximum', [], 'Value', [], 'LastVal', [], 'Caller', caller_name); end - + %% ===== ADD COMPONENTS ===== function UpdateConstraints(pBar, isImage) import java.awt.GridBagConstraints; @@ -585,17 +593,11 @@ function UpdateConstraints(pBar, isImage) c.weighty = 0; c.insets = Insets(0,12,9,12); pBar.jPanel.add(pBar.jProgressBar, c); -% % CANCEL BUTTON -% c.gridy = 4; -% c.weighty = 0; -% c.insets = Insets(0,12,9,12); -% c.weightx = 0; -% pBar.jPanel.add(pBar.jButtonCancel, c); + % % CANCEL BUTTON + % c.gridy = 4; + % c.weighty = 0; + % c.insets = Insets(0,12,9,12); + % c.weightx = 0; + % pBar.jPanel.add(pBar.jButtonCancel, c); end - -end - - - - - +end \ No newline at end of file From 685d198a7e406eccef4d45e875534ad581b38234 Mon Sep 17 00:00:00 2001 From: Edouard Date: Mon, 23 Mar 2026 18:19:15 -0400 Subject: [PATCH 26/34] adjust ident --- toolbox/core/bst_progress.m | 122 ++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 2118c0bf85..2b6d5a1113 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -122,7 +122,7 @@ pBar = createProgressBar(DefaultSize, caller_name, ix); GlobalData.Program.ProgressBar{ix} = pBar; - + pBar = start(pBar, varargin{2:end}); % ==== STOP ==== @@ -376,69 +376,67 @@ % SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); % jBstFrame.setVisible(1); % end - - -function pBar = start(pBar, wndTitle, msg, valStart, valStop) - % JAVA imports - import org.brainstorm.icon.*; - % Set as "always on top" - java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); - java_call(pBar.jWindow, 'setFocusable', 'Z', 0); - java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); - % Call: bst_progress(''start'', title, msg) - if (nargin == 3) && ischar(wndTitle) && ischar(msg) - % Set Progress bar in inderminate mode - pBar.jProgressBar.setIndeterminate(1); - pBar.jProgressBar.setStringPainted(0); - % Set progress bar bounds - pBar.jProgressBar.setMinimum(0); - pBar.jProgressBar.setMaximum(100); - % Set initial value to start - pBar.jProgressBar.setValue(0); - % Update values in GlobalData - GlobalData.Program.ProgressBar{end}.Values.Minimum = 0; - GlobalData.Program.ProgressBar{end}.Values.Maximum = 100; - GlobalData.Program.ProgressBar{end}.Values.Value = 0; - GlobalData.Program.ProgressBar{end}.Values.LastVal = 0; + function pBar = start(pBar, wndTitle, msg, valStart, valStop) + % JAVA imports + import org.brainstorm.icon.*; + % Set as "always on top" + java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); + java_call(pBar.jWindow, 'setFocusable', 'Z', 0); + java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); + % Call: bst_progress(''start'', title, msg) + if (nargin == 3) && ischar(wndTitle) && ischar(msg) + % Set Progress bar in inderminate mode + pBar.jProgressBar.setIndeterminate(1); + pBar.jProgressBar.setStringPainted(0); + % Set progress bar bounds + pBar.jProgressBar.setMinimum(0); + pBar.jProgressBar.setMaximum(100); + % Set initial value to start + pBar.jProgressBar.setValue(0); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = 0; + GlobalData.Program.ProgressBar{end}.Values.Maximum = 100; + GlobalData.Program.ProgressBar{end}.Values.Value = 0; + GlobalData.Program.ProgressBar{end}.Values.LastVal = 0; + + % Call: bst_progress(''start'', title, msg, start, stop) + elseif ((nargin == 5) && ischar(wndTitle) && ischar(msg) && isnumeric(valStart) && isnumeric(valStop)) + % Set Progress bar in derminate mode + pBar.jProgressBar.setIndeterminate(0); + pBar.jProgressBar.setStringPainted(1); + + % Test bounds + if ( (valStart >= valStop) || (valStop <= 0) ) + % Set indeterminate bounds + pBar.jProgressBar.setIndeterminate(1); + pBar.jProgressBar.setStringPainted(0); + valStart = 0; + valStop = 100; + end + % Set progress bar bounds + pBar.jProgressBar.setMinimum(valStart); + pBar.jProgressBar.setMaximum(valStop); + pBar.jProgressBar.setValue(valStart); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = valStart; + GlobalData.Program.ProgressBar{end}.Values.Maximum = valStop; + GlobalData.Program.ProgressBar{end}.Values.Value = valStart; + GlobalData.Program.ProgressBar{end}.Values.LastVal = valStart; + else + error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); + end + % Set window title + pBar.jWindow.setTitle(wndTitle); + % Set window comment (central label) + pBar.jLabel.setText(msg); + % Show window + java_call(pBar.jWindow, 'setVisible', 'Z', 1); + % Repaing window + pBar.jWindow.getContentPane().repaint(); + % Set watch cursor + jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); - % Call: bst_progress(''start'', title, msg, start, stop) - elseif ((nargin == 5) && ischar(wndTitle) && ischar(msg) && isnumeric(valStart) && isnumeric(valStop)) - % Set Progress bar in derminate mode - pBar.jProgressBar.setIndeterminate(0); - pBar.jProgressBar.setStringPainted(1); - - % Test bounds - if ( (valStart >= valStop) || (valStop <= 0) ) - % Set indeterminate bounds - pBar.jProgressBar.setIndeterminate(1); - pBar.jProgressBar.setStringPainted(0); - valStart = 0; - valStop = 100; end - % Set progress bar bounds - pBar.jProgressBar.setMinimum(valStart); - pBar.jProgressBar.setMaximum(valStop); - pBar.jProgressBar.setValue(valStart); - % Update values in GlobalData - GlobalData.Program.ProgressBar{end}.Values.Minimum = valStart; - GlobalData.Program.ProgressBar{end}.Values.Maximum = valStop; - GlobalData.Program.ProgressBar{end}.Values.Value = valStart; - GlobalData.Program.ProgressBar{end}.Values.LastVal = valStart; - else - error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); - end - % Set window title - pBar.jWindow.setTitle(wndTitle); - % Set window comment (central label) - pBar.jLabel.setText(msg); - % Show window - java_call(pBar.jWindow, 'setVisible', 'Z', 1); - % Repaing window - pBar.jWindow.getContentPane().repaint(); - % Set watch cursor - jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); - -end function [caller_name, stacklist] = getCallerName() % Get the name of the function that is calling bst_progress From 8ef284b0ce1ae35699fb66f39f9641fc96ba52ae Mon Sep 17 00:00:00 2001 From: Edouard Date: Thu, 26 Mar 2026 18:52:12 -0400 Subject: [PATCH 27/34] fix image loading --- toolbox/core/bst_progress.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 2b6d5a1113..ed9b83d6ed 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -297,9 +297,9 @@ if ~isempty(PlugDesc.LogoFile) % Image in label pBar.jImage.setIcon(javax.swing.ImageIcon(PlugDesc.LogoFile)); - GlobalData.Program.ProgressBar.isImage = 1; + GlobalData.Program.ProgressBar{end}.isImage = 1; % Extend size of the frame - UpdateConstraints(1); + UpdateConstraints(pBar, 1); pBar.jWindow.setPreferredSize([]); pBar.jWindow.pack(); end From ea4d71568ad5300cbdc84931a137a11e63cb7637 Mon Sep 17 00:00:00 2001 From: Edouard Date: Thu, 26 Mar 2026 18:55:20 -0400 Subject: [PATCH 28/34] remove unused code --- toolbox/core/bst_progress.m | 194 +++++++++++------------------------- 1 file changed, 60 insertions(+), 134 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index ed9b83d6ed..18498cc4ce 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -312,131 +312,68 @@ error('Unknown command: %s', commandName); end - -% %% ===== CLOSE CALLBACK ===== -% function CloseCallback() -% % Hide progress bar -% %java_call(pBar.jWindow, 'setVisible', 'Z', 0); -% bst_progress('stop'); -% -% if bst_iscompiled() -% try -% % Get command window -% cmdWindow = com.mathworks.mde.cmdwin.CmdWin.getInstance(); -% cmdWindow.grabFocus(); -% %2) Wait for focus transfer to complete (up to 2 seconds) -% focustransferTimer = tic; -% while ~cmdWindow.isFocusOwner -% pause(0.1); %Pause some small interval -% if (toc(focustransferTimer) > 2) -% error('Error transferring focus for CTRL+C press.') -% end -% end -% -% %3) Use Java robot to execute a CTRL+C in the (now focused) command window. -% -% %3.1) Setup a timer to relase CTRL + C in 0.3 second -% % Try to reuse an existing timer if possible (this would be a holdover -% % from a previous execution) -% t_all = timerfindall; -% releaseTimer = []; -% ix_timer = 1; -% while isempty(releaseTimer) && (ix_timer<= length(t_all)) -% if isequal(t_all(ix_timer).TimerFcn, @releaseCtrl_C) -% releaseTimer = t_all(ix_timer); -% end -% ix_timer = ix_timer+1; -% end -% if isempty(releaseTimer) -% releaseTimer = timer; -% releaseTimer.TimerFcn = @(h,ev)releaseCtrl_C; -% end -% releaseTimer.StartDelay = 0.3; -% start(releaseTimer); -% -% %3.2) Press press CTRL+C -% pressCtrl_C(); -% catch -% disp('BST> Could not post a CTRL+C signal in the command window.'); -% end -% end -% end -% -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% function pressCtrl_C() -% SimKey = java.awt.Robot; -% SimKey.keyPress(java.awt.event.KeyEvent.VK_CONTROL); -% SimKey.keyPress(java.awt.event.KeyEvent.VK_C); -% end -% -% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% function releaseCtrl_C() -% SimKey = java.awt.Robot; -% SimKey.keyRelease(java.awt.event.KeyEvent.VK_CONTROL); -% SimKey.keyRelease(java.awt.event.KeyEvent.VK_C); -% jBstFrame.setVisible(1); -% end - function pBar = start(pBar, wndTitle, msg, valStart, valStop) - % JAVA imports - import org.brainstorm.icon.*; - % Set as "always on top" - java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); - java_call(pBar.jWindow, 'setFocusable', 'Z', 0); - java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); - % Call: bst_progress(''start'', title, msg) - if (nargin == 3) && ischar(wndTitle) && ischar(msg) - % Set Progress bar in inderminate mode + function pBar = start(pBar, wndTitle, msg, valStart, valStop) + % JAVA imports + import org.brainstorm.icon.*; + % Set as "always on top" + java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); + java_call(pBar.jWindow, 'setFocusable', 'Z', 0); + java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); + % Call: bst_progress(''start'', title, msg) + if (nargin == 3) && ischar(wndTitle) && ischar(msg) + % Set Progress bar in inderminate mode + pBar.jProgressBar.setIndeterminate(1); + pBar.jProgressBar.setStringPainted(0); + % Set progress bar bounds + pBar.jProgressBar.setMinimum(0); + pBar.jProgressBar.setMaximum(100); + % Set initial value to start + pBar.jProgressBar.setValue(0); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = 0; + GlobalData.Program.ProgressBar{end}.Values.Maximum = 100; + GlobalData.Program.ProgressBar{end}.Values.Value = 0; + GlobalData.Program.ProgressBar{end}.Values.LastVal = 0; + + % Call: bst_progress(''start'', title, msg, start, stop) + elseif ((nargin == 5) && ischar(wndTitle) && ischar(msg) && isnumeric(valStart) && isnumeric(valStop)) + % Set Progress bar in derminate mode + pBar.jProgressBar.setIndeterminate(0); + pBar.jProgressBar.setStringPainted(1); + + % Test bounds + if ( (valStart >= valStop) || (valStop <= 0) ) + % Set indeterminate bounds pBar.jProgressBar.setIndeterminate(1); pBar.jProgressBar.setStringPainted(0); - % Set progress bar bounds - pBar.jProgressBar.setMinimum(0); - pBar.jProgressBar.setMaximum(100); - % Set initial value to start - pBar.jProgressBar.setValue(0); - % Update values in GlobalData - GlobalData.Program.ProgressBar{end}.Values.Minimum = 0; - GlobalData.Program.ProgressBar{end}.Values.Maximum = 100; - GlobalData.Program.ProgressBar{end}.Values.Value = 0; - GlobalData.Program.ProgressBar{end}.Values.LastVal = 0; - - % Call: bst_progress(''start'', title, msg, start, stop) - elseif ((nargin == 5) && ischar(wndTitle) && ischar(msg) && isnumeric(valStart) && isnumeric(valStop)) - % Set Progress bar in derminate mode - pBar.jProgressBar.setIndeterminate(0); - pBar.jProgressBar.setStringPainted(1); - - % Test bounds - if ( (valStart >= valStop) || (valStop <= 0) ) - % Set indeterminate bounds - pBar.jProgressBar.setIndeterminate(1); - pBar.jProgressBar.setStringPainted(0); - valStart = 0; - valStop = 100; - end - % Set progress bar bounds - pBar.jProgressBar.setMinimum(valStart); - pBar.jProgressBar.setMaximum(valStop); - pBar.jProgressBar.setValue(valStart); - % Update values in GlobalData - GlobalData.Program.ProgressBar{end}.Values.Minimum = valStart; - GlobalData.Program.ProgressBar{end}.Values.Maximum = valStop; - GlobalData.Program.ProgressBar{end}.Values.Value = valStart; - GlobalData.Program.ProgressBar{end}.Values.LastVal = valStart; - else - error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); + valStart = 0; + valStop = 100; end - % Set window title - pBar.jWindow.setTitle(wndTitle); - % Set window comment (central label) - pBar.jLabel.setText(msg); - % Show window - java_call(pBar.jWindow, 'setVisible', 'Z', 1); - % Repaing window - pBar.jWindow.getContentPane().repaint(); - % Set watch cursor - jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); - + % Set progress bar bounds + pBar.jProgressBar.setMinimum(valStart); + pBar.jProgressBar.setMaximum(valStop); + pBar.jProgressBar.setValue(valStart); + % Update values in GlobalData + GlobalData.Program.ProgressBar{end}.Values.Minimum = valStart; + GlobalData.Program.ProgressBar{end}.Values.Maximum = valStop; + GlobalData.Program.ProgressBar{end}.Values.Value = valStart; + GlobalData.Program.ProgressBar{end}.Values.LastVal = valStart; + else + error(['Usage : bst_progress(''start'', title, comment) ' 10 ' bst_progress(''start'', title, comment, valStart, valStop)']); end + % Set window title + pBar.jWindow.setTitle(wndTitle); + % Set window comment (central label) + pBar.jLabel.setText(msg); + % Show window + java_call(pBar.jWindow, 'setVisible', 'Z', 1); + % Repaing window + pBar.jWindow.getContentPane().repaint(); + % Set watch cursor + jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); + + end + function [caller_name, stacklist] = getCallerName() % Get the name of the function that is calling bst_progress @@ -524,13 +461,8 @@ pBar.jWindow.setModal(0); % Closing callback - % if bst_iscompiled() - pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); - % else - % pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.DO_NOTHING_ON_CLOSE); - % java_setcb(pBar.jWindow, 'WindowClosingCallback', @(h,ev)CloseCallback); - % end - + pBar.jWindow.setDefaultCloseOperation(pBar.jWindow.HIDE_ON_CLOSE); + % Configure window pBar.jWindow.setPreferredSize(DefaultSize); % Main panel @@ -591,11 +523,5 @@ function UpdateConstraints(pBar, isImage) c.weighty = 0; c.insets = Insets(0,12,9,12); pBar.jPanel.add(pBar.jProgressBar, c); - % % CANCEL BUTTON - % c.gridy = 4; - % c.weighty = 0; - % c.insets = Insets(0,12,9,12); - % c.weightx = 0; - % pBar.jPanel.add(pBar.jButtonCancel, c); end end \ No newline at end of file From 8771f457c433eec5bba22cf9ff95bba4b0549d48 Mon Sep 17 00:00:00 2001 From: Edouard Date: Thu, 26 Mar 2026 19:01:12 -0400 Subject: [PATCH 29/34] move inc function --- toolbox/core/bst_progress.m | 82 ++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 18498cc4ce..ce1f18fc19 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -123,7 +123,7 @@ GlobalData.Program.ProgressBar{ix} = pBar; - pBar = start(pBar, varargin{2:end}); + pBar = pb_start(pBar, varargin{2:end}); % ==== STOP ==== case 'stop' @@ -132,27 +132,10 @@ java_call(pBar.jWindow, 'dispose'); GlobalData.Program.ProgressBar = GlobalData.Program.ProgressBar(1:end-1); + % ==== INCREMENT ==== case 'inc' - % Parse arguments - if ((nargin == 2) && isnumeric(varargin{2})) - valInc = varargin{2}; - else - error('Usage : bst_progress(''inc'', valInc)'); - end - % Get current value - minValue = GlobalData.Program.ProgressBar{ix}.Values.Minimum; - maxValue = GlobalData.Program.ProgressBar{ix}.Values.Maximum; - curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; - newVal = min(curValue + valInc + minValue, maxValue); - % Plot the incremented progress if it moves at least 1% of the bar range - if (abs(newVal - GlobalData.Program.ProgressBar{ix}.Values.LastVal) / (maxValue - minValue)) > 1/100 - % Get the incremented progress bar position - pBar.jProgressBar.setValue(newVal); - % Update value in GlobalData - GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; - end - GlobalData.Program.ProgressBar{ix}.Values.Value = newVal; + pBar = pb_inc(pBar, varargin{2:end}); % ==== SET POSITION ==== case 'set' @@ -264,9 +247,9 @@ end % (Re)start bar if pBarParams.isIndeterminate - pBar = start(pBar, pBarParams.Title, pBarParams.Msg); + pBar = pb_start(pBar, pBarParams.Title, pBarParams.Msg); else - pBar = start(pBar, pBarParams.Title, pBarParams.Msg, pBarParams.Min, pBarParams.Max); + pBar = pb_start(pBar, pBarParams.Title, pBarParams.Msg, pBarParams.Min, pBarParams.Max); pBar = set (pBar, pBarParams.Value); end @@ -291,7 +274,7 @@ end % Start progress bar if needed if ~pBar.jWindow.isVisible() - pBar = start(pBar, ['Plugin: ' PlugDesc.Name], ''); + pBar = pb_start(pBar, ['Plugin: ' PlugDesc.Name], ''); end % Set logo file if ~isempty(PlugDesc.LogoFile) @@ -312,7 +295,7 @@ error('Unknown command: %s', commandName); end - function pBar = start(pBar, wndTitle, msg, valStart, valStop) + function pBar = pb_start(pBar, wndTitle, msg, valStart, valStop) % JAVA imports import org.brainstorm.icon.*; % Set as "always on top" @@ -374,20 +357,28 @@ end - function [caller_name, stacklist] = getCallerName() - - % Get the name of the function that is calling bst_progress - stacks = dbstack(2); - if isempty(stacks) - stacks = struct('name_file', 'cmd_windows'); - else - % We find the first progress bar, that is a parent of the caller - for i = 1:length(stacks) - stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); - end + function pBar = pb_inc(pBar, valInc) + + % Parse arguments + if ~((nargin == 2) && isnumeric(valInc)) + error('Usage : bst_progress(''inc'', valInc)'); end - caller_name = stacks(1).name_file; - stacklist = {stacks.name_file}; + + % Get current value + minValue = GlobalData.Program.ProgressBar{end}.Values.Minimum; + maxValue = GlobalData.Program.ProgressBar{end}.Values.Maximum; + curValue = GlobalData.Program.ProgressBar{end}.Values.Value; + newVal = min(curValue + valInc + minValue, maxValue); + + % Plot the incremented progress if it moves at least 1% of the bar range + if (abs(newVal - GlobalData.Program.ProgressBar{end}.Values.LastVal) / (maxValue - minValue)) > 1/100 + % Get the incremented progress bar position + pBar.jProgressBar.setValue(newVal); + % Update value in GlobalData + GlobalData.Program.ProgressBar{end}.Values.LastVal = newVal; + end + GlobalData.Program.ProgressBar{end}.Values.Value = newVal; + end function pBar = set (pBar, newVal) @@ -408,6 +399,23 @@ end end + + function [caller_name, stacklist] = getCallerName() + + % Get the name of the function that is calling bst_progress + stacks = dbstack(2); + if isempty(stacks) + stacks = struct('name_file', 'cmd_windows'); + else + % We find the first progress bar, that is a parent of the caller + for i = 1:length(stacks) + stacks(i).name_file = sprintf('%s/%s', stacks(i).file, stacks(i).name); + end + end + caller_name = stacks(1).name_file; + stacklist = {stacks.name_file}; + end + function [pBar, ix] = getProgressBar(caller_name, stacklist) pBar = []; From 3eb6babcaa98afe30c3934e2b073f7ca82264ecd Mon Sep 17 00:00:00 2001 From: Edouard Date: Thu, 26 Mar 2026 19:22:47 -0400 Subject: [PATCH 30/34] generate some function --- toolbox/core/bst_progress.m | 192 ++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 85 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index ce1f18fc19..c116ba8456 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -135,11 +135,23 @@ % ==== INCREMENT ==== case 'inc' - pBar = pb_inc(pBar, varargin{2:end}); + + % Parse arguments + if ~((nargin == 2) && isnumeric(varargin{2})) + error('Usage : bst_progress(''inc'', valInc)'); + end + + pBar = pb_inc(pBar, varargin{2}); % ==== SET POSITION ==== case 'set' - pBar = set (pBar, varargin{2:end}); + + % Parse arguments + if ~((nargin == 2) && isnumeric(varargin{2})) + error('Usage : bst_progress(''set'', pos)'); + end + + pBar = pb_set(pBar, varargin{2}); % ==== GET POSITION ==== case 'get' @@ -149,27 +161,20 @@ % ==== SET TEXT ==== case 'text' % Parse arguments - if ((nargin == 2) && ischar(varargin{2})) - % Set new label - pBar.jLabel.setText(varargin{2}); - else - % Get label - pBar.jLabel.getText(); + if ~((nargin == 2) && ischar(varargin{2})) + error('Usage : bst_progress(''text'', txt)'); end - + + % Set new label + pBar.jLabel.setText(varargin{2}); + % ==== IS VISIBLE ==== case 'isvisible' pBar = pBar.jWindow.isVisible(); % ==== SHOW ==== case 'show' - % Set as "always on top" - java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); - java_call(pBar.jWindow, 'setFocusable', 'Z', 0); - java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); - % Show window - java_call(pBar.jWindow, 'setVisible', 'Z', 1); - % Set watch cursor - jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); + + pBar = pb_show(pBar); % ==== HIDE ==== case 'hide' @@ -184,28 +189,8 @@ % ==== SET IMAGE ==== case 'setimage' - % Get image path - imagefile = varargin{2}; - searchDirs = {'', bst_get('BrainstormDocDir'), bst_fullfile(bst_get('BrainstormDocDir'), 'plugins')}; - for iDir = 1 : length(searchDirs) - tmp = bst_fullfile(searchDirs{iDir}, imagefile); - if file_exist(tmp) - imagefile = tmp; - break - end - end - if ~file_exist(imagefile) - warning(['Image not found: ' imagefile]); - return - end - % Image in label - pBar.jImage.setIcon(javax.swing.ImageIcon(imagefile)); - GlobalData.Program.ProgressBar{ix}.isImage = 1; - % Extend size of the frame - UpdateConstraints(pBar, 1); - pBar.jWindow.setPreferredSize([]); - pBar.jWindow.pack(); - + pBar = pb_setImage(pBar, varargin{2:end}); + % ==== SET LINK ==== case 'setlink' url = varargin{2}; @@ -250,46 +235,17 @@ pBar = pb_start(pBar, pBarParams.Title, pBarParams.Msg); else pBar = pb_start(pBar, pBarParams.Title, pBarParams.Msg, pBarParams.Min, pBarParams.Max); - pBar = set (pBar, pBarParams.Value); + pBar = pb_set(pBar, pBarParams.Value); end % ==== SET PLUGIN LOGO ==== case 'setpluginlogo' - % PlugName/PlugDesc is required - if (nargin < 2) - return - else - % Get plugin descriptor - PlugDesc = varargin{2}; - if ischar(PlugDesc) - PlugDesc = bst_plugin('GetSupported', PlugDesc); - end - if isempty(PlugDesc) - return - end - end - % Get logo if not defined in the plugin structure - if isempty(PlugDesc.LogoFile) - PlugDesc.LogoFile = bst_plugin('GetLogoFile', PlugDesc); - end - % Start progress bar if needed - if ~pBar.jWindow.isVisible() - pBar = pb_start(pBar, ['Plugin: ' PlugDesc.Name], ''); - end - % Set logo file - if ~isempty(PlugDesc.LogoFile) - % Image in label - pBar.jImage.setIcon(javax.swing.ImageIcon(PlugDesc.LogoFile)); - GlobalData.Program.ProgressBar{end}.isImage = 1; - % Extend size of the frame - UpdateConstraints(pBar, 1); - pBar.jWindow.setPreferredSize([]); - pBar.jWindow.pack(); - end - % Set link - if ~isempty(PlugDesc.URLinfo) - java_setcb(pBar.jImage, 'MouseClickedCallback', @(h,ev)web(PlugDesc.URLinfo, '-browser')); + + % is required + if ~((nargin == 2) && ischar(varargin{2})) + error('Usage : bst_progress(''setpluginlogo'', PlugName/PlugDesc)'); end + pBar = pb_setPluginLogo(pBar, varargin{2}); otherwise error('Unknown command: %s', commandName); @@ -359,11 +315,6 @@ function pBar = pb_inc(pBar, valInc) - % Parse arguments - if ~((nargin == 2) && isnumeric(valInc)) - error('Usage : bst_progress(''inc'', valInc)'); - end - % Get current value minValue = GlobalData.Program.ProgressBar{end}.Values.Minimum; maxValue = GlobalData.Program.ProgressBar{end}.Values.Maximum; @@ -381,12 +332,7 @@ end - function pBar = set (pBar, newVal) - % Parse arguments - if ~((nargin == 2) && isnumeric(varargin{2})) - error('Usage : bst_progress(''set'', pos)'); - end - + function pBar = pb_set(pBar, newVal) % Get current value curValue = GlobalData.Program.ProgressBar{ix}.Values.Value; % Plot the position if it changes @@ -398,7 +344,83 @@ GlobalData.Program.ProgressBar{ix}.Values.LastVal = newVal; end end + + function pBar = pb_setImage(pBar, imagefile) + + % Get image path + searchDirs = {'', bst_get('BrainstormDocDir'), bst_fullfile(bst_get('BrainstormDocDir'), 'plugins')}; + for iDir = 1 : length(searchDirs) + tmp = bst_fullfile(searchDirs{iDir}, imagefile); + if file_exist(tmp) + imagefile = tmp; + break + end + end + if ~file_exist(imagefile) + warning(['Image not found: ' imagefile]); + return + end + % Image in label + pBar.jImage.setIcon(javax.swing.ImageIcon(imagefile)); + GlobalData.Program.ProgressBar{ix}.isImage = 1; + % Extend size of the frame + UpdateConstraints(pBar, 1); + pBar.jWindow.setPreferredSize([]); + pBar.jWindow.pack(); + end + + function pBar = pb_show(pBar) + + import org.brainstorm.icon.*; + import java.awt.Dimension; + % Set as "always on top" + java_call(pBar.jWindow, 'setAlwaysOnTop', 'Z', 1); + java_call(pBar.jWindow, 'setFocusable', 'Z', 0); + java_call(pBar.jWindow, 'setFocusableWindowState', 'Z', 0); + % Show window + java_call(pBar.jWindow, 'setVisible', 'Z', 1); + % Set watch cursor + jBstFrame.setCursor(java_create('java.awt.Cursor', 'I', java.awt.Cursor.WAIT_CURSOR)); + end + + function pBar = pb_setPluginLogo(pBar, PlugDesc) + + % Get plugin descriptor + if ischar(PlugDesc) + PlugDesc = bst_plugin('GetSupported', PlugDesc); + end + if isempty(PlugDesc) + return + end + + % Get logo if not defined in the plugin structure + if isempty(PlugDesc.LogoFile) + PlugDesc.LogoFile = bst_plugin('GetLogoFile', PlugDesc); + end + + % Start progress bar if needed + if ~pBar.jWindow.isVisible() + pBar = pb_start(pBar, ['Plugin: ' PlugDesc.Name], ''); + end + + % Set logo file + if ~isempty(PlugDesc.LogoFile) + % Image in label + pBar.jImage.setIcon(javax.swing.ImageIcon(PlugDesc.LogoFile)); + GlobalData.Program.ProgressBar{end}.isImage = 1; + % Extend size of the frame + UpdateConstraints(pBar, 1); + pBar.jWindow.setPreferredSize([]); + pBar.jWindow.pack(); + end + + + % Set link + if ~isempty(PlugDesc.URLinfo) + java_setcb(pBar.jImage, 'MouseClickedCallback', @(h,ev)web(PlugDesc.URLinfo, '-browser')); + end + end function [caller_name, stacklist] = getCallerName() From 0b15742a7ced39e2e8a246fe23f35f6a53c558f7 Mon Sep 17 00:00:00 2001 From: Edouard Date: Fri, 27 Mar 2026 16:15:26 -0400 Subject: [PATCH 31/34] import freesurfer: avoid a million figure --- toolbox/core/bst_progress.m | 22 ++++++++++++------ toolbox/io/import_anatomy_fs.m | 42 ++++++++++++++++++---------------- toolbox/io/import_mri.m | 13 ++++------- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index c116ba8456..7b2ae40891 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -71,6 +71,7 @@ elseif isempty(GlobalData) GlobalData = db_template('globaldata'); end + % If running in NOGUI mode: just display the message in the command window if ~bst_get('isGUI') switch lower(commandName) @@ -161,12 +162,19 @@ % ==== SET TEXT ==== case 'text' % Parse arguments - if ~((nargin == 2) && ischar(varargin{2})) + if ~((nargin >= 2) && ischar(varargin{2})) error('Usage : bst_progress(''text'', txt)'); end + + if (nargin == 2) + % Set new label + pBar.jLabel.setText(varargin{2}); + elseif (nargin == 3) + % Set new label + pBar.jWindow.setTitle(varargin{3}); + pBar.jLabel.setText(varargin{3}); + end - % Set new label - pBar.jLabel.setText(varargin{2}); % ==== IS VISIBLE ==== case 'isvisible' @@ -225,11 +233,11 @@ % ==== SET BAR PARAMETERS ==== case 'setbarparams' % Parse arguments - if (nargin == 2) - pBarParams = varargin{2}; - else + if ~(nargin == 2) error('Usage : bst_progress(''setbarparams'', barParams)'); end + + pBarParams = varargin{2}; % (Re)start bar if pBarParams.isIndeterminate pBar = pb_start(pBar, pBarParams.Title, pBarParams.Msg); @@ -245,7 +253,7 @@ if ~((nargin == 2) && ischar(varargin{2})) error('Usage : bst_progress(''setpluginlogo'', PlugName/PlugDesc)'); end - pBar = pb_setPluginLogo(pBar, varargin{2}); + pBar = pb_setPluginLogo(pBar, varargin{2:end}); otherwise error('Unknown command: %s', commandName); diff --git a/toolbox/io/import_anatomy_fs.m b/toolbox/io/import_anatomy_fs.m index 00638c4fba..cc2b6888cd 100644 --- a/toolbox/io/import_anatomy_fs.m +++ b/toolbox/io/import_anatomy_fs.m @@ -294,7 +294,7 @@ BstTessLhFile = BstTessLhFile{1}; % Load atlases if ~isempty(AnnotLhFiles) - bst_progress('start', 'Import FreeSurfer folder', 'Loading atlases: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading atlases: left pial...'); [sAllAtlas, err] = import_label(BstTessLhFile, AnnotLhFiles, 1); if ~isempty(err) disp(['BST> ERROR: ' strrep(err(1:end-1), char(10), [10 'BST> ERROR: '])]); % Not a blocking error anymore @@ -303,14 +303,14 @@ end % Load sphere if ~isempty(TessLsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading registered sphere: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading registered sphere: left pial...'); [TessMat, err] = tess_addsphere(BstTessLhFile, TessLsphFile, 'FS', 0); if ~isempty(err) errorMsg = [errorMsg err]; end end if ~isempty(TessLRsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading contralateral sphere: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading contralateral sphere: left pial...'); [TessMat, err] = tess_addsphere(BstTessLhFile, TessLRsphFile, 'FS', 1); if ~isempty(err) errorMsg = [errorMsg err]; @@ -318,7 +318,7 @@ end % Downsample - bst_progress('start', 'Import FreeSurfer folder', 'Downsampling: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Downsampling: left pial...'); [BstTessLhLowFile, iLhLow, xLhLow] = tess_downsize(BstTessLhFile, nVertHemi, 'reducepatch'); end % Right pial @@ -328,7 +328,7 @@ BstTessRhFile = BstTessRhFile{1}; % Load atlases if ~isempty(AnnotRhFiles) - bst_progress('start', 'Import FreeSurfer folder', 'Loading atlases: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading atlases: right pial...'); [sAllAtlas, err] = import_label(BstTessRhFile, AnnotRhFiles, 1); if ~isempty(err) disp(['BST> ERROR: ' strrep(err(1:end-1), char(10), [10 'BST> ERROR: '])]); % Not a blocking error anymore @@ -337,7 +337,7 @@ end % Load sphere if ~isempty(TessRsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading registered sphere: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading registered sphere: right pial...'); [TessMat, err] = tess_addsphere(BstTessRhFile, TessRsphFile, 'FS', 0); if ~isempty(err) errorMsg = [errorMsg err]; @@ -346,7 +346,7 @@ % Load sphere if ~isempty(TessRLsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading contralateral sphere: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading contralateral sphere: right pial...'); [TessMat, err] = tess_addsphere(BstTessRhFile, TessRLsphFile, 'FS', 1); if ~isempty(err) errorMsg = [errorMsg err]; @@ -355,7 +355,7 @@ % Downsample - bst_progress('start', 'Import FreeSurfer folder', 'Downsampling: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Downsampling: right pial...'); [BstTessRhLowFile, iRhLow, xRhLow] = tess_downsize(BstTessRhFile, nVertHemi, 'reducepatch'); end % Left white matter @@ -365,7 +365,7 @@ BstTessLwFile = BstTessLwFile{1}; % Load atlases if ~isempty(AnnotLhFiles) - bst_progress('start', 'Import FreeSurfer folder', 'Loading atlases: left white...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading atlases: left white...'); [sAllAtlas, err] = import_label(BstTessLwFile, AnnotLhFiles, 1); if ~isempty(err) disp(['BST> ERROR: ' strrep(err(1:end-1), char(10), [10 'BST> ERROR: '])]); % Not a blocking error anymore @@ -373,14 +373,14 @@ end end if ~isempty(TessLsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading registered sphere: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading registered sphere: left pial...'); [TessMat, err] = tess_addsphere(BstTessLwFile, TessLsphFile, 'FS', 0); if ~isempty(err) errorMsg = [errorMsg err]; end end if ~isempty(TessLRsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading contralateral sphere: left pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading contralateral sphere: left pial...'); [TessMat, err] = tess_addsphere(BstTessLwFile, TessLRsphFile, 'FS', 1); if ~isempty(err) errorMsg = [errorMsg err]; @@ -388,7 +388,7 @@ end % Downsample - bst_progress('start', 'Import FreeSurfer folder', 'Downsampling: left white...'); + bst_progress('text', 'Import FreeSurfer folder', 'Downsampling: left white...'); [BstTessLwLowFile, iLwLow, xLwLow] = tess_downsize(BstTessLwFile, nVertHemi, 'reducepatch'); end % Right white matter @@ -398,7 +398,7 @@ BstTessRwFile = BstTessRwFile{1}; % Load atlases if ~isempty(AnnotRhFiles) - bst_progress('start', 'Import FreeSurfer folder', 'Loading atlases: right white...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading atlases: right white...'); [sAllAtlas, err] = import_label(BstTessRwFile, AnnotRhFiles, 1); if ~isempty(err) disp(['BST> ERROR: ' strrep(err(1:end-1), char(10), [10 'BST> ERROR: '])]); % Not a blocking error anymore @@ -407,7 +407,7 @@ end % Load sphere if ~isempty(TessRsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading registered sphere: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading registered sphere: right pial...'); [TessMat, err] = tess_addsphere(BstTessRwFile, TessRsphFile, 'FS', 0); if ~isempty(err) errorMsg = [errorMsg err]; @@ -416,7 +416,7 @@ % Load sphere if ~isempty(TessRLsphFile) - bst_progress('start', 'Import FreeSurfer folder', 'Loading contralateral sphere: right pial...'); + bst_progress('text', 'Import FreeSurfer folder', 'Loading contralateral sphere: right pial...'); [TessMat, err] = tess_addsphere(BstTessRwFile, TessRLsphFile, 'FS', 1); if ~isempty(err) errorMsg = [errorMsg err]; @@ -424,7 +424,7 @@ end % Downsample - bst_progress('start', 'Import FreeSurfer folder', 'Downsampling: right white...'); + bst_progress('text', 'Import FreeSurfer folder', 'Downsampling: right white...'); [BstTessRwLowFile, iRwLow, xRwLow] = tess_downsize(BstTessRwFile, nVertHemi, 'reducepatch'); end % Process error messages @@ -452,13 +452,13 @@ BstTessRmFile = []; % Do not compute without volume atlases, to make a very light default import if isVolumeAtlas && ~isempty(TessLhFile) && ~isempty(TessRhFile) && ~isempty(TessLwFile) && ~isempty(TessRwFile) - bst_progress('start', 'Import FreeSurfer folder', 'Generating mid-surface...'); + bst_progress('text', 'Import FreeSurfer folder', 'Generating mid-surface...'); % Average pial and white surfaces [BstTessLmFile, ~, errMsgL] = tess_average({BstTessLhFile, BstTessLwFile}); [BstTessRmFile, ~, errMsgR] = tess_average({BstTessRhFile, BstTessRwFile}); % If computed: downsample the surfaces if ~isempty(BstTessLmFile) && ~isempty(BstTessRmFile) - bst_progress('start', 'Import FreeSurfer folder', 'Downsampling: mid-surface...'); + bst_progress('text', 'Import FreeSurfer folder', 'Downsampling: mid-surface...'); [BstTessLmLowFile, iLmLow, xLmLow] = tess_downsize(BstTessLmFile, nVertHemi, 'reducepatch'); [BstTessRmLowFile, iRmLow, xRmLow] = tess_downsize(BstTessRmFile, nVertHemi, 'reducepatch'); else @@ -615,6 +615,9 @@ db_save(); % Unload everything bst_memory('UnloadAll', 'Forced'); +% Close progress bar +bst_progress('stop'); + % Give a graphical output for user validation if isInteractive % Display the downsampled cortex + head + ASEG @@ -626,8 +629,7 @@ % Set orientation figure_3d('SetStandardView', hFig, 'left'); end -% Close progress bar -bst_progress('stop'); + diff --git a/toolbox/io/import_mri.m b/toolbox/io/import_mri.m index 2aa49c7f60..70d969b82e 100644 --- a/toolbox/io/import_mri.m +++ b/toolbox/io/import_mri.m @@ -154,10 +154,8 @@ end %% ===== LOAD MRI FILE ===== -isProgress = bst_progress('isVisible'); -if ~isProgress - bst_progress('start', ['Import ', volType], ['Loading ', volType, ' file...']); -end +bst_progress('start', ['Import ', volType], ['Loading ', volType, ' file...']); + % MNI / Atlas / CT / PET? isMni = ismember(FileFormat, {'ALL-MNI', 'ALL-MNI-ATLAS'}); isAtlas = ismember(FileFormat, {'ALL-ATLAS', 'ALL-MNI-ATLAS', 'SPM-TPM'}); @@ -555,7 +553,7 @@ db_save(); % Unload MRI (if a MRI with the same name was previously loaded) bst_memory('UnloadMri', BstMriFile); - +bst_progress('stop') %% ===== MRI VIEWER ===== if isInteractive @@ -583,14 +581,11 @@ hFig = view_mri(BstMriFile); end end -else - if ~isProgress - bst_progress('stop'); - end end + From 4e3aa63bfbe915e564031b96efb5bfcc64f0cb77 Mon Sep 17 00:00:00 2001 From: Edouard Date: Fri, 27 Mar 2026 16:42:47 -0400 Subject: [PATCH 32/34] wip improve progress bar --- toolbox/anatomy/tess_downsize.m | 2 +- toolbox/core/bst_progress.m | 2 +- toolbox/io/import_surfaces.m | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/toolbox/anatomy/tess_downsize.m b/toolbox/anatomy/tess_downsize.m index a97f30bca2..e5f16f0999 100644 --- a/toolbox/anatomy/tess_downsize.m +++ b/toolbox/anatomy/tess_downsize.m @@ -140,7 +140,7 @@ %% ===== RESAMPLE ===== -bst_progress('start', 'Resample surface', ['Resampling surface: ' TessMat.Comment '...']); +bst_progress('text', 'Resample surface', ['Resampling surface: ' TessMat.Comment '...']); % Resampling methods switch (Method) % ===== REDUCEPATCH ===== diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 7b2ae40891..56cadd17e8 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -459,7 +459,7 @@ ix = find(strcmp(progress_list, caller_name), 1, 'last'); if isempty(ix) - ix = find(cellfun(@(x) any(strcmp(stacklist,x)), progress_list),1,'last'); + ix = find(cellfun(@(x) any(strcmp(stacklist,x)), progress_list), 1, 'last'); if isempty(ix) ix = 0; diff --git a/toolbox/io/import_surfaces.m b/toolbox/io/import_surfaces.m index f36e7b66c2..782dca867a 100644 --- a/toolbox/io/import_surfaces.m +++ b/toolbox/io/import_surfaces.m @@ -138,15 +138,17 @@ %% ===== LOAD EACH SURFACE ===== % Process all the selected surfaces +bst_progress('start', 'Importing tesselation', '', 0, length(SurfaceFiles)); + for iFile = 1:length(SurfaceFiles) TessFile = SurfaceFiles{iFile}; - + % ===== LOAD SURFACE FILE ===== - bst_progress('start', 'Importing tesselation', ['Loading file "' TessFile '"...']); + bst_progress('text', ['Loading file "' TessFile '"...']); + % Load surfaces(s) [Tess, Labels] = in_tess(TessFile, FileFormat, sMri, OffsetMri, SelLabels); if isempty(Tess) - bst_progress('stop'); return end @@ -230,11 +232,14 @@ OutputSurfacesFiles{end+1} = BstTessFile; % Return number of vertices nVertices(end+1) = length(NewTess.Vertices); + + bst_progress('inc', 1); end % Save database db_save(); bst_progress('stop'); + end From 78af744f12e9070c9d8b2ec175a4e869b43abe5c Mon Sep 17 00:00:00 2001 From: Edouard Date: Tue, 14 Apr 2026 15:13:48 -0400 Subject: [PATCH 33/34] Limite the number of progress bar to 5 --- toolbox/core/bst_progress.m | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/toolbox/core/bst_progress.m b/toolbox/core/bst_progress.m index 56cadd17e8..7efda340ef 100644 --- a/toolbox/core/bst_progress.m +++ b/toolbox/core/bst_progress.m @@ -93,6 +93,10 @@ pause(0.05); end +% define the maximum number of active bar +max_bar = 5; + + % Retrieve the progress bar [caller_name, stacklist] = getCallerName(); [pBar, ix] = getProgressBar(caller_name, stacklist); @@ -118,11 +122,13 @@ switch (lower(commandName)) % ==== START ==== case 'start' - % Create a new progress bar - ix = ix + 1; - pBar = createProgressBar(DefaultSize, caller_name, ix); - GlobalData.Program.ProgressBar{ix} = pBar; + if ix < max_bar + % Create a new progress bar + ix = ix + 1; + pBar = createProgressBar(DefaultSize, caller_name, ix); + GlobalData.Program.ProgressBar{ix} = pBar; + end pBar = pb_start(pBar, varargin{2:end}); From a218649991b789eac3d01e05e07e25a523d3e9da Mon Sep 17 00:00:00 2001 From: Edouard2laire Date: Tue, 14 Apr 2026 15:21:07 -0400 Subject: [PATCH 34/34] Update toolbox/io/import_mri.m --- toolbox/io/import_mri.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolbox/io/import_mri.m b/toolbox/io/import_mri.m index 70d969b82e..f150f37938 100644 --- a/toolbox/io/import_mri.m +++ b/toolbox/io/import_mri.m @@ -553,7 +553,7 @@ db_save(); % Unload MRI (if a MRI with the same name was previously loaded) bst_memory('UnloadMri', BstMriFile); -bst_progress('stop') +bst_progress('stop'); %% ===== MRI VIEWER ===== if isInteractive