source: trunk/Lucide/SOURCE/gui/printDlg.cpp @ 93

Last change on this file since 93 was 93, checked in by Eugene Romanenko, 15 years ago

basic printing, postscript and bitmap

File size: 12.7 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#define INCL_WIN
36#define INCL_DEV
37#define INCL_ERRORS
38#define INCL_SPL
39#define INCL_SPLDOSPRINT
40#include <os2.h>
41
42#include <ludoc.xh>
43
44#include "globals.h"
45#include "printDlg.h"
46#include "Lucide_res.h"
47#include "luutils.h"
48
49
50PrintDlg::PrintDlg( HWND hWndFrame, LuDocument *_doc, long _currentpage )
51{
52    hFrame      = hWndFrame;
53    doc         = _doc;
54    scalable    = _doc->isScalable( ev );
55    currentpage = _currentpage;
56    psetup      = new PrintSetup;
57    memset( psetup, 0, sizeof( PrintSetup ) );
58}
59
60PrintDlg::~PrintDlg()
61{
62    delete psetup;
63}
64
65ULONG PrintDlg::showDialog()
66{
67    return WinDlgBox( HWND_DESKTOP, hFrame, printDlgProc,
68                      NULLHANDLE, IDD_PRINT, this );
69}
70
71void PrintDlg::getPrintSetup( PrintSetup *p ) {
72    memcpy( p, psetup, sizeof( PrintSetup ) );
73}
74
75void PrintDlg::setCurrentQInfo( HWND hwnd, PPRQINFO3 q )
76{
77    memcpy( &(psetup->QueueInfo), q, sizeof( PRQINFO3 ) );
78    WinSetDlgItemText( hwnd, IDC_PNAME, psetup->QueueInfo.pszComment );
79    WinSetDlgItemText( hwnd, IDC_PDESCRIPTION, psetup->QueueInfo.pszDriverName );
80    WinEnableControl( hwnd, IDC_JOBPROPERTIES, TRUE );
81    WinEnableControl( hwnd, DID_OK, TRUE );
82
83    // Set the print type
84    if ( doc->isPostScriptExportable( ev ) && isPostscriptDevice() ) {
85        WinEnableControl( hwnd, IDC_TYPE_POSTSCRIPT, TRUE );
86        WinCheckButton( hwnd, IDC_TYPE_POSTSCRIPT, TRUE );
87    }
88    else {
89        WinEnableControl( hwnd, IDC_TYPE_POSTSCRIPT, FALSE );
90        WinCheckButton( hwnd, IDC_TYPE_ASIMAGE, TRUE );
91    }
92
93    WinSendMsg( hwnd, WM_CONTROL,
94                MPFROM2SHORT( IDC_TYPE_POSTSCRIPT, BN_CLICKED ),
95                MPFROMHWND( WinWindowFromID( hwnd, IDC_TYPE_POSTSCRIPT ) ) );
96}
97
98void PrintDlg::enumQueues( HWND hwnd )
99{
100    HWND list = WinWindowFromID( hwnd, IDC_PNAME );
101    ULONG cReturned = 0, cTotal = 0, cbNeeded = 0;
102    SPLERR se = SplEnumQueue( NULL, 3, NULL, 0L, &cReturned,
103                              &cTotal, &cbNeeded, NULL );
104    if ( cTotal == 0L ) {
105        // TODO: 'no printers installed' message  (?)
106    }
107
108    pQueueInfo = (PPRQINFO3)malloc( cbNeeded );
109
110    se = SplEnumQueue( NULL, 3, pQueueInfo, cbNeeded, &cReturned,
111                       &cTotal, &cbNeeded, NULL );
112    if ( se != NO_ERROR ) {
113        // TODO: error message
114        free( pQueueInfo );
115        pQueueInfo = NULL;
116        return;
117    }
118
119    USHORT sEntry;
120    for ( ULONG i = 0; i < cReturned; i++ )
121    {
122        sEntry = (SHORT)WinSendMsg( list, LM_INSERTITEM, MPFROMSHORT(LIT_END),
123                                    MPFROMP( pQueueInfo[i].pszComment ) );
124        WinSendMsg( list, LM_SETITEMHANDLE,
125                    MPFROMSHORT(sEntry), MPFROMP( &(pQueueInfo[i]) ) );
126
127        if ( pQueueInfo[i].fsType & PRQ3_TYPE_APPDEFAULT ) {
128            setCurrentQInfo( hwnd, &( pQueueInfo[i] ) );
129        }
130    }
131}
132
133
134void PrintDlg::showJobProperties()
135{
136    if ( psetup->QueueInfo.pszName[0] == 0 ) {
137        return;
138    }
139
140    char achDriverName[ DRIVERNAME_LENGTH ];
141    char achDeviceName[ DEVICENAME_LENGTH ];
142
143    // The pszDriverName is of the form DRIVER.DEVICE (e.g.,
144    // LASERJET.HP LaserJet IID) so we need to separate it at the dot
145    int i = strcspn( psetup->QueueInfo.pszDriverName, "." );
146    if ( i > 0 ) {
147        strncpy( achDriverName, psetup->QueueInfo.pszDriverName, i );
148        achDriverName[ i ] = '\0';
149        strcpy( achDeviceName, &( psetup->QueueInfo.pszDriverName[ i + 1 ] ) );
150    }
151    else {
152        strcpy( achDriverName, psetup->QueueInfo.pszDriverName );
153        *achDeviceName = '\0';
154    }
155
156    // There may be more than one printer assigned to this print queue
157    // We will use the first in the comma separated list.  We would
158    // need an expanded dialog for the user to be more specific.
159    char *pszTemp = strchr( psetup->QueueInfo.pszPrinters, ',' );
160    if ( pszTemp != NULL ) {
161        // Strip off comma and trailing printer names
162        *pszTemp = '\0';
163    }
164
165    // Post the job properties dialog for the printer to allow the
166    // user to modify the options
167    DevPostDeviceModes( hab, psetup->QueueInfo.pDriverData, achDriverName,
168                        achDeviceName, psetup->QueueInfo.pszPrinters, DPDM_POSTJOBPROP );
169}
170
171bool PrintDlg::isPostscriptDevice()
172{
173    char *achDriverName = new char[ DRIVERNAME_LENGTH ];
174
175    // build a devopenstruct for the call to DevOpenDC
176    DEVOPENSTRUC *dos   = new DEVOPENSTRUC;
177    memset( dos, 0, sizeof( DEVOPENSTRUC ) );
178    dos->pszLogAddress = psetup->QueueInfo.pszName;              // 1
179    strcpy( achDriverName, psetup->QueueInfo.pszDriverName );
180    achDriverName[ strcspn( achDriverName, "." ) ] = '\0';
181    dos->pszDriverName = achDriverName;                          // 2
182    dos->pdriv = psetup->QueueInfo.pDriverData;                  // 3
183
184    long lTech = 0;
185    HDC hdcPrinterInfo = DevOpenDC( hab, OD_INFO, "*", 3L, (PDEVOPENDATA)dos, NULLHANDLE );
186    if ( hdcPrinterInfo != DEV_ERROR ) {
187        DevQueryCaps( hdcPrinterInfo, CAPS_TECHNOLOGY, sizeof(long), &lTech );
188        DevCloseDC( hdcPrinterInfo );
189    }
190
191    delete achDriverName;
192    delete dos;
193    return ( lTech == CAPS_TECH_POSTSCRIPT );
194}
195
196MRESULT EXPENTRY PrintDlg::printDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
197{
198    // This is a static method, so we don't know which instantiation we're
199    // dealing with. But we can get a pseudo-this from the parameter to
200    // WM_INITDLG, which we therafter store with the window and retrieve
201    // as follows:
202    PrintDlg *_this = (PrintDlg *)WinQueryWindowULong( hwnd, QWL_USER );
203
204    switch (msg)
205    {
206
207        // Dialog has just been created
208        case WM_INITDLG:
209        {
210            // Save the mp2 into our user data so that subsequent calls have
211            // access to the parent C++ object
212            WinSetWindowULong( hwnd, QWL_USER, (ULONG)mp2 );
213            _this = (PrintDlg *)mp2;
214            localizeDialog( hwnd );
215            centerWindow( _this->hFrame, hwnd );
216
217            // Print range
218            WinCheckButton( hwnd, IDC_RANGEALL, TRUE );
219
220            // Set the print range spins
221            long pages = _this->doc->getPageCount( ev );
222            WinSendDlgItemMsg( hwnd, IDC_PGFROM, SPBM_SETLIMITS,
223                               MPFROMLONG( pages ), MPFROMLONG( 1 ) );
224            WinSendDlgItemMsg( hwnd, IDC_PGFROM, SPBM_SETCURRENTVALUE,
225                               MPFROMLONG( 1 ), MPVOID );
226            WinSendDlgItemMsg( hwnd, IDC_PGTO, SPBM_SETLIMITS,
227                               MPFROMLONG( pages ), MPFROMLONG( 1 ) );
228            WinSendDlgItemMsg( hwnd, IDC_PGTO, SPBM_SETCURRENTVALUE,
229                               MPFROMLONG( pages ), MPVOID );
230
231            // Enum printer queues
232            _this->enumQueues( hwnd );
233
234            return (MRESULT)FALSE;
235        }
236
237        case WM_CONTROL:
238        {
239            switch ( SHORT1FROMMP(mp1) )
240            {
241                case IDC_PNAME:
242                {
243                    if ( SHORT2FROMMP(mp1) == CBN_ENTER )
244                    {
245                        SHORT rc = (SHORT)WinSendDlgItemMsg( hwnd, IDC_PNAME, LM_QUERYSELECTION,
246                                                             MPFROMSHORT( LIT_CURSOR ), MPVOID );
247                        if ( rc != LIT_NONE ) {
248                            MRESULT r = WinSendDlgItemMsg( hwnd, IDC_PNAME, LM_QUERYITEMHANDLE,
249                                                           MPFROMSHORT( rc ), MPVOID );
250                            _this->setCurrentQInfo( hwnd, (PPRQINFO3)r );
251                        }
252                    }
253                }
254                break;
255
256                case IDC_RANGEALL:
257                case IDC_RANGECURRENT:
258                case IDC_RANGEPAGES:
259                {
260                    BOOL en = WinQueryButtonCheckstate( hwnd, IDC_RANGEPAGES );
261                    WinEnableControl( hwnd, IDC_LABELFROM, en );
262                    WinEnableControl( hwnd, IDC_PGFROM, en );
263                    WinEnableControl( hwnd, IDC_LABELTO, en );
264                    WinEnableControl( hwnd, IDC_PGTO, en );
265                }
266                break;
267
268                case IDC_TYPE_POSTSCRIPT:
269                case IDC_TYPE_ASIMAGE:
270                {
271                    BOOL asimg = WinQueryButtonCheckstate( hwnd, IDC_TYPE_ASIMAGE );
272                    WinEnableControl( hwnd, IDC_HIGHER_IMAGE_QUALITY,
273                                      asimg && _this->scalable );
274                }
275                break;
276
277            }
278        }
279        break;
280
281        case WM_COMMAND:
282            switch (SHORT1FROMMP(mp1))
283            {
284                case IDC_JOBPROPERTIES:
285                    _this->showJobProperties();
286                    return (MRESULT)FALSE;
287
288                case DID_OK:
289                    {
290                        _this->psetup->range = RangeAll;
291                        _this->psetup->pgfrom = 1;
292                        _this->psetup->pgto = _this->doc->getPageCount( ev );
293
294                        if ( WinQueryButtonCheckstate( hwnd, IDC_RANGECURRENT ) ) {
295                            _this->psetup->range = RangeCurrent;
296                            _this->psetup->pgfrom = _this->currentpage;
297                            _this->psetup->pgto = _this->currentpage;
298                        }
299
300                        if ( WinQueryButtonCheckstate( hwnd, IDC_RANGEPAGES ) )
301                        {
302                            _this->psetup->range = RangePages;
303                            LONG tmpVal = 0;
304                            BOOL rc = (BOOL)WinSendDlgItemMsg( hwnd, IDC_PGFROM, SPBM_QUERYVALUE, MPFROMP( &tmpVal ), MPFROM2SHORT( 0, SPBQ_UPDATEIFVALID ) );
305                            if ( rc && ( tmpVal > 0 ) ) {
306                                _this->psetup->pgfrom = tmpVal;
307                            }
308                            rc = (BOOL)WinSendDlgItemMsg( hwnd, IDC_PGTO, SPBM_QUERYVALUE, MPFROMP( &tmpVal ), MPFROM2SHORT( 0, SPBQ_UPDATEIFVALID ) );
309                            if ( rc && ( tmpVal > 0 ) ) {
310                                _this->psetup->pgto = tmpVal;
311                            }
312                            if ( _this->psetup->pgfrom > _this->psetup->pgto ) {
313                                long tmp = _this->psetup->pgfrom;
314                                _this->psetup->pgfrom = _this->psetup->pgto;
315                                _this->psetup->pgto = tmp;
316                            }
317                        }
318
319                        _this->psetup->ptype = TypePostScript;
320                        if ( WinQueryButtonCheckstate( hwnd, IDC_TYPE_ASIMAGE ) ) {
321                            _this->psetup->ptype = TypeAsImage;
322                        }
323                        _this->psetup->higherQuality = WinQueryButtonCheckstate( hwnd, IDC_HIGHER_IMAGE_QUALITY );
324
325                        WinDismissDlg( hwnd, DID_OK );
326                    }
327                    return (MRESULT)FALSE;
328
329                case DID_CANCEL:
330                    WinDismissDlg( hwnd, DID_CANCEL );
331                    return (MRESULT)FALSE;
332            };
333            return (MRESULT)FALSE;
334    }
335    return WinDefDlgProc( hwnd, msg, mp1, mp2 );
336}
337
338
Note: See TracBrowser for help on using the repository browser.