App-Chart

 view release on metacpan or  search on metacpan

lib/App/Chart/Gtk2/WatchlistDialog.pm  view on Meta::CPAN

sub _do_symlist_selection_changed {
  my ($selection) = @_;
  my $self = $selection->get_tree_view->get_toplevel;
  _update_delete_sensitive ($self);
  _update_edit_sensitive ($self);
}

# 'response' signal handler
sub _do_response {
  my ($self, $response) = @_;
  ### Watchlist _do_response(): $response

  if ($response eq RESPONSE_REFRESH) {
    $self->refresh;

  } elsif ($response eq RESPONSE_DELETE) {
    my $notebook = $self->{'notebook'};
    my $pagenum = $notebook->get_current_page;
    my $treeview;
    if ($pagenum == NOTEBOOK_PAGENUM_SYMLISTS) {
      $treeview = $self->{'symlists_treeview'};
      # supposed to be insensitive when no selection, but check anyway
      my $key = $self->get_symlists_selected_key || return;

      # ignore somehow unknown key
      my $symlist = App::Chart::Gtk2::Symlist->new_from_key ($key) || return;

      if (! $symlist->is_empty) {
        # dialog if symlist not empty
        require App::Chart::Gtk2::DeleteSymlistDialog;
        App::Chart::Gtk2::DeleteSymlistDialog->popup ($symlist, $self);
        return;
      }
    } else {
      $treeview = $self->{'symbols_treeview'};
    }
    require Gtk2::Ex::TreeViewBits;
    Gtk2::Ex::TreeViewBits::remove_selected_rows ($treeview);

  } elsif ($response eq RESPONSE_INTRADAY) {
    # supposed to be insensitive when no selected symbol, but check anyway
    my $symbol = $self->get_selected_symbol // return;
    App::Chart::Gtk2::Ex::ToplevelBits::popup
        ('App::Chart::Gtk2::IntradayDialog',
         properties => { symbol => $symbol },
         screen => $self);

  } elsif ($response eq RESPONSE_EDIT_NAME) {
    my $notebook = $self->{'notebook'};
    my $pagenum = $notebook->get_current_page;
    # supposed to be visible only when symlists showing, but check anyway
    ($pagenum == NOTEBOOK_PAGENUM_SYMLISTS) or return;

    my $treeview = $self->{'symlists_treeview'};
    my $selection = $treeview->get_selection;
    my ($symlists_model, $iter) = $selection->get_selected;
    # supposed to be insensitive if no selection, but check anyway
    if (! defined $iter) { return; }

    my $path = $symlists_model->get_path($iter);
    ### set_cursor to path: $path->to_string
    $treeview->grab_focus;
    my $renderer = $self->{'symlists_name_renderer'};
    $renderer->set (editable => 1);
    $treeview->set_cursor ($path, $self->{'symlists_name_treecolumn'}, 1);
    $renderer->set (editable => 0);

  } elsif ($response eq 'close') {
    # as per a keyboard close, defaults to raising 'delete-event', which in
    # turn defaults to a destroy
    $self->signal_emit ('close');

  } elsif ($response eq 'help') {
    require App::Chart::Manual;
    App::Chart::Manual->open(__p('manual-node','Watchlist'), $self);
  }
}

sub refresh {
  my ($self) = @_;
  Gtk2::Ex::WidgetCursor->busy;
  if (my $symlist = $self->{'symlist'}) {
    require App::Chart::Gtk2::Job::Latest;
    App::Chart::Gtk2::Job::Latest->start_symlist ($symlist);
  }
}

sub _do_symbol_menu_popup {
  my ($treeview, $event) = @_;
  if ($event->button == 3) {
    require App::Chart::Gtk2::WatchlistSymbolMenu;
    App::Chart::Gtk2::WatchlistSymbolMenu->popup_from_treeview ($event, $treeview);
  }
  return Gtk2::EVENT_PROPAGATE;
}

sub _do_symlist_menu_popup {
  # nothing yet ...
  #   my ($treeview, $event) = @_;
  #   my $self = $treeview->get_toplevel;
  return Gtk2::EVENT_PROPAGATE;
}

# 'query-tooltip' signal on symbols_treeview
sub _do_query_tooltip {
  my ($treeview, $x, $y, $keyboard_tip, $tooltip) = @_;
  # ### Watchlist _do_query_tooltip() "$x,$y"

  my ($bin_x, $bin_y, $model, $path, $iter)
    = $treeview->get_tooltip_context ($x, $y, $keyboard_tip);
  if (! defined $path) { return 0; }

  my $symbol = $model->get_value($iter, $model->COL_SYMBOL);
  if (! defined $symbol) { return 0; }
  require App::Chart::Latest;
  my $latest = App::Chart::Latest->get ($symbol);

  require App::Chart::Database;
  my $tip = $symbol;
  if (my $name = ($latest->{'name'}
                  || App::Chart::Database->symbol_name ($symbol))) {
    $tip .= ' - ' . $name;
  }
  $tip .= "\n";

  if (my $quote_date = $latest->{'quote_date'}) {
    my $quote_time = $latest->{'quote_time'} || '';
    $tip .= __x("Quote: {quote_date} {quote_time}",
                quote_date => $quote_date,
                quote_time => $quote_time);
    $tip .= "\n";
  }

  if (my $last_date = $latest->{'last_date'}) {
    my $last_time = $latest->{'last_time'} || '';
    $tip .= __x("Last:  {last_date} {last_time}",
                last_date => $last_date,
                last_time => $last_time);
    $tip .= "\n";
  }

  $tip .= __x('{location} time; source {source}',
              location => App::Chart::TZ->for_symbol($symbol)->name,
              source => $latest->{'source'});

  ### $tip
  $tooltip->set_text ($tip);
  $treeview->set_tooltip_row ($tooltip, $path);
  return 1;
}

sub _do_symlist_entry_activate {
  my ($entry_or_button) = @_;
  my $self = $entry_or_button->get_toplevel;
  my $treeview = $self->{'symlists_treeview'};
  my $pos = treeview_pos_after_selected_or_top_of_visible ($treeview);

  my $entry = $self->{'symlist_entry'};
  my $name = $entry->get_text;
  require App::Chart::Gtk2::Symlist::User;
  App::Chart::Gtk2::Symlist::User->add_symlist ($pos, $name);

  my $path = Gtk2::TreePath->new_from_indices ($pos);
  Gtk2::Ex::TreeViewBits::scroll_cursor_to_path ($treeview, $path);
}

# 'activate' signal handler on the Gtk2::Entry for a symbol 
sub _do_symbol_entry_activate {
  my ($entry_or_button) = @_;
  my $self = $entry_or_button->get_toplevel;
  my $treeview = $self->{'symbols_treeview'};
  my $pos = treeview_pos_after_selected_or_top_of_visible ($treeview);

  my $entry = $self->{'symbol_entry'};
  my $symlist = $self->{'symlist'};
  if (! $symlist->can_edit) {  # supposed to be insensitive anyway
    $entry->error_bell;
    return;
  }

  # select text for ease of typing another
  Gtk2::Ex::EntryBits::select_region_noclip ($entry, 0, -1);

  my $symbol = $entry->get_text;
  if (my $path = $symlist->find_symbol_path ($symbol)) {
    # already exists, move to it
    Gtk2::Ex::TreeViewBits::scroll_cursor_to_path ($treeview, $path);
    return;
  }
  $symlist->insert_with_values ($pos, 0=>$symbol);

  my $path = Gtk2::TreePath->new_from_indices ($pos);
  Gtk2::Ex::TreeViewBits::scroll_cursor_to_path ($treeview, $path);

  # request this, everything else as extras
  if ($symbol ne '') {
    require App::Chart::Gtk2::Job::Latest;
    App::Chart::Gtk2::Job::Latest->start ([$symbol]);
  }
}

#------------------------------------------------------------------------------
# generic helpers

sub treeview_pos_after_selected_or_top_of_visible {
  my ($treeview) = @_;

  my ($lo_path, $hi_path) = $treeview->get_visible_range;
  my ($lo) = $lo_path ? $lo_path->get_indices : (-1);
  my ($hi) = $hi_path ? $hi_path->get_indices : (-1);
  my $pos = $lo + 1;

  my $selection = $treeview->get_selection;
  my ($sel_path) = $selection->get_selected_rows;
  if ($sel_path) {
    my ($sel) = $sel_path->get_indices;
    if ($sel >= $lo && $sel <= $hi) {
      $pos = $sel + 1;
    }
  }
  return $pos;
}

#------------------------------------------------------------------------------

sub main {
  my ($class, $args) = @_;

  Gtk2->disable_setlocale;  # leave LC_NUMERIC alone for version nums
  Gtk2->init;

  require Gtk2::Ex::ErrorTextDialog::Handler;
  Glib->install_exception_handler
    (\&Gtk2::Ex::ErrorTextDialog::Handler::exception_handler);
  ## no critic (RequireLocalizedPunctuationVars)
  $SIG{'__WARN__'} = \&Gtk2::Ex::ErrorTextDialog::Handler::exception_handler;
  ## use critic

  require App::Chart::Gtk2::TickerMain;
  my $symlist = App::Chart::Gtk2::TickerMain::args_to_symlist ($args);

  my $self = $class->new;
  $self->set (symlist => $symlist);
  $self->signal_connect (destroy =>
                         \&App::Chart::Gtk2::TickerMain::_do_destroy_main_quit);
  $self->show_all;
  Gtk2->main;
}

1;
__END__

=for stopwords watchlist Watchlist Popup



( run in 2.069 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )