// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I // base class for interaction modes of MIDAS #ifndef SMMODEH #define SMMODEH #include #include #include #include #include #include #include #include #include class operating_mode; extern operating_mode* mode; const int N_PLOT_MODES = 11; enum { UNBINNED_SPECTRUM = 0, BINNED_SPECTRUM, RAWPLOT, UNBINNED_TOMPLOT, BINNED_TOMPLOT, GS2_LOW_RES, GS2_HIGH_RES }; const int MAX_SQUARE_SIZE = 256; const timeclass one_day(0, 1, 0, 0, 0), one_minute(0, 0, 0, 1); union timeint { timeclass* t; int i; timeint(timeclass& T) { t = &T; } timeint(int I) { i = I; } }; // The following is necessary because compilers disagree on whether // explicit scope qualifiers are necessary and even permitted for // protected functions. GNU C++ does it wrongly. #ifdef MSDOS #define OPMODE &operating_mode:: #endif #ifdef SUN #define OPMODE #endif // on VM machines, there is no problem allocating as much space as we // are likely to need on the stack. This is not true for DOS, where // the large amount of stack space used by the array data_array in // the routine _scale will cause a very rapid crash. Consequently, we // define a class that works on the heap and emulates a 4D array of // short ints. /* class fourshort { int16** sip; int16 a, b, c, d; int _start_channel, _end_channel; public: fourshort(const int, const int, const int, const int, const int, const int); ~fourshort(void); inline operator int(void) { return (sip ? 1 : 0); } int16& datum(const int, const int, const int, const int); inline int actual_start_channel(void) { return _start_channel; } inline int actual_end_channel(void) { return _end_channel; } }; */ class operating_mode { #ifdef MSWINDOWS friend class midas_window; #endif protected: enum { fixed = 0, variable, jpl_phiex, pds_phiex, pds_browse, pds_bbrowse, pds }; BIG_ARRAY(binned_edr) Binned_record; boolean To_file, Autoscale_tomplot, Next_called_implicitly; boolean Valid_data[256]; boolean * Is_binned; volatile boolean Cancelled; data_file* Edr_f; float Version; float Step[201][2]; GMDR Gmdr; high_rate_frame* High_rate_frame_p; int Brightness, Current_pra_mode, Current_sc_mode, Duration, End_channel, Filesize, File_record_length, File_type, Gs2_n_data, Gs2_n_strips, High_ignore_value, High_recall_value, High_res_channel, Low_ignore_value, Low_recall_value, N_tomplot_channels, Pol_contrast, Pol_intensity_threshold, Previous_edr_record_nr, Records_processed, Saturation, Spacecraft, Start_channel, Start_tomplot_channel, Tplotmode, Upper_square_value; int Pra_submodes_present[16], Sc_modes_present[N_SC_MODES]; uint16 Sq_width, Sq_height; uint16 Background[201][2], Midground[201][2], Tomplot_dn_range[201][2]; uint32 Filesize_in_bytes; timeclass End_time, Minimum_time, Maximum_time, Start_time; pds_phiex_frame* Gs2_frame_pds; phiex_frame* Gs2_frame_jpl; phiex_position Current_phiex_position, Last_phiex_position; scet_type Gs2_scet; set Binned_modes, Spectral_modes, Pds_browse_modes, Low_rate_modes, High_rate_modes, Pra_modes_present; set Equivalent_sc_modes[N_SC_MODES]; DREstring Comment, Current_file_name, Printer_name; surface* Pad, *Screen_device, *Hardcopy_device; struct time_index { public: int n; timeclass t; time_index(void) : n(0), t(0) { } }; // A bug in gcc requires us _not_ to use a macro call to a template // class when the type being passed is not a builtin or simple typedef. // This appears to result from the fact that the compiler does not // conform to r.7.1.3. #ifdef __GNUC__ big_array Sorted_list; #else BIG_ARRAY(time_index) Sorted_list; #endif void _bin(void); void _bin(const int rec_nr); void _comment(DREstring&); void _execute_low_rate_plot_command(void); int _first_after(const timeclass &); int _last_before(const timeclass &); // logical to physical mapping inline int _ltp(const int k) { return Sorted_list[k].n; } DREstring _pra_modes_string(void); DREstring _sc_modes_string(void); DREstring _time_range_string(void); timeclass _time_of_record(const int logical_rec_nr); virtual boolean _open(DREstring&); void _check_pad(DREstring&); boolean _file_not_open(void); boolean _modes_in_file(void); void _plot_full_frame(void); void _plot_gs2_hi_res(const phiex_position&, const int, const int); virtual void _pol_contrast(void) { } virtual void _pol_threshold(void) { } virtual void _popup(DREstring& title, DREstring& msg) { display_status(title + ": " + msg); } int _pra_mode_fm_submode(int); int _rawplot(const timeint&, const timeint&); int _scale(timeclass&, timeclass&); void _title(DREstring&); int _tomplot(const timeint&, const timeint&); boolean _valid(const uint16); void _x_axis(void); void _y_axis(void); virtual void verbose(DREstring&) = 0; typedef int (operating_mode::*PMFTITI)(const timeint&, const timeint&); PMFTITI _plot_function; void _print(void) { Pad->print(); } inline void _show_pra_modes(void) { if (!_file_not_open()) then _popup((DREstring)"PRA MODES", _pra_modes_string()); } inline void _show_sc_modes(void) { if (!_file_not_open()) then _popup((DREstring)"SC MODES", _sc_modes_string()); } inline void _show_time_range(void) { if (!_file_not_open()) then _popup((DREstring)"TIME RANGE", _time_range_string()); } public: operating_mode(void); virtual ~operating_mode(void); // the commands -- In a fully C++ environment, these would all be virtual. // Unfortunately, in the current release of the C++ spec, one cannot // find the absolute address of a virtual function. In the sunview_mode // class such addresses have to be passed to the (C) notifier. Therefore // we simply override these functions in derived classes. It is inelegant, // but the only way to get the job done. void initialise(void); void first(void); void last(void); int next(void); void plotall(void); void plotrmdr(void); void print(void); int prior(void); void replot(void); // other functions virtual void clear_status(void) = 0; int display_spectral(const timeint&, const timeint&); virtual void display_status(DREstring&) = 0; int do_plot(const timeint&, const timeint&); virtual void error(DREstring&) = 0; virtual void busy(DREstring& msg); virtual void unbusy(void) { display_status((DREstring)""); } virtual void information(const char* cp) { ::information(cp); } int file_percentage(void) const; virtual void display_progress(const int n) { display_status(DREstring10(n) + (DREstring)"%"); } virtual void undisplay_progress(void) { display_status((DREstring)""); } }; #endif