Can I to modify and clear cells content at run time?

General TRichView support forum. Please post your questions here
Post Reply
jhonalone
Posts: 31
Joined: Mon Apr 07, 2008 5:59 pm
Location: Madrid

Can I to modify and clear cells content at run time?

Post by jhonalone »

I'm trying to insert barcode and text into existing table cells.
So that, I designed a test procedure, before insert it to proyect.
I've an "EAccessViolation" error that I do not know how to solve.

Can you help me?

Code: Select all

...
table := TRVTableItemInfo.CreateEx(NumR,NumC, rve.RVData);
...
if rve.InsertItem('test', table) then begin  end;
...
procedure TForm1.rveDblClick(Sender: TObject);
var
   table:TRVTableItemInfo;
   i : integer;
   r,c : integer;
begin
for i := 0 to rve.ItemCount-1
do if (rve.GetItemStyle(i)=rvsTable) and
      (rve.GetItemText(i)='test') 
   then begin
        table :=  TRVTableItemInfo(EditorActivo.GetItem(i));
        table.GetEditedCell(r,c);
        table.Cells[r,c].Clear;
        table.Cells[r,c].AddNL('Test test test',7,0);
        rve.Format;
        table.EditCell(r,c);
        end;
end;
Sergey Tkachenko
Site Admin
Posts: 17555
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

1) Are rve and EditorActivo the same
2) Your code expects that some table cell is being edited. You should check if table.GetEditedCell(r,c)<>nil
3) Do you want to implement this procedure as an editing operation (undoable?)
In this case:

Code: Select all

procedure TForm1.rveDblClick(Sender: TObject); 
var 
   table:TRVTableItemInfo; 
   celledit: TCustomRichViewEdit;
   i : integer; 
   r,c : integer; 
begin 
for i := 0 to rve.ItemCount-1 do 
  if (rve.GetItemStyle(i)=rvsTable) and 
      (rve.GetItemText(i)='test') 
   then begin 
        table :=  TRVTableItemInfo(rve.GetItem(i)); 
        celledit := table.GetEditedCell(r,c);
        if celledit<>nil then begin
          celledit.SelectAll;
          // celledit.DeleteSelection;
          celledit.CurTextStyleNo := 7;
          celledit.CurParaStyleNo := 0;
          celledit.InsertText('Test test test'); 
        end; 
end; 
jhonalone
Posts: 31
Joined: Mon Apr 07, 2008 5:59 pm
Location: Madrid

Post by jhonalone »

Yes, rve and EditorActivo are the same. This is a copy error.

Yes, code is undoable by the editor. I do not want the end user to modify anyware.

I'm trying to do an exact image of DIN-A4 8x3 labels matrix in a table of 8x3 rows/cols. Well, each cell is one barcode label. If the user double-click on one cell then barcode appears into cell, if double-clic again in the same cell, then the cell is cleared and codebar is also cleared.

Therefore, the end user can select and deselect which 8x3 label will be printed.

I have not implemented the labels drawing yet.

Is it possible to draw the codebar directly on the cells canvas? and how can I do it?

I thank you a lot, again.
Sergey Tkachenko
Site Admin
Posts: 17555
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

The code I posted above works as an editing operation, i.e. the user can undo it with Ctrl+Z.
If you do not want to allow editing document, it's better using TRichView instead of TRichViewEdit. And the code would be:

Code: Select all

uses CRVFData;
procedure TForm3.RichViewEdit1RVMouseDown(Sender: TCustomRichView;
  Button: TMouseButton; Shift: TShiftState; ItemNo, X, Y: Integer);
var ClickedItemNo, ClickedOffs: Integer;
    ClickedRVData: TCustomRVFormattedData;
    pt: TPoint;
begin
  if ssDouble in Shift then begin
    pt := Sender.ClientToDocument(Point(X, Y));
    Sender.GetItemAt(pt.X, pt.Y, ClickedRVData, ClickedItemNo, ClickedOffs, False);
    if (ClickedRVData.GetSourceRVData is TRVTableCellData) and
       (TRVTableCellData(ClickedRVData.GetSourceRVData).GetTable.ItemText='test') then begin
      ClickedRVData.Clear;
      ClickedRVData.AddNL('Test test test', 7, 0);
      Sender.Format;
    end;
  end;
end;
As for drawing, you can try to use table.OnDrawBorder for drawing inside table cell, but I think it's better to insert metafiles in cells.
jhonalone
Posts: 31
Joined: Mon Apr 07, 2008 5:59 pm
Location: Madrid

Post by jhonalone »

Hello again, Sergey!

I just tried both procedures. But the latest procedure can be modified by user, also. Therefore, I decided to use the procedure below.

Code: Select all

...
 EtiActiva:Array[0..7,0..2] of Boolean;
//All EtiActiva[r,c] begin at false
...
procedure TFormUnidad1.RichViewEdit1DblClick(Sender: TObject);
var
      table : TRVTableItemInfo;
   CellEdit : TCustomRichViewEdit;
          i : integer;
        r,c : integer;
     Imagen : TBitmap;
begin
Imagen := TBitmap.Create;
Imagen.Height := 40;
Imagen.Width := 235;
PrinCb.SendToCell('Name Name Name',Imagen.Canvas);

for i := 0 to RVE.ItemCount-1 do
  if (RVE.GetItemStyle(i)=rvsTable) and
     (RVE.GetItemText(i)='Labels')
   then begin
        table :=  TRVTableItemInfo(RVE.GetItem(i));
        CellEdit := table.GetEditedCell(r,c);
        if CellEdit<>nil
        then begin
              CellEdit.SelectAll;
             if EtiActiva[r,c]
             then begin
                  CellEdit.DeleteSelection;
                  RVE.ClearUndo;
                  UpdateUndoMenu;
                  EtiActiva[r,c] := False;
                  end
             else begin
                  CellEdit.AddPictureEx('', Imagen, 0, rvvaMiddle);
                  CellEdit.AddNL('Name Name Name',7,0);
                  RVE.ClearUndo;
                  UpdateUndoMenu;
                  EtiActiva[r,c] := True;
                  end;
             end;
        end;
end;
 
But there is a little problem with this code:
It runs fine if I double-click over the top side of the cells.

If I double-click on the lower half of the cell, nothing appears into cell until I click on another cell or on the upper part of this cell.

I'm very surprised by this.

Can you help me, please?

Many thanks, as always!
Sergey Tkachenko
Site Admin
Posts: 17555
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Call RVE.Format after using non-editing methods (like AddNL and AddPictureEx)
jhonalone
Posts: 31
Joined: Mon Apr 07, 2008 5:59 pm
Location: Madrid

Post by jhonalone »

Sergey, I tried this option before asking you. Then I got a EAccessViolation error. ( !? )

Well, I don't want to use this type of solution, but I'm thinking about using this code:

Code: Select all


if (r > 0) and (c > 0) // we can't go back from the first cell
                  then begin
                       // back to the previous cell
                       keybd_event(VK_SHIFT,0,0,0); // Down 
                       keybd_event(VK_TAB,0,0,0);   // Down 
                       keybd_event(VK_TAB,0,2,0);   // Up   
                       keybd_event(VK_SHIFT,0,2,0); // Up   
                       // to the following cell
                       keybd_event(VK_TAB,0,0,0);   // Down 
                       // thus, we go back to the clicked cell
                       end
                  else begin  // if it is the first cell
                       // first we go to the next cell 
                       keybd_event(VK_TAB,0,0,0);   // Down 
                       // now we go back to the clicked cell
                       keybd_event(VK_SHIFT,0,0,0); // Down 
                       keybd_event(VK_TAB,0,0,0);   // Down 
                       keybd_event(VK_TAB,0,2,0);   // Up   
                       keybd_event(VK_SHIFT,0,2,0); // Up  
                       end;
I've tried this code and it seems to run really well.
Thank you again for your efforts and quick answer.
Sergey Tkachenko
Site Admin
Posts: 17555
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Well, correct, RVE.Format cannot be called from OnDblClick (because it moves the caret outside the cell; it destroys the cell inplace editor, but it is not allowed inside this event).
So use InsertPicture and InsertText instead.
Post Reply