App-Chart

 view release on metacpan or  search on metacpan

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

  $notebook->set_current_page (1);
  _do_notebook_page ($notebook, undef); # initial button sensitives

  my $hbox = Gtk2::HBox->new (0, 0);
  $vbox->pack_start ($hbox, 0,0,0);
  $hbox->pack_start (Gtk2::Label->new (__('Symbol')), 0,0,0);
  my $entry = $self->{'entry'} = Gtk2::Entry->new;
  $hbox->pack_start ($entry, 1, 1, 0.5 * Gtk2::Ex::Units::em($entry));
  $entry->signal_connect (activate => \&_do_entry_activate);
  $entry->grab_focus;

  $vbox->show_all;

  # Size per a sensible height for the notebook.

  # With all the scrolleds in 'never' mode they give their contained
  # treeviews as their width.
  # FIXME: ... which is not true any more ...
  Gtk2::Ex::Units::set_default_size_with_subsizes
      ($self, [$notebook, -1, '25 lines']);
}

sub _init_series {
  my ($notebook, $scrolled, $pagenum) = @_;

  $scrolled->{'dirty'} = 1;
  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = $scrolled->{'seriestreeview'}
    = App::Chart::Gtk2::SeriesTreeView->new;
  $scrolled->add ($treeview);

  $scrolled->show_all;
}

sub _init_dividends {
  my ($notebook, $vbox, $pagenum) = @_;

  my $self = $notebook->get_toplevel;
  my $scrolled = Gtk2::ScrolledWindow->new;
  $scrolled->set (hscrollbar_policy => 'never');
  $vbox->pack_start ($scrolled, 1,1,0);

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;

  my $em = Gtk2::Ex::Units::em($self);
  my $date_width = App::Chart::Gtk2::GUI::string_width ($treeview, '2099-99-99 ');
  my $date_width_editable = $date_width * 1.4; # diff font, and pulldown
  my $digit_width = Gtk2::Ex::Units::digit_width ($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'ex_date, record_date, pay_date, amount, imputation, type, qualifier, note',
                from     => 'dividend',
                order_by => 'ex_date DESC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [ { name          => 'ex_date',
                     header_markup => __('Ex'),
                     x_absolute    => $date_width_editable,
                     validation    => \&validate_date,
                     # renderer      => 'date',
                   },
                   { name          => 'record_date',
                     header_markup => __('Record'),
                     x_absolute    => $date_width_editable,
                     validation    => \&validate_date,
                     # renderer      => 'date',
                   },
                   { name          => 'pay_date',
                     header_markup => __('Pay'),
                     x_absolute    => $date_width_editable,
                     validation    => \&validate_date,
                     # renderer      => 'date',
                   },
                   { name          => 'amount',
                     header_markup => __('Amount'),
                     align         => 'right',
                     x_absolute    => 8 * $digit_width,
                     validation    => \&validate_number,
                   },
                   { name          => 'imputation',
                     header_markup => __('Imputation'),
                     align         => 'right',
                     x_absolute    => 8 * $digit_width,
                     validation    => \&validate_number,
                   },
                   { name          => 'type',
                     header_markup => __('Type'),
                     x_absolute    => 6 * $em,
                   },
                   { name          => 'qualifier',
                     header_markup => __('Qualifier'),
                     x_absolute    => 6 * $em,
                   },
                   { name          => 'note',
                     header_markup => __('Note'),
                     x_absolute    => 10 * $em,
                   },
                 ],
     });
  $vbox->{'insert_defaults'} = \&_dividends_insert_defaults;
  _datasheet_init ($self, $vbox, $datasheet);
}
sub _dividends_insert_defaults {
  my ($self, $pagewidget) = @_;
  my $datasheet = $pagewidget->{'datasheet'};
  my $num = $datasheet->{'column_name_to_number_mapping'};
  return ($num->{'ex_date'}, $self->default_date,
          $num->{'amount'},  0,
          $num->{'note'},    '');
}

sub default_date {
  my ($self) = @_;
  my $symbol = $self->{'symbol'} // '';
  my $timezone = App::Chart::TZ->for_symbol ($symbol);
  require App::Chart::Download;
  my $tdate = App::Chart::Download::tdate_today ($timezone);
  return App::Chart::tdate_to_iso($tdate);
}

