Friday, November 03, 2006

"Previous posts" vs. "Recent posts" vs. "All posts"

I've transferred this blog to the new beta.blogger.com. Unfortunately "Previous posts" section does not work as it used to. So I've renamed "Previous posts" to "Recent posts" and added a new section titled "All posts" using FeedBurner BuzzBoost service. Here is the code:


[]

Tuesday, October 31, 2006

Double-click

To learn and to practise what is learned
time and again is pleasure, is it not?

To have friends come from afar (to share learning)
is happiness, is it not?

To be unperturbed when not appreciated by
others is gentlemanly, is it not?

--- K'UNG-FU-TZU, Lun Yu (circa 500 BC)


Do you know that there exists a mouse with double-click button? If you don't, now you know!

What happens when you double-click on the file (or shortcut) in Windows operating system (OS)? Based on the file extension (usually 2, 3 or 4 letters after the last dot in the file name) OS determines its file type and then executes an application that can open (display) selected file. BTW, this is the default behaviour - you can set that this action is triggered by single-click:


We've already seen that using doknir it is possible to open (view) files with the extension .PS or .DJVU. Wouldn't it be nice to open such files directly using double-click? Well, after first two steps it is not difficult to make the third step: We will write a simple Delphi executable (called "doknir launcher") that will, when executed by double-click on a file, copy that file to the incoming folder. The source follows:

We need three functions: to get "My documents" folder (because there is our incoming folder), to get the file size and to copy file:
---

function GetMyDocuments: string;
var
Res: Bool;
Path: array[0..Max_Path] of Char;
begin
Res := ShGetSpecialFolderPath(0, Path, csidl_Personal, False);
if not Res then raise
Exception.Create('Could not determine My Documents path');
Result := Path;
end; // GetMyDocuments
...
function GetFSize(cFile: string): Int64;
var
fs: TFileStream;
begin
fs:=NIL;
result:=-1;
try
fs:=TFileStream.Create(cFile,
fmOpenRead+fmShareDenyNone);
result:=fs.Size;
finally
fs.Free;
end;
end; // GetFSize
...
function FileCopy(cF, cT: string):integer;
begin
CopyFile( PChar(cF), PChar(cT), FALSE );
result:=0;
end; // F
ileCopy
---
I could use OnCreate event to copy file, but I prefer timer (I named it Launcher) because it gives me more flexibility:
---
 procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption:=CmdLine;
Label2.Caption:=ParamStr(1);
cFileDok:=ParamStr(1);
cMyDok:=GetMyDocuments()+'/[_doknir_]';
cPhase:='WAIT';
Launcher.Enabled:=TRUE; // enable timer
end; // FormCreate
...
procedure TForm1.LauncherTimer(Sender: TObject);
var
nSize: integer;
cTo: string;
begin
Launcher.Enabled:=FALSE;
if cFileDok='' then begin Close; Exit end;
if not FileExists(cFileDok) then begin
ShowMessage('File not accessible!');
Close; Exit;
end;
cPhase:='LAUNCH';
nSize:=GetFSize(cFileDok);
if nSize<0>
ShowMessage('Error<0');
end else if nSize=0 then begin
ShowMessage('Error=0');
end else begin // nSize>0
try
cTo:=cMyDok+'\'+ExtractFileName(cFileDok);
FileCopy(cFileDok, cTo);
except
ShowMessage('Error copy: '+cFileDok);
end;
end;
Close;
end; //LauncherTimer
---

Now we will try to "teach" Windows how to open files using our new "doknir launcher". First we have to find a file that we wish to view in doknir (for example PDF file). Press [Shift] and right-click on it. There should be "Open with ..." option visible in the pop-up menu - select it. The following dialog appears:

Click on button [Browse...] to select newly created "doknir launcher" executable, check "Alway use the selected program to open this kind of file" and press OK. This means that from now on whenever we will double-click on PDF file, it will be displayed in doknir. We can repeat above steps for other file types. For example, I've associated 'doknir launcher' to the following file extensions: .PDF, .PS, .DJVU and .SXW. Nice, is it not?

[]

Tuesday, September 19, 2006

111 gibibytes of doknir, s'il vous plait

According to the http://torrent.vmware.com:6969/, more than 100 GiB of doknir were downloaded. BTW, size of doknir.zip is 772 MiB.

Friday, August 04, 2006

OpenOffice Viewer

In posts about Crystal Reports and Word 2007 I brought up an issue of printer metrics (and page layout) so I've searched about "printer independent layout". I've discovered a document titled "Printer Independent Layout" [2003-MAR-12] on the following page: "Spec Proposals for OOo 1.1.x".

Document has an extension SXW and I have no application associated to it in my Windows environment. According to the Wikipedia, SXW is acronym for StarOffice XML Writer and it is the file extension for OpenOffice.org text files. Is there a tiny SXW viewer for Windows? Yes, it is: Visioo-writer - Visionneuse OpenOffice.org, but it is still in development (version 0.6.1). It is based on Python and here is a result (part of the first page):


Unfortunately, printing is not implemented yet ... I shall wait for version 1.0.1 ...

