• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to get coordinates of table cell in a multi column text frame

Contributor ,
Apr 25, 2023 Apr 25, 2023

Copy link to clipboard

Copied

Hi All,

 

I am using following code to get the table coordinate as it shown in the info panel.

 

InterfacePtr<ITextStoryThread> storyThread(txtModel->QueryStoryThread(startPos + 1));
if(storyThread){
GridAddress gridAdd;
ParcelKey parcelKey;
 
InterfacePtr<ICellContent> cellcontentp(storyThread, UseDefaultIID());
if(cellcontentp){
gridAdd = cellcontentp->GetGridAddress();
parcelKey = cellcontentp->GetNthParcelKey(0);
}
else {
break;
}
 
InterfacePtr<ITableLayout> tableLayout(tableModel, UseDefaultIID());
if(tableLayout){
ITableLayout::frame_iterator begframeIter = tableLayout->begin_frame_iterator();
ITableLayout::frame_iterator endframeIter = tableLayout->end_frame_iterator();
 
// Having problem in getting ITableFrame directly from the startPos
// So iterate over the table frames to find which one contains the address of our cell content
for(;begframeIter != endframeIter; ++begframeIter){
InterfacePtr<ITableFrame> tableFrame(begframeIter->QueryFrame());
if(tableFrame){
CellParcelAddr cpa(gridAdd, parcelKey);
if(tableFrame->Contains(cpa)){
GridID gridID(cellcontentp->GetGridID());
GridAddress gridAddress(cellcontentp->GetGridAddress());
 
// Till here, the point seems to be right, we need to convert to table and then to frame coords i guess
// InterfacePtr<ITableGeometry> tableGeo(tableModel, UseDefaultIID());
// PMRect cellRect = tableGeo->GetCellBounds(gridAddress);
PMRect cellRect = tableFrame->GetCellBounds(gridAddress);
int32 xPos = cellRect.Left();
int32 yPos = cellRect.Bottom() - cellRect.Height();
}
}
}
}
}
 
Can some suggest a good approach to get the x,y coordinate of table cell in multi column frame.

 

Regards,

Alam

TOPICS
SDK

Views

1.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Apr 29, 2023 Apr 29, 2023

This should give you the rect relative to parent frame. Seems to work with tables within tables.

 

How you arrive at storythreadp and key is up to you.

 

As Dirk mentioned you will have to consider indents and others.

 

                InterfacePtr<ICellContent> cellcontentp(storythreadp, UseDefaultIID());

                if ( cellcontentp )

.... .... ...

                    PMRect cr = cellcontentp->GetCellPathBounds ( key );

                    PMMatrix m = cellcontentp->GetParcelToFrameMatrix ( key );

 

...

Votes

Translate

Translate
Community Expert ,
Apr 26, 2023 Apr 26, 2023

Copy link to clipboard

Copied

Hi @alam_84 ,

search the InDesign forum, recently we had a solution for this:

 

How to get coordinates of table column or cell
Phil28637952i5ng, Apr 19, 2023
https://community.adobe.com/t5/indesign-discussions/how-to-get-coordinates-of-table-column-or-cell/t...

 

Also look into the TableCellBox.jsx script by Marc Autret:

https://github.com/indiscripts/IdGoodies/blob/master/snip/TableCellBox.jsx

 

The Magic Parent Bounding Box
Marc Autret, August 04, 2022

https://www.indiscripts.com/post/2022/08/magic-parent-bounding-box

 

And a discussion in German that inspired Marc Autret at hilfdirselbst.ch:

https://www.hilfdirselbst.ch/foren/Koordinaten_einer_Tabellenzelle_P583998.html

 

Regards,
Uwe Laubender
( Adobe Community Expert )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 26, 2023 Apr 26, 2023

Copy link to clipboard

Copied

Oh. Sorry. You are looking for a SDK solution.

 

Regards,
Uwe Laubender
( Adobe Community Expert )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Apr 26, 2023 Apr 26, 2023

Copy link to clipboard

Copied

Yes, I am looking for SDk solution.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 26, 2023 Apr 26, 2023

Copy link to clipboard

Copied

Have a look at the transforms in ITableFrame.h.

 

virtual PMMatrix GetToFrameMatrix() const = 0;

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Apr 26, 2023 Apr 26, 2023

Copy link to clipboard

Copied

My issue is that when we design a 3X3 table in a 3 column text frame in such a way that each row fit in each column, means 1st row in 1st column, 2nd row in 2nd column and 3rd row in 3rd column as shown in below image then my code that I shared initially return same x,y position of all cells.

Screenshot 2023-04-27 at 8.31.31 AM.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

Can someone suggest the good approach to get the top, left of each cell irrespective of thier position in multi-column frame as shown in image.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

Hi @alam_84 ,

with ExtendScript we have an answer for this.

See Marc Autret's code at github.

I linked to it in my first answer above.

 

Regards,
Uwe Laubender
( Adobe Community Expert )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

Not sure whether it is relevant, but I iterate the cells straight from ITableModel.

Using QueryCellContentBoss() I likely end up at the same ICellContent as your cellcontentp.

To the parcel via GetNthParcelKey.

GetParcelToFrameMatrix looks promising (growing tx).

There could be better ways, I've covered only few interfaces.

 

Of course you should also handle overset, graphics cells etc.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

Btw, the parcel's GetParcelFrameUID() is the matching kFrameItemBoss (text column) within the kMultiColumnItemBoss (actual text frame) if you prefer to compute on coordinates.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