sub _init_splits {
  my ($notebook, $vbox, $pagenum) = @_;

  my $self = $notebook->get_toplevel;
  my $scrolled = Gtk2::ScrolledWindow->new;
  $scrolled->set (hscrollbar_policy => 'never');
  $vbox->pack_start ($scrolled, 1,1,0);

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;

  my $em = Gtk2::Ex::Units::em($self);
  my $date_width = App::Chart::Gtk2::GUI::string_width ($treeview, '2099-99-99 ');
  my $date_width_editable = $date_width * 1.4; # diff font, and pulldown
  my $digit_width = Gtk2::Ex::Units::digit_width ($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'date, new, old, note',
                from     => 'split',
                order_by => 'date DESC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [ { name          => 'date',
                     header_markup => __('Date'),
                     x_absolute    => $date_width_editable,
                     validation    => \&validate_date,
                     # renderer      => 'date',
                   },
                   { name          => 'new',
                     header_markup => __('New'),
                     align         => 'right',
                     x_absolute    => 3 * $digit_width,
                     validation    => \&validate_number,
                   },
                   { name          => 'old',
                     header_markup => __('Old'),
                     align         => 'right',
                     x_absolute    => 3 * $digit_width,
                     validation    => \&validate_number,
                   },
                   { name          => 'note',
                     header_markup => __('Note'),
                     x_absolute    => 10 * $em,
                   },
                 ],
     });
  _datasheet_init ($self, $vbox, $datasheet);
  $vbox->{'insert_defaults'} = \&_splits_insert_defaults;
}
sub _splits_insert_defaults {
  my ($self, $pagewidget) = @_;
  my $datasheet = $pagewidget->{'datasheet'};
  my $num = $datasheet->{'column_name_to_number_mapping'};
  return ($num->{'date'}, $self->default_date,
          $num->{'new'},  1,
          $num->{'old'},  1,
          $num->{'note'}, '');
}

sub _init_latest {
  my ($notebook, $scrolled, $pagenum) = @_;

  $scrolled->{'dirty'} = 1;
  $scrolled->set (hscrollbar_policy => 'never'); # label wrap

  my $viewport = Gtk2::Viewport->new;
  $scrolled->add ($viewport);

  my $rawlatest = $scrolled->{'rawlatest'} = App::Chart::Gtk2::RawLatest->new;
  $viewport->add ($rawlatest);

  $scrolled->show_all;
}

sub _init_info {
  my ($notebook, $scrolled, $pagenum) = @_;

  $scrolled->{'dirty'} = 1;
  $scrolled->set (hscrollbar_policy => 'never'); # label wrap

  my $viewport = Gtk2::Viewport->new;
  $scrolled->add ($viewport);

  my $rawinfo = $scrolled->{'rawinfo'} = App::Chart::Gtk2::RawInfo->new;
  $viewport->add ($rawinfo);

  $scrolled->show_all;
}

sub _init_extra {
  my ($notebook, $scrolled, $pagenum) = @_;
  my $self = $notebook->get_toplevel;

  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;
  my $em = Gtk2::Ex::Units::em($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'key, value',
                from     => 'extra',
                order_by => 'key ASC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [
                  { name => 'key',
                    header_markup => __('Key'),
                    x_absolute    => 15 * $em,
                  },
                  { name => 'value',
                    header_markup => __('Value'),
                    x_absolute    => 15 * $em,
                  },
                 ],
     });
  $scrolled->{'insert_defaults'} = \&_extra_insert_defaults;
  _datasheet_init ($self, $scrolled, $datasheet);
}
sub _extra_insert_defaults {
  my ($self, $pagewidget) = @_;
  return;
}

sub _init_intraday {
  my ($notebook, $scrolled, $pagenum) = @_;
  my $self = $notebook->get_toplevel;

  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;
  my $em = Gtk2::Ex::Units::em($self);
  my $digit_width = Gtk2::Ex::Units::digit_width ($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'mode, error, fetch_timestamp, url, etag, last_modified',
                from     => 'intraday_image',
                order_by => 'mode ASC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [ { name          => 'mode',
                     header_markup => __('Mode'),
                     x_absolute    => 4 * $em,
                   },
                   { name          => 'error',
                     header_markup => __('Error'),
                     x_absolute    => 10 * $em,
                   },
                   { name          => 'fetch_timestamp',
                     header_markup => __('Fetch Timestamp'),
                     x_absolute    => (length('2009-03-09 22:01:31+00:00')
                                       * $digit_width),
                     validation    => \&validate_integer,
                   },
                   { name          => 'url',
                     header_markup => __('URL'),
                     x_absolute    => 10 * $em,
                   },
                   { name          => 'etag',
                     header_markup => __('ETag'),
                     x_absolute    => 10 * $em,
                   },
                   { name          => 'last_modified',
                     header_markup => __('Last Modified'),
                     x_absolute    => 10 * $em,
                   },
                 ],
       multi_select => 1,
     });
  _datasheet_init ($self, $scrolled, $datasheet);
}

