Copy link to clipboard
Copied
Hello,
In my C++ code I am using the character kTextChar_FrameBoxBreak to make my text jump to the next chained/linked box, and kTextChar_ColumnBreak to make text jump to the next column, and both work fine.
But I cannot find the equivalent character to make text jump to the next cell of a table.
In the InDesign UI typing TAB moves the insertion point to the next cell, but using a tab char in my code does not jump to the next cell (all tabs are placed in the same initial cell).
Does anyone know what the code is ?
Very best regards,
Olivier
Copy link to clipboard
Copied
Hi @Olivier Beltrami I don't think there is any break character for changing the cell. The tab key is actually not inserting any character but acts like a shortcut for an action. I think you will explicitly have to target the insertionpoint in the desired cell.
-Manan
Copy link to clipboard
Copied
You should think of each cell in a table as its own text frame - they are not contiguously linked the way that columns in a text frame or linked text frames across a story are. Rather, each cell is in a way its own story. It's complicated in the C++ API, because there is one ITextModel that spans all the linked frames as well as all the contained tables, but within the text model there are a set of ITextStoryThread objects, managed by an ITextStoryThreadDict. Examples of ITextStoryThread objects include table cells, footnotes, notes, text macros, and deleted text. See ITextStoryThread.h for a better explanation.
To fully answer your question, you'll need to be more specific about what you're trying to achieve. Are you trying to actually set the selection in each cell? Are you trying to insert text in each cell? You may want to look at the table model iterator as a way to iterate through the cells of a table model:
ITableModel::iterator tableItr(tableModel->begin());
ITableModel::iterator tableItrEnd(tableModel->end());
for(; tableItr != tableItrEnd; ++tableItr)
{
InterfacePtr<ICellContent> cellContent(tableModel->QueryCellContentBoss(*tableItr));
if(cellContent == nil)
{
ASSERT(cellContent);
break;
}
InterfacePtr<ITextStoryThread> textStoryThread(cellContent, UseDefaultIID());
if(textStoryThread == nil)
{
ASSERT(textStoryThread);
break;
}
TextIndex startIndex = textStoryThread->GetTextStart();
TextIndex endIndex = textStoryThread->GetTextEnd();
[do whatever you need here]
But it's hard to fully answer without knowing more what you're trying to achieve.
Copy link to clipboard
Copied
@Lawrence Horwitz Thank you very much for your response.
Below is an example of what I am doing, using linked/chained frames. A token in the first frame generates text which flows across the linked frames by the insertiion of a kTextChar_FrameBoxBreak between each date. I was hoping to be able to do the same with a table; have the token in the first cell and have the generated text flow into cells.
Copy link to clipboard
Copied
Hi Oliver, that clarifies things. You won't be able to insert a character to jump between the cells of a table. Text does not flow from one cell to the next the way it does in text columns or in linked text frames.
Instead, try using the iterator I mentioned above. Once you have the beginning text index for a cell, you can insert text into the story just the way you do for any other text. By using that index, what you insert will go into the given cell. I believe you should be able to use the iterator to jump to the next cell after even after inserting new text and you should still get the correct text index for the next cell.
There are other ways of addressing cells using grid addresses if you need more control over the iteration, but it gets complicated because of the ways that cells can be merged. Given that your example shows a table with a single row, I think using the iterator is probably your best bet.
Copy link to clipboard
Copied
As mentioned by @Lawrence Horwitz - do not think about Cells as TextFrames - treat them as they are - Cells in the Table.
From the Cell's name get col / row, increase col, then get the reference to the next cell. Of course, you need to check if you're in the last col already 😉
Then you can get reference to the Text inside this Cell.
Copy link to clipboard
Copied
@Robert at ID-Tasker Because of merged cells, just incrementing grid addresses doesn't always work. In a merged cell, there can be multiple grid addresses, and only one of them is considered the "anchor cell". Some API methods that accept a GridAddress expect an anchor cell, while others don't.
You could use your method, but use ITableModel::IsAnchor to see if a given address is an anchor, and if not skip it and go onto the next. But because of the complexity of merging cells, the order you actually iterate over the cells might surprise you.
An ITableModel::iterator might be an easier solution here.
Copy link to clipboard
Copied
@Robert at ID-Tasker Because of merged cells, just incrementing grid addresses doesn't always work. In a merged cell, there can be multiple grid addresses, and only one of them is considered the "anchor cell".
By @Lawrence Horwitz
I'm not talking about "just incrementing" - I thought it was obvious 😉
If Cell is merged - you can read this information - together with the info how many Cells are merged - InDesign only allows rectangular merging so it's easy.
Using this info - you can calculate name / address of the next "physical" Cell.
Or - at least in scripting - there are other methods - I would say more convoluted 😉 - to get to the next Cell in row - even without using nextItem().
Copy link to clipboard
Copied
@Lawrence Horwitz Thank you very much for all the detailed hints. It might be the way to go, but as mentioned to @Robert at ID-Tasker , I'll have to see if there is an important enough advantage to being able to use tables in a way that I am already able to use linked frames (and multicolumn frames).
Copy link to clipboard
Copied
@Robert at ID-Tasker Thank you very much. I'll have to think about whether the convenience of using a table offsets the extra work needed to implement this.
Copy link to clipboard
Copied
@Robert at ID-Tasker Thank you very much. I'll have to think about whether the convenience of using a table offsets the extra work needed to implement this.
By @Olivier Beltrami
You're welcome.
Unless C++ plugins are so much more complicated - it shouldn't be a big deal? Just a simple math?
I still prefer good old Visual Basic and regular scripting 😉 even JS isn't powerful enough 😉
Copy link to clipboard
Copied
An alternative: use any character, e.g. tab as column separator, return as row separator.
Then use the equivalent to menu Table >> Convert Text to Table … .
ITableUtils::ConvertTextToTable() should do, or the same in ITableSuite .
Copy link to clipboard
Copied
But it could create a mess with more "complicated" Tables? Especially with multiple Paragraphs as Cell's contents?
Copy link to clipboard
Copied
Sure it can get more complicated, but only in leap years.
7 14 21 28 4 11 18 25 1 8
Copy link to clipboard
Copied
Sure it can get more complicated, but only in leap years.
7 14 21 28 4 11 18 25 1 8
By @Dirk Becker
I was talking more broadly 😉 about tables in general - not about this particular situation 😉
Copy link to clipboard
Copied
You can use any character as row separator, need not be the paragraph end.
Actually there are versions of the call that take string lists for the separators.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now