What happens if we want to print the SXW file via doknir? This:

In Kanotix there is no default application for SXW extension, so let's select KWord, which is currently default for DOC file type:
And this is the result:
This is much better than Visioo-Writer, but still not perfect: If we take a closer look:

we can see that letters a, i, e in word "applies" are different from the letters in "StarOffice"
To be sure, if this is correct or not, we have to install OpenOffice:

  • sux
  • apt-get update
  • apt-get install openoffice.org
...
Need to get 96.4MB of archives.
After unpacking 219MB of additional disk space will be used.
...

Quite a lot of megabytes just to view SXW file ;). In my case, version 2.0.3-6 was installed - here is the current changelog. Anyhow, the following screenshot shows how the above document is displayed in OpenOffice Writer, which is now the default application for SXW extension:

We can see that KWord was not able to display SXW document correctly.

BTW, here is the abstract of the above document:

Many users complain about changing layouts of their document once these documents are printed to different printers or even on different driver versions of one and the same printer.

Even if this behaviour is technically correct (due to different printer and font metrics) it is confusing for the user. This is especially true if the number of pages increases or decreases.

To avoid such re-formatting a printer independent layout mode will be introduced.

As a side-effect we will buy in better MS Office compatibility ;o)

IMHO this behaviour is technically correct if you are a printer. But I'm not a printer and for me technically correct means that page layout does not change when changing printer. Fortunately this is the default in the latest OpenOffice:

[]

Thursday, August 03, 2006

Incoming folder

Programming is one of the most
difficult branches of applied mathematics;
the poorer mathematicians
had better remain pure mathematicians.
--- EDSGER WYBE DIJKSTRA, How do we tell truths that might hurt? (1975)

Arrogance in computer science is measured in nanodijkstras.
--- ALAN KAY, ?

Implementation of the "right click" functionality was just the first step on our journey to the Grand Unification of the Host and her Guest. Today we are going to make the second step: "incoming folder".

As we can see in "Crystal Reports" or "Word 2007" examples, the following actions are required:
  • open the folder
  • find the file
  • right-click on it
  • select 'doknir' in pop-up menu
By implementing "incoming folder" in the Windows host we will eliminate these actions. How will "incoming folder" work? Very simple, we will modify our Windows Delphi utility so that it will monitor specific subfolder [_doknir_] in "My Documents" folder. Whenever new file will appear in that folder, it will be sent to the 'doknir' virtual appliance. What follows is technical description of Delphi source changes:
  • We need to split method wodShellMenu1Click - new method is called CreateJob:

procedure TForm1.wodShellMenu1Click(ASender: TObject;
const Item: IMenuItem; const Name, Directory, Targets: WideString);
var
cFile: string;
begin
Memo1.Lines.Add(Directory);
Memo1.Lines.Add(Name);
Memo1.Lines.Add('['+Targets+']');
if Pos(';',Targets)>0 then begin
ShowMessage('Please select only one file!');
end else begin
if UpperCase(ExtractFileExt(Targets)) = '.LNK' Then begin
cFile:=GetTarget(Targets);
Memo1.Lines.Add(cFile);
end else begin
cFile:=Targets;
end;
end;
CreateJob(cFile);
Memo1.Lines.Add('------------------------------');
end; // wodShellMenu1Click


procedure TForm1.CreateJob(cFile: string);
var
SearchRec: TSearchRec;
cTmpFile, cJob, cJb, cFile2: string;
nSize: integer;
cExt, cExt2: string;
begin
nSize:=-1;
if FileExists(cFile) then begin
if not Forms.Application.Active then
Forms.Application.Restore;
if WindowState=wsMinimized then WindowState:=wsNormal;
Forms.Application.BringToFront;
FindFirst(cFile, faAnyFile, SearchRec); // +cExt.Caption
if (Length(SearchRec.Name)>0) and (SearchRec.Size>0) then begin
nSize:=SearchRec.Size;
Memo1.Lines.Add('size='+IntToStr(nSize) ) ;
end;
FindClose(SearchRec);
if nSize>50000000 then begin
if MessageDlg('File '+cFile+' is large! Do you want to continue?',
mtConfirmation, [mbYes, mbNo], 0) <> mrYes then begin
Memo1.Lines.Add('------------------------------');
exit;
end;
end;
cExt:=ExtractFileExt( cFile );
if cExt<>'' then begin
cFile2:=LeftStr(cFile, Length(cFile)-Length(cExt) );
cExt2:=ExtractFileExt( cFile2 );
if cExt2<>'' then cExt:=cExt2+cExt;
end;
// ShowMessage(cExt);
cTmpFile:=TmpFile( cTmpPath, cExt );
try
FileCopy(cFile, cTmpFile);
except
ShowMessage('Error copy: '+cFile);
end;
if FileExists( cTmpFile ) then begin
// create job (random file name)
cJb:=TmpFile(cJobsPath,'.jb');
cJob:=ChangeFileExt(cJb,'.job');
Memo1.Lines.Add('job='+ cJob);
with TIniFile.Create(cJob) do begin
WriteString('doknir job', 'tmp file', ExtractFileName(cTmpFile));
WriteString('doknir job', 'original file', cFile);
UpdateFile;
Free;
end;
RenameFile(cJb, cJob);
end;
end;
end; // CreateJob

  • We need a function to get "My Documents" folder:

 function GetMyDocuments: string;
