Files correlati : Ricompilazione Demo : [ ] Commento :correzioni dovute al passaggio al nuovo compilatore git-svn-id: svn://10.65.10.50/trunk@14698 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2522 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2522 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <automask.h>
 | |
| #include <colors.h>
 | |
| #include <config.h>
 | |
| #include <defmask.h>
 | |
| #include <diction.h>
 | |
| #include <dongle.h>
 | |
| #include <modaut.h>
 | |
| #include <printer.h>
 | |
| #include <progind.h>
 | |
| #include <reprint.h>
 | |
| #include <spotlite.h>
 | |
| #include <statbar.h>
 | |
| #include <urldefid.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include <bagn003.h>
 | |
| 
 | |
| static bool _print_aborted = false;
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Utility
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| static void advanced_draw_justified_text_line(TWindow& win, const char* text, short x, short y, short dx)
 | |
| {
 | |
|   TString256 txt(text); txt.rtrim(); 
 | |
|   int spaces = 0;
 | |
|   for (int s = 0; txt[s]; s++)
 | |
|     if (isspace(txt[s])) spaces++;
 | |
| 
 | |
|   WINDOW w = win.win();
 | |
| 
 | |
|   // Il testo e' giustificabile se ha degli spazi ed occupa meno della riga
 | |
|   if (spaces > 0)
 | |
|   {
 | |
|     const int tw = xvt_dwin_get_text_width(w, txt, -1);
 | |
|     if (tw < dx)
 | |
|     {
 | |
|       txt << ' '; // Aggiunge spazio finale
 | |
|       const double kspc = double(dx - tw) / spaces;
 | |
|       int start = 0;
 | |
|       double kx = x;
 | |
|       for (int i = 0; txt[i]; i++) if (isspace(txt[i]))
 | |
|       {
 | |
|         const bool last_word = txt[i+1] == '\0';
 | |
|         const TString& parola = txt.sub(start, i + (last_word ? 0 : 1));
 | |
|         const int lw = xvt_dwin_get_text_width(w, parola, -1);
 | |
|         if (last_word) // ultima parola
 | |
|           kx = x+dx-lw;
 | |
|         xvt_dwin_draw_text(w, int(kx+0.5), y, parola, -1);
 | |
|         kx += lw + kspc;
 | |
|         start = i+1;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|       xvt_dwin_draw_text(w, x, y, txt, -1); // Stringa che deborda dalla riga
 | |
|   }
 | |
|   else
 | |
|     xvt_dwin_draw_text(w, x, y, txt, -1); // Stringa senza spazi
 | |
| }
 | |
| 
 | |
| void advanced_draw_text_line(TWindow& win, const char* text, const RCT& r, char halign, char valign)
 | |
| {
 | |
|   WINDOW w = win.win();
 | |
| 
 | |
|   const short dx = r.right-r.left;
 | |
|   const short dy = r.bottom-r.top;
 | |
|   short x = r.left;
 | |
|   short y = r.bottom;
 | |
|   
 | |
|   if (halign != 'L')
 | |
|   {
 | |
|     const int tw = xvt_dwin_get_text_width(w, text, -1);
 | |
|     switch (halign)
 | |
|     {
 | |
|     case 'C': x += (dx - tw)/2; break;
 | |
|     case 'R': x = r.right-tw; break;
 | |
|     default : break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Text Height
 | |
|   int leading, ascent, descent;
 | |
|   xvt_dwin_get_font_metrics(w, &leading, &ascent, &descent);
 | |
|   switch (valign)
 | |
|   {
 | |
|   case 'C': y -= (dy - ascent)/2; break;
 | |
|   case 'T': y = r.top + leading + ascent; break;
 | |
|   default : y -= descent; break;
 | |
|   }
 | |
| 
 | |
|   RCT orig; xvt_dwin_get_clip(w, &orig);
 | |
|   const bool restore_clip = !xvt_rect_is_empty(&orig);
 | |
|   if (restore_clip)
 | |
|   {
 | |
| 	  RCT clipper;
 | |
| 	  xvt_rect_intersect(&clipper, &orig, (RCT*)&r);
 | |
| 	  xvt_dwin_set_clip(w, (RCT*)&clipper);
 | |
| 
 | |
|   }
 | |
|   else
 | |
| 	  xvt_dwin_set_clip(w, (RCT*)&r);
 | |
|   
 | |
|   if (halign == 'J')
 | |
|     advanced_draw_justified_text_line(win, text, x, y, dx);
 | |
|   else
 | |
|     xvt_dwin_draw_text(w, x, y, text, -1);
 | |
| 
 | |
|   if (restore_clip)
 | |
|     xvt_dwin_set_clip(w, &orig);
 | |
|   else
 | |
|     xvt_dwin_set_clip(w, NULL);
 | |
| }
 | |
| 
 | |
| bool finisce_per_punto(const TString& str)
 | |
| {
 | |
|   bool yes = false;
 | |
|   const int len = str.len();
 | |
|   if (len > 0)
 | |
|   {
 | |
|     const char last = str[len-1];
 | |
|     yes = strchr(".!?:", last) != NULL;
 | |
|   }
 | |
|   return yes;
 | |
| }
 | |
| 
 | |
| void advanced_draw_paragraph(TWindow& win, const TString_array& para, const RCT& rct, 
 | |
|                              char halign, char valign, int default_10row_height)
 | |
| {
 | |
|   const int rows = para.items();
 | |
|   if (rows > 1) // Devo scrivere piu' righe?
 | |
|   {
 | |
|     int leading, ascent, descent;
 | |
|     xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent);
 | |
|   
 | |
|     int ky10 = (leading + ascent + descent) * 10;
 | |
|     // Aggiusta l'altezza di una riga standard, se necessario
 | |
|     if (ky10 < default_10row_height && ky10 > 75*default_10row_height/100)
 | |
|       ky10 = default_10row_height;
 | |
| 
 | |
|     const int rct_height = rct.bottom - rct.top;
 | |
| 
 | |
|     int ybase = rct.top;
 | |
|     switch (valign)
 | |
|     {
 | |
|     case 'C': ybase += (rct_height - (rows * ky10) / 10) / 2; break;
 | |
|     case 'B': ybase += rct_height - (rows * ky10) / 10; break;
 | |
|     default : break;
 | |
|     }
 | |
|     
 | |
|     for (int row = 0; row < rows; row++)
 | |
|     {
 | |
|       const int top = ybase + (ky10 * row) / 10;
 | |
|       if (top < rct.bottom)
 | |
|       {
 | |
|         const TString& line = para.row(row);
 | |
|         if (line.full())
 | |
|         {
 | |
|           RCT rctline = rct;
 | |
|           rctline.top = top;
 | |
|           rctline.bottom = top + ky10 / 10;
 | |
|           char ha = halign;
 | |
|           if (ha == 'J' && (row == rows-1 || finisce_per_punto(line)))
 | |
|             ha = 'L'; // Le righe finali non vanno giustificate
 | |
|           advanced_draw_text_line(win, line, rctline, ha, 'T'); 
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (halign == 'J') halign = 'L'; // Le righe isolate non vanno giustificate
 | |
|     advanced_draw_text_line(win, para.row(0), rct, halign, valign); 
 | |
|   }
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_link
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void TReport_link::set(const char* field, const TString& var)
 | |
| {
 | |
|   _fields.add(field, var, true);
 | |
| }
 | |
| 
 | |
| const TString& TReport_link::get(const char* field) const
 | |
| {
 | |
|   const TString* var = (const TString*)_fields.objptr(field);
 | |
|   return var != NULL ? *var : (const TString&)EMPTY_STRING;
 | |
| }
 | |
| 
 | |
| void TReport_link::add_rect(const RCT& rct)
 | |
| {
 | |
|   // Non memorizzo tutti i rettangoli del link, ma la loro unione
 | |
|   if (xvt_rect_is_empty(&_rct))
 | |
|     _rct = rct;
 | |
|   else
 | |
|   {
 | |
|     if (rct.left < _rct.left) _rct.left = rct.left;
 | |
|     if (rct.top < _rct.top) _rct.top = rct.top;
 | |
|     if (rct.right > _rct.right) _rct.right = rct.right;
 | |
|     if (rct.bottom > _rct.bottom) _rct.bottom = rct.bottom;
 | |
|   }
 | |
| }
 | |
| 
 | |
| int TReport_link::hit_test(const PNT& p) const
 | |
| {
 | |
|   if (p.v < _rct.top)
 | |
|     return -1;
 | |
|   if (p.v > _rct.bottom)
 | |
|     return +1;
 | |
|   if (p.h < _rct.left)
 | |
|     return -1;
 | |
|   if (p.h > _rct.right)
 | |
|     return +1;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int TReport_link::compare(const TSortable& s) const
 | |
| {
 | |
|   const TReport_link& lnk = (const TReport_link&)s;
 | |
|   int cmp = _rct.top - lnk._rct.top;
 | |
|   if (cmp == 0)
 | |
|     cmp = _rct.left - lnk._rct.left;
 | |
|   return cmp;
 | |
| }
 | |
|   
 | |
| TReport_link::TReport_link(const char* table)
 | |
|             : _table(table)
 | |
| {
 | |
|   xvt_rect_set_empty(&_rct);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TPrint_preview_window
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TPrint_preview_window : public TField_window
 | |
| {
 | |
|   TBook* _book;
 | |
|   word _page;
 | |
|   int _zoom;
 | |
|   bool _grid;
 | |
|   
 | |
|   TAssoc_array _alinks;
 | |
|   TPointer_array _plinks;
 | |
| 
 | |
| protected:
 | |
|   void page_select();
 | |
|   void popup_menu(EVENT* ep);
 | |
|   const TReport_link* find_link(const PNT& pnt) const;
 | |
| 
 | |
|   virtual void handler(WINDOW win, EVENT* ep);
 | |
|   virtual void update();
 | |
|   virtual bool on_key(KEY k);
 | |
| 
 | |
|   void update_scroll_range();
 | |
|   void do_scroll(int kx, int ky);
 | |
| 
 | |
| public:
 | |
|   virtual PNT log2dev(long lx, long ly) const;
 | |
|   TAssoc_array& alinks() { return _alinks; }
 | |
|   TPointer_array& plinks() { return _plinks; }
 | |
| 
 | |
|   TPrint_preview_window(int x, int y, int dx, int dy, WINDOW parent, 
 | |
|                         TWindowed_field* owner, TBook* book);
 | |
|   virtual ~TPrint_preview_window();
 | |
| };
 | |
| 
 | |
| PNT TPrint_preview_window::log2dev(long lx, long ly) const
 | |
| {
 | |
|   PNT pnt = { short(lx), short(ly) };
 | |
|   
 | |
|   const TPoint res = _book->page_res();
 | |
|   if (res.x > 0 && res.y > 0) // Should always be true :-)
 | |
|   {
 | |
|     pnt.h = short(lx * _zoom / res.x);
 | |
|     pnt.v = short(ly * _zoom / res.y);
 | |
|   }
 | |
| 
 | |
|   const TPoint orig = origin();
 | |
|   pnt.h -= short(orig.x);
 | |
|   pnt.v -= short(orig.y);
 | |
| 
 | |
|   return pnt;
 | |
| }
 | |
| 
 | |
| void TPrint_preview_window::update_scroll_range()
 | |
| {
 | |
|   PNT pnt = { 0, 0 };
 | |
| 
 | |
|   const TPoint res = _book->page_res();
 | |
|   if (res.x > 0 && res.y > 0) // Should always be true :-)
 | |
|   {
 | |
|     const TPoint size = _book->page_size();
 | |
|     pnt.h = short(size.x * _zoom / res.x);
 | |
|     pnt.v = short(size.y * _zoom / res.y);
 | |
| 
 | |
|     RCT rct; xvt_vobj_get_client_rect(win(), &rct);
 | |
|     pnt.h -= rct.right; if (pnt.h < 0) pnt.h = 0;
 | |
|     pnt.v -= rct.bottom; if (pnt.v < 0) pnt.v = 0;
 | |
|   }
 | |
|  
 | |
|   update_thumb(0, 0);
 | |
|   set_scroll_max(pnt.h, pnt.v);
 | |
| }
 | |
| 
 | |
| void TPrint_preview_window::update()
 | |
| {
 | |
|   clear(MASK_BACK_COLOR);
 | |
|   RCT rct; xvt_vobj_get_client_rect(win(), &rct);
 | |
| 
 | |
|   const TPoint size = _book->page_size();
 | |
|   const PNT pag = log2dev(size.x, size.y);
 | |
|   if (pag.h < rct.right) rct.right = pag.h;
 | |
|   if (pag.v < rct.bottom) rct.bottom = pag.v;
 | |
|   hide_pen();
 | |
|   set_brush(COLOR_WHITE);
 | |
|   xvt_dwin_draw_rect(win(), &rct); // Disegna foglio bianco
 | |
| 
 | |
|   if (_grid)
 | |
|   {
 | |
|     const TPoint res = _book->page_res();
 | |
|     const int lpi = _book->lpi();
 | |
|     for (int i = 1; lpi > 0; i++)
 | |
|     {
 | |
|       set_pen(i%lpi ? MAKE_COLOR(232,232,255) : MAKE_COLOR(255,192,255));
 | |
|       const short y = i * res.y / lpi;
 | |
|       if (y > size.y)
 | |
|         break;
 | |
|       line(0, y, (short)size.x, y);
 | |
|     }
 | |
|     const int cpi = _book->cpi();
 | |
|     for (int j = 1; cpi > 0; j++)
 | |
|     {
 | |
|       set_pen(j%10 ? MAKE_COLOR(232,232,255) : MAKE_COLOR(255,192,255));
 | |
|       const short x = j * res.x / cpi;
 | |
|       if (x > size.x)
 | |
|         break;
 | |
|       line(x, 0, x, (short)size.y);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   _book->print_page(*this, _page);
 | |
| 
 | |
|   TString80 str; str.format(FR("Pagina %u di %u"), _page, _book->pages());
 | |
|   statbar_set_title(TASK_WIN, str);
 | |
| }
 | |
| 
 | |
| #define POPUP_FIRST      20883
 | |
| #define POPUP_PREV       20884
 | |
| #define POPUP_NEXT       20885
 | |
| #define POPUP_SEARCH     20886
 | |
| #define POPUP_LAST       20887
 | |
| #define POPUP_ZOOMIN     20888
 | |
| #define POPUP_ZOOMOUT    20889
 | |
| #define POPUP_GRID       20890
 | |
| 
 | |
| void TPrint_preview_window::popup_menu(EVENT* ep)
 | |
| {
 | |
|   MENU_ITEM menu[16];  // Stiamo larghi
 | |
|   memset(menu, 0, sizeof(menu));
 | |
|   menu[0].tag = POPUP_FIRST;   menu[0].text = (char*)PR("Prima");    menu[0].enabled = _page > 1;
 | |
|   menu[1].tag = POPUP_PREV;    menu[1].text = (char*)PR("Indietro"); menu[1].enabled = _page > 1;
 | |
|   menu[2].tag = POPUP_NEXT;    menu[2].text = (char*)PR("Avanti");   menu[2].enabled = _page < _book->pages();
 | |
|   menu[3].tag = POPUP_LAST;    menu[3].text = (char*)PR("Ultima");   menu[3].enabled = _page < _book->pages();
 | |
|   menu[4].tag = -1;            menu[4].separator = true;
 | |
|   menu[5].tag = POPUP_ZOOMIN;  menu[5].text = (char*)PR("Zoom +");   menu[5].enabled = _zoom < 300;
 | |
|   menu[6].tag = POPUP_ZOOMOUT; menu[6].text = (char*)PR("Zoom -");   menu[6].enabled = _zoom > 50;
 | |
|   menu[7].tag = -1;            menu[7].separator = true;
 | |
|   menu[8].tag = POPUP_GRID;    menu[8].text = (char*)PR("Griglia");  menu[8].enabled = true; 
 | |
|                                menu[8].checkable = true;             menu[8].checked = _grid;
 | |
| 
 | |
|   const PNT& p = ep->v.mouse.where;
 | |
|   xvt_menu_popup(menu, win(), p, XVT_POPUP_CENTER, 0);
 | |
| }
 | |
| 
 | |
| void TPrint_preview_window::page_select()
 | |
| {
 | |
|   TMask m(TR("Ricerca"), 1, 28, 4);
 | |
| 
 | |
|   m.add_number(101, 0, TR("Pagina "), 1, 1, 4,  "U").check_type(CHECK_REQUIRED);
 | |
|   m.add_button(DLG_OK, 0, "", -12, -1, 10, 2); 
 | |
|   m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
 | |
|   if (m.run())
 | |
|   {
 | |
|     _page = m.get_int(101);
 | |
|     if (_page < 1) _page = 1;
 | |
|     if (_page > _book->pages()) 
 | |
|       _page = _book->pages();
 | |
|   }
 | |
| }
 | |
| 
 | |
| const TReport_link* TPrint_preview_window::find_link(const PNT& pnt) const
 | |
| {
 | |
|   int primo = 0, ultimo = _plinks.last();
 | |
|   while (primo <= ultimo)
 | |
|   {
 | |
|     const int in_mezzo = (primo+ultimo)/2;
 | |
|     const TReport_link* lnk = (const TReport_link*)_plinks.objptr(in_mezzo);
 | |
|     const int cmp = lnk->hit_test(pnt);
 | |
|     if (cmp == 0)
 | |
|       return lnk;
 | |
|     if (cmp < 0)
 | |
|       ultimo = in_mezzo-1;
 | |
|     else
 | |
|       primo = in_mezzo+1;
 | |
|   }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| void TPrint_preview_window::handler(WINDOW win, EVENT* ep)
 | |
| {
 | |
|   static PNT ptPan;
 | |
|   
 | |
|   switch (ep->type)
 | |
|   {
 | |
|   case E_MOUSE_MOVE:
 | |
|     switch (ep->v.mouse.button)
 | |
|     {
 | |
|     case 2:
 | |
|       {
 | |
|         const PNT& ptCur = ep->v.mouse.where;
 | |
|         TPoint orig = origin();
 | |
|         orig.x += ptPan.h - ptCur.h;
 | |
|         orig.y += ptPan.v - ptCur.v;
 | |
|         update_thumb(orig.x, orig.y);
 | |
|         force_update();
 | |
|         ptPan = ptCur;
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       if (find_link(ep->v.mouse.where) != NULL)
 | |
|         xvt_win_set_cursor(win, 8004);          // Ditino
 | |
|       else
 | |
|         xvt_win_set_cursor(win, CURSOR_ARROW);  // Freccia
 | |
|       break;
 | |
|     }
 | |
|     break;
 | |
|   case E_MOUSE_DOWN:
 | |
|     switch (ep->v.mouse.button)
 | |
|     {
 | |
|     case 0:
 | |
|       {
 | |
|         const TReport_link* lnk = find_link(ep->v.mouse.where);
 | |
|         if (lnk != NULL && _book != NULL) 
 | |
|           _book->on_link(*lnk);
 | |
|       }
 | |
|       break;
 | |
|     case 1:
 | |
|       popup_menu(ep);
 | |
|       break;
 | |
|     case 2:
 | |
|       ptPan = ep->v.mouse.where;
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|     break;
 | |
|   case E_COMMAND:
 | |
|     {
 | |
|       bool processed = true;
 | |
|       switch(ep->v.cmd.tag)
 | |
|       {
 | |
|       case POPUP_FIRST  : 
 | |
|         processed = _page > 1; 
 | |
|         if (processed) _page = 1; 
 | |
|         break;
 | |
|       case POPUP_PREV   : 
 | |
|         processed = _page > 1; 
 | |
|         if (processed) _page--; 
 | |
|         break;
 | |
|       case POPUP_SEARCH : page_select(); break;
 | |
|       case POPUP_NEXT   : 
 | |
|         processed = _page < _book->pages(); 
 | |
|         if (processed) _page++; 
 | |
|         break;
 | |
|       case POPUP_LAST   : 
 | |
|         processed = _page < _book->pages(); 
 | |
|         if (processed) _page = _book->pages(); 
 | |
|         break;
 | |
|       case POPUP_ZOOMIN : if (_zoom < 300) { _zoom += 10; update_scroll_range(); } break;
 | |
|       case POPUP_ZOOMOUT: if (_zoom >  50) { _zoom -= 10; update_scroll_range(); } break;
 | |
|       case POPUP_GRID   : _grid = !_grid; break;
 | |
|       default:processed = false; break;
 | |
|       }
 | |
|       if (processed)
 | |
|         force_update();
 | |
|     }
 | |
|     break;
 | |
|   case E_HSCROLL:
 | |
|   case E_VSCROLL:
 | |
|     {
 | |
|       int kx = 0, ky = 0;
 | |
|       int& k = ep->type == E_HSCROLL ? kx : ky;
 | |
|       switch(ep->v.scroll.what)
 | |
|       {
 | |
|       case SC_PAGE_UP  : k = -3; break;
 | |
|       case SC_LINE_UP  : k = -1; break;
 | |
|       case SC_PAGE_DOWN: k = +3; break;
 | |
|       case SC_LINE_DOWN: k = +1; break;
 | |
|       default          : TField_window::handler(win, ep); break;
 | |
|       }
 | |
|       if (k != 0)
 | |
|         do_scroll(kx, ky); break;
 | |
|     }
 | |
|     break;
 | |
|   default:
 | |
|     TField_window::handler(win, ep);
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TPrint_preview_window::do_scroll(int kx, int ky)
 | |
| {
 | |
|   const TPoint& r = range();
 | |
|   TPoint orig = origin();
 | |
|   orig.x += kx * r.x/8;
 | |
|   orig.y += ky * r.y/6;
 | |
|   if (orig.x < 0) orig.x = 0;
 | |
|   if (orig.x > r.x) orig.x = r.x;
 | |
|   if (orig.y < 0) orig.y = 0;
 | |
|   if (orig.y > r.y) orig.y = r.y;
 | |
|   if (orig != origin())
 | |
|   {
 | |
|     update_thumb(orig.x, orig.y);
 | |
|     force_update();
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TPrint_preview_window::on_key(KEY k)
 | |
| {
 | |
|   bool ok = true;
 | |
|   switch (k)
 | |
|   {
 | |
|   case '+'     : dispatch_e_menu(win(), POPUP_ZOOMIN); break; 
 | |
|   case '-'     : dispatch_e_menu(win(), POPUP_ZOOMOUT); break;
 | |
|   case K_HOME  :
 | |
|   case K_LHOME : dispatch_e_menu(win(), POPUP_FIRST); break;
 | |
|   case K_PREV  : dispatch_e_menu(win(), POPUP_PREV); break;
 | |
|   case K_NEXT  : dispatch_e_menu(win(), POPUP_NEXT); break;
 | |
|   case K_END:
 | |
|   case K_LEND  : dispatch_e_menu(win(), POPUP_LAST); break;
 | |
|   case K_LEFT  : do_scroll(-1, 0); break;
 | |
|   case K_RIGHT : do_scroll(+1, 0); break;
 | |
|   case K_UP    : do_scroll(0, -1); break;
 | |
|   case K_DOWN  : do_scroll(0, +1); break;
 | |
|   case 'G'     : 
 | |
|   case 'g'     : dispatch_e_menu(win(), POPUP_GRID); break;
 | |
|   default      : 
 | |
|     if (k > K_CTRL)
 | |
|       dispatch_e_char(parent(), k);  // Gestione acceleratori
 | |
|     else
 | |
|       ok = TField_window::on_key(k); 
 | |
|     break;
 | |
|   };
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TPrint_preview_window::TPrint_preview_window(int x, int y, int dx, int dy, WINDOW parent, 
 | |
|                                              TWindowed_field* owner, TBook* book)
 | |
| : TField_window(x, y, dx, dy, parent, owner), _book(book), _page(1), _zoom(100), _grid(false)
 | |
| { 
 | |
|   _pixmap = true;
 | |
|   update_scroll_range();
 | |
| 
 | |
|   TConfig ini(CONFIG_GUI, "Preview");
 | |
|   _grid = ini.get_bool("Grid");
 | |
| }
 | |
| 
 | |
| TPrint_preview_window::~TPrint_preview_window()
 | |
| {
 | |
|   TConfig ini(CONFIG_GUI, "Preview");
 | |
|   ini.set("Grid", _grid ? "X" : "");
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TPrint_preview_field
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TPrint_preview_field : public TWindowed_field
 | |
| {
 | |
|   TBook* _book;
 | |
| 
 | |
| protected:
 | |
|   virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent);
 | |
| 
 | |
| public:
 | |
|   TPrint_preview_field(TMask* m, TBook* book) : TWindowed_field(m), _book(book) { }
 | |
| };
 | |
| 
 | |
| TField_window* TPrint_preview_field::create_window(int x, int y, int dx, int dy, WINDOW parent)
 | |
| {
 | |
|   return new TPrint_preview_window(x, y, dx, dy, parent, this, _book);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TPreview_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TPreview_mask : public TAutomask
 | |
| {
 | |
|   TBook* _book;
 | |
|   TPrint_preview_field* _pvf;
 | |
| 
 | |
| protected:
 | |
|   virtual bool on_key(KEY k);
 | |
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   virtual TMask_field* parse_field(TScanner& scanner);
 | |
|   virtual void handler(WINDOW win, EVENT* ep);
 | |
|   
 | |
| public:
 | |
|   TPreview_mask(TBook* book);
 | |
| };
 | |
| 
 | |
| bool TPreview_mask::on_key(KEY k)
 | |
| {
 | |
|   switch (k)
 | |
|   {
 | |
|   case '+'    :
 | |
|   case '-'    :
 | |
|   case K_HOME : 
 | |
|   case K_LHOME: 
 | |
|   case K_LEFT : 
 | |
|   case K_RIGHT:
 | |
|   case K_END  :
 | |
|   case K_LEND :
 | |
|   case K_PREV : 
 | |
|   case K_NEXT : 
 | |
|   case 'G'    :
 | |
|   case 'g'    :
 | |
|     dispatch_e_char(_pvf->win().win(), k);
 | |
|     return true;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return TAutomask::on_key(k);
 | |
| }
 | |
| 
 | |
| void TPreview_mask::handler(WINDOW win, EVENT* ep)
 | |
| {
 | |
|   // Riflessione eventi di scroll
 | |
|   if (ep->type == E_HSCROLL || ep->type == E_VSCROLL) 
 | |
|     ::dispatch_event(_pvf->win().win(), *ep, false);
 | |
| 
 | |
|   TAutomask::handler(win, ep);
 | |
| }
 | |
| 
 | |
| bool TPreview_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   if (e == fe_button)
 | |
|   {
 | |
|     short idm = 0;
 | |
|     switch (o.dlg()) 
 | |
|     {
 | |
|     case DLG_FIRSTREC: idm = POPUP_FIRST;  break;
 | |
|     case DLG_PREVREC : idm = POPUP_FIRST;  break;
 | |
|     case DLG_FINDREC : idm = POPUP_SEARCH; break;
 | |
|     case DLG_NEXTREC : idm = POPUP_NEXT;   break;
 | |
|     case DLG_LASTREC : idm = POPUP_LAST;   break;
 | |
|     default: break;
 | |
|     }
 | |
|     if (idm > 0)
 | |
|       dispatch_e_menu(_pvf->win().win(), idm);
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| TMask_field* TPreview_mask::parse_field(TScanner& scanner)
 | |
| {
 | |
|   if (scanner.token().starts_with("PR"))
 | |
|   {
 | |
|     _pvf = new TPrint_preview_field(this, _book);
 | |
|     return _pvf;
 | |
|   }
 | |
|   return TAutomask::parse_field(scanner);
 | |
| }
 | |
| 
 | |
| TPreview_mask::TPreview_mask(TBook* book) : _book(book)
 | |
| {
 | |
|   read_mask("bagn008", 0, -1); 
 | |
|   set_handlers();
 | |
| 
 | |
|   int pos = id2pos(DLG_FINDREC);
 | |
|   if (pos >= 0 && id2pos(DLG_FIRSTREC) >= 0) //se e' un bottone pentapartito...
 | |
| 	{
 | |
| 		TButton_field& f_find = (TButton_field &)fld(pos);
 | |
| 		RCT rct_base;	f_find.get_rect(rct_base);
 | |
|     const int bwidth = (rct_base.right - rct_base.left);
 | |
|     const int bheight = (rct_base.bottom - rct_base.top);
 | |
|     if (bwidth > 3*bheight/2) // Controllo se ho gia' ridimensionato i bottoni in precedenza
 | |
|     {
 | |
| 		  int bx = bwidth / 3;
 | |
| 		  int by = bheight / 2;
 | |
| 
 | |
|       RCT r = rct_base; r.left += bx-2;  r.right -= bx-2;
 | |
| 			f_find.set_rect(r); // Ridimensiona il bottone centrale di ricerca
 | |
| 			
 | |
|       bx += 5; by += 3;   // Aggiusta dimensioni bottoni sussidiari
 | |
| 
 | |
| 		  pos = id2pos(DLG_FIRSTREC);
 | |
| 		  if (pos >= 0)
 | |
| 		  {	
 | |
| 			  r = rct_base; r.top = r.bottom - by;  r.right = r.left + bx;
 | |
| 			  fld(pos).set_rect(r);
 | |
| 		  }
 | |
| 		  pos = id2pos(DLG_PREVREC);
 | |
| 		  if (pos >= 0) 
 | |
| 		  {
 | |
| 			  r = rct_base; r.bottom = r.top + by;  r.right = r.left + bx;
 | |
| 			  fld(pos).set_rect(r);
 | |
|       }
 | |
| 		  pos = id2pos(DLG_NEXTREC);
 | |
| 		  if (pos >= 0) 
 | |
| 		  {
 | |
| 			  r = rct_base; r.bottom = r.top + by;  r.left = r.right - bx;
 | |
| 			  fld(pos).set_rect(r);
 | |
| 		  }
 | |
| 		  pos = id2pos(DLG_LASTREC);
 | |
| 		  if (pos >= 0) 
 | |
| 		  {
 | |
| 			  r = rct_base; r.top = r.bottom - by;  r.left = r.right - bx;
 | |
| 			  fld(pos).set_rect(r);
 | |
| 		  }
 | |
|     }
 | |
| 	}
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TWindow_printer
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TWindow_printer : public TWindow
 | |
| {
 | |
|   long _pvr, _phr;
 | |
| 
 | |
| protected:
 | |
|   bool is_ok() const { return win() != NULL_WIN; }
 | |
|   virtual PNT log2dev(long x, long y) const;
 | |
| 
 | |
| 
 | |
| public:
 | |
|   bool print_doc(const TFilename& name);
 | |
| 
 | |
|   TWindow_printer(PRINT_RCD* rcd, const char* title);
 | |
| 
 | |
|   ~TWindow_printer();
 | |
| };
 | |
| 
 | |
| PNT TWindow_printer::log2dev(long x, long y) const
 | |
| {
 | |
|   PNT ptdev;
 | |
|   ptdev.h = (x * _phr) / BOOKDPI;
 | |
|   ptdev.v = (y * _pvr) / BOOKDPI;
 | |
|   return ptdev;
 | |
| }
 | |
| 
 | |
| bool TWindow_printer::print_doc(const TFilename& name)
 | |
| {
 | |
|   bool ok = name.exist();
 | |
|   if (ok)
 | |
|   {
 | |
|     const bool printing = is_ok();
 | |
|     if (printing)
 | |
|       xvt_print_suspend_thread();
 | |
|     ok = xvt_sys_goto_url(name, "print") != 0;
 | |
|     if (printing)
 | |
|       xvt_print_restart_thread();
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TWindow_printer::TWindow_printer(PRINT_RCD* rcd, const char* title)
 | |
| { 
 | |
|   long ph, pw;
 | |
|   WINDOW prwin = xvt_print_create_win(rcd, title);
 | |
| 
 | |
|   set_win(prwin);
 | |
|   _pixmap = true;
 | |
|   xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, rcd, &ph, &pw, &_pvr, &_phr);
 | |
| }
 | |
| 
 | |
| TWindow_printer::~TWindow_printer()
 | |
| {
 | |
|   if (is_ok())
 | |
|   {
 | |
|     xvt_vobj_destroy(win()); 
 | |
|     set_win(NULL_WIN);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Writing a page
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| // Converte da coordinate logiche (1/100 caratteri) a coordinate di stampa 
 | |
| TPoint TBook::log2dev(const TPoint& ptlog) const
 | |
| {
 | |
|   TPoint ptdev;
 | |
|   ptdev.x = (ptlog.x * _phr) / (100 * cpi());
 | |
|   ptdev.y = (ptlog.y * _pvr) / (100 * lpi());
 | |
| 	return ptdev;
 | |
| }
 | |
| 
 | |
| PNT TBook::log2pix(const TPoint& ptlog) const
 | |
| {
 | |
|   TPoint ptdev = log2dev(ptlog);
 | |
| 	return _printwin->log2dev(ptdev.x, ptdev.y);
 | |
| }
 | |
| 
 | |
| int TBook::compute_text_frame(const TString& tmp, const TReport_font& font, TRectangle& rect, TString_array& para) const
 | |
| {
 | |
|   // Calcola la larghezza massima e l'altezza di 10 righe
 | |
|   const TRectangle rect_riga(0,0,rect.width(),1000);
 | |
|   const PNT size = log2pix(rect_riga.size());
 | |
|   const int max_row_width = size.h;
 | |
|   const int def_10row_height = size.v;
 | |
| 
 | |
|   WINDOW w = _printwin->win();
 | |
|   CHECK(w == PRINTER_WIN, "Finestra di stampa non valida");
 | |
|   xvt_dwin_set_font(w, font.get_xvt_font(*_printwin));
 | |
|   int leading, ascent, descent;
 | |
|   xvt_dwin_get_font_metrics(w, &leading, &ascent, &descent);
 | |
|   int ky10 = (leading + ascent + descent) * 10;
 | |
|   // Aggiusta l'altezza di 10 righe standard, se necessario
 | |
|   if (ky10 < def_10row_height && ky10 > 75*def_10row_height/100)
 | |
|     ky10 = def_10row_height;
 | |
| 
 | |
|   TToken_string p(tmp, '\n');
 | |
|   FOR_EACH_TOKEN(p, line)
 | |
|     para.add(line);
 | |
|   for (int i = 0; i < para.items(); i++)
 | |
|   {
 | |
|     TString& row = para.row(i);
 | |
|     int pix = xvt_dwin_get_text_width(w, row, -1);
 | |
|     if (pix > max_row_width)
 | |
|     {
 | |
|       int good_len = 0;
 | |
|       const int first_space = row.find(' ');
 | |
|       if (first_space >= 0)
 | |
|       {
 | |
|         // Linea con almeno uno spazio
 | |
|         for (int i = first_space; row[i]; i++) if (row[i] == ' ')
 | |
|         {
 | |
|           pix = xvt_dwin_get_text_width(w, row, i); 
 | |
|           if (pix <= max_row_width)
 | |
|             good_len = i;
 | |
|           else
 | |
|             break;
 | |
|         }
 | |
|       }
 | |
|       if (good_len == 0) // Puo' succedere per linee senza spazi o con parole lunghissime
 | |
|       {     
 | |
|         for (good_len = row.len() * max_row_width / w + 1; good_len > 0; good_len--)
 | |
|         {
 | |
|           const int pix = xvt_dwin_get_text_width(w, row, good_len); 
 | |
|           if (pix < max_row_width)
 | |
|             break;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       TString next_row = row.mid(good_len);
 | |
|       next_row.ltrim();
 | |
|       para.insert(next_row, i+1);
 | |
|       row.cut(good_len);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   int h = para.items() * ky10 * 100 / def_10row_height;
 | |
|   const int resto = h % 100;
 | |
|   if (resto != 0)
 | |
|     h += 100-resto;
 | |
|   rect.set_height(h);
 | |
| 
 | |
|   return ky10;
 | |
| }
 | |
| 
 | |
| TPoint TBook::page_size() const
 | |
| {
 | |
|   if (_pw <= 0 || _ph <= 0) // Valori nulli: mi invento un A4
 | |
|   {
 | |
|     TPoint pag = page_res();
 | |
|     pag.x *= 8; pag.y *= 11;
 | |
|     return pag;
 | |
|   }
 | |
|   return TPoint(_pw, _ph);
 | |
| }
 | |
| 
 | |
| TPoint TBook::page_res() const
 | |
| {
 | |
|   const int resx = _phr > 0 ? _phr : 96;
 | |
|   const int resy = _pvr > 0 ? _pvr : 96;
 | |
|   return TPoint(resx, resy);
 | |
| }
 | |
| 
 | |
| bool TBook::open_page()
 | |
| {
 | |
|   if (_out == NULL)  // Sto per scrivere la prima pagina
 | |
|   {
 | |
|     _out = new ofstream(_file);
 | |
|     _max_frame = 0;  // Azzero la dimensione del massimo frame
 | |
|   }
 | |
| 
 | |
|   _page++;
 | |
|   _index.add_long(_out->tellp(), page()); // Scrive alla posizione 1 l'inizio di pagina 1
 | |
|  
 | |
|   *_out << "<page number=" << page() << '>' << endl;
 | |
| 
 | |
|   memset(&_tools, 0, sizeof(_tools));
 | |
|   _font.create("", 12, XVT_FA_ALL);
 | |
|   _horizontal_alignment = 'L';
 | |
|   _vertical_alignment = 'T';
 | |
|   _rect.set(-1,-1,0,0);
 | |
| 
 | |
|   _print_aborted = false;
 | |
|   _page_is_open = true;
 | |
|   return _page_is_open;
 | |
| }
 | |
| 
 | |
| bool TBook::close_page()
 | |
| {
 | |
|   if (!_page_is_open)
 | |
|     return false;
 | |
| 
 | |
|   *_out << "</page number=" << page() << '>' << endl;
 | |
| 
 | |
|   _pages++;
 | |
|   _page_is_open = false;
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TBook::set_font(const TReport_font& f)
 | |
| {
 | |
|   if (f != _font)
 | |
|   {
 | |
|     _font = f;
 | |
|     *_out << "<font"
 | |
|           << " name=\"" << f.name() << '"'
 | |
|           << " size=" << f.size()
 | |
|           << " style=" << f.style() 
 | |
|           << " />" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::define_frame(const TRectangle& rect)
 | |
| {
 | |
|   if (rect != _rect)
 | |
|   {
 | |
|     _rect = rect;
 | |
|     *_out << "<frame"
 | |
|           << " x=" << _rect.x << " y=" << _rect.y
 | |
|           << " dx=" << _rect.width() << " dy=" << _rect.height()
 | |
|           << " />" << endl;
 | |
|     if (_rect.right() > _max_frame)
 | |
|       _max_frame = _rect.right();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::set_clip(long top, long bottom)
 | |
| {
 | |
|   if (bottom >= top)
 | |
|   {
 | |
|     const TRectangle rect(0, top, logical_page_width(), bottom-top);
 | |
|     define_frame(rect);
 | |
|     *_out << "<clip>" << endl;
 | |
|   }
 | |
|   else
 | |
|     *_out << "</clip>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_text(const TRectangle& r, const char* txt)
 | |
| {
 | |
|   const TFixed_string str(txt);
 | |
|   if (str.full())
 | |
|   {
 | |
|     define_frame(r);
 | |
|     *_out << "<text>" << endl << str << endl << "</text>" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::draw_text(const TRectangle& r, const TString_array& txt)
 | |
| {
 | |
|   if (!txt.empty())
 | |
|   {
 | |
|     define_frame(r);
 | |
|     *_out << "<text>" << endl;
 | |
|     for (int i = 0; i < txt.items(); i++)
 | |
|     {
 | |
|       const char* line = txt.row(i);
 | |
|       *_out << line << endl; 
 | |
|     }
 | |
|     *_out << "</text>" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::draw_book_pages(const TRectangle& r)
 | |
| {
 | |
|   define_frame(r);
 | |
|   *_out << "<pages/>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::set_pen(COLOR color, int width, PEN_STYLE style)
 | |
| {
 | |
|   if (_tools.pen.color != color || _tools.pen.width != width || _tools.pen.style != style)
 | |
|   {
 | |
|     _tools.pen.color = color;
 | |
|     _tools.pen.width = width;
 | |
|     _tools.pen.style = style;
 | |
|     *_out << "<pen color=" << color 
 | |
|           << " width=" << width 
 | |
|           << " style=" << style << " />" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::set_brush(COLOR color, PAT_STYLE pattern)
 | |
| {
 | |
|   if (_tools.brush.color != color || _tools.brush.pat != pattern)
 | |
|   {
 | |
|     _tools.brush.color = color;
 | |
|     _tools.brush.pat = pattern;
 | |
|     *_out << "<brush color=" << color << " pattern=" << pattern << " />" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::set_text_color(COLOR fore, COLOR back, bool opaque)
 | |
| {
 | |
|   if (_tools.fore_color != fore || _tools.back_color != back || _tools.opaque_text != short(opaque))
 | |
|   {
 | |
|     _tools.fore_color = fore;
 | |
|     _tools.back_color = back;
 | |
|     _tools.opaque_text = opaque;
 | |
|     *_out << "<text_color fore=" << fore 
 | |
|           << " back=" << back 
 | |
|           << " opaque=" << opaque << " />" << endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TBook::set_text_align(char halign, char valign)
 | |
| {
 | |
|   if (_horizontal_alignment != halign || _vertical_alignment != valign)
 | |
|   {
 | |
|     _horizontal_alignment = halign;
 | |
|     _vertical_alignment = valign;
 | |
|     *_out << "<text_align horizontal=" << halign << " vertical=" << valign << " />" << endl;
 | |
|   }
 | |
| }
 | |
|  
 | |
| void TBook::draw_rectangle(const TRectangle& r)
 | |
| {
 | |
|   define_frame(r);
 | |
|   *_out << "<rectangle/>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_round_rectangle(const TRectangle& r, int radius)
 | |
| {
 | |
|   define_frame(r);
 | |
|   *_out << "<rounded_rectangle radius=" << radius << " />" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_ellipse(const TRectangle& r)
 | |
| {
 | |
|   define_frame(r);
 | |
|   *_out << "<ellipse/>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_line(const TRectangle& r)
 | |
| {
 | |
|   define_frame(r);
 | |
|   *_out << "<line/>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_link(const TRectangle& rect, const char* text, const char* link)
 | |
| {
 | |
|   define_frame(rect);
 | |
|   *_out << "<a href=\"" << link << "\" >" << text << "</a>" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::draw_image(const TRectangle& rect, const char* name)
 | |
| {
 | |
|   define_frame(rect);
 | |
|   *_out << "<image src=\"" << name << "\" />" << endl;
 | |
| }
 | |
| 
 | |
| void TBook::add_doc(const TString& name)
 | |
| {
 | |
|   TBook::open_page();
 | |
|   *_out << "<doc url=\"" << name << "\" />"<< endl;
 | |
|   TBook::close_page();
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Reading a page
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| bool get_xml_string(const TString& line, const char* attr, TString& value)
 | |
| {
 | |
|   TString80 str; str << ' ' << attr << '=';
 | |
|   const int pos = line.find(str);
 | |
|   if (pos >= 0)
 | |
|   {
 | |
|     const int apicia = pos + strlen(attr) + 2;
 | |
|     if (line[apicia] == '"')
 | |
|     {
 | |
|       const int apicic = line.find('"', apicia+1);
 | |
|       if (apicic > apicia)
 | |
|       {
 | |
|         value = line.sub(apicia+1, apicic);
 | |
|         return true;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       const int space = line.find(' ', apicia);
 | |
|       if (space > 0)
 | |
|       {
 | |
|         value = line.sub(apicia, space);
 | |
|         return true;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| int get_xml_int(const TString& line, const char* attr, int def)
 | |
| {
 | |
|   TString16 str;
 | |
|   if (get_xml_string(line, attr, str))
 | |
|     def = atoi(str);
 | |
|   return def;
 | |
| }
 | |
| 
 | |
| void TBook::print_doc(TWindow& win, const TFilename& name)
 | |
| {
 | |
|   const bool print = win.win() == 883;
 | |
| 
 | |
|   if (print)
 | |
|   {
 | |
|     TWindow_printer& wp = (TWindow_printer&)win;
 | |
|     wp.print_doc(name);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     TPoint ps = page_size();
 | |
|     TRectangle rect(TPoint(0,0), ps);
 | |
|     RCT page; win.log2dev(rect, page);
 | |
|     advanced_draw_text_line(win, name, page, 'C', 'T');
 | |
| 
 | |
|     TString8 ext = name.ext(); ext.lower();
 | |
|     if (ext == "bmp" || ext == "gif" || ext == "jpg" || ext == "jpeg")
 | |
|     {
 | |
|       const TImage* img = _images.image(name);
 | |
|       if (img != NULL)
 | |
|       {
 | |
|         const TPoint pr = page_res();
 | |
|         rect.deflate(pr.x/2, pr.y/2);
 | |
|         win.log2dev(rect, page);
 | |
| 
 | |
|         const double sx = double(page.right) / double(img->width());
 | |
|         const double sy = double(page.bottom) / double(img->height());
 | |
|         const double s = sx < sy ? sx : sy;
 | |
|         const int w = int(s * img->width());
 | |
|         const int h = int(s * img->height());
 | |
|         RCT rct; 
 | |
|         rct.left = (page.right+page.left-w)/2; rct.right = rct.left + w;
 | |
|         rct.top  = (page.bottom+page.top-h)/2; rct.bottom = rct.top + h;
 | |
|         img->draw(win.win(), rct);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TBook::print_page(TWindow& win, size_t page)
 | |
| {
 | |
|   if (page <= 0 || page > pages()) 
 | |
|     return false;
 | |
| 
 | |
|   WINDOW w = win.win();
 | |
|   const bool preview = w != PRINTER_WIN;
 | |
|   RCT visible;
 | |
|   if (preview)
 | |
|   {
 | |
|     xvt_vobj_get_client_rect(w, &visible);
 | |
|     TPrint_preview_window& pw = (TPrint_preview_window&)win;
 | |
|     pw.alinks().destroy();
 | |
|   }
 | |
|  
 | |
|   const int buffer_size = 1024;
 | |
|   TString str(buffer_size);
 | |
|   char* buffer = str.get_buffer();
 | |
| 
 | |
|   TString_array paragrafo; // Testo completo di un campo
 | |
| 
 | |
|   // Calcolo altezza riga standard
 | |
|   const TRectangle rect_riga(0,0,1000,1000);
 | |
|   RCT rct_riga; win.log2dev(rect_riga, rct_riga);
 | |
|   const int default_10row_height = rct_riga.bottom - rct_riga.top;
 | |
| 
 | |
|   const streampos pos = _index.get_long(page);
 | |
|   ifstream ifs(_file);
 | |
|   ifs.seekg(pos);
 | |
| 
 | |
|   _rect.set(-1,-1,0,0); // Reset frame
 | |
|   RCT rct = { 0,0,0,0 };
 | |
| 
 | |
|   _horizontal_alignment = 'L'; // Reset text alignment
 | |
|   _vertical_alignment = 'T';
 | |
| 
 | |
|   bool page_is_open = false; // Stato attuale della pagina della stampante
 | |
|   
 | |
|   while (!ifs.eof())
 | |
|   {
 | |
|     ifs.getline(buffer, str.size());
 | |
|     if (str.starts_with("</page"))
 | |
|       break;
 | |
| 
 | |
|     if (str.starts_with("<page "))
 | |
|     {
 | |
|       // Non apro ora la pagina sulla stampante perche' potrei incontrare un allegato
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     if (str.starts_with("<doc")) // Stampa il documento allegato senza aprire la pagina su carta
 | |
|     {
 | |
|       TFilename name; get_xml_string(str, "url", name);
 | |
|       print_doc(win, name);
 | |
|       continue;
 | |
|     }
 | |
|     
 | |
|     // Per i comandi successivi serve una pagina aperta!
 | |
|     if (!page_is_open && !preview)
 | |
|     {
 | |
|       page_is_open = xvt_print_open_page(_rcd) != 0;
 | |
|       if (!page_is_open) 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     if (str.starts_with("<a "))
 | |
|     {
 | |
|       if (preview && rct.bottom >= visible.top && rct.top <= visible.bottom)
 | |
|       {
 | |
|         TString link;
 | |
|         if (get_xml_string(str, "href", link))
 | |
|         {
 | |
|           TPrint_preview_window& pw = (TPrint_preview_window&)win;
 | |
|           TAssoc_array& links = pw.alinks();
 | |
| 
 | |
|           TToken_string tok(link, '.');
 | |
|           TString80 table, field, key;
 | |
|           tok.get(0, table); tok.get(1, field);
 | |
| 
 | |
|           key << table << ',' << _rect.y;
 | |
|           TReport_link* rl = (TReport_link*)links.objptr(key);
 | |
|           if (rl == NULL)
 | |
|           {
 | |
|             rl = new TReport_link(table);
 | |
|             links.add(key, rl);
 | |
|           }
 | |
| 
 | |
|           const int inizio = str.find('>')+1;
 | |
|           const int fine = str.rfind('<');
 | |
|           const TString& stringona = str.sub(inizio, fine);
 | |
|           rl->set(field, stringona);
 | |
|           rl->add_rect(rct);
 | |
| 
 | |
|           if (stringona.full() && rct.right > rct.left) // Possono esserci campi chiave nascosti
 | |
|           {
 | |
|             DRAW_CTOOLS dct;
 | |
|             xvt_dwin_get_draw_ctools(w, &dct);
 | |
| 
 | |
|             XVT_FNTID oldfont = xvt_dwin_get_font(w);
 | |
|             XVT_FNTID newfont = xvt_font_create();
 | |
|             xvt_font_copy(newfont, oldfont, XVT_FA_ALL);
 | |
|             xvt_font_set_style(newfont, xvt_font_get_style(oldfont) | XVT_FS_UNDERLINE);
 | |
|             xvt_dwin_set_font(w, newfont);
 | |
|             win.set_color(COLOR_BLUE, dct.back_color);
 | |
|             advanced_draw_text_line(win, stringona, rct, _horizontal_alignment, _vertical_alignment);
 | |
|             win.set_color(dct.fore_color, dct.back_color);
 | |
|             xvt_dwin_set_font(w, oldfont);
 | |
|             xvt_font_destroy(newfont);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<brush "))
 | |
|     {
 | |
|       COLOR col = COLOR_BLACK; 
 | |
|       PAT_STYLE pat = PAT_SOLID;
 | |
|       sscanf(str, "<brush color=%u pattern=%u />", &col, &pat);
 | |
|       if (pat <= PAT_HOLLOW)
 | |
|         win.hide_brush();
 | |
|       else
 | |
|         win.set_brush(col, pat);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<clip"))
 | |
|     {
 | |
|       xvt_dwin_set_clip(w, &rct);
 | |
|     } else
 | |
| 
 | |
| 
 | |
|     if (str.starts_with("</clip"))
 | |
|     {
 | |
|       xvt_dwin_set_clip(w, NULL);
 | |
|     } else
 | |
| 
 | |
| 
 | |
|     if (str == "<ellipse/>")
 | |
|     {
 | |
|       xvt_dwin_draw_oval(w, &rct);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<frame "))
 | |
|     {
 | |
|       long x, y, dx, dy;
 | |
|       sscanf(str, "<frame x=%ld y=%ld dx=%ld dy=%ld />", &x, &y, &dx, &dy);
 | |
|       _rect.set(x, y, dx, dy);
 | |
|       win.log2dev(_rect, rct);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<font "))
 | |
|     {
 | |
|       TString80 name = DEFAULT_FONT_NAME; get_xml_string(str, "name", name);
 | |
|       const int size = get_xml_int(str, "size", 12);
 | |
|       const XVT_FONT_STYLE_MASK style = get_xml_int(str, "style", 0);
 | |
|       TReport_font font; font.create(name, size, style);
 | |
|       if (preview)
 | |
|         xvt_dwin_set_font(w, font.get_preview_font(win, page_res()));
 | |
|       else
 | |
|         xvt_dwin_set_font(w, font.get_xvt_font(win));
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<image "))
 | |
|     {
 | |
|       TFilename name; get_xml_string(str, "src", name);
 | |
|       TImage* img = _images.image(name);
 | |
|       if (img != NULL)
 | |
|       {
 | |
|         if (is_pdf())
 | |
|         {
 | |
|           name.custom_path();
 | |
|           xvt_dwin_draw_image_on_pdf(w, name, &rct);
 | |
|         }
 | |
|         else
 | |
|           img->draw(w, rct);
 | |
|       }
 | |
| 
 | |
|       continue;
 | |
|     }
 | |
|     if (str == "<line/>")
 | |
|     {
 | |
|       const PNT fr = { rct.top, rct.left };
 | |
|       const PNT to = { rct.bottom, rct.right };
 | |
|       xvt_dwin_draw_set_pos(w, fr);
 | |
|       xvt_dwin_draw_line(w, to);
 | |
| 
 | |
|       continue;
 | |
|     }
 | |
|     if (str == "<pages/>")
 | |
|     {
 | |
|       TString8 str; str.format("%u", pages());
 | |
|       advanced_draw_text_line(win, str, rct, _horizontal_alignment, _vertical_alignment);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<pen "))
 | |
|     {
 | |
|       COLOR col = COLOR_BLACK; 
 | |
|       int width = 0;
 | |
|       PEN_STYLE style = P_SOLID;
 | |
|       sscanf(str, "<pen color=%u width=%d style=%u />", &col, &width, &style);
 | |
|       if (width < 0)
 | |
|         win.hide_pen();
 | |
|       else
 | |
|       {
 | |
|         if (preview)
 | |
|           win.set_pen(col, width);
 | |
|         else
 | |
|           win.set_pen(col, width * _phr / 72); // Converte width in 72' di pollice
 | |
|       }
 | |
|       continue;
 | |
|     }
 | |
|     if (str == "<rectangle/>")
 | |
|     {
 | |
|       xvt_dwin_draw_rect(w, &rct);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<rounded_rectangle"))
 | |
|     {
 | |
|       const int radius = get_xml_int(str, "radius", 0);
 | |
|       
 | |
|       const TRectangle rr(0,0,radius,radius);
 | |
|       RCT re; win.log2dev(rr, re);
 | |
|       const int rad = (re.right-re.left) * lpi() / (cpi() * 2);
 | |
|       xvt_dwin_draw_roundrect(w, &rct, rad, rad);
 | |
|       continue;
 | |
|     }
 | |
|     if (str == "<text>")
 | |
|     {
 | |
|       paragrafo.destroy();
 | |
|       while (!ifs.eof())
 | |
|       {
 | |
|         ifs.getline(buffer, str.size());
 | |
|         if (str == "</text>")
 | |
|           break;
 | |
|         paragrafo.add(str);
 | |
|       }
 | |
|       advanced_draw_paragraph(win, paragrafo, rct, 
 | |
|                               _horizontal_alignment, _vertical_alignment,
 | |
|                               default_10row_height);
 | |
| 
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<text_align "))
 | |
|     {
 | |
|       sscanf(str, "<text_align horizontal=%c vertical=%c />", 
 | |
|              &_horizontal_alignment, &_vertical_alignment);
 | |
|       continue;
 | |
|     }
 | |
|     if (str.starts_with("<text_color"))
 | |
|     {
 | |
|       COLOR fore, back;
 | |
|       int opaque; 
 | |
|       sscanf(str, "<text_color fore=%u back=%u opaque=%d />", &fore, &back, &opaque);
 | |
|       win.set_color(fore, back);
 | |
|       win.set_opaque_text(opaque != 0);
 | |
|       continue;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (preview)
 | |
|   {
 | |
|     TPrint_preview_window& pw = (TPrint_preview_window&)win;
 | |
|     TAssoc_array& alinks = pw.alinks();
 | |
|     TPointer_array& plinks = pw.plinks();   
 | |
|     plinks.destroy();
 | |
|     if (alinks.items() > 0)
 | |
|     {
 | |
|       FOR_EACH_ASSOC_OBJECT(alinks, h, key, l)
 | |
|         plinks.add((TReport_link*)l);
 | |
|       plinks.sort();
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (page_is_open)
 | |
|       xvt_print_close_page(_rcd);
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TBook::export_text(const TFilename& fname)
 | |
| {
 | |
|   const TFixed_string ext(fname.ext());
 | |
|   if (ext.compare("pdf", true) == 0)
 | |
|     export_pdf(fname);
 | |
| 
 | |
|   TString str(1024);
 | |
|   char* buffer = str.get_buffer();
 | |
| 
 | |
|   ifstream ifs(_file);
 | |
|   ofstream ofs(fname);
 | |
| 
 | |
|   TString_array page;
 | |
|   int row, col, wid, hei;
 | |
| 
 | |
|   const TPoint res = page_res();
 | |
| 
 | |
|   while (!ifs.eof())
 | |
|   {
 | |
|     ifs.getline(buffer, str.size());
 | |
| 
 | |
|     if (str.starts_with("<frame "))
 | |
|     {
 | |
|       long x, y, dx, dy;
 | |
|       sscanf(str, "<frame x=%ld y=%ld dx=%ld dy=%ld />", &x, &y, &dx, &dy);
 | |
|       row = y * lpi() / res.y;
 | |
|       col = x * cpi() / res.x;
 | |
|       wid = dx * cpi() / res.x;
 | |
|       hei = dy * lpi() / res.y;
 | |
|     } else
 | |
|     if (str == "<line/>")
 | |
|     {
 | |
|       if (hei == 0 && wid > 0)
 | |
|       {
 | |
|         if (page.objptr(row) == NULL)
 | |
|           page.add("", row);
 | |
|         TString& line = page.row(row);
 | |
|         for (int i = 0; i < wid; i++)
 | |
|         {
 | |
|           const int j = i+col;
 | |
|           if (j >= line.len())
 | |
|             line.overwrite("-", j);
 | |
|           else
 | |
|           {
 | |
|             if (line[j] == '|')
 | |
|               line[j] = '+';
 | |
|             else
 | |
|             {
 | |
|               if (line[j] == ' ')
 | |
|                 line[j] = '-';
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       } else
 | |
|       if (hei > 0 && wid == 0)
 | |
|       {
 | |
|         for (int i = row; i < row+hei; i++)
 | |
|         {
 | |
|           if (page.objptr(i) == NULL)
 | |
|             page.add("", i);
 | |
|           TString& line = page.row(i);
 | |
|           if (line.len() <= col)
 | |
|             line.overwrite("|", col);
 | |
|           else
 | |
|           {
 | |
|             if (line[col] == '-')
 | |
|               line[col] = '+';
 | |
|             else
 | |
|             {
 | |
|               if (line[col] == ' ')
 | |
|                 line[col] = '|';
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     if (str.starts_with("<page "))
 | |
|     {
 | |
|       page.destroy();
 | |
|     } else
 | |
|     if (str.starts_with("</page "))
 | |
|     {
 | |
|       const int last_row = page.last();
 | |
|       for (int i = 0; i <= last_row; i++)
 | |
|       {
 | |
|         const TString* line = (const TString*)page.objptr(i);
 | |
|         if (line != NULL)
 | |
|           ofs << *line;
 | |
|         ofs << endl;
 | |
|       }
 | |
|     } else
 | |
|     if (str == "<pages/>")
 | |
|     {
 | |
|       TString8 str; str.format("%u", pages());
 | |
|       TString& line = page.row(row);
 | |
|       switch (_horizontal_alignment)
 | |
|       {
 | |
|       case 'C': line.overwrite(str, col+(wid-str.len())/2); break;
 | |
|       case 'R': line.overwrite(str, col+wid-str.len()); break;
 | |
|       default : line.overwrite(str, col); break;
 | |
|       }      
 | |
|     } else
 | |
|     if (str == "<text>")
 | |
|     {
 | |
|       TString stringona;
 | |
|       while (!ifs.eof())
 | |
|       {
 | |
|         ifs.getline(buffer, str.size());
 | |
|         if (str == "</text>")
 | |
|           break;
 | |
|         stringona << str << '\n';
 | |
|       }
 | |
|       stringona.rtrim();
 | |
|       TParagraph_string para(stringona, wid);
 | |
|       for (int i = 0; i < hei && i < para.items(); i++)
 | |
|       {
 | |
|         const int j = row+i;
 | |
|         if (page.objptr(j) == NULL)
 | |
|           page.add("", j);
 | |
|         str = para.get();
 | |
|         TString& line = page.row(j);
 | |
|         switch (_horizontal_alignment)
 | |
|         {
 | |
|         case 'C': line.overwrite(str, col+(wid-str.len())/2); break;
 | |
|         case 'R': line.overwrite(str, col+wid-str.len()); break;
 | |
|         default : line.overwrite(str, col); break;
 | |
|         }      
 | |
|       }
 | |
|     } else
 | |
|     if (str.starts_with("<text_align "))
 | |
|     {
 | |
|       sscanf(str, "<text_align horizontal=%c vertical=%c />", 
 | |
|              &_horizontal_alignment, &_vertical_alignment);
 | |
|       continue;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TBook::init()
 | |
| {
 | |
|   if (is_pdf())
 | |
|   {
 | |
|     int size;
 | |
|     _rcd = xvt_print_create_by_name(&size, XVT_PDF_PRINTER_NAME);
 | |
|   }
 | |
|   else
 | |
|     _rcd = printer().get_printrcd();
 | |
| 
 | |
|   if (!xvt_print_is_valid(_rcd))
 | |
|     return error_box(TR("Stampante non valida"));
 | |
| 
 | |
|   xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, _rcd, &_ph, &_pw, &_pvr, &_phr);
 | |
| 
 | |
|   if (_pw <= 0 || _ph <= 0)
 | |
|     return error_box(TR("Dimensioni pagina NULLE"));
 | |
| 
 | |
|   _ph = _ph * BOOKDPI / _pvr;
 | |
|   _pw = _pw * BOOKDPI / _phr;
 | |
|   _pvr = _phr = BOOKDPI;
 | |
| 
 | |
|   if (_printwin != NULL)
 | |
|     delete _printwin;
 | |
|   _printwin = new TWindow_printer(_rcd, _pdf_file);
 | |
|   
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TBook::close_output()
 | |
| {
 | |
|   if (_out != NULL)
 | |
|   {
 | |
|     _out->close();
 | |
|     delete _out;
 | |
|   }
 | |
|   _out = NULL;
 | |
| }
 | |
| 
 | |
| bool TBook::split_file_if_needed()
 | |
| {
 | |
|   const int mf = (_max_frame * _phr) / (100 * cpi());   // log2dev dei poveri
 | |
|   const int colonne = (mf+_pw-1) / _pw;
 | |
|   if (colonne < 2)
 | |
|     return false;
 | |
| 
 | |
|   TString str(1024);
 | |
|   str.format(FR("Spezzatura delle pagine su %d fogli"), colonne);
 | |
| 
 | |
|   if (!yesno_box(str))
 | |
|     return false;
 | |
|   
 | |
|   TProgind pi(pages(), str, true, true);
 | |
| 
 | |
|   TFilename temp; temp.temp();
 | |
|   ofstream out(temp);
 | |
|   TPointer_array index;
 | |
|   
 | |
|   close_output();  // Chiudo file di stampa eventualmente aperto
 | |
|   ifstream ifs(_file); // Apro file di stampa da splittare
 | |
| 
 | |
|   char* buffer = str.get_buffer();
 | |
|   for (unsigned int page = 1; page <= pages(); page++) 
 | |
|   {
 | |
|     if (!pi.setstatus(page))
 | |
|       break;
 | |
|     const streampos pos = _index.get_long(page);
 | |
|     for (int c = 0; c < colonne; c++)
 | |
|     {
 | |
|       const TRectangle rct_page(c*_pw, 0, _pw, _ph);
 | |
|       
 | |
|       ifs.seekg(pos);
 | |
|       while (!ifs.eof())
 | |
|       {
 | |
|         ifs.getline(buffer, str.size());
 | |
|         
 | |
|         if (str.starts_with("<page "))
 | |
|         {
 | |
|           const int p = (page-1)*colonne+1+c;
 | |
|           index.add_long(out.tellp(), p);
 | |
|           str.format("<page number=%d>", p);
 | |
|         } else
 | |
|         if (str.starts_with("<frame "))
 | |
|         {
 | |
|           long x, y, dx, dy;
 | |
|           sscanf(str, "<frame x=%ld y=%ld dx=%ld dy=%ld />", &x, &y, &dx, &dy);
 | |
|           str.format("<frame x=%ld y=%ld dx=%ld dy=%ld />", x-rct_page.x, y, dx, dy);
 | |
|         } else
 | |
|         if (str.starts_with("</page "))
 | |
|         {
 | |
|           str.format("</page number=%d>", index.last());
 | |
|         }
 | |
| 
 | |
|         out << str << endl;
 | |
|         if (str.starts_with("</page "))
 | |
|           break;
 | |
|       } 
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   out.close();
 | |
|   
 | |
|   // Sostituisce il file di stampa con quello splittato ed aggiorna l'indice delle pagine
 | |
|   fcopy(temp, _file);
 | |
|   xvt_fsys_removefile(temp);
 | |
|   _index = index;
 | |
|   _pages = _index.last();
 | |
|   _max_frame = 0; // Impedisce ulteriore splitting
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TBook::main_loop()
 | |
| {
 | |
|   _print_aborted = true;
 | |
|   if (!init())
 | |
|     return false;
 | |
| 
 | |
|   if (_pageto < _pagefrom)
 | |
|     _pageto = pages();
 | |
| 
 | |
|   _print_aborted = false;
 | |
|   for (size_t c = 0; c < _copies && !_print_aborted; c++)
 | |
|   {
 | |
|     for (size_t page = _pagefrom; page <= _pageto && !_print_aborted; page++)
 | |
|     {
 | |
|       if (!print_page( *_printwin, page))
 | |
|         _print_aborted = true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (is_pdf())
 | |
|   {
 | |
|     xvt_print_destroy(_rcd);
 | |
|     _rcd = NULL;
 | |
|   }
 | |
| 
 | |
|   return !_print_aborted;
 | |
| }
 | |
| 
 | |
| static BOOLEAN main_loop_callback(long jolly)
 | |
| {
 | |
|   TBook* pp = (TBook*)jolly;
 | |
|   return pp->main_loop();
 | |
| }
 | |
| 
 | |
| bool TBook::print(size_t pagefrom, size_t pageto, size_t copies)
 | |
| {
 | |
|   bool ok = pages() > 0;
 | |
|   if (ok) 
 | |
|   {
 | |
|     if (pagefrom == 0)
 | |
|     {
 | |
|       TPrinter& p = printer();
 | |
|       TMask msk("bagn003");
 | |
|       msk.set(F_PRINTER, p.printername());
 | |
|       msk.set(F_FORM, p.get_form_name());
 | |
|       msk.set(F_FONT, p.fontname());
 | |
|       msk.set(F_SIZE, p.get_char_size());
 | |
|     
 | |
|       msk.set(F_ISGRAPHICS, p.isgraphics() ? "X" : "");
 | |
|       msk.set(F_FROMPAGE, 1);
 | |
|       msk.set(F_TOPAGE, pages());
 | |
|       msk.set(F_COPIES, 1);
 | |
|       if (msk.run() == K_ENTER)
 | |
|       {
 | |
|         _copies = msk.get_int(F_COPIES);
 | |
|         _pagefrom = msk.get_int(F_FROMPAGE);
 | |
|         _pageto = msk.get_int(F_TOPAGE);
 | |
|       }
 | |
|       else
 | |
|         return false;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       _pagefrom = pagefrom;
 | |
|       _pageto = pageto;
 | |
|       _copies = copies;
 | |
|     }
 | |
| 
 | |
|     _pdf_file.cut(0);
 | |
|     ok = xvt_print_start_thread(main_loop_callback, (long)this) != 0;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TBook::export_pdf(const TFilename& filename)
 | |
| {
 | |
|   bool ok = (pages() > 0) && dongle().active(RSAUT);
 | |
|   if (ok)
 | |
|   {
 | |
|     _pdf_file = filename;
 | |
|     _pagefrom = 1;
 | |
|     _pageto = 0;
 | |
|     _copies = 1;
 | |
|     ok = xvt_print_start_thread(main_loop_callback, (long)this) != 0;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TBook::esporta()
 | |
| {
 | |
|   if (pages() <= 0)
 | |
|     return false;
 | |
| 
 | |
|   split_file_if_needed();
 | |
| 
 | |
|   const KEY key = spotlite_ask_name(_pdf_file);
 | |
|   bool ok = key >= 'A' && key <= 'Z';
 | |
|   switch (key)
 | |
|   {
 | |
|   case 'A': 
 | |
|     ok = archive(); 
 | |
|     break;
 | |
|   case 'E': 
 | |
|     ok = export_text(_pdf_file); 
 | |
|     if (ok)
 | |
|       xvt_sys_goto_url(_pdf_file, "open");
 | |
|     break;
 | |
|   case 'M':
 | |
|     ok = send_mail(_pdf_file);
 | |
|     break;
 | |
|   case 'P': 
 | |
|     ok = export_pdf(_pdf_file); 
 | |
|     if (ok)
 | |
|       xvt_sys_goto_url(_pdf_file, "open");
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TBook::archive(const char* repname)
 | |
| {
 | |
|   TFilename pdf; 
 | |
|   bool ok = spotlite_generate_name(repname, pdf);
 | |
|   if (ok)
 | |
|   {
 | |
|     ok = export_pdf(pdf);
 | |
|     if (ok)
 | |
|       spotlite_notify(pdf);
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TBook::send_mail(const TFilename& file)
 | |
| {
 | |
|   bool ok = export_pdf(file);
 | |
|   if (ok)
 | |
|     ok = spotlite_send_mail(file);
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TBook::preview()
 | |
| {
 | |
|   split_file_if_needed();
 | |
| 
 | |
|   TPreview_mask msk(this);
 | |
|   const KEY k = msk.run();
 | |
|   switch (k)
 | |
|   {
 | |
|   case K_QUIT: break;
 | |
|   case K_SAVE: esporta(); break;
 | |
|   default    : print(); break;      
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TBook::print_or_preview()
 | |
| {
 | |
|   bool ok = true;
 | |
|   switch (printer().printtype())
 | |
|   {
 | |
|   case screenvis: 
 | |
|     ok = preview(); 
 | |
|     break;
 | |
|   case exportprinter:
 | |
|     {
 | |
|       const TFilename f = printer().get_export_file();
 | |
|       ok = export_text(f);
 | |
|       if (ok)
 | |
|         xvt_sys_goto_url(f, "open");
 | |
|     }
 | |
|     break;
 | |
|   default:
 | |
|     ok = print();
 | |
|     break;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TBook::TBook(const char* name) 
 | |
|      : _out(NULL), _is_temporary(false),
 | |
|        _pw(0), _ph(0), _pvr(0), _phr(0), _max_frame(0),
 | |
|        _pages(0), _page(0), _rcd(NULL), _printwin(NULL), _page_is_open(false)
 | |
| 
 | |
| 
 | |
| {
 | |
|   _file = name;
 | |
|   if (_file.blank())
 | |
|   {
 | |
|     _file.temp("rep");
 | |
|     _is_temporary = true;
 | |
|   }
 | |
| }
 | |
| 
 | |
| TBook::~TBook()
 | |
| {
 | |
|   close_output();
 | |
|   if (_is_temporary)
 | |
|     xvt_fsys_removefile(_file);
 | |
| 
 | |
|   if (_printwin != NULL)
 | |
|     delete _printwin;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TPrintind
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TPrintind : public TProgind
 | |
| {
 | |
|   TArray _modules;
 | |
| 
 | |
| protected:
 | |
|   virtual void update_bar();
 | |
| 
 | |
| public:
 | |
|   TPrintind(long n, const char* msg);
 | |
| };
 | |
| 
 | |
| void TPrintind::update_bar()
 | |
| {
 | |
|   TProgind::update_bar();
 | |
| 
 | |
|   const int m = _modules.items();
 | |
|   if (m > 0) // come dire ADVANCED_GRAPHICS
 | |
|   {
 | |
|     const int n = _status * 100 / _max;
 | |
|     const TImage& img = (const TImage&)_modules[n%m];
 | |
|     RCT r; get_bar_rct(r);
 | |
|     img.draw(win(), r.right - img.width(), r.bottom + 2);
 | |
|   }
 | |
| }
 | |
| 
 | |
| TPrintind::TPrintind(long n, const char* msg) : TProgind(n, msg, true, true)
 | |
| 
 | |
| {
 | |
|   if (ADVANCED_GRAPHICS)
 | |
|   {
 | |
|     for (int i = 0; i < 4; i++)
 | |
|     {
 | |
|       TImage* img = new TImage(BMP_MODULE1 + i); 
 | |
|       img->convert_transparent_color(MASK_BACK_COLOR);
 | |
|       _modules.add(img);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TReport_book
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void TReport_book::define_frame(const TRectangle& r)
 | |
| {
 | |
|   TPoint ptlog = r; ptlog += _delta;
 | |
|   TPoint szlog = r.size();
 | |
|   const TRectangle rect(log2dev(ptlog), log2dev(szlog));
 | |
|   TBook::define_frame(rect);
 | |
| }
 | |
| 
 | |
| long TReport_book::print_section(char type, int level)
 | |
| {
 | |
|   long h = -3;  // Hidden
 | |
|   TReport_section* rs = _report->find_section(type, level);
 | |
|   if (rs != NULL)
 | |
|     h = print_section(*rs);
 | |
|   return h;
 | |
| }
 | |
| 
 | |
| bool TReport_book::open_page()
 | |
| {
 | |
|   if (!TBook::open_page())
 | |
|     return false;
 | |
| 
 | |
|   _report->set_page(++_rep_page, page());
 | |
| 
 | |
|   _page_break_allowed = false;
 | |
|   _delta.reset();
 | |
| 
 | |
|   TReport_section* page_background = _report->find_section('B', 0);
 | |
|   if (page_background != NULL)
 | |
|   {
 | |
|     _delta = page_background->pos();
 | |
|     print_section(*page_background);
 | |
|     _delta.reset();
 | |
|   }
 | |
| 
 | |
|   if (_rep_page == 1)
 | |
|   {
 | |
|     const long height = print_section('H', 1);
 | |
|     if (height > 0)
 | |
|       _delta.y += height;
 | |
|   }
 | |
| 
 | |
|   TReport_section* page_head = _report->find_section('H', 0);
 | |
|   if (page_head != NULL && (_rep_page > 1 || !page_head->hidden_if_needed()))
 | |
|   {
 | |
|     _delta += page_head->pos();
 | |
|     const long height = print_section(*page_head);
 | |
|     if (height > 0)
 | |
|     {
 | |
|       _delta.y += height;
 | |
|       _delta.x = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TReport_book::close_page()
 | |
| {
 | |
|   if (_page_is_open)
 | |
|   {
 | |
|     TReport_section* page_foot = _report->find_section('F', 0);
 | |
|     if (page_foot != NULL && (!_is_last_page || !page_foot->hidden_if_needed()))
 | |
|     {
 | |
|       _delta.x = page_foot->pos().x;
 | |
|       _delta.y = _logical_foot_pos;
 | |
|       print_section(*page_foot);
 | |
|     }
 | |
|   }
 | |
|   return TBook::close_page();
 | |
| }
 | |
| 
 | |
| void TReport_book::reprint_group_headers(const TReport_section& rs)
 | |
| {
 | |
|   int max_group = _report->find_max_level('H');
 | |
|   if (rs.type() == 'H' && rs.level() <= max_group)
 | |
|     max_group = rs.level()-1;
 | |
| 
 | |
|   for (int level = 2; level <= max_group; level++)
 | |
|   {
 | |
|     TReport_section& rs = _report->section('H', level);
 | |
|     if (rs.repeat_on_page())
 | |
|     {
 | |
|       const long height = rs.compute_size().y; // Compute size after the initilization script!
 | |
|       if (height > 0)
 | |
|       {
 | |
|         rs.print(*this);
 | |
|         _delta.y += height;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (rs.level() > 10) // E' una sottosezione ?
 | |
|   {
 | |
|     TPointer_array headers; // Elenco degli header di sottosezione che devo stampare
 | |
|     for (int level = rs.level(); level > 10; level /= 10)
 | |
|     {
 | |
|       TReport_section& rs = _report->section('H', level);
 | |
|       if (rs.repeat_on_page())
 | |
|       {
 | |
|         const long height = rs.compute_size().y; // Compute size after the initilization script!
 | |
|         if (height > 0)
 | |
|           headers.add(rs);
 | |
|       }
 | |
|     }
 | |
|     for (int i = headers.last(); i >= 0; i--)  // Stampo in ordine livello
 | |
|     {
 | |
|       TReport_section& rs = (TReport_section&)headers[i];
 | |
|       const long height = rs.compute_size().y;
 | |
|       rs.print(*this);
 | |
|       _delta.y += height;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Stampa una sezione e ne ritorna l'altezza.  
 | |
| // In caso di problemi particolari torna un'altezza negativa:
 | |
| // -1 Abort
 | |
| // -2 Condizione di stampa non verificata
 | |
| // -3 Nascosta
 | |
| long TReport_book::print_section(TReport_section& rs)
 | |
| {
 | |
|   if (_print_aborted)
 | |
|     return -1;
 | |
| 
 | |
|   rs.load_fields();
 | |
|   rs.init_dynamic_heights(*this);
 | |
| 
 | |
|   // Non sono sicuro se vada prima di load_fields o dopo execute_prescript
 | |
|   if (rs.condition().full())
 | |
|   {
 | |
|     TVariant var;
 | |
|     _report->evaluate(rs.condition(), var, _alfafld);
 | |
|     if (!var.as_bool())
 | |
|       return -2;
 | |
|   }
 | |
| 
 | |
|   if (!rs.execute_prescript(*this))
 | |
|   {
 | |
|     _print_aborted = true;
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   if (rs.hidden())
 | |
|   {
 | |
|     if (!rs.execute_postscript()) // Faccio ugualmente i post-script
 | |
|       _print_aborted = true;
 | |
|     return -3;
 | |
|   }
 | |
| 
 | |
|   const long height = rs.compute_size().y; // Compute size after the initilization script!
 | |
| 
 | |
|   if (height > 0) // Has some visible fields
 | |
|   {
 | |
|     long reprint_from = 0;  // Posizione di stampa per sezione interrotte a meta'
 | |
| 
 | |
|     bool page_break = _page_break_allowed && rs.page_break(); // Salto pagina "forzato"
 | |
|     if (!page_break && rs.level() > 0)  // Controlla se il salto pagina e' "necessario"
 | |
|     {
 | |
|       long h = height;
 | |
|       if (rs.keep_with_next()) // Devo mantenermi con la prossima sezione
 | |
|       {
 | |
|         char next_type = 'B';  // Spesso la prossima sezione e' body 1
 | |
|         int next_level = 1;
 | |
|         if (rs.type() == 'H')  // Tento di essere piu' preciso con gli headers
 | |
|         {
 | |
|           const int maxlev = rs.report().find_max_level('H'); 
 | |
|           if (rs.level() < maxlev)
 | |
|           {
 | |
|             next_type = 'H';
 | |
|             next_level = rs.level()+1;
 | |
|             h += 100;  // Bonus per il body successivo all'header successivo
 | |
|           }
 | |
|         }
 | |
|         const TReport_section& next_section = rs.report().section(next_type, next_level);
 | |
|         if (next_section.page_break())
 | |
|           h += _ph;
 | |
|         else   
 | |
|           h += next_section.compute_size().y;
 | |
|       }
 | |
|       
 | |
|       const long space_left = _logical_foot_pos - _delta.y; // Calcola spazio rimasto
 | |
|       page_break = h > space_left; // Controlla se e' sufficiente
 | |
|       
 | |
|       // Controllo se la sezione puo' essere stampata su due pagine
 | |
|       if (page_break && space_left >= 100 && rs.can_be_broken())
 | |
|       {
 | |
|         reprint_from = space_left / 100 * 100;
 | |
|         rs.print_clipped(*this, 0, reprint_from);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (page_break)
 | |
|     {
 | |
|       close_page();
 | |
|       open_page();
 | |
|       reprint_group_headers(rs);
 | |
|     }
 | |
|     if (_page_is_open)
 | |
|     {
 | |
|       if (reprint_from > 0)
 | |
|       {
 | |
|         _delta.y -= reprint_from;
 | |
|         rs.print_clipped(*this, reprint_from, height);
 | |
|       }
 | |
|       else
 | |
|         rs.print(*this);
 | |
|     }
 | |
| 
 | |
|     if (rs.level() > 0 && (rs.type() != 'H' || rs.level() > 1)) // Ho stampato qualcosa che non sia lo sfondo!
 | |
| 			_page_break_allowed = true;
 | |
|   }
 | |
| 
 | |
|   if (!rs.execute_postscript())
 | |
|   {
 | |
|     _print_aborted = true;
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   return height;
 | |
| }
 | |
| 
 | |
| bool TReport_book::init(TReport& rep)
 | |
| {
 | |
|   // Controlla orientamento della carta prima di inizializzare
 | |
|   const int report_orientation = rep.orientation();
 | |
|   if (report_orientation > 0)
 | |
|   {
 | |
|     PRINT_RCD* rcd = printer().get_printrcd();
 | |
|     if (xvt_print_is_valid(rcd))
 | |
|     {
 | |
|       long ph, pw, phr, pvr;
 | |
|       xvt_app_escape (XVT_ESC_GET_PRINTER_INFO, rcd, &ph, &pw, &phr, &pvr);
 | |
|       const int priter_orientation = ph > pw ? 1 : 2;
 | |
|       if (report_orientation != priter_orientation)
 | |
|       {
 | |
|         // Scambia orientamento della carta
 | |
|         xvt_app_escape(XVT_ESC_SET_PRINTER_INFO, rcd, &pw, &ph, NULL, NULL);
 | |
|         // I parametri verranno riletti dalla TBook::init()
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!TBook::init())
 | |
|     return false;
 | |
| 
 | |
|   _report = &rep;
 | |
|   if (rep.use_printer_font())
 | |
|     rep.load_printer_font();
 | |
| 
 | |
|   const TPoint siz = page_size();
 | |
|   const TPoint res = page_res();
 | |
| 
 | |
|   const double pollici_pagina_y = (double)siz.y / (double)res.y;
 | |
|   const double righe_pagina = pollici_pagina_y * lpi();
 | |
|   _logical_page_height = long(righe_pagina*100.0);
 | |
| 
 | |
|   const double pollici_pagina_x = (double)siz.x / (double)res.x;
 | |
|   const double colonne_pagina = pollici_pagina_x * cpi();
 | |
|   _logical_page_width = long(colonne_pagina*100.0);
 | |
|   
 | |
|   const TReport_section& footer = _report->section('F',0);
 | |
|   _logical_foot_pos = footer.pos().y;
 | |
|   if (_logical_foot_pos <= 0)
 | |
|   {
 | |
|     const long logical_footer_height = footer.compute_size().y;
 | |
|     _logical_foot_pos = _logical_page_height - logical_footer_height;  
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TReport_book::print_subsections(int father)
 | |
| {
 | |
|   for (int i = 1; i <= 9 && !_print_aborted; i++)
 | |
|   {
 | |
|     const int level = father*10+i;
 | |
|     TReport_section* rs = _report->find_section('B', level);
 | |
|     if (rs == NULL)
 | |
|       break;
 | |
| 
 | |
|     TRecordset* rex = rs->recordset();
 | |
|     if (rex != NULL)
 | |
|     {
 | |
|       rex->requery();
 | |
|       if (rex->items() > 0)
 | |
|       {
 | |
|         long height = print_section('H', level);
 | |
|         if (height > 0)
 | |
|           _delta.y += height;
 | |
|         for (bool ok = rex->move_to(0); ok && !_print_aborted; ok = rex->move_next())
 | |
|         {
 | |
|           height = print_section('B', level);
 | |
|           if (height >= 0)
 | |
|           {
 | |
|             _delta.y += height;
 | |
|             print_subsections(level);
 | |
|           }
 | |
|         }
 | |
|         height = print_section('F', level);
 | |
|         if (height > 0)
 | |
|           _delta.y += height;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TReport_book::add(TReport& rep, bool progind)
 | |
| {
 | |
|   if (!init(rep))
 | |
|     return false;
 | |
| 
 | |
|   if (!_report->execute_prescript())
 | |
|     return false;
 | |
| 
 | |
|   TRecordset* rex = _report->recordset();
 | |
|   if (rex == NULL)
 | |
|     return true;
 | |
| 
 | |
|   rex->requery();
 | |
|   const TRecnotype rex_items = rex->items();
 | |
|   if (rex_items <= 0)
 | |
|     return true;
 | |
| 
 | |
|   TString msg = TR("Elaborazione report");
 | |
|   msg << ' ' << _report->filename();
 | |
|   
 | |
|   TProgind* pi = NULL;
 | |
|   if (progind && rex_items > 1)
 | |
|     pi = new TPrintind(rex_items, msg);
 | |
| 
 | |
|   TString_array oldgroup, newgroup;
 | |
|   const int max_group = _report->find_max_level('H');
 | |
|   if (max_group >= 2)
 | |
|   {
 | |
|     for (int g = 2; g <= max_group; g++)
 | |
|       oldgroup.add(EMPTY_STRING, g);
 | |
|   }
 | |
|   const int max_body = _report->find_max_level('B');
 | |
|   int last_body_height = 0;
 | |
|   
 | |
|   _rep_page = rep.last_printed_page(); // Azzera numero di pagina relativo
 | |
|   _is_last_page = false;
 | |
| 	
 | |
| 	bool ok = rex->move_to(0);
 | |
| 	
 | |
| 	open_page();
 | |
|   for (; ok && !_print_aborted; ok = rex->move_next())
 | |
|   {
 | |
|     if (max_group >= 2) // Gestione raggruppamenti
 | |
|     {
 | |
|       int first_changed = 0;
 | |
|       TVariant var;
 | |
|       for (int g = 2; g <= max_group; g++)
 | |
|       {
 | |
|         const TString& expr = _report->section('H', g).grouped_by();
 | |
|         _report->evaluate(expr, var, _alfafld);
 | |
|         const TString& grp = var.as_string();
 | |
|         newgroup.add(grp, g);
 | |
|         if (newgroup.row(g) != oldgroup.row(g) || rex->current_row() == 0)
 | |
|         {
 | |
|           if (first_changed == 0)
 | |
|             first_changed = g;
 | |
|         }
 | |
|       }
 | |
|       if (first_changed)
 | |
|       {
 | |
|         oldgroup = newgroup;
 | |
| 
 | |
|         if (_delta.x > 0) // Devo tornare a capo!
 | |
|           _delta.y += last_body_height;
 | |
|         _delta.x = 0;
 | |
|         
 | |
|         if (rex->current_row() > 0)
 | |
|         {
 | |
|           for (int g = max_group; g >= first_changed ; g--)
 | |
|           {
 | |
|             const long height = print_section('F', g);
 | |
|             if (height > 0)
 | |
|               _delta.y += height;
 | |
|           }
 | |
|         }
 | |
|         for (int g = first_changed; g <= max_group; g++)
 | |
|         {
 | |
|           const long height = print_section('H', g);
 | |
|           if (height > 0)
 | |
|             _delta.y += height;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     // Stampa di tutti i body
 | |
|     for (int b = 1; b <= max_body; b++)
 | |
|     {
 | |
|       const int dy = print_section('B', b);
 | |
|       if (dy > 0) // Ho stampato fisicamente qualcosa
 | |
|       {
 | |
|         // Cerco di vedere se e' possibile la stampa etichette
 | |
|         int column_delta = 0;
 | |
|         const int dx = _report->section('B', b).size().x;
 | |
|         // Se dx > 0 ho una sezione a dimensione fissa
 | |
|         if (dx > 0 && _delta.x+2*dx <= _logical_page_width)
 | |
|         {
 | |
|           column_delta = dx;
 | |
|           last_body_height = dy;
 | |
|         }
 | |
|       
 | |
|         if (column_delta > 0)
 | |
|           _delta.x += column_delta;
 | |
|         else
 | |
|         {
 | |
|           _delta.x = 0;
 | |
|           _delta.y += dy;
 | |
|           last_body_height = 0; // Non servirebbe strettamente
 | |
|         }  
 | |
|       }
 | |
|       if (dy >= 0)
 | |
|       {
 | |
|         // Stampa eventuali sottosezioni
 | |
|         print_subsections(b);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (pi != NULL)
 | |
|     {
 | |
|       if (!pi->addstatus(1))
 | |
|         _print_aborted = true;
 | |
|     }
 | |
| 
 | |
|   }
 | |
|   if (!_print_aborted)
 | |
|   {
 | |
|     // Devo stampare tutte le code degli eventuali raggrupamenti
 | |
|     for (int g = max_group; g >= 2 ; g--)
 | |
|     {
 | |
|       const long height = print_section('F', g);
 | |
|       if (height > 0)
 | |
|         _delta.y += height;
 | |
|     }
 | |
| 
 | |
|     TReport_section* fl = _report->find_section('F',1);
 | |
|     if (fl != NULL)          // Gestione footer last (se esite)
 | |
|     {
 | |
|       const int fy = fl->pos().y;
 | |
|       if (fy > 0)            // Ha una coordinata y imposta
 | |
|       {
 | |
|         if (fy < _delta.y)   // Sono gia' andato oltre quindi salto pagina
 | |
|         {
 | |
|           close_page();
 | |
|           open_page();
 | |
|         }
 | |
|         _delta.x = 0;
 | |
|         _delta.y = fy;
 | |
| 
 | |
|         // Azzero temporaneamente le dimensioni del footer per evitare salti pagina
 | |
|         const int lfp = _logical_foot_pos;
 | |
|         _logical_foot_pos = _logical_page_height; 
 | |
|         print_section(*fl);
 | |
|         _logical_foot_pos = lfp;
 | |
|       }
 | |
|       else
 | |
|         print_section(*fl);  // Stampa normale
 | |
|     }
 | |
| 
 | |
|     _is_last_page = true;
 | |
|     close_page();
 | |
| 
 | |
|     _report->execute_postscript();
 | |
| 
 | |
|     if (!_print_aborted)
 | |
|     {
 | |
|       const TString_array& all = _report->allegates();
 | |
|       for (int a = 0; a < all.items(); a++)
 | |
|       {
 | |
|         TFilename name = all.row(a);
 | |
|         if (name.find('#') >= 0) // Se puo' essere un'espressione
 | |
|         {
 | |
|           TVariant var;
 | |
|           if (_report->evaluate(name, var, _alfafld))
 | |
|             name = var.as_string();
 | |
|         }
 | |
|         add_doc(name);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (pi != NULL)
 | |
|     delete pi;
 | |
| 
 | |
|   return !_print_aborted;
 | |
| }
 | |
| 
 | |
| int TReport_book::lpi() const
 | |
| {
 | |
|   if (_report != NULL)
 | |
|     return _report->print_lpi();
 | |
|   return TBook::lpi();
 | |
| }
 | |
| 
 | |
| int TReport_book::cpi() const
 | |
| {
 | |
|   if (_report != NULL)
 | |
|     return _report->print_cpi();
 | |
|   return TBook::cpi();
 | |
| }
 | |
| 
 | |
| bool TReport_book::print(size_t pagefrom, size_t pageto, size_t copies)
 | |
| {
 | |
|   if (pages() <= 0)
 | |
|     return false;
 | |
|   split_file_if_needed();
 | |
| 
 | |
|   if (pagefrom <= 0)
 | |
|   {
 | |
|     TPrinter& p = printer();
 | |
|     TMask msk("bagn003");
 | |
|     msk.set(F_PRINTER, p.printername());
 | |
|     if (_report != NULL)
 | |
|     {
 | |
|       msk.set(F_FORM, _report->filename());
 | |
|       msk.set(F_FONT, _report->print_font().name());
 | |
|       msk.set(F_SIZE, _report->print_font().size());
 | |
|     }
 | |
|     msk.set(F_ISGRAPHICS, p.isgraphics() ? "X" : "");
 | |
|     msk.set(F_FROMPAGE, 1);
 | |
|     msk.set(F_TOPAGE, page());
 | |
|     msk.set(F_COPIES, 1);
 | |
|     if (msk.run() == K_ENTER)
 | |
|     {
 | |
|       copies = msk.get_int(F_COPIES);
 | |
|       pagefrom = msk.get_int(F_FROMPAGE);
 | |
|       pageto = msk.get_int(F_TOPAGE);
 | |
|     }
 | |
|     else
 | |
|       return false;
 | |
|   }
 | |
|   
 | |
|   return TBook::print(pagefrom, pageto, copies);
 | |
| }
 | |
| 
 | |
| bool TReport_book::archive(const char* repname)
 | |
| {
 | |
|   TFilename n = repname;
 | |
|   if (n.blank() && _report != NULL)
 | |
|   {
 | |
|     n = _report->filename().name();
 | |
|     n.ext("");
 | |
|   }
 | |
|   return TBook::archive(n);
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TReport_book::on_link(const TReport_link& lnk)
 | |
| {
 | |
|   bool ok = false;
 | |
|   if (_report != NULL)
 | |
|     ok = _report->on_link(lnk);
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TReport_book::TReport_book(const char* name) 
 | |
|             : TBook(name), _report(NULL)
 | |
| { } |