Files correlati : ba0.exe Ricompilazione Demo : [ ] Commento : 0000959: Icone lancio programmi Invece di utlizzare la stessa icona (quella di campo enterprise) per tutti i pgm è possibile utlizzarne una diversa in base alla tipologia (esempio Gestione, eleaborazione stampa). Allego tre icone, libreria icone (per estrarre le icone dalla librerira si può usare e-ICON). git-svn-id: svn://10.65.10.50/trunk@17593 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1235 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1235 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <xinclude.h>
 | |
| 
 | |
| #include <applicat.h>
 | |
| #include <automask.h>
 | |
| #include <colors.h>
 | |
| #include <defmask.h>
 | |
| #include <execp.h>
 | |
| #include <modaut.h>
 | |
| #include <odbcrset.h>
 | |
| #include <prefix.h>
 | |
| #include <printer.h>
 | |
| #include <reprint.h>
 | |
| #include <treectrl.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include "ba8300.h"
 | |
| #include "ba8301.h"
 | |
| #include <bagn003.h>
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_sheet
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TReport_sheet : public TSheet
 | |
| {
 | |
|   TReport_section& _section;
 | |
| 
 | |
| protected:
 | |
|   virtual long get_items() const { return _section.items(); }
 | |
|   virtual void get_row(long r, TToken_string& row);
 | |
| 
 | |
| public:
 | |
|   virtual KEY run();
 | |
|   int selection(int& first, int& last) const;
 | |
|   TReport_sheet(TReport_section& sec);
 | |
| };
 | |
| 
 | |
| void TReport_sheet::get_row(long r, TToken_string& row)
 | |
| {
 | |
|   const TReport_field& rf = (const TReport_field&)_section[r];
 | |
|   const TRectangle& rect = rf.get_rect();
 | |
|   row = checked(r) ? "X" : " ";
 | |
|   row.add(rf.type_name());
 | |
|   row.add(rf.id());
 | |
|   row.add(num2str(rect.top()));
 | |
|   row.add(num2str(rect.left()));
 | |
|   row.add(num2str(rect.width()));
 | |
|   row.add(num2str(rect.height()));
 | |
|   if (rf.field().not_empty())
 | |
|     row.add(rf.field());
 | |
|   else
 | |
|     row.add(rf.picture());
 | |
| }
 | |
| 
 | |
| int TReport_sheet::selection(int& first, int& last) const
 | |
| {
 | |
|   int tot = 0;
 | |
|   first = items()+1;
 | |
|   last = -1;
 | |
|   FOR_EACH_ARRAY_ITEM_BACK(_section, i, o)
 | |
|   {
 | |
|     const TReport_field& rf = *(const TReport_field*)o;
 | |
|     if (rf.selected())
 | |
|     {
 | |
|       if (i < first) first = i;
 | |
|       if (i > last) last = i;
 | |
|       tot++;
 | |
|     }
 | |
|   }
 | |
|   return tot;
 | |
| }
 | |
| 
 | |
| KEY TReport_sheet::run()
 | |
| {
 | |
|   int first = -1;
 | |
|   uncheck(-1);
 | |
|   FOR_EACH_ARRAY_ITEM(_section, i, o)
 | |
|   {
 | |
|     const TReport_field& rf = *(const TReport_field*)o;
 | |
|     if (rf.selected())
 | |
|     {
 | |
|       check(i);
 | |
|       if (first < 0)
 | |
|         first = i;
 | |
|     }
 | |
|   }
 | |
|   if (first > 0)
 | |
|     select(first);
 | |
|   const KEY k = TSheet::run();
 | |
|   if (k != K_ESC)
 | |
|   {
 | |
|     FOR_EACH_ARRAY_ITEM(_section, i, o)
 | |
|     {
 | |
|       TReport_field& rf = *(TReport_field*)o;
 | |
|       rf.select(checked(i));
 | |
|     }
 | |
|   }
 | |
|   return k;
 | |
| }
 | |
| 
 | |
| TReport_sheet::TReport_sheet(TReport_section& sec)
 | |
|              : TSheet(-1, -1, -2, -4, TR("Campi"), 
 | |
|                       HR("@1|Tipo@10|ID@4R|Riga@R|Col.@R|Larg.@R|Alt.@R|Testo@50"), 0xE),
 | |
|                _section(sec)
 | |
| { }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TSection_properties_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TSection_properties_mask : public TReport_base_mask
 | |
| {
 | |
| protected:
 | |
|   virtual void update();
 | |
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   void set_num(short id, long num);
 | |
|   short get_num(short id) const;
 | |
| 
 | |
|   void vedo_non_vedo();
 | |
|   void set_section(const TReport_section& rs);
 | |
| 
 | |
| public:
 | |
|   void get_section(TReport_section& rs) const;
 | |
|   TSection_properties_mask(TReport_section& rs);
 | |
| };
 | |
| 
 | |
| void TSection_properties_mask::update()
 | |
| {
 | |
|   for (int i = 0; i < 2; i++)
 | |
|   {
 | |
|     TMask_field& fld = field(i == 0 ? F_FGCOLOR : F_BGCOLOR);
 | |
|     if (fld.active() && fld.parent() == curr_win())
 | |
|     {
 | |
|       RCT rctfld; fld.get_rect(rctfld); 
 | |
|       const int x = rctfld.right / CHARX + 1;
 | |
|       const int y = rctfld.top / ROWY + 1;
 | |
|       RCT& rct = resize_rect(x, y, -3, 1, W_PLAIN, fld.parent());
 | |
|       rct.top =  rctfld.top; rct.bottom = rctfld.bottom;
 | |
|       xi_draw_3d_rect((XinWindow)fld.parent(), (XinRect*)&rct, TRUE, 2, MASK_LIGHT_COLOR, 
 | |
|         i == 0 ? _fgcolor : _bgcolor, MASK_DARK_COLOR);
 | |
|     }
 | |
|   }
 | |
|   TReport_base_mask::update();
 | |
| }
 | |
| 
 | |
| void TSection_properties_mask::set_num(short id, long num)
 | |
| {
 | |
|   set(id, num2str(num));
 | |
| }
 | |
| 
 | |
| short TSection_properties_mask::get_num(short id) const
 | |
| {
 | |
|   return str2num(get(id));
 | |
| }
 | |
| 
 | |
| void TSection_properties_mask::vedo_non_vedo()
 | |
| {
 | |
|   const char type = get(F_TYPE)[0];
 | |
|   const int level = get_int(F_LEVEL);
 | |
|   const bool can_pos = (type != 'H' && level == 0) || (type == 'F' && level == 1);
 | |
|   show(F_X, can_pos); show(F_Y, can_pos);
 | |
|   show(F_CONDITION, level > 0 && level < 10);
 | |
|   show(F_GROUP_BY, type == 'H' && level > 1 && level < 10);
 | |
|   show(F_SQL, type == 'B' && level > 10);
 | |
| 
 | |
|   show(F_PAGE_BREAK, level > 0); // Non posso forzare il salto pagina nelle sezioni di pagina
 | |
|   show(F_KEEP_WITH_NEXT, level > 1 && type == 'H');
 | |
|   show(F_CAN_BREAK, level > 0 && type == 'B');
 | |
|   show(F_HIDE_IF_NEEDED, level == 0 && type != 'B');
 | |
|   show(F_REPEAT, level > 1 && type == 'H');
 | |
| 
 | |
|   bool can_delete = false;
 | |
|   if (level > 1)
 | |
|   {
 | |
|     if (level > 10)
 | |
|       can_delete = _report.find_section('B', level+1) == NULL;
 | |
|     else
 | |
|       can_delete = true;
 | |
|   }
 | |
|   enable(DLG_DELREC, can_delete);
 | |
| }
 | |
| 
 | |
| bool TSection_properties_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   switch(o.dlg())
 | |
|   {
 | |
|   case F_TYPE:
 | |
|   case F_LEVEL:
 | |
|     if (e == fe_modify)
 | |
|       vedo_non_vedo();
 | |
|     break;
 | |
|   case F_DX:
 | |
|   case F_DY:
 | |
|     if (e == fe_modify)
 | |
|     {
 | |
|       const int num = get_num(o.dlg());
 | |
|       set_num(o.dlg(), num); // Reformat
 | |
|     }
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return TReport_base_mask::on_field_event(o, e, jolly);
 | |
| }
 | |
| 
 | |
| void TSection_properties_mask::set_section(const TReport_section& rs)
 | |
| {
 | |
|   char s[2] = { rs.type(), '\0' };
 | |
|   set(F_TYPE, s);
 | |
|   set(F_LEVEL, rs.level());
 | |
| 
 | |
|   vedo_non_vedo();
 | |
| 
 | |
|   if (field(F_X).active())
 | |
|   {
 | |
|     set_num(F_X, rs.pos().x);  
 | |
|     set_num(F_Y, rs.pos().y);
 | |
|   }
 | |
|   set_num(F_DX, rs.width());  
 | |
|   set_num(F_DY, rs.height());
 | |
|   set(F_CONDITION, rs.condition());
 | |
|   set(F_GROUP_BY, rs.grouped_by());
 | |
| 
 | |
|   if (field(F_SQL).shown())
 | |
|   {
 | |
|     const TRecordset* recset = rs.recordset();
 | |
|     if (recset != NULL)
 | |
|       set(F_SQL, recset->query_text());
 | |
|   }
 | |
| 
 | |
|   set(F_HIDE_IF_NEEDED, rs.hidden_if_needed());
 | |
|   set(F_HIDDEN, rs.hidden());
 | |
|   set(F_PAGE_BREAK, rs.page_break());
 | |
|   set(F_KEEP_WITH_NEXT, rs.keep_with_next());
 | |
|   set(F_CAN_BREAK, rs.can_be_broken());
 | |
|   set(F_REPEAT, rs.repeat_on_page());
 | |
|   set(F_DISABLED, rs.deactivated());
 | |
| 
 | |
|   set(F_BORDER, rs.border());
 | |
|   set(F_PATTERN, rs.pattern());
 | |
|   set_num(F_RADIUS, rs.radius());
 | |
|   _fgcolor = rs.fore_color();
 | |
|   _bgcolor = rs.back_color();
 | |
|   set_font_info(rs.font());
 | |
| 
 | |
|   set(F_PRESCRIPT, rs.prescript());
 | |
|   set(F_POSTSCRIPT, rs.postscript());
 | |
| 
 | |
| }
 | |
| 
 | |
| void TSection_properties_mask::get_section(TReport_section& rs) const
 | |
