Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 lines
7.2 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1998
  3. All rights reserved.
  4. Module Name:
  5. Select.cxx
  6. Abstract:
  7. Handles queuing and processing of commands.
  8. This module should _not_ be aware of any interfaces beyond
  9. TPrinter and MPrinterClient (i.e., no listview code).
  10. Author:
  11. Albert Ting (AlbertT) 07-13-1995
  12. Steve Kiraly (SteveKi) 10-23-1995 Additional comments.
  13. Revision History:
  14. --*/
  15. #include "precomp.hxx"
  16. #pragma hdrstop
  17. #include "select.hxx"
  18. /********************************************************************
  19. Retrieve state of selected items.
  20. ********************************************************************/
  21. TSelection::
  22. TSelection(
  23. IN const MPrinterClient* pPrinterClient,
  24. IN const TPrinter* pPrinter
  25. ) : _pid( NULL ), _cSelected( 0 )
  26. /*++
  27. Routine Description:
  28. Get the JobIds of all selected jobs and the one that currently
  29. has focus. This is used when a refresh occurs and we need
  30. to update the queue while keeping selected items selected.
  31. Note: this routine is very slow, so we may want to optimize
  32. it if it uses too much cpu bandwidth. It should only be called on a
  33. full refresh (every 10 seconds on downlevel, rare on uplevel).
  34. This routine is very inefficient with TDataNotify, and not
  35. as bad with TDataRefresh.
  36. Must be called from UI thread.
  37. Arguments:
  38. pPrinterClient - Client from which we will grab selections.
  39. pPrinter - Printer.
  40. Return Value:
  41. --*/
  42. {
  43. UNREFERENCED_PARAMETER( pPrinter );
  44. SINGLETHREAD(UIThread);
  45. //
  46. // Quit if no printer client.
  47. //
  48. if( !pPrinterClient ){
  49. return;
  50. }
  51. //
  52. // Quit if no selections.
  53. //
  54. _cSelected = pPrinterClient->cSelected();
  55. if( !_cSelected ){
  56. return;
  57. }
  58. //
  59. // Allocate the variable length Job Id array within the
  60. // selection class. This optimizes the number of memory allocations.
  61. // Note the non-use of the new operator. This really is not a good
  62. // thing, it is the price we pay for greater efficiency.
  63. //
  64. _pid = (PIDENT) AllocMem( sizeof( IDENT ) * _cSelected );
  65. if( !_pid ){
  66. return;
  67. }
  68. if( pPrinterClient ){
  69. //
  70. // Put selected jobs in array.
  71. //
  72. HITEM hItem = pPrinterClient->GetFirstSelItem();
  73. COUNT i = 0;
  74. //
  75. // Strange looking FOR loop to prevent GetNextSelItem being
  76. // called any extra times.
  77. //
  78. for( ; ; ){
  79. _pid[i] = pPrinterClient->GetId( hItem );
  80. ++i;
  81. if( i == _cSelected ){
  82. break;
  83. }
  84. hItem = pPrinterClient->GetNextSelItem( hItem );
  85. }
  86. }
  87. }
  88. TSelection::
  89. ~TSelection(
  90. VOID
  91. )
  92. /*++
  93. Routine Description:
  94. Free the object.
  95. Callable from any thread.
  96. Arguments:
  97. Return Value:
  98. --*/
  99. {
  100. FreeMem( _pid );
  101. }
  102. /********************************************************************
  103. Command line argument selection
  104. ********************************************************************/
  105. TSelect::
  106. TSelect(
  107. VOID
  108. )
  109. {
  110. }
  111. TSelect::
  112. ~TSelect(
  113. VOID
  114. )
  115. {
  116. }
  117. TSelect::
  118. bValid(
  119. VOID
  120. )
  121. {
  122. return TRUE;
  123. }
  124. BOOL
  125. TSelect::
  126. bLookup(
  127. IN Selection *pSelection,
  128. IN PVOID pInfo,
  129. IN LPCTSTR pKey,
  130. IN LPCTSTR pValue
  131. )
  132. {
  133. SPLASSERT( pSelection );
  134. SPLASSERT( pInfo );
  135. SPLASSERT( pKey );
  136. SPLASSERT( pValue );
  137. BOOL bStatus = FALSE;
  138. if( pKey && pValue )
  139. {
  140. for( ; pSelection->iKeyWord; pSelection++ )
  141. {
  142. if( bMatch( pKey, pSelection->iKeyWord ) )
  143. {
  144. switch( pSelection->eDataType )
  145. {
  146. case kString:
  147. *(LPCTSTR *)((LPBYTE)pInfo+pSelection->iOffset) = pValue;
  148. bStatus = TRUE;
  149. break;
  150. case kInt:
  151. {
  152. LPCTSTR pszFmt = (*pValue == TEXT('0') && *(pValue+1) == TEXT('x')) ? TEXT("%x") : TEXT("%d");
  153. bStatus = _stscanf( pValue, pszFmt, (LPBYTE)pInfo+pSelection->iOffset );
  154. }
  155. break;
  156. case kBitTable:
  157. bStatus = bLookupBitTable( (SelectionBit *)pSelection->pTable, pValue );
  158. break;
  159. case kValTable:
  160. bStatus = bLookupValTable( (SelectionVal *)pSelection->pTable, pInfo, pValue );
  161. break;
  162. default:
  163. bStatus = FALSE;
  164. break;
  165. }
  166. break;
  167. }
  168. }
  169. }
  170. return bStatus;
  171. }
  172. BOOL
  173. TSelect::
  174. bLookupBitTable(
  175. IN SelectionBit *pBitTable,
  176. IN LPCTSTR pKey
  177. )
  178. {
  179. SPLASSERT( pBitTable );
  180. SPLASSERT( pKey );
  181. BOOL bStatus = FALSE;
  182. if( pKey )
  183. {
  184. EOperation Op = kNop;
  185. switch ( *pKey )
  186. {
  187. case TEXT('-'):
  188. Op = kNot;
  189. pKey++;
  190. break;
  191. case TEXT('+'):
  192. Op = kOr;
  193. pKey++;
  194. break;
  195. case TEXT('&'):
  196. Op = kAnd;
  197. pKey++;
  198. break;
  199. case TEXT('^'):
  200. Op = kXor;
  201. pKey++;
  202. break;
  203. default:
  204. Op = kOr;
  205. break;
  206. }
  207. for( ; pBitTable->iKeyWord; pBitTable++ )
  208. {
  209. if( bMatch( pKey, pBitTable->iKeyWord ) )
  210. {
  211. pBitTable->Op = Op;
  212. bStatus = TRUE;
  213. break;
  214. }
  215. }
  216. }
  217. return bStatus;
  218. }
  219. BOOL
  220. TSelect::
  221. bLookupValTable(
  222. IN SelectionVal *pValTable,
  223. IN PVOID pInfo,
  224. IN LPCTSTR pKey
  225. )
  226. {
  227. SPLASSERT( pValTable );
  228. SPLASSERT( pInfo );
  229. SPLASSERT( pKey );
  230. BOOL bStatus = FALSE;
  231. if( pKey )
  232. {
  233. for( ; pValTable->iKeyWord; pValTable++ )
  234. {
  235. if( bMatch( pKey, pValTable->iKeyWord ) )
  236. {
  237. *(UINT *)((LPBYTE)pInfo+pValTable->iOffset) = pValTable->uValue;
  238. bStatus = TRUE;
  239. break;
  240. }
  241. }
  242. }
  243. return bStatus;
  244. }
  245. BOOL
  246. TSelect::
  247. bApplyBitTableToValue(
  248. IN SelectionBit *pBitTable,
  249. IN UINT uBit,
  250. IN LPDWORD pdwBit
  251. )
  252. {
  253. SPLASSERT( pBitTable );
  254. SPLASSERT( pdwBit );
  255. BOOL bStatus = FALSE;
  256. for( ; pBitTable->iKeyWord; pBitTable++ )
  257. {
  258. switch ( pBitTable->Op )
  259. {
  260. case kNot:
  261. uBit = uBit & ~pBitTable->uBit;
  262. bStatus = TRUE;
  263. break;
  264. case kOr:
  265. uBit = uBit | pBitTable->uBit;
  266. bStatus = TRUE;
  267. break;
  268. case kAnd:
  269. uBit = uBit & pBitTable->uBit;
  270. bStatus = TRUE;
  271. break;
  272. case kXor:
  273. uBit = uBit ^ pBitTable->uBit;
  274. bStatus = TRUE;
  275. break;
  276. case kNop:
  277. break;
  278. default:
  279. break;
  280. }
  281. }
  282. if( bStatus && pdwBit )
  283. {
  284. *pdwBit = uBit;
  285. }
  286. return bStatus;
  287. }
  288. BOOL
  289. TSelect::
  290. bMatch(
  291. IN LPCTSTR pszString,
  292. IN UINT iResId
  293. )
  294. {
  295. TString strString;
  296. TStatusB bStatus;
  297. bStatus DBGCHK = strString.bLoadString( ghInst, iResId );
  298. return bStatus && !_tcsicmp( pszString, strString );
  299. }