var
Res: Bool;
Path: array[0..Max_Path] of Char;
begin
Res := ShGetSpecialFolderPath(0, Path, csidl_Personal, False);
if not Res then raise
Exception.Create('Could not determine My Documents path');
Result := Path;
end; // GetMyDocuments

  • We need two timers: "TimerMon" and "TimerChg". They are disabled and with intervals 500 and 2500 ms, respectively. The first timer monitors "incoming folder". When a new file appears, it stops and starts the second timer which checks if the size of incoming file is changing. If not it stops, creates a job to send the document to the virtual appliance and it starts the first timer.
  • Specific subfolder in "My documents" will be called [_doknir_] (so that it will be alphabetically on the top in the list of folders). The method FormCreate has these new lines:

    cMyDok:=GetMyDocuments()+'\[_doknir_]';
bFindFirst:=TRUE;
TimerMon.Enabled:=TRUE; // start monitor cMyDok

  • And finally, here are two methods for the timer events:

procedure TForm1.TimerMonTimer(Sender: TObject);
// monitor incoming folder
var
nRes: integer;
begin
TimerMon.Enabled:=FALSE;
if bFindFirst then begin
nRes:=FindFirst(cMyDok+'\*.*', faArchive , srDok);
end else begin
nRes:=FindNext(srDok);
end;
if (nRes=0) then begin
if bFindFirst then begin
Memo1.Lines.Add('--------------');
Memo1.Lines.Add('findfirst: '+srDok.Name+
' size='+IntToStr(srDok.Size) );
bFindFirst:=FALSE;
end;
if (srDok.Name<>'.') and (srDok.Size>0) then begin
TimerChg.Enabled:=TRUE;
end else begin
TimerMon.Enabled:=TRUE;
end;
end else begin // nRes<>0
if not bFindFirst then begin
bFindFirst:=TRUE;
FindClose(srDok);
end;
TimerMon.Enabled:=TRUE;
end;
end; // TimerMonTimer

procedure TForm1.TimerChgTimer(Sender: TObject);
// is size of file changing ...
var
nSize: Int64;
fs: TFileStream;
cTo: string;
begin
TimerChg.Enabled:=FALSE;
Memo1.Lines.Add('incoming: '+srDok.Name);
fs:=NIL;
try
nSize:=-1;
fs:=TFileStream.Create(cMyDok+'/'+srDok.Name,
fmOpenRead+fmShareDenyNone);
nSize:=fs.Size;
finally
fs.Free;
end;
Memo1.Lines.Add('stream size: ' + IntToStr(nSize) );
if (srDok.Size=nSize) then begin // size ok
cTo:=cMyDok+'/done/'+srDok.Name;
Memo1.Lines.Add('size ok: '+IntToStr(nSize) );
if FileExists(cTo) then
DeleteFile(cTo); // temporary ***
if RenameFile(cMyDok+'/'+srDok.Name, cTo) then begin
CreateJob(cTo);
end;
end;
TimerMon.Enabled:=TRUE; // monitor for next file
end; // TimerChgTimer

So, from now on, every time we save or put a document into the subfolder [_doknir_] of folder "My Documents", it will appear in the virtual appliance.
[]

Word 2007 (.docx) and ISO 19005 (PDF/A)

Word 2007 is the fourth generation of the most popular Windows word processor. First generation are Word 1.0, 1.1, 1.2 and 2.0. Second are Word 6.0 and Word 95 (this is 32-bit Word 6.0 with support for long file names and "red-squiggle underlined spell-checking"). Third generation (VBA replaced WordBasic) consists of Word 97, Word 2000, Word XP and Word 2003.

We can characterize Word versions by library riched20.dll. For example, Word 2000 came with version 5.30.23.1203, and Word 2007 beta is using version 12.0.4017.1003. BTW, for unicode support, the file usp10.dll (Uniscribe Unicode script processor) is important.

Word default file extension used to be .doc. Let's download one document and try to open it in doknir: "Windows Vista Hardware Start Button Specification". This is the result:

Upgrading KWord to version 1.5.2 does not help - again "The application KWord (kword) crashed and caused the signal 6 (SIGABRT)". So we will need to use Word - in our case that will be version 2007 beta.

Before starting Word 2007, stop windows print spooler just like in "Crystal reports" example. Word 2007 behaves more friendly than Crystal reports, but again, only limited number of paper sizes are available (Letter, A4, Legal, A3, B4, B5) - fortunately, it is possible to define custom paper size.

There is no file menu in new Word - we must use "Office Button" instead:

For example, if we click on "Print", nothing happens, because print spooler is not running. BTW, because of the new button it is not possible to close window by double-clicking the little horizontal line icon in the upper-left corner:


That's why I've added little '×' next to the "Office Button" to close Word...

So, how to print Word file using doknir? Fortunately, Word 2007 has very useful new feature: "Save As PDF". You must select folder and enter the name of the PDF file and click on button Publish. To display PDF in 'doknir', open that folder, select newly created PDF, right-click on it and select 'doknir' in pop-up menu. Here is the first page of above document, displayed in 'doknir' - VMware virtual appliance:

What kind of joke is this ?!!! Aren't PDF documents portable? Ehm, no! Let's take a look at Word "Save As PDF" options:

Option "ISO 19005-1 compliant (PDF/A)" seems interesting - let's try it:

Aha, now it is OK. So what's the difference between the two PDF documents? If we look at the "Document Properties"->"Fonts" in Adobe Reader:


we can see that fonts in correct PDF document are embedded and this is the main difference between PDF and PDF/A:

The constraints include:

  • Audio and video content are forbidden
  • Javascript and executable file launches are prohibited
  • All fonts must be embedded and also must be legally embeddable for unlimited, universal rendering
  • Colorspaces specified in a device-independent manner
  • Encryption is disallowed
  • Use of standards-based metadata is mandated

At the end of this post, let's take a look at the new Word extension .docx. 'X' means that this is (compressed) Open XML format and I've found an excellent example with a lot of mathematical formulas. Bellow is the second page printed via 'doknir':




The quality of formulas in PDF files is still not perfect, but I hope Microsoft will correct this in the final version of Word 2007.

In the future, we will write a VBA macro to automate Word printing via 'doknir' ...

[]

Wednesday, August 02, 2006

spoolsv.exe

Simplicity is prerequisite for reliability.
--- EDSGER WYBE DIJKSTRA, How do we tell truths that might hurt? (1975)


Dr.
Jeffrey Jaffe (CTO for Novell) says in his blog:
"True, Windows is far from perfect. It is not comfortable to “ctrl-alt-del” every time my printer driver gets confused and hangs the system."

Why does printer driver get confused? I don't know. Why does printer driver hang the system? Because Windows print spooler gets confused. What is print spooler?

Software that manages printing in the computer. When an application is requested to print a document, it quickly generates the output on disk and sends it to the print spooler, which feeds the print images to the printer at slower printing speeds. The printing is then done in the background while the user interacts with other applications in the foreground.

Why does print spooler get confused? Because printer driver gets confused ...



Windows Printing Arhitecture (WPA) is one of the major components of the Windows architecture and it is indeed quite complex (here are two articles: "Printing Architecture" and "How Network Printing Works"). Basically, print spooler is executable implemented as service (spoolsv.exe) that waits for an RPC call from the client side of the spooler (winspool.drv). Spoolsv.exe calls the print router (spollss.dll) that determines which print provider to call, based on a printer name or handle supplied with each function call, and passes the function call to the correct provider ...

What follow are the consequences of this complexity:

And here are two links to solutions:

Another story is printing via Remote Desktop(RDP), Terminal Services or Citrix:

Above are only partial solutions - radical approach is to stop Windows print spooler service and use alternative solution. One of those radical ways how not to use Windows print spooler is to replace Windows, as Novell CTO suggests, with Linux:

"... that the Linux desktop has more than arrived – it has become the better desktop."

Well, here is my way how to tame print spooler: continue to use Windows desktop, but stop print spooler service and use "doknir" (VMware virtual appliance) as print spooler replacement.

[]

Saturday, July 29, 2006

Adobe Reader 7.0.8 for Linux

In "Crystal Reports" example, we were able to print report by exporting it to PDF file, which was displayed in doknir inside KGhostView windows. Unfortunately, KGhostView is not able to display certain complex PDF files. There is also no plugin for web browsers. Finally, even simple PDF is not printed correctly, if it is in landscape A4 format, for example.

Then there exist XPDF, poppler (XPDF fork), KPDF (which was based on XPDF, but now uses poppler), Evince (GNOME viewer, based on poppler). None of the packages convinced me!

So, only Adobe Reader remains. This used to be a problem, because there was no version 6 for Linux. This has changed with Adobe Reader 7. The installation file (.tar.gz) is larger than 40 MB.
Unzip it and go to Konsole, enter command sux and start installation with ./INSTALL. When the script asks about installing plugin, answer yes (and if it wants to owerwrite nppdf.so, also answer yes).



If PDF is by default still opened by KGhostView, we need to change the application preference order. Start Konquerer, go to menu "Settings">>"Configure Konqueror...", click on "File associations", click on + before "applications", select "pdf" and move "Adobe Reader" to the top:

But there exists big difference between Linux and Windows version - "Digital Editions ..." is not listed in the "File" menu of Adobe Reader for Linux!

The following text is from Adobe documentation:

Q: What is a digital edition (formerly known as an eBook)?

A: A digital edition is an electronic edition of a physical book, magazine,
journal, newspaper, sheet music, or newsletter. A digital edition is a file that
has been converted to Adobe Portable Document Format (PDF). Adobe digital rights
management (DRM) helps protect Adobe PDF files.

---
System Requirements
The digital edition capabilities of Reader 7.0 and Acrobat 7.0 are supported on the following operating systems:

  • Windows® XP Professional, Home, or Tablet PC Edition
  • Windows 2000 with Service Pack 2 or later
  • Mac OS X version 10.2.4 or later

---
You must activate Adobe Reader before you can use it to purchase or read Digital Editions. Adobe Reader automatically starts an Easy Activation the first time you attempt to open a protected Digital Edition. To move documents to other computers, you must complete the full activation using an Adobe ID or .NET Passport login:

  • If you have just completed an Easy Activation, click the Sign In And Reactivate button on the congratulatory page that appears after the Easy Activation process, and follow the on-screen prompts to complete the full activation.
  • In Adobe Reader, choose File > Digital Editions > Authorize Devices. On the Adobe DRM Activator website, sign in using your Adobe ID or .NET Passport ID and follow the on-screen instructions to activate Adobe Reader.
  • Go to the Adobe website at http://aractivate.adobe.com (Adobe DRM Activator), and follow the on-screen prompts.

DRM (Digital Restrictions/Rights Management) is mentioned above - you can read more about PDF and DRM relation in the two parts essay by John Mark Ockerbloom (1 & 2).

[]

Tuesday, July 25, 2006

Expand (resize/enlarge) virtual disk

Only for advanced users!


This is quite complicated procedure (because of reiserfs partition), so if you are not advanced user, I recommend to wait for "doknir II" which will be released in fall 2006.

For adventurous people, here are the details for growing VMware virtual disk:
  1. We will need the latest version of "resize_reiserfs" utility:
    apt-get update
    apt-get install reiserfsprogs
  2. Close virtual appliance and copy entire folder to new folder.
  3. Resize virtual disk in new folder using "Virtual DiskFactory". There must be VMware Server or Workstation installed, because utility depends on "DiskManager GUI" (command is vmware-vdiskmanager):

  4. Add enlarged disk to original VM as second SCSI disk (sdb)
  5. Start virtual appliance
  6. Use QTParted to remove linux swap partition (do not forget to commit) from second disk
  7. Start Konsole and type sux
  8. Use fdisk to change partition table of second SCSI disk (this will not delete data) in the following way:
    - delete existing partition sdb1 (Start Cylinder: 1, End: 283)
    - create new partition (Start Cylinder: 1, End: 450)
    - write changes to partition table and exit
  9. Start QTParted and create linux swap partition from remaining free space (cylinders from 451 to 509). Commit and exit!
  10. Expand the filesystem to fully fill the new size of the partition with the following command:
    resize_reiserfs /dev/sdb1
  11. Close VM and remove second SCSI disk from it
  12. Start new (cloned) VM.
  13. Verify the size of partition:

[]

Free disk space

One of the ways to see how much of disk space is used is to run 'QTParted' utility, which is located in 'System' menu of 'K' menu:


There is another way that does not require root password: "KInfoCenter" in "System" menu (click on Partitions):


According to the above screenshots, it's time for enlarging doknir's virtual disk ...

[]

Resolution (display size)

Default screen resolution of doknir is 1024×768. Since screen resolution of my host is 1600×1200, I decided to enlarge resolution of virtual appliance to 1400×1050. Here are the steps:
  1. Start Konsole and enter command sux
  2. Start: vmware-config-tools.pl
  3. Accept default answers to all question by pressing key 'enter' until the next question:
    Do you want to change your guest X resolution? (yes/no) [no]
  4. Reply with 'y' and select new display size:

Restart the virtual appliance!

BTW, maximum size is 2364 × 1773 !

[]

Monday, July 24, 2006

Crystal Reports

In two previous posts we saw examples from "academic" world: .DJVU and .PS files. Now let's take a look at an example from "business" world. Here is a quote from wikipedia:
Crystal Reports is a Business Intelligence application used to design and generate reports from a wide range of data sources. Several other applications, such as Microsoft Visual Studio, bundle an OEM version of Crystal Reports as a general purpose reporting tool.
BTW, there also exists "Crystal Reports for Delphi 2005".

We can download Crystal Reports XI trial (or Crystal Reports XI Release 2 with support for Visual Studio 2005) from "Business Objects" website. We also need a database - DBF (dBase) file is the simplest Here is one inside ZIP file (language classification table by Dr. Stephen Huffman).

Before we start building report let's stop Microsoft Windows Print Spooler (since doknir is its replacement). This can be done in several ways:
  1. Enter command net stop spooler in Windows Command Prompt (cmd).
  2. Start "Control Panel"->"Administrative Tools"->"Services". Double click on line "Print Spooler" and click on button "Stop".
  3. Same as 2.) but you can open "Services" tool using Start->Run dialog by entering command: services.msc
We can verify that print spooler is not running by trying to "Add Printer" - the following message should appear: "Operation could not be completed. The print spooler service is not running".

Now, start Crystal Reports (I use version 10) to create new report based on DBF file (BTW, I tried to open existing report and the following message appeared: "Invalid Printer: The default printer is not valid. Printing will be disabled.". Obviously, Crystal Reports was confused because windows print spooler was not running. Well, thanks to doknir, we will be able to print report :)

Anyhow, click on "New" in menu "File" to start report creation wizard. The most important thing is to choose the data file. To do this, click '+' in front of "Create New Connection" and then click again on '+' in front of 'xBase'. Select 'lang_family.dbf':

Continue with report creation by clicking on 'Next'.

Let's take a look at "Printer Setup" in File menu. As we can see "No Printer" is checked and disabled. Default "Paper Size" is Letter and if we click on combobox, there are only five choices: A4, A5, B5, Legal and Letter:



There is no custom paper size!!! It is sad that after so many years "Crystal Reports" are still based on printer drivers. I hope that it will be possible to define custom page size in version XII.
For example, Microsoft Word does not depend on windows printer subsystem since version Word 97, according to this article (KB 166016):
Use printer metrics
to lay out document

If this option is
enabled, Word will
use the information from the printer
driver that is installed as in some
earlier versions of Word.

If this option is
disabled (default),
Word will use build-in metrics to lay
out the document. This means your
document will look the same no matter
what printer driver is installed.
Here are some additional arguments why it is not good to rely on printer drivers.

Back to Crystal Reports - how to print our new report? Fortunately it is possible to export report to PDF file by clicking on "Export..." in "File" menu:



Open folder where new PDF report is saved, right-click on PDF file and choose 'doknir' to "print" it in virtual appliance - it will appear inside KGhostView window. For example, I printed and scanned first page and bellow is the result:

Can this process be simpler? Of course ... [in work]

P.S. For more information about Crystal Reports, read "Underground News" by Ken Hamady or read free chapters of new book by Brian Bischof.

[]

Friday, July 21, 2006

VMware Server 1.0 (build 28343)

VMware server 1.0 was released (2006-JUL-10). Instructions from previous post for installing new VMware tools are still OK:

[]

Monday, July 03, 2006

DjVu klik

No, it's not a mistake - I don't want to discuss about "Deja Vu" and "Click"! I will talk about "DjVu" and "klik".

DJVU format is similar to the Adobe Acrobat PDF, but unfortunately less known (despite its qualities). You can read about it in article (DjVu: Saving for our paper heritage) on NewsForge. It is also mentioned in the following article: Playboy Seeks Digital Exposure.

One way to install DJVU in Kanotix is using "klik" at http://klik.atekon.de. After some investigation I came to the conclusion that this was not the best way because:
  1. Latest version is not available.
  2. Only standalone viewer is installed - there is no browser plugin.
  3. Application is not automatically associated to the .djvu extension.
So we will use "apt". Before installation we must update information about packages (if we don't do that, apt will try to install older versions of packages, which will result in error because they will not be available on Debian servers anymore):


  1. Start Konsole and enter command 'sux'
  2. Start apt update with command:
    apt-get update
    The process can take several minutes:
  3. Install DJVU with command:
    apt-get install djvulibre-plugin
  4. After installation we can check the versions of packages:
    apt-show-versions | grep djv*
    Here is the result:
    libdjvulibre15/testing uptodate 3.5.17-1
    djvulibre-plugin/testing uptodate 3.5.17-1
    djview/testing uptodate 3.5.17-1
  5. Close Konsole.

Now we can switch to our beloved Windows host and try to find some DJVU files. Let's go the first server of the University at Albany, running since September 1993, called OMEGA. There are several files with .djvu extenstion - let's download "euclid.djvu" (BTW, it is much smaller than PostScript file). Open folder where downloaded document is located, right-click on .djvu file and select "doknir" ... DJView will start in virtual appliance. At first start, set the viewer preferences:

If you wish also make the toolbar always visible. Now let's print first (current) page. In the "Print Dialog" there is a "Print Command" setting - default value is "lp", but better alternative is "kprinter --stdin":

Here is scanned first page:
So, today '.djvu' wins over '.pdf' and 'apt' wins over 'klik'!

QED.

P.S. DJVU is part of the OLPC (One Laptop Per Child) project.
[]

Saturday, July 01, 2006

PS - PostScript (.ps)

Yet now and then your men of wit
Will condescend to take a bit.
- JONATHAN SWIFT, Cadenus and Vanessa (1713)
OK, we've prepared both windows and linux executables and mounted shared folder. Both executables are running and printer is ready so we can finally test 'doknir'.

For the first test I've choosen format that is by default supported in Linux, but not in Windows: PostScript. There are different ways how to add support for PostScript documents to Windows:


  1. GhostScript and GSView
  2. Adobe Acrobat Distiller
  3. CygWin and ps2pdf
  4. http://www.ps2pdf.com/
  5. PStill

Thanks to the virtualization there is another way to view and print postscript files: doknir! First we have to find a postscript file. Let's go to the Donald Ervin Knuth website. There are sneak previews of Volume 4 of "The Art of Computer Programming" (TAOCP), for example Pre-Fascicle 0b: Boolean Basics. It is compressed postscript file (.ps.gz), which can be unzipped with 7-zip or WinRAR. Open folder with unzipped document (fasc0b.ps) and right-click on it:

Click on 'doknir' and wait until the document appears in virtual appliance:



Let's print page 5:




Here is the scanned result:


QEF.

P.S. Can this process be simpler? Of course ... [in work]

[]

Friday, June 30, 2006

Remote LPD queue (LPR printing)

As already noted, we can convert USB printer to network printer with cheap device that consists of router and USB print server. What we have to do is to configure "Remote LPD queue":

  • Open 'Start menu'->'Settings'->'Printing Manager'

  • Click on printer, click on "Properties" tab, click on icon "Interface" and press button "Change..."

  • Choose "Remote LPD queue"


  • Click 'Next >' and define 'Host' and 'Queue'. In our case, values are '192.168.1.1' and 'lp0':

That's it. Printer should work ... It's time for the first test ...

[]

Thursday, June 29, 2006

Cheap Network Printer (black & white laser)

When I started to develop 'doknir', I didn't have a printer. After spending some time searching Slovenian computer stores, I decided to buy B&W laser Samsung ML-1610 (price: 75 EUR). Since this is not network printer, I also bought broadband router with USB print server (Digitus DN 11004 for 35 EUR). So printer+server for less than 139.99 USD. Anyhow, here are instructions how to install both devices to 'doknir':

  • Connect printer to router!
  • Kanotix (Debian Sid) supports many Samsung printers, but ML-1610 is not among them. Fortunately, Samsung has just released new version of "Uniform Driver". Download is here:
    Unified Linux Driver (ver.2.00.90)
  • Unzip the dowloaded file!
  • Start Konsole, enter command 'sux' and move to the folder with unzipped driver.
  • Enter command 'cdroot/autorun' to start 'Add printer wizard'
  • Choose "Manual select":

  • As connection select 'lpd://'. LPD address consists of two arguments: an IP address and a queue name. In our case, IP is 192.168.1.1 and queue name is lp0. So LPD address should be lpd://192.168.1.1/lp0. Unfortunately this does not work in Samsung wizard, so add just 192.168.1.1 without queue name. We will repair this later ...
  • Select driver "Samsung ML-1610 Series (SPL II)":

  • In printer options, we can change page size "US Letter" to "A4":
  • Now we can finish the wizard and test the printer. Because of wrong LPD address nothing will happen. To solve the problem, read this post ...

[]

Wednesday, June 28, 2006

Monitoring shared folder

By default, shared folder is mounted as /mnt/hgfs/doknir/. As already noted, hgfs (acronym for VMware's Host Guest File System) is disabled in VMware Player and Server. So we need to modify our doknir Linux executable to monitor /mnt/ntfs/doknir/ or /mnt/fat/doknir/. Details follow:


  • Start Konsole
  • Enter command "sux" and root password
  • Move to folder /home/doknir/prg/
  • Source is located in file "doknir.prg"
  • Replace beginning of the function 'Main' with the following code. You can use MC (Midnight Commander) to edit file. MC in similar to popular DOS utility NC (Norton Commander).
|| *************************
|| function Main(cShareType)
|| *************************
|| * cShareType: 'hgfs' 'ntfs' 'fat'
|| local nF, aF, cF
|| local i
|| local nSec, nReal
|| local cShare, cNiz
|| local oIni
|| ? ' Doknir 0.02b3 '
|| ? '==============='
|| if PCount()=0 .or. cShareType==''
|| cShareType:='hgfs'
|| else
|| cShareType:=Lower(cShareType)
|| endif
|| cShare:='/mnt/'+ cShareType +'/doknir/'
|| ? ' '
|| ? 'shared folder: '+cShare
|| ? ' '
|| // cShare:='/mnt/hgfs/doknir/'
|| cJobPath:=cShare+'win32/jobs/'
|| cTmpPath:=cShare+'win32/tmp/'
  • Save changes and close MC
  • Enter command "./bld.sh doknir". This will use Harbour compiler to translate "doknir.prg" to "doknir.c" and then build executable "doknir". There is no ".exe" in Linux - each file has property whether it is executable or not!
VoilĂ , we have new executable '/home/doknir/prg/doknir' and there is already a shortcut on the desktop. If we want to monitor shared NTFS folder, we must add argument ntfs to the command as shown on the next picture:



[]

Monday, June 26, 2006

Shared Folder

My original implementation of "doknir" is based on feature called "Shared Folders" that is part of "VMware Tools". Unfortunately shared folders capability is enabled only in Workstation and ACE.

BTW, this feature was enabled in early beta of VMware Player, but it was disabled because of security reasons.

If we want to run "doknir" with free VMware products (Server and Player), we need to use another approach: first share folder in Windows XP and then mount it in "doknir". Details follow:

  1. In Control Panel (classic view) open "Folder Options", select "View" tab and disable "Use simple file sharing".
  2. In Control Panel open "User Accounts" and create user "doknir".
  3. Create strong password.
  4. Create folder in Windows host that you want to share with "doknir" virtual appliance.
  5. Right click on new folder and select "Sharing and Security ..."
  6. Select "Share this folder" and set "Share name" to "doknir"
  7. Click on "Permissions" and allow "Full Control". OK and Apply!
  8. Click on "Security" tab. (There is no security tab, if folder is located on FAT32 partition)
  9. Select group "Users" and allow "Full Control". Apply and OK!
  10. In Control Panel open "System" and select "Computer Name" tab. Remember "Full computer name".
  11. Go to the "doknir" virtual appliance and start Konsole. Enter "sux" into command line and press ENTER (default root password is doknir).
  12. Created folders /mnt/ntfs/doknir and /mnt/fat/doknir:
    mkdir -p /mnt/ntfs/doknir
    mkdir -p /mnt/fat/doknir
  13. Mount shared folder (replace text MASTER with computer name that you remember from step 10). The following line is for NTFS folder

    mount -t smbfs -o username=doknir,
    fmask=777,dmask=777,lfs
    //master/doknir /mnt/ntfs/doknir


    and the next line is for FAT folder

    mount -t smbfs -o username=doknir,
    fmask=777,dmask=777
    //master/doknir /mnt/fat/doknir

    In each case "doknir" will prompt you for password. Use the one from step 3.
  14. Read how to monitor shared folder ...

[]

Sunday, June 25, 2006

VMware Server RC2

My license for VMware workstation has expired, so
I've downloaded and installed latest build of VMware
Server (RC2 - build 27828):
http://www.vmware.com/download/server/

Next step is to upgrade VMware Tools. To do this, click
"Install VMware Tools..." in menu "VM". Icon (shape of CD)
with name "VMware Tools" appears on the desktop. Extract
contents "VMwareTools-1.0.0-27828.tar.gz" to /home/doknir/tmp

Start Konsole and type "sux"
( http://fgouget.free.fr/sux/sux-readme.shtml )
Go to folder /home/doknir/tmp/vmware-tools-distrib/
and start ./vmware-install.pl
Press ENTER as reply to all questions.

BTW, after "vmware-install.pl", script "/usr/bin/vmware-config-tools.pl" starts -
here is part of its screen output:

Before running VMware Tools for the first time, you need to configure it by
invoking the following command: "/usr/bin/vmware-config-tools.pl". Do you want
this program to invoke the command for you now? [yes]

Stopping VMware Tools services in the virtual machine:
Guest operating system daemon: done
Guest filesystem driver: done
Deconfiguring network interfaces...done.
Guest vmxnet fast network device: done
Trying to find a suitable vmhgfs module for your running kernel.

None of the pre-built vmhgfs modules for VMware Tools is suitable for your
running kernel. Do you want this program to try to build the vmhgfs module for
your system (you need to have a C compiler installed on your system)? [yes]

Using compiler "/usr/bin/gcc". Use environment variable CC to override.

What is the location of the directory of C header files that match your running
kernel? [/lib/modules/2.6.16.16-kanotix-1/build/include]


...
Detected X.org version 7.0.

Do you want to change your guest X resolution? (yes/no) [no]


...
You must restart your X session before any mouse or graphics changes take
effect.

You can now run VMware Tools by invoking the following command:
"/usr/bin/vmware-toolbox" during an X session.

[]

Wednesday, May 31, 2006

How to create "doknir.exe" with Delphi 2006 Trial?

Part of "doknir" virtual appliance is small win32 utility.
Here are instructions how to build it from source:

Part I:

  1. Register at Borland and download Delphi 2006 Trial.
  2. Start installation. You can select only "Borland Delphi for Microsoft Win32".
  3. After installation and before starting Delphi put activation file into your home folder.

Part II: Importing ActiveX component (this was easier with previous versions of Delphi)

  1. You need free "wodShellMenu" component from WeOnlyDo! Software
    http://www.weonlydo.com/index.asp?showform=ShellMenu
    Download it and install it!
  2. Start Delphi and in menu "File" select New->Package
  3. Start "Import Compoment" wizard (in menu "Component")
    - choose "Import Type Library"
    - select WeOnlyDo! Shell ContextMenu COM object (if there is no such line, click Add and find wodShellMenu.dll in your system folder
    - set "Palette Page" to ActiveX
    - choose "Add unit to Package.bdsproj" project
    - Finish!
  4. In "Structure" window click on "Classes" and:
    - rename TMenuItem to TwodMenuItem and TMenuItems to TwodMenuItems
    - compile; there will be an error - rename as above
  5. Save all (for example to "wod.bdsproj")
  6. Compile - this will generate wod.bpl file.
  7. Close all
  8. Package is ready - install it via "Install Packages" in menu "Component":
    - click "Add..." and select wod.bpl

Part III: Building "doknir.exe"

  1. Open project "doknir.dpr"
  2. Delphi will report: Cannot find resource file: \doknir.res. Recreated.
  3. Compile project!

[]

Friday, May 26, 2006

Doknir Virtual Appliance

Microsoft Windows Print Spooler Service Replacement
(view and print documents in VMware virtual appliance)

Download at:
http://www.vmware.com/vmtn/appliances/directory/304



(This is how I imagine virtualization ;)
[]