// ****************************************************************************
//  U_CBFix.pas                                                     12/06/2005
//  Written by Brian Layman (AKA Capt. Queeg)
//  Visit him at http://www.TheCodeCave.com
//
//  A quick program to autoformat the clipboard contents to upper or proper
//  case.  A requested app for a member of http://www.ztw3.com/forum/forum.cgi
//
//  Usage: CBFixerUpper.exe
//
//  History:
//     12/06/2005 - BL - Created
//
// ****************************************************************************
unit u_CBFix;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, Clipbrd;

type
  TfrmCBFix = class(TForm)
    editCorrectedText: TEdit;
    Timer1: TTimer;
    xboxProperCase: TCheckBox;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end; // tfrmCBFix

var
  frmCBFix: TfrmCBFix;

implementation

{$R *.DFM}

{******************************************************************************
  ProperCase
  Converts a string to proper case by capitalizing each letter after a space or
  punctuation.  The only common punctuation not used is the apostrophe/single
  quote.  This avoids changing don't to Don'T, but will sentences quoted
  inside single quotes will not have their first letter capitalized.
 ******************************************************************************}
function ProperCase(aSrcStr: String): String;
var
  Len, Index: integer;
begin // ProperCase
  // Convert it all to lowercase so that we can raise only the proper letters
  aSrcStr := Lowercase(aSrcStr);
  // Get the length once, it won't be changing
  Len := Length(aSrcStr);
  // Always convert the first char
  aSrcStr[1] := UpperCase(String(aSrcStr[1]))[1];

  // Iterate the rest of the characters bumping the ones that follow spaces.
  for Index := 1 to Len - 1
  do begin
    if (aSrcStr[Index] in [' ','$','"','(',')','`','!','?','<','!','>','#','=',
                           '+',':',',','/','.','&','-','{','}','[',']','|'])
    then aSrcStr[Index + 1] := UpperCase(String(aSrcStr[Index + 1]))[1];
  end;

  // Pass back the result.
  Result := aSrcStr;
end;  // ProperCase

{******************************************************************************
  Timer1Timer
  Fires periodically (orignally every 250ms), checks the clip board for text,
  if it has changed, convert it to proper case and put the result in the
  clipboard and the edit control.
 ******************************************************************************}
procedure TfrmCBFix.Timer1Timer(Sender: TObject);
begin // Timer1Timer
  // Only convert the clipboard contents if it is text
  if (Clipboard.HasFormat(CF_TEXT))
  then begin
    // Optimize by only converting if the text hadn't yet been converted.
    // This means that you need to recapture the clipboard text if you change
    // the checkbox setting.
    if (editCorrectedText.Text <> Clipboard.AsText)
    then begin
      // Do the correct conversion, Upper or Proper.
      if (xboxProperCase.Checked)
      then editCorrectedText.Text := ProperCase(LowerCase(Clipboard.AsText))
      else editCorrectedText.Text := UpperCase(Clipboard.AsText);

      // Now reassign the text.
      Clipboard.AsText := editCorrectedText.Text;
    end;
  end;
end;  // Timer1Timer

end.