| {
 | |
|   if (field(F_X).active())
 | |
|   {
 | |
|     const TPoint pos(get_num(F_X), get_num(F_Y));
 | |
|     rs.set_pos(pos);
 | |
|   }
 | |
|   rs.set_width(get_num(F_DX));
 | |
|   rs.set_height(get_num(F_DY));
 | |
|   rs.show(!get_bool(F_HIDDEN));
 | |
|   rs.activate(!get_bool(F_DISABLED));
 | |
| 
 | |
|   rs.set_condition(get(F_CONDITION));
 | |
|   rs.group_by(get(F_GROUP_BY));
 | |
|   if (field(F_SQL).shown())
 | |
|     rs.set_recordset(get(F_SQL));
 | |
|   rs.hide_if_needed(get_bool(F_HIDE_IF_NEEDED));
 | |
|   rs.force_page_break(get_bool(F_PAGE_BREAK));
 | |
|   rs.keep_with_next(get_bool(F_KEEP_WITH_NEXT));
 | |
|   rs.can_break(get_bool(F_CAN_BREAK));
 | |
|   rs.set_repeat_on_page(get_bool(F_REPEAT));
 | |
| 
 | |
|   rs.set_pattern((PAT_STYLE)get_int(F_PATTERN));
 | |
|   rs.set_border(get_int(F_BORDER));
 | |
|   rs.set_radius(get_num(F_RADIUS));
 | |
|   rs.set_fore_color(_fgcolor);
 | |
|   rs.set_back_color(_bgcolor);
 | |
| 
 | |
|   TReport_font f;
 | |
|   if (get_font_info(f))
 | |
|     rs.set_font(f);
 | |
| 
 | |
|   rs.set_prescript(get(F_PRESCRIPT));
 | |
|   rs.set_postscript(get(F_POSTSCRIPT));
 | |
| }
 | |
| 
 | |
| TSection_properties_mask::TSection_properties_mask(TReport_section& rs) 
 | |
|                         : TReport_base_mask("ba8300c", rs.report())
 | |
| { 
 | |
|   set_section(rs);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_properties_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TReport_properties_mask : public TReport_base_mask
 | |
| {
 | |
| protected:
 | |
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   void set_report(const TReport& r);
 | |
| 
 | |
| public:
 | |
|   void get_report(TReport& r) const;
 | |
|   TReport_properties_mask(TReport& rep) : TReport_base_mask("ba8300d", rep) { set_report(rep); }
 | |
| };
 | |
| 
 | |
| bool TReport_properties_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   return TReport_base_mask::on_field_event(o, e, jolly);
 | |
| }
 | |
| 
 | |
| void TReport_properties_mask::set_report(const TReport& r)
 | |
| {
 | |
|   set(F_FONT_AUTO, r.use_printer_font());
 | |
|   set(F_SAVE_PRINTER, r.save_last_printer());
 | |
|   set(F_ORIENTATION, r.orientation());
 | |
|   set(F_DX, r.user_defined_cpi());
 | |
| 
 | |
|   set(F_DY, r.lpi());
 | |
|   set_font_info(r.font());
 | |
|   set(F_CLASS, r.get_class());
 | |
|   set(F_COMMAND, r.command_line());
 | |
|   set(F_INCLUDE, ((TReport&)r).get_libraries());
 | |
|   set(F_PRESCRIPT, r.prescript());
 | |
|   set(F_POSTSCRIPT, r.postscript());
 | |
|   set(F_PAGE_SPLIT, r.page_split_allowed());
 | |
|   set(F_PAGE_MERGE, r.page_merge_allowed());
 | |
| 
 | |
|   sfield(F_PARAMS).rows_array() = r.params();
 | |
|   sfield(F_LINK).rows_array() = r.allegates();
 | |
| }
 | |
| 
 | |
| void TReport_properties_mask::get_report(TReport& r) const
 | |