Hi Dirk,

I could get the ITableFrame from api GetParcelFrameUID and if I use GetCellBounds() then it return same top, left for first column in each row whereas left of 2nd and 3rd row should be different.

Let me know the next step that I should follow

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

Does it has any relattion with ITextFrameColumn as I am getting 

ITextFrameColumn as follows and passing that to 

::TransformInnerPointToPasteboard(textframe, refthePoint);

InterfacePtr<IFrameList>frmList(txtModel->QueryFrameList());

if(frmList){

InterfacePtr<ITextFrameColumn> textframe(frmList->QueryFrameContaining(startPos, nil));

}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 28, 2023 Apr 28, 2023

Copy link to clipboard

Copied

I'm using a plug-in that dumps out various getters of interfaces, as far I've needed them within the past 20 years, mostly on basis of simple iteration. Back in 2018 that came across ITableModel and CellContent, but I never covered ITableLayout or ITableGeometry because I did not need them. I also don't know how far they are covered in the programming guide.

 

Therefor we've accidentally come to talk about different interfaces, coming from entirely different models (table vs. text). My "not sure whether this is relevant".

 

Within the containing text model (my approach), kTableFrameBoss is an owned item, basically one per the 3 visual table fragments matching the 3 text columns. I never looked at the table frame though because I also ignored most of its interfaces, and in the 422k lines file produced from a minimum document I first came via table model to ICellContent - as mentioned.

 

Apparently my ICellContent::GetParcelFrameUID refers to a different object (the text colum kFrameItemBoss) while yours (still going thru ITableLayout::GetParcelFrameUID?) reaches the table frame.

 

If you look at ITableLayout, it has an own concept / nested class of parcel, frame etc. These are likely far more appropriate for your computations - I just don't cover them yet. E.g. see ITableLayout::Frame::GetParcelKey comment, looks like a bridge to reach the parcel enclosing the table frame. No separate types (TextParcelKey vs. TableParcelKey) though, because you can nest tables within tables ... See ITableFrame::GetFrameRef() - does it lead to my kFrameItemBoss or to the enclosing kMultiColumnItemBoss?

 

So with all these parcels around, nested frames (either table or text) and so forth, it is not trivial to even create test data to validate assumptions about what parcelkey is relative to what parcellist etc. Is that parcel key #0 relative here or there? What matrix is suddenly turned to non-ident by a cell stroke. Do you use the correct matrix, and all of them, or will it fall apart when you modify some cell padding (is there such a concept?). Add rotation somewhere, table within table, or disturb the flow, e.g. with anchored items or with text wrap on top of text cells, producing multiple parcels within a cell. Text wrap pushing into the outside text column producing multiple parcels there - how will the table frame stretch or split? Such an exhaustive effort will take several days just to produce test data. Can tables appear within footnotes and type-on-path?

 

Far beyond the scope of a forum post, where I don't know where in your larger context you're heading. Hit test, text drawing an own adornment, other decoration. Maybe the bounds and transforms in ITableFrame are your solution?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 29, 2023 Apr 29, 2023

Copy link to clipboard

Copied

This should give you the rect relative to parent frame. Seems to work with tables within tables.

 

How you arrive at storythreadp and key is up to you.

 

As Dirk mentioned you will have to consider indents and others.

 

                InterfacePtr<ICellContent> cellcontentp(storythreadp, UseDefaultIID());

                if ( cellcontentp )

.... .... ...

                    PMRect cr = cellcontentp->GetCellPathBounds ( key );

                    PMMatrix m = cellcontentp->GetParcelToFrameMatrix ( key );

                    m.Transform ( &cr );

... ... ...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
May 04, 2023 May 04, 2023

Copy link to clipboard

Copied

Hi Pictory,

 

Thanks for info yes the above code works

After transform api, I checked PMRect cr for left, top, bottom and right

and it gives the cell x,y position but not the x,y position of start of text in each cell.

And I further used following code to get the x,y position from the start of text in each cell

InterfacePtr<ITableModel>tableModel(tableFrame->QueryModel());

if(!tableModel){

break;

}

// Getting cell inset

InterfacePtr<ITableAttrAccessor> attrAccessor(tableModel, UseDefaultIID());

if (!attrAccessor)

break;

 

        InterfacePtr<ITableAttrRealNumber> parentLeftInsetNumber(attrAccessor->QueryCellAttribute(gridAddress, kCellAttrLeftInsetBoss, IID_ITABLEATTRREALNUMBER), UseDefaultIID());

        PMReal parentLeftInset = parentLeftInsetNumber->Get();

 

Regards,

Alam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 04, 2023 May 04, 2023

Copy link to clipboard

Copied

LATEST

Look at IWaxLine

 

                        InterfacePtr<ITableModel> tableModel(cellcontentp->GetTableModel(), UseDefaultIID());

                        if ( !tableModel )

                            break;

                        InterfacePtr<ITableAttrAccessor> attrAccessor(tableModel, UseDefaultIID());

                        if ( !attrAccessor )

                            break;

                        InterfacePtr<ITableAttrRealNumber> leftInset((ITableAttrRealNumber*)attrAccessor->QueryCellAttribute

                                                                     (cellcontentp->GetGridAddress(), kCellAttrLeftInsetBoss, IID_ITABLEATTRREALNUMBER));

                        PMReal leftInsetValue = 0;

                        if (leftInset != nil) {

                            leftInsetValue = leftInset->Get();

                        }

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines