view scripts/plot/waitbar.m @ 15848:424edeca3c66

Redo portions of file editor to use more signals/slots rather than casting. * file-editor-tab.cc, file-editor-tab.h (file_editor_tab::~file_editor_tab): Add. Delete lexer to prevent memory leak. Delete _edit_area to prevent memory leak. (file_editor_tab::conditional_close): Add. Simple slot that uses QWidget pointer as unique ID, not for function call. (file_editor_tab::file_name_query): Add. Simple slot that signals file name to whomever is connected. (file_editor_tab::find, file_editor_tab : public QWidget): Removed use of exec() and keep a pointer to the find_dialog as a member. Toggle hide()/show() via a connected slot to toggle visibility as desired. * file-editor.cc, file-editor.h, file-editor-tab.cc file-editor-tab.h (file_editor : public file_editor_interface, file_editor_tab : public QWidget, file_editor_tab::file_editor_tab, file_editor_tab::closeEvent, file_editor_tab::load_file, file_editor_tab::new_file, file_editor_tab::run_file): Remove _file_editor pointer member from file_editor_tab and rid file_editor::get_main_window from file_editor. There should be no need for such information about higher-level hierarchy inside lower-level objects. (file_editor::request_open_file, file_editor_tab::open_file): Move QFileDialog to file_editor::request_open_file and delete file_editor_tab::open_file since most of the remaining functionality is in file_editor_tab::load_file. (file_editor::active_editor_tab): Deleted. (file_editor::fetab_change_request, file_editor_tab::change_editor_state): Added to initiate a request for the editor tab to change focus. (file_editor_tab::editor_state_changed): Added arguments to pass the copy status and the directory path so that editor doesn't have to call functions for such information. (file_editor::handle_editor_state_changed): Add copying directory of the file_editor_tab to the current editing directory. (file_editor::check_conflict_save, file_editor_tab::editor_check_conflict_save, file_editor_tab::save_file_as, file_editor_tab::handle_save_file_as_answer): Moved a portion of the save-file-as dialog mechanism to the file_editor where all file names can be obtained to check for conflict with already open files. The new signal indicates to the editor that a name check be done, and in turn the editor signals the tab to save the file. * main-window.cc, file-editor.cc, file-editor.h, file-editor-interface.h (file_editor::terminal, file_editor : public file_editor_interface, file_editor_interface : public QDockWidget): Since file_editor_tab no longer looks up to main_window, remove _main_window and _terminal from file_editor and file_editor_interface, as well as file_editor::terminal. * file-editor-tab.cc (file_editor_tab::file_has_changed): Make the dialog boxes non-modal and use slots to handle user answers. (file_editor_tab::closeEvent): Remove portion that accesses upper hierarchy member functions, can find better approaches. (file_editor_tab::file_editor_tab): Make there no parent for QsciScintilla so that window modality can be set to individual editor. * file-editor-tab.cc, file-editor.cc (file_editor_tab::load_file): Use show() member rather than exec() and set modality to window so that rest of application may function. Return a QString with message rather than a boolean. * file-editor-tab.cc, (file_editor_tab::file_has_changed): Remove static variable alreadyAsking. Multiple file_editor_tabs are using this code so do not want to block recognition of multiple file having changed on disk (bug #37406). Instead, simply stop tracking via the file watcher. (file_editor_tab::save_file, file_editor_tab::save_file_as, file_editor_tab::handle_save_file_as_answer, file_editor_tab::handle_save_file_as_answer_close): Added a remove_on_success variable. Changed the QFileDialog to WindowModal and created slots to handle file selected signal and finished signal. Signal/slot connects vary based upon remove_on_success setting. (file_editor_tab::check_file_modified): Changed the QFileDialog to NonModal and attach some slots. Editor tab can't be parent in case deleted, so use read-only state of the editor area. * file-editor-tab.h (file_editor_tab : public QWidget): New signals for file_editor for tab and file name management. (file_editor_tab::get_file_name): Delete. * file-editor.h (file_editor : public file_editor_interface): Make QStringList sessionFileNames a member of file_editor so that it can retain data between file_editor_tab signals. Also can be used for checking precense of filenames and prevent opening multiple copies (bug #36869) Added signals for file editor tabs--settings_changed, fetab_close_request, and query_file_name. Three new slots for tab and file name management. * file-editor-interface.h, file-editor.h (file_editor_interface::add_file_editor_tab, file_editor::add_file_editor_tab): Made the text name for the tab an input variable. * file-editor.cc (file_editor::~file_editor): Replace dynamic_cast with simple signal querying all file editor tabs for file names which end up in savedSessionTabs. (file_editor::handle_file_name_changed): Dynamic cast not necessary since QObject and QWidget are compatible. (file_editor::handle_tab_close_request): Replace dynamic_cast with signal to request file_editor_tab with associated tabID tag should close. (file_editor::handle_tab_remove_request): Rename of handle_tab_close_request. Instead of dynamic cast, loop through pointers comparing QWidget* to QObject*, if same tag remove tab via index and also delete which fixes a memory leak. (file_editor::handle_add_filename_to_list): Simple slot that uses append() of the list member functions. (file_editor::notice_settings): Rather than dynamic cast, emit signal for the file_editor_tabs. (file_editor::add_file_editor_tab): New variety of connections for improved flow. (file_editor::request_open_file): Given error messages are made WindowModal, the tab shouldn't be delete if file open is not successful. The file_editor_tab takes care of that. (file_editor::request_open_file): Added check and message box for the requested file already open in editor. For the non-interactive overloaded version, open a message dialog box to tell the user file not found, e.g., could not find file in the settings when launched. (file_editor::request_open_file): Inquire file names and update list before checking for existence of files. Supply empty title to editor tab then have file_editor_tab update name. * file-editor-tab.h, file-editor-tab.cc, file-editor.cc (file_editor_tab::run_file): New signal process_octave_code. (file_editor::add_file_editor_tab): Connect signal process_octave_code to file_editor's parent's slot handle_command_double_clicked.
author Daniel J Sebald <daniel.sebald@ieee.org>
date Sun, 23 Dec 2012 14:33:48 -0600
parents 7a7ce92cff56
children eaab03308c0b
line wrap: on
line source

## Copyright (C) 2012 John W. Eaton
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or (at
## your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Function File} {@var{h} =} waitbar (@var{frac})
## @deftypefnx {Function File} {@var{h} =} waitbar (@var{frac}, @var{msg})
## @deftypefnx {Function File} {@var{h} =} waitbar (@dots{}, "FigureProperty", "Value", @dots{})
## @deftypefnx {Function File} {} waitbar (@var{frac})
## @deftypefnx {Function File} {} waitbar (@var{frac}, @var{hwbar})
## @deftypefnx {Function File} {} waitbar (@var{frac}, @var{hwbar}, @var{msg})
## Return a handle @var{h} to a new waitbar object.  The waitbar is
## filled to fraction @var{frac} which must be in the range [0, 1].  The
## optional message @var{msg} is centered and displayed above the waitbar.
## The appearance of the waitbar figure window can be configured by passing
## property/value pairs to the function.
## 
## When called with a single input the current waitbar, if it exists, is
## updated to the new value @var{frac}.  If there are multiple outstanding
## waitbars they can be updated individually by passing the handle @var{hwbar}
## of the specific waitbar to modify.
## @end deftypefn

## Author: jwe

function retval = waitbar (varargin)

  persistent curr_waitbar;

  if (nargin < 1)
    print_usage ();
  endif

  frac = varargin{1};
  varargin(1) = [];

  if (! (isnumeric (frac) && isscalar (frac) && frac >= 0 && frac <= 1))
    error ("waitbar: FRAC must be between 0 and 1");
  endif

  ## Use existing waitbar if it still points to a valid graphics handle.
  if (nargin == 1 && ishandle (curr_waitbar))
    h = curr_waitbar;
  else
    h = false;
  endif

  if (! isempty (varargin) && isnumeric (varargin{1}))
    if (! ishandle (varargin{1}))
      error ("waitbar: H must be a handle to a waitbar object");
    else
      h = varargin{1};
      varargin(1) = [];
      if (! isfigure (h) || ! strcmp (get (h, "tag"), "waitbar"))
        error ("waitbar: H must be a handle to a waitbar object");
      endif
    endif
  endif

  msg = false;

  if (! isempty (varargin))
    msg = varargin{1};
    varargin(1) = [];
    if (! (ischar (msg) || iscellstr (msg)))
      error ("waitbar: MSG must be a character string or cell array of strings");
    endif
  endif

  if (rem (numel (varargin), 2) != 0)
    error ("waitbar: invalid number of property-value pairs");
  endif

  if (h)
    p = findobj (h, "type", "patch");
    set (p, "xdata", [0; frac; frac; 0]);
    ax = findobj (h, "type", "axes");
    if (ischar (msg) || iscellstr (msg))
      th = get (ax, "title");
      curr_msg = get (th, "string");
      ## graphics handles always store data as column vectors
      if (iscellstr (msg))
        msg = msg(:);  
      endif
      cmp = strcmp (msg, curr_msg);
      if (! all (cmp(:)))
        set (th, "string", msg);
      endif
    endif
  else
    h = __go_figure__ (NaN, "position", [250, 500, 400, 100],
                       "numbertitle", "off",
                       "toolbar", "none", "menubar", "none",
                       "integerhandle", "off",
                       "handlevisibility", "callback",
                       "tag", "waitbar",
                       varargin{:});

    ax = axes ("parent", h, "xtick", [], "ytick", [],
               "xlim", [0, 1], "ylim", [0, 1],
               "xlimmode", "manual", "ylimmode", "manual",
               "position", [0.1, 0.3, 0.8, 0.2]);

    patch (ax, [0; frac; frac; 0], [0; 0; 1; 1], [0, 0.35, 0.75]);

    if (! (ischar (msg) || iscellstr (msg)))
      msg = "Please wait...";
    endif
    title (ax, msg);
  endif

  drawnow ();

  if (nargout > 0)
    retval = h;
  endif

  ## If there were no errors, update current waitbar.
  curr_waitbar = h;

endfunction


%!demo
%! h = waitbar (0, '0.00%');
%! for i = 0:0.01:1
%!   waitbar (i, h, sprintf ('%.2f%%', 100*i));
%! end
%! close (h);

%!demo
%! h = waitbar (0, 'please wait...');
%! for i = 0:0.01:0.6
%!   waitbar (i);
%! end
%! i = 0.3;
%! waitbar (i, h, 'don''t you hate taking a step backward?');
%! pause (0.5);
%! for i = i:0.005:0.7
%!   waitbar (i, h);
%! end
%! waitbar (i, h, 'or stalling?');
%! pause (1);
%! for i = i:0.003:0.8
%!   waitbar (i, h, 'just a little longer now');
%! end
%! for i = i:0.001:1
%!   waitbar (i, h, 'please don''t be impatient');
%! end
%! close (h);

%!demo
%! h1 = waitbar (0, 'Waitbar #1');
%! h2 = waitbar (0, 'Waitbar #2');
%! h2pos = get (h2, 'position');
%! h2pos(1) = h2pos(1) + (h2pos(3) + 50);
%! set (h2, 'position', h2pos);
%! pause (0.5);
%! for i = 1:4
%!   waitbar (i/4, h1);
%!   pause (0.5);
%!   waitbar (i/4, h2);
%!   pause (0.5);
%! end
%! pause (0.5);
%! close (h1);
%! close (h2);

%% Test input validation
%!error <FRAC must be between 0 and 1> waitbar (-0.5)
%!error <FRAC must be between 0 and 1> waitbar (1.5)
%!error <MSG must be a character string> waitbar (0.5, struct ())
%!error <invalid number of property-value pairs> waitbar (0.5, "msg", "Name")