sub _init_lines {
  my ($notebook, $scrolled, $pagenum) = @_;
  my $self = $notebook->get_toplevel;

  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;
  my $date_width = App::Chart::Gtk2::GUI::string_width ($treeview, '2099-99-99 ');
  my $date_width_editable = $date_width * 1.4; # diff font, and pulldown
  my $em = Gtk2::Ex::Units::em($treeview);
  my $digit_width = Gtk2::Ex::Units::digit_width ($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'id,date1,price1,date2,price2,horizontal',
                from     => 'line',
                order_by => 'id ASC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [
                  { name => 'id',
                    header_markup => __('Id'),
                    x_absolute    => 3 * $em,
                  },
                  { name          => 'date1',
                    header_markup => __('Date1'),
                    x_absolute    => $date_width_editable,
                    validation    => \&validate_date,
                    # renderer      => 'date',
                  },
                  { name          => 'price1',
                    header_markup => __('Price1'),
                    x_absolute    => 15 * $digit_width,
                    validation    => \&validate_number,
                  },
                  { name          => 'date2',
                    header_markup => __('Date2'),
                    x_absolute    => $date_width_editable,
                    validation    => \&validate_date,
                    # renderer      => 'date',
                  },
                  { name          => 'price2',
                    header_markup => __('Price2'),
                    x_absolute    => 15 * $digit_width,
                    validation    => \&validate_number,
                  },
                  { name          => 'horizontal',
                    header_markup => __('Horizontal'),
                    # validation    => \&validate_boolean,
                  },
                 ],
     });
  _datasheet_init ($self, $scrolled, $datasheet);
  $scrolled->{'insert_defaults'} = \&_lines_insert_defaults;
}
sub _lines_insert_defaults {
  my ($self, $pagewidget) = @_;
  my $datasheet = $pagewidget->{'datasheet'};
  my $num = $datasheet->{'column_name_to_number_mapping'};
  #### $num
  my $date = $self->default_date;
  return ($num->{'date1'},  $date,
          $num->{'price1'}, 0,
          $num->{'date2'},  $date,
          $num->{'price2'}, 1);
}

sub _init_alerts {
  my ($notebook, $scrolled, $pagenum) = @_;
  my $self = $notebook->get_toplevel;

  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = Gtk2::TreeView->new;
  $scrolled->add ($treeview);

  require App::Chart::DBI;
  my $dbh = App::Chart::DBI->instance;
  my $em = Gtk2::Ex::Units::em($treeview);
  my $digit_width = Gtk2::Ex::Units::digit_width ($self);

  my $datasheet = Gtk2::Ex::Datasheet::DBI->new
    ({ dbh => $dbh,
       sql => { select   => 'id,price,above',
                from     => 'alert',
                order_by => 'id ASC',
                where    => 'symbol=?',
                bind_values => [ '' ],
              },
       treeview => $treeview,
       fields => [
                  { name => 'id',
                    header_markup => __('Id'),
                    x_absolute    => 3 * $em,
                  },
                  { name          => 'price1',
                    header_markup => __('Price1'),
                    x_absolute    => 15 * $digit_width,
                    validation    => \&validate_number,
                  },
                  { name          => 'above',
                    header_markup => __('Above'),
                    # validation    => \&validate_boolean,
                  },
                 ],
     });

  _datasheet_init ($self, $scrolled, $datasheet);
}

sub _datasheet_init {
  my ($self, $pagewidget, $datasheet) = @_;

  my $scrolled = $pagewidget;
  if ($pagewidget->isa ('Gtk2::VBox')) {
    ($scrolled) = $pagewidget->get_children;
    if ($datasheet->{'read_only'}) {
      $pagewidget->pack_start (Gtk2::Label->new(__('*** Read only ***')),
                               0,0,0);
    }
  }

  $pagewidget->{'dirty'} = 1;
  $pagewidget->{'datasheet'} = $datasheet;
  push @{$self->{'datasheets'}}, $datasheet;

  my $treeview = $scrolled->get_child;
  foreach my $column ($treeview->get_columns) {
    $column->set (resizable => 1);
    $column->set_sizing ('fixed');
  }
  $treeview->set_fixed_height_mode (1);

  $pagewidget->show_all;
  _refresh_page ($pagewidget);
}

sub _init_weblinks {
  my ($notebook, $scrolled, $pagenum) = @_;

  $scrolled->set (hscrollbar_policy => 'automatic');

  my $treeview = Gtk2::TreeView->new;
  $treeview->set (tooltip_column => 2);
  $treeview->signal_connect (row_activated => \&_do_weblink_row_activate);
  $treeview->signal_connect (button_press_event => \&_do_weblink_button_press);
  $scrolled->add ($treeview);

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

sub _do_weblink_menu_copy {
  my ($item) = @_;
  my $clipboard = Gtk2::Clipboard->get_for_display
    ($item->get_display, Gtk2::Gdk::Atom->new('PRIMARY'));
  $clipboard->set_text ($item->{'url'});
}

sub set_symbol {
  my ($self, $symbol) = @_;
  if (! defined $symbol) { $symbol = ''; }
  if ($symbol eq $self->{'symbol'}) { return; }

  if ($symbol) {
    $self->set_title (__x('Chart: RawDialog: {symbol}',
                          symbol => $symbol));
  } else {
    $self->set_title (__('Chart: RawDialog'));
  }
  $self->{'symbol'} = $symbol;  # per default GET_PROPERTY
  $self->{'entry'}->set_text ($symbol);
  $self->refresh;
  $self->notify ('symbol');
}

sub SET_PROPERTY {
  my ($self, $pspec, $newval) = @_;
  my $pname = $pspec->get_name;
  if ($pspec->get_name eq 'symbol') {
    $self->set_symbol ($newval);
  } else {
    $self->{$pname} = $newval;   # per default GET_PROPERTY
  }
}

# 'notify::page' signal on the Gtk2::Notebook
sub _do_notebook_page {
  my ($notebook) = @_;
  my $self = $notebook->get_toplevel;
  my $pagenum = $notebook->get_current_page;
  my $pagewidget = $notebook->get_nth_page ($pagenum);

  $self->set_response_sensitive (RESPONSE_APPLY,  $pagewidget->{'datasheet'});
  $self->set_response_sensitive (RESPONSE_UNDO,   $pagewidget->{'datasheet'});
  $self->set_response_sensitive (RESPONSE_DELETE, $pagewidget->{'datasheet'});
  $self->set_response_sensitive (RESPONSE_INSERT, $pagewidget->{'insert_defaults'});

  _refresh_page ($self, $pagewidget);
}

sub _refresh_page {
  my ($self, $pagewidget) = @_;
  ### _refresh_page(): $pagewidget->{'dirty'}
  ### for: $self->{'symbol'}

  if ($pagewidget->{'dirty'}) {
    Gtk2::Ex::WidgetCursor->busy;
    $pagewidget->{'dirty'} = 0;
    my $symbol = $self->{'symbol'};
    if (my $datasheet = $pagewidget->{'datasheet'}) {
      ### datasheet query
      $datasheet->query ({bind_values => [$symbol]}, 0);

    } elsif (my $seriestreeview = $pagewidget->{'seriestreeview'}) {
      my $series;
      if ($symbol) {
        require App::Chart::Series::Database;
        $series = App::Chart::Series::Database->new ($symbol);
      }
      $seriestreeview->set (series => $series);

    } elsif (my $rawlatest = $pagewidget->{'rawlatest'}) {
      $rawlatest->set (symbol => $symbol);

    } elsif (my $rawinfo = $pagewidget->{'rawinfo'}) {
      $rawinfo->set (symbol => $symbol);

    } elsif (my $store = $pagewidget->{'weblinks_store'}) {
      require App::Chart::Weblink;
      my @weblinks = App::Chart::Weblink->links_for_symbol ($symbol);
      ### weblinks for: $symbol, scalar(@weblinks)
      $store->clear;
      foreach my $weblink (@weblinks) {
        $store->set ($store->append,
                     0 => mnemonic_to_markup ($weblink->name),
                     1 => $weblink->url ($symbol),
                     2 => __('Double click to open this URL in a browser'));
      }
    } else {
      die 'Oops, unknown raw refresh';
    }
  }
}

sub refresh {
  my ($self) = @_;
  ### RawDialog refresh()
  my $notebook = $self->{'notebook'};
  $notebook->foreach (sub {
                        my ($scrolled) = @_;
                        $scrolled->{'dirty'} = 1;
                      });
  _do_notebook_page ($notebook); # redraw current page
}

# 'response' signal on ourselves
sub _do_response {
  my ($self, $response) = @_;

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

  } elsif ($response eq RESPONSE_INSERT) {
    my $notebook = $self->{'notebook'};
    my $pagenum = $notebook->get_current_page;
    my $pagewidget = $notebook->get_nth_page ($pagenum);
    if ((my $datasheet = $pagewidget->{'datasheet'})
        && (my $defaults_func = $pagewidget->{'insert_defaults'})) {
      $datasheet->insert ($defaults_func->($self, $pagewidget));
    }

  } elsif ($response eq RESPONSE_DELETE) {



( run in 0.611 second using v1.01-cache-2.11-cpan-2398b32b56e )