| {
 | |
|   const bool af = get_bool(F_FONT_AUTO);
 | |
|   r.set_use_printer_font(af);
 | |
|   if (!af)
 | |
|   {
 | |
|     r.set_cpi(get_int(F_DX));
 | |
|     r.set_lpi(get_int(F_DY));
 | |
|     TReport_font f;
 | |
|     if (get_font_info(f))
 | |
|       r.set_font(f);
 | |
|   }
 | |
|   r.set_orientation(get_int(F_ORIENTATION));
 | |
|   r.set_save_last_printer(get_bool(F_SAVE_PRINTER));
 | |
|   r.set_class(get(F_CLASS));
 | |
|   r.set_command_line(get(F_COMMAND));
 | |
| 
 | |
|   
 | |
|   const TString& oldlib = r.get_libraries();
 | |
|   if (oldlib != get(F_INCLUDE))
 | |
|   {
 | |
|     r.set_libraries(get(F_INCLUDE));
 | |
|     r.include_libraries(); // reload
 | |
|   }
 | |
|   r.set_prescript(get(F_PRESCRIPT));
 | |
|   r.set_postscript(get(F_POSTSCRIPT));
 | |
| 
 | |
|   r.set_params(sfield(F_PARAMS).rows_array());
 | |
|   r.set_allegates(sfield(F_LINK).rows_array());
 | |
| 
 | |
|   r.allow_page_split(get_bool(F_PAGE_SPLIT));
 | |
|   r.allow_page_merge(get_bool(F_PAGE_MERGE));
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_query_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TReport_query_mask : public TAutomask
 | |
| {
 | |
| protected:
 | |
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   bool select_query();
 | |
| 
 | |
| public:
 | |
|   TReport_query_mask();
 | |
| };
 | |
| 
 | |
| bool TReport_query_mask::select_query()
 | |
| {
 | |
|   TFilename path; 
 | |
|   bool ok = select_custom_file(path, "qry");
 | |
|   if (ok)
 | |
|   {
 | |
|     TXmlItem item; 
 | |
|     item.Load(path);
 | |
| 
 | |
|     const TXmlItem* sql = item.FindFirst("sql");
 | |
|     ok = sql != NULL;
 | |
|     if (ok)
 | |
|     {
 | |
|       TString str; sql->GetEnclosedText(str);
 | |
|       set(F_SQL, str, true);
 | |
|     }
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TReport_query_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   switch (o.dlg())
 | |
|   {
 | |
|   case F_SQL:
 | |
|     if (e == fe_init || e == fe_modify)
 | |
|       enable(F_SHOW_QRY, !o.empty());
 | |
|     break;
 | |
|   case F_NEW_QRY:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       TExternal_app q("ba8 -1");
 | |
|       q.run();
 | |
|     }
 | |
|     break;
 | |
|   case F_IMPORT_QRY:
 | |
|     if (e == fe_button)
 | |
|       select_query();
 | |
|     break;
 | |
|   case F_SHOW_QRY:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       const TString& sql = get(F_SQL);
 | |
|       TRecordset* rex = create_recordset(sql);
 | |
|       if (rex != NULL)
 | |
|       {
 | |
|         if (rex->items() > 0)
 | |
|         {
 | |
|           TRecordset_sheet sht(*rex);
 | |
|           sht.run();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           if (sql.find("SELECT ") >= 0 || sql.starts_with("USE "))
 | |
|             warning_box(TR("Nessuna riga risultato"));
 | |
|         }
 | |
|         delete rex;
 | |
|       }
 | |
|     }
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| TReport_query_mask::TReport_query_mask() : TAutomask("ba8300f")
 | |
| {
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TReport_mask : public TAutomask
 | |
| {
 | |
|   TReport _report;
 | |
|   TReport_section* _curr_section;
 | |
| 
 | |
|   TReport_tree _tree;
 | |
|   TFilename _curr_report;
 | |
|   bool _is_dirty;
 | |
| 
 | |
| protected:
 | |
|   virtual TMask_field* parse_field(TScanner& scanner);
 | |
|   virtual void notify_focus_field(short id);
 | |
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   virtual void handler(WINDOW win, EVENT* ep);
 | |
| 
 | |
| protected:
 | |
|   bool select_report();
 | |
|   void select_section(bool rebuild_tree = false);
 | |
|   void update_report(bool rebuild_tree = false) const;
 | |
| 
 | |
|   TReport_section& curr_section();
 | |
|   void add_field();
 | |
|   void edit_field(TReport_field& rf);
 | |
|   void fields_properties();
 | |
|   bool add_section();
 | |
|   void section_properties();
 | |
|   void report_properties();
 | |
|   void report_query();
 | |
|   bool enumerate_bodies(int level, TToken_string& code, TToken_string& desc) const;
 | |
| 
 | |
|   bool get_rep_path(TFilename& path) const;
 | |
|   void set_num_attr(TXmlItem& item, const char* attr, short num, short def = 0) const;
 | |
|   void set_col_attr(TXmlItem& item, const char* attr, COLOR col, COLOR def) const;
 | |
|   WINDOW dlg2win(short id) const;
 | |
|   void add_pane(short id, const char* title, int hook);
 | |
|   void update_toolbar(); // Aggiorna dis/abilitazioni dei bottoni
 | |
| 
 | |
| public:
 | |
|   void on_print();
 | |
|   void on_pdf();
 | |
|   bool save_report();
 | |
|   bool save_if_needed();
 | |
|   void global_reset();
 | |
|   bool delete_report();
 | |
|   bool load_report();
 | |
| 
 | |
|   TReport_tree& sections() { return _tree; }
 | |
|   TReport_mask();
 | |
| };
 | |
| 
 | |
| TMask_field* TReport_mask::parse_field(TScanner& scanner)
 | |
| {
 | |
|   const TString& tok = scanner.token();
 | |
|   if (tok.starts_with("RE"))
 | |
|     return new TReport_drawer(this);
 | |
|   if (tok.starts_with("OU"))
 | |
|     return new TOutlook_field(this);
 | |
|   return TAutomask::parse_field(scanner);
 | |
| }
 | |
| 
 | |
| bool TReport_mask::get_rep_path(TFilename& path) const
 | |
| {
 | |
|   const TString& name = get(F_CODICE);
 | |
|   const bool ok = name.full();
 | |
|   if (ok)
 | |
|   {
 | |
|     path = name;
 | |
|     if (!path.is_absolute_path())
 | |
|     {
 | |
|       path = firm2dir(-1);
 | |
|       path.add("custom");
 | |
|       if (!path.exist())
 | |
|         xvt_fsys_mkdir(path);
 | |
|       path.add(name);
 | |
|       path.ext("rep");
 | |
|       if (!path.exist() && is_power_station())
 | |
|         path = name;
 | |
|     }
 | |
|     path.ext("rep");
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TReport_mask::save_report()
 | |
| {
 | |
|   bool ok = _curr_report.full();
 | |
|   if (!ok)
 | |
|     ok = get_rep_path(_curr_report);
 | |
|   if (!ok)
 | |
|     return field(F_CODICE).on_key(K_ENTER); // Segnala errore
 | |
|   _report.set_description(get(F_DESCR));
 | |
|   if (is_power_station())
 | |
|   {
 | |
|     FILE_SPEC fsp; 
 | |
|     xvt_fsys_convert_str_to_fspec(_curr_report, &fsp);
 | |
|     ok = xvt_dm_post_file_save(&fsp, TR("Nome report")) == FL_OK;
 | |
|     if (ok)
 | |
|       xvt_fsys_convert_fspec_to_str(&fsp, _curr_report.get_buffer(), _curr_report.size());
 | |
|   }
 | |
|   if (ok)
 | |
|   {
 | |
|     ok = _report.save(_curr_report);
 | |
|     if (ok)
 | |
|       _is_dirty = false;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TReport_mask::save_if_needed()
 | |
| {
 | |
|   if (!_is_dirty)
 | |
|     return true;
 | |
|   if (!yesno_box(TR("Si desidera registrare il report?")))
 | |
|     return false;
 | |
|   return save_report();
 | |
| }
 | |
| 
 | |
| void TReport_mask::global_reset()
 | |
| {
 | |
|   _report.destroy();
 | |
|   reset();
 | |
|   update_report();
 | |
|   update_toolbar();
 | |
| }
 | |
| 
 | |
| bool TReport_mask::load_report()
 | |
| {
 | |
|   TFilename path; get_rep_path(path);
 | |
|   bool ok = path.exist();
 | |
|   if (ok)
 | |
|   {
 | |
|     _curr_report = path;
 | |
|     global_reset();
 | |
|     ok = _report.load(path);
 | |
|     if (ok)
 | |
|     {
 | |
|       path = path.name(); path.ext("");
 | |
|       set(F_CODICE, path);
 | |
| 
 | |
|       set(F_DESCR, _report.description());
 | |
|       _is_dirty = false;
 | |
| 
 | |
|       TTree_field& sections = tfield(F_SECTIONS);
 | |
|       _tree.goto_node('B', 1);
 | |
|       sections.select_current();
 | |
|       select_section(true);
 | |
|       xvt_notebk_set_tab_title(notebook(), 0, path); // Mette il titolo nel tab button
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TReport_mask::delete_report()
 | |
| {
 | |
|   TFilename path; get_rep_path(path);
 | |
|   const bool ok = path.exist() && yesno_box(FR("Si desidera eliminare il file '%s'"), (const char*)path);
 | |
|   if (ok)
 | |
|   {
 | |
|     ::remove(path);
 | |
|     global_reset();
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| void TReport_mask::on_print()
 | |
| {
 | |
|   const TString& app = _report.command_line();
 | |
|   if (app.full() && yesno_box(FR("Si desidera stampare utilizzando '%s'"), (const char*)app))
 | |
|   {
 | |
|     TExternal_app a(app);
 | |
|     a.run();
 | |
|   }
 | |
|   else
 | |
|   {
 | |
| #ifdef DBG
 | |
|     TFilename tmp; tmp.tempdir(); 
 | |
|     tmp.add("ba8300.txt");
 | |
|     TReport_book book(tmp);
 | |
| #else
 | |
|     TReport_book book;
 | |
| #endif
 | |
|     book.add(_report);
 | |
|     book.print_or_preview();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TReport_mask::on_pdf()
 | |
| {
 | |
|   TReport_book book;
 | |
|   book.add(_report);
 | |
|   TFilename tmp; tmp.tempdir(); 
 | |
|   tmp.add(_report.filename().name());
 | |
|   tmp.ext("pdf");
 | |
|   book.export_pdf(tmp);
 | |
|   xvt_sys_goto_url(tmp, "open");
 | |
| }
 | |
| 
 | |
| TReport_section& TReport_mask::curr_section()
 | |
| {
 | |
|   return *_curr_section;
 | |
| }
 | |
| 
 | |
| void TReport_mask::select_section(bool rebuild)
 | |
| {
 | |
|   TTree_field& tf = tfield(F_SECTIONS); 
 | |
|   tf.select_current();
 | |
|   _curr_section = &_tree.curr_section();
 | |
|   
 | |
|   TReport_drawer& rd = (TReport_drawer&)field(F_REPORT); 
 | |
|   rd.set_report_section(*_curr_section);
 | |
| 
 | |
|   const char type = _curr_section->type();
 | |
|   const int level = _curr_section->level();
 | |
| 
 | |
|   char htype = 'H';
 | |
|   int hlevel = level;
 | |
| 
 | |
|   switch (type)
 | |
|   {
 | |
|   case 'H':
 | |
|     {
 | |
|       if (level <= 1)
 | |
|         hlevel = 1-level;
 | |
|       else
 | |
|       {
 | |
|         if (level < 10)
 | |
|         {
 | |
|           if (_report.find_section('H', level-1))
 | |
|             hlevel = level-1;
 | |
|         }
 | |
|         else
 | |
|           htype = 'B';
 | |
|       }
 | |
|     }
 | |
|     break;
 | |
|   case 'B':
 | |
|     if (level >= 1)
 | |
|     {
 | |
|       if (level < 10)
 | |
|       {
 | |
|         hlevel = _report.find_max_level('H');
 | |
|         if (hlevel <= 1)
 | |
|           hlevel = 0;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|       hlevel = 0;
 | |
|     break;
 | |
|   case 'F':
 | |
|     if (level > 1)
 | |
|     {
 | |
|       if (level > 10)
 | |
|         htype = 'B';
 | |
|       else
 | |
|       {
 | |
|         if (_report.find_section('F', level-1))
 | |
|           hlevel = level-1;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|       hlevel = 1-level;
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   TReport_drawer& rdh = (TReport_drawer&)field(F_REPORTH); 
 | |
|   rdh.set_report_section(_report.section(htype, hlevel));
 | |
| 
 | |
|   update_report(rebuild);
 | |
| }
 | |
| 
 | |
| void TReport_mask::update_report(bool rebuild) const
 | |
| {
 | |
|   TTree_field& tf = tfield(F_SECTIONS); 
 | |
|   if (rebuild)
 | |
|   {
 | |
|     tf.tree()->goto_root();
 | |
|     tf.win().force_update();              // Rebuild tree
 | |
|   }
 | |
|   else
 | |
|     tf.win().TWindow::force_update();     // Redraw only, do NOT rebuild
 | |
| 
 | |
|   TReport_drawer& rdh = (TReport_drawer&)field(F_REPORTH); 
 | |
|   rdh.win().force_update();
 | |
| 
 | |
|   TReport_drawer& rd = (TReport_drawer&)field(F_REPORT); 
 | |
|   rd.win().force_update();
 | |
| }
 | |
| 
 | |
| void TReport_mask::add_field()
 | |
| {
 | |
|   TReport_section& rs = curr_section();
 | |
|   TReport_field* rf = new TReport_field(&rs);
 | |
|   rf->set_type('S');
 | |
|   rf->set_pos(0, rs.compute_size().y+100);
 | |
|   TReport_field_mask m(*rf);
 | |
|   m.disable(DLG_DELREC);
 | |
|   if (m.run() == K_ENTER)
 | |
|   {
 | |
|     m.get_field(*rf);
 | |
|     rs.add(rf);
 | |
|     update_report();
 | |
|   }
 | |
|   else
 | |
|     delete rf;
 | |
| }
 | |
| 
 | |
| void TReport_mask::edit_field(TReport_field& rf)
 | |
| {
 | |
|   TReport_section& rs = rf.section();
 | |
|   TReport_field_mask m(rf);
 | |
|   const KEY key = m.run();
 | |
|   switch(key)
 | |
|   {
 | |
|     case K_ENTER: 
 | |
|       m.get_field(rf); 
 | |
|       break;
 | |
|     case K_DEL: 
 | |
|       {
 | |
|         for (int i = rs.last(); i >= 0; i--) if (rs.objptr(i) == &rf)
 | |
|         {
 | |
|           rs.destroy(i, true);
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     default: break;
 | |
|   }
 | |
|   if (key != K_ESC)
 | |
|   {
 | |
|     _is_dirty = true;
 | |
|     rs.sort();
 | |
|     update_report();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TReport_mask::fields_properties()
 | |
| {
 | |
|   TReport_section& rs = curr_section();
 | |
|   TReport_sheet sheet(rs);
 | |
| 
 | |
|   int first, last;
 | |
|   int selected = sheet.selection(first, last);
 | |
|   if (selected == 1)
 | |
|   {
 | |
|     TReport_field& rf = rs.field(first);
 | |
|     edit_field(rf);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   KEY key = K_ENTER;
 | |
|   while (key != K_ESC)
 | |
|   {
 | |
|     key = sheet.run();
 | |
|     selected = sheet.selection(first, last);
 | |
|     if (selected == 0 && (key == K_ENTER || key == K_DEL))
 | |
|     {
 | |
|       first = last = sheet.selected();
 | |
|       selected = 1;
 | |
|       sheet.check(first);
 | |
|     }
 | |
|       
 | |
|     switch (key)
 | |
|     {
 | |
|     case K_INS:
 | |
|       add_field();
 | |
|       break;
 | |
|     case K_ENTER:
 | |
|       {
 | |
|         for (int i = first; i <= last; i++) if (sheet.checked(i))
 | |
|         {
 | |
|           TReport_field& rf = rs.field(i);
 | |
|           edit_field(rf);
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     case K_DEL:
 | |
|       if (selected > 0 && yesno_box(FR("Comfermare la cancellazione di %d elementi"), selected))
 | |
|       {
 | |
|         for (int i = last; i >= first; i--) if (sheet.checked(i))
 | |
|           rs.destroy(i, true);
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|     update_report();
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TReport_mask::enumerate_bodies(int level, TToken_string& code, TToken_string& desc) const
 | |
| {
 | |
|   TReport_section* rs = _report.find_section('B', level);
 | |
|   if (rs != NULL)
 | |
|   {
 | |
|     TString str; str.format("B%d", level);
 | |
|     code.add(str);
 | |
|     describe_section('B', level, str); str.trim();
 | |
|     desc.add(str);
 | |
| 
 | |
|     enumerate_bodies(level*10+1, code, desc);  // Figlio
 | |
|     enumerate_bodies(level+1, code, desc);     // Fratello
 | |
|   }
 | |
|   return rs != NULL;
 | |
| }
 | |
| 
 | |
| bool TReport_mask::add_section()
 | |
| {
 | |
|   TMask m("ba8300e");
 | |
| 
 | |
|   TToken_string code, desc;
 | |
|   enumerate_bodies(1, code, desc);
 | |
|   TList_field& list = (TList_field&)m.field(102);
 | |
|   list.replace_items(code, desc);
 | |
| 
 | |
|   if (m.run() == K_ENTER)
 | |
|   {
 | |
|     char type = m.get(101)[0];
 | |
|     int level = 0;
 | |
| 
 | |
|     if (type == 'S')
 | |
|     {
 | |
|       type = 'B';
 | |
|       const int father = atoi(m.get(102).mid(1));
 | |
|       if (father < 100000L)
 | |
|       {
 | |
|         int i;
 | |
|         for (i = 1; i <= 9; i++)  // Cerca l'ultimo figlio del nodo padre
 | |
|         {
 | |
|           level = father*10+i;
 | |
|           if (_report.find_section(type, level) == NULL)
 | |
|             break;
 | |
|         }
 | |
|         if (i > 9)
 | |
|           level = 0;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if (type == 'H')
 | |
|       {
 | |
|         const int hl = _report.find_max_level('H');
 | |
|         const int fl = _report.find_max_level('F');
 | |
|         level = max(hl, fl) + 1;
 | |
|       }
 | |
|       else
 | |
|         level = _report.find_max_level('B')+1;
 | |
|       if (level > 9)
 | |
|         level = 0;
 | |
|     }
 | |
|     if (level > 0)
 | |
|     {
 | |
|       _curr_section = &_report.section(type, level);
 | |
|       _tree.shrink_all();
 | |
|       _tree.goto_node(type, level);
 | |
|       TTree_field& tf = tfield(F_SECTIONS);
 | |
|       tf.win().force_update();
 | |
|       tf.select_current();
 | |
|       section_properties();
 | |
|     }
 | |
|     else
 | |
|       error_box(TR("Livello non ammesso"));
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| void TReport_mask::section_properties()
 | |
| {
 | |
|   TReport_section& rs = curr_section();
 | |
|   TSection_properties_mask m(rs);
 | |
|   switch (m.run())
 | |
|   {
 | |
|   case K_ENTER: 
 | |
|     m.get_section(rs); 
 | |
|     _tree.goto_node(rs.type(), rs.level());
 | |
|     _is_dirty = true;
 | |
|     break;
 | |
|   case K_DEL: 
 | |
|     if (yesno_box(TR("Confermare l'eliminazione della sezione")))
 | |
|     {
 | |
|       const char t = rs.type();
 | |
|       const int l = rs.level();
 | |
|       rs.report().kill_section(t, l); 
 | |
|       _tree.goto_node(t, l-1);
 | |
|       _is_dirty = true;
 | |
|     }
 | |
|     break;
 | |
|   default: 
 | |
|     break;
 | |
|   }
 | |
|   if (_is_dirty)
 | |
|     select_section();
 | |
| }
 | |
| 
 | |
| void TReport_mask::report_properties()
 | |
| {
 | |
|   TReport_properties_mask m(_report);
 | |
|   if (m.run() == K_ENTER)
 | |
|   {
 | |
|     m.get_report(_report); 
 | |
|     _is_dirty = true;
 | |
|     update_report();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TReport_mask::report_query()
 | |
| {
 | |
|   TReport_query_mask qm;
 | |
|   if (_report.recordset() != NULL)
 | |
|     qm.set(F_SQL, _report.recordset()->query_text());
 | |
|   if (qm.run() == K_ENTER)
 | |
|   {
 | |
|     _report.set_recordset(qm.get(F_SQL));
 | |
|     _is_dirty = true;
 | |
|     const bool ok = _report.recordset() != NULL;
 | |
|     enable(DLG_PRINT, ok);
 | |
|     enable(DLG_PDF, ok);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TReport_mask::notify_focus_field(short id)
 | |
| {
 | |
|   TAutomask::notify_focus_field(id);
 | |
|   if (id == F_REPORTH || id == F_REPORT)
 | |
|   {
 | |
|     TReport_drawer& rd = (TReport_drawer&)field(id);
 | |
|     _curr_section = &rd.curr_section();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TReport_mask::update_toolbar()
 | |
| {
 | |
|   const bool full = !efield(F_CODICE).empty();
 | |
|   enable(DLG_SAVEREC, full);
 | |
|   enable(DLG_DELREC, full);
 | |
|   const bool printok = full && _report.recordset() != NULL;
 | |
|   enable(DLG_PRINT, printok);
 | |
|   enable(DLG_PDF, printok);
 | |
| }
 | |
| 
 | |
| bool TReport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   switch (o.dlg())
 | |
|   {
 | |
|   case F_CODICE:
 | |
|     if (e == fe_init || e == fe_modify)
 | |
|     {
 | |
|       if (e == fe_init)
 | |
|       {
 | |
|         if (main_app().argc() >= 3)
 | |
|         {
 | |
|           set(F_CODICE, main_app().argv(2));
 | |
|           load_report();
 | |
|         }
 | |
|       } else
 | |
|       if (e == fe_modify)
 | |
|       {
 | |
|         save_if_needed();
 | |
|         load_report();
 | |
|       }
 | |
|       update_toolbar();
 | |
|     }
 | |
|     break;
 | |
|   case F_SECTIONS:
 | |
|     if (e == fe_init || e == fe_modify)
 | |
|       select_section();
 | |
|     if (e == fe_info)
 | |
|     {
 | |
|       section_properties();
 | |
|       return false; // No info dialog
 | |
|     }
 | |
|     break;
 | |
|   case F_TOOLS:
 | |
|     if (e == fe_modify)
 | |
|     {
 | |
|       const TReport_section& rs = _tree.curr_section();
 | |
|       const bool on = strchr("HBF", rs.type()) != NULL;
 | |
|       switch (atoi(o.get()))
 | |
|       {
 | |
|       case 0: if (on) add_field(); break;
 | |
|       case 1: if (on) fields_properties(); break;
 | |
|       case 2: add_section(); break;
 | |
|       case 3: if (on) section_properties(); break;
 | |
|       case 4: report_properties(); break;
 | |
|       case 5: report_query(); break;
 | |
|       default: break;
 | |
|       }
 | |
|     }
 | |
|     break;
 | |
|   case DLG_PRINT:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       on_print();
 | |
|       return false;
 | |
|     }
 | |
|     break;
 | |
|   case DLG_PDF:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       on_pdf();
 | |
|       return false;
 | |
|     }
 | |
|     break;
 | |
|   case DLG_NEWREC:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       save_if_needed();
 | |
|       global_reset();
 | |
|     }
 | |
|     break;
 | |
|   case DLG_FINDREC:
 | |
|     if (e == fe_button)
 | |
|       send_key(K_F9, F_CODICE);
 | |
|     break;
 | |
|   case DLG_SAVEREC:
 | |
|     if (e == fe_button)
 | |
|     {
 | |
|       get_rep_path(_curr_report);
 | |
|       save_report();
 | |
|     }
 | |
|     break;
 | |
|   case DLG_DELREC:
 | |
|     if (e == fe_button && jolly == 0)  // Elimina della Toolbar 
 | |
|     {
 | |
|       delete_report();
 | |
|       return false; // Do not exit!
 | |
|     }
 | |
|     break;
 | |
|   case DLG_QUIT:
 | |
|     save_if_needed();
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TReport_mask::handler(WINDOW win, EVENT* ep)
 | |
| {
 | |
|   if (ep->type == E_COMMAND)
 | |
|   {
 | |
|     switch (ep->v.cmd.tag)
 | |
|     {
 | |
|     case POPUP_NEWFIELD  : add_field();          break;
 | |
|     case POPUP_PROPERTIES: fields_properties();  break;
 | |
|     case POPUP_SECTION   : section_properties(); break;
 | |
|     default: break;
 | |
|     }
 | |
|   }
 | |
|   return TAutomask::handler(win, ep);
 | |
| }
 | |
| 
 | |
| WINDOW TReport_mask::dlg2win(short id) const
 | |
| {
 | |
|   WINDOW w = NULL_WIN;
 | |
|   const int pos = id2pos(id);
 | |
|   if (pos >= 0)
 | |
|   {
 | |
|     TMask_field& f = fld(pos);
 | |
|     CHECKD(f.is_kind_of(CLASS_WINDOWED_FIELD), "Not a windowed field ", id);
 | |
|     w = ((TWindowed_field&)f).win().win();
 | |
|   }
 | |
|   return w;
 | |
| }
 | |
| 
 | |
| void TReport_mask::add_pane(short id, const char* title, int hook)
 | |
| {
 | |
|   WINDOW parent = page_win(0);
 | |
|   WINDOW child  = dlg2win(id);
 | |
|   xvt_pane_add(parent, child, title, hook, 0);
 | |
| }
 | |
| 
 | |
| TReport_mask::TReport_mask() : _tree(_report), _is_dirty(false)
 | |
| { 
 | |
|   read_mask("ba8300a", 0, -1); 
 | |
| 
 | |
|   TOutlook_field& of = (TOutlook_field&)field(F_TOOLS);
 | |
|   of.add_item(10210, PR("Nuovo Campo"), 0);
 | |
|   of.add_item(10210, PR("Proprieta' Campo"), 0);
 | |
|   of.add_item(10202, PR("Nuova Sezione"), 0);
 | |
|   of.add_item(10202, PR("Proprieta' Sezione"), 0);
 | |
|   of.add_item(10217, PR("Proprieta' Report"), 0);
 | |
|   of.add_item(10214, PR("Query Principale"), 0);
 | |
| 
 | |
|   TTree_field& albero = tfield(F_SECTIONS);
 | |
|   RCT rct_sec; albero.get_rect(rct_sec);
 | |
|   const short sec[2] = { F_REPORT, F_REPORTH };
 | |
|   for (int s = 0; s < 2; s++)
 | |
|   {
 | |
|     TReport_drawer& rd = (TReport_drawer&)field(sec[s]);
 | |
|     RCT rct_rep; rd.get_rect(rct_rep);
 | |
|     rct_rep.left = rct_sec.right+ROWY;
 | |
|     rct_rep.right -= ROWY;
 | |
|     rct_rep.bottom -= ROWY;
 | |
|     rd.set_rect(rct_rep);
 | |
|     switch (s)
 | |
|     {
 | |
|     case 1 : 
 | |
|       rd.set_report_section(_report.section('H', 0));
 | |
|       break;
 | |
|     default:
 | |
|       _curr_section = &_report.section('B', 1);
 | |
|       rd.set_report_section(*_curr_section);
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   _tree.goto_node('B', 1);
 | |
|   const int ih = _tree.image_height();
 | |
|   if (ih > CHARY)
 | |
|     albero.set_row_height(ih); // Imposta le dimensioni delle immagini
 | |
| 
 | |
|   _tree.goto_root();
 | |
|   _tree.expand_all();
 | |
|   albero.set_tree(&_tree);
 | |
| 
 | |
|   add_pane(F_SECTIONS, TR("Struttura"), 1); // Left upper pane
 | |
|   add_pane(F_TOOLS,    TR("Strumenti"), 1); // Left lower pane
 | |
|   add_pane(F_REPORTH,  TR("Testa"),    52); // Center top pane
 | |
|   add_pane(F_REPORT,   TR("Corpo"),    54); // Center bottom pane
 | |
| 
 | |
|   set_handlers();
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReporter_app 
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TReporter_app : public TSkeleton_application
 | |
| {
 | |
|   TReport_mask* _msk;
 | |
| 
 | |
| protected:
 | |
|   virtual bool create();
 | |
|   virtual void main_loop();
 | |
|   virtual bool destroy();
 | |
|   virtual void print();
 | |
| 
 | |
| public:
 | |
|   TReporter_app() : _msk(NULL) { }
 | |
| };
 | |
| 
 | |
| void TReporter_app::print()
 | |
| {
 | |
|   if (_msk != NULL)
 | |
|     _msk->on_print();
 | |
| }
 | |
| 
 | |
| bool TReporter_app::create()
 | |
| {
 | |
|   if (!has_module(RSAUT))
 | |
|     return error_box(TR("Modulo non autorizzato"));
 | |
| 
 | |
|   _msk = new TReport_mask;
 | |
|   xvt_sys_sleep(500);
 | |
|   return TSkeleton_application::create();
 | |
| }
 | |
| 
 | |
| bool TReporter_app::destroy()
 | |
| {
 | |
|   if (_msk != NULL)
 | |
|   {
 | |
|     delete _msk;
 | |
|     _msk = NULL;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TReporter_app::main_loop()
 | |
| {
 | |
|   _msk->run();
 | |
| }
 | |
| 
 | |
| int ba8300(int argc, char* argv[])
 | |
| {     
 | |
|   TReporter_app app;
 | |
|   app.run(argc, argv, TR("Report Generator"));
 | |
|   return 0;
 | |
| } |