Iterating through controls on a form - controls

I am using C++ Builder. I want to locate several string grids that I have located on different tab sheets of a page control. I know how to iterate through the child controls of a specific control. In my case, each string grid is contained under a separate tab sheet control. My question is, is there a list of all controls in an app, without regards to the hierarchy of where they are contained?

There is such a list: Application->Components, consider code below
for (int i = 0; i < Application->ComponentCount; i++) {
for (int j = 0; j < Application->Components[i]->ComponentCount; j++) {
if (dynamic_cast<TStringGrid*>(Application->Components[i]->Components[j])){
//there is your TStringGrid* regardless of a place in application
}
}
}
You may as well iterate through your tab controls children if you are sure that your string grids are only there.

Related

How can I access on a widget at [i], stored in a Gtk::Box / Gtk::Grid?

I have a std::vector of Gtk::Boxes, that store widgets. Now, I want to access a certain widget in the Box at [i].
for(auto& it : layouts) {
for(int i = 0; i < it->size(); ++i) {
if(it->itemAt(i)->widget()) {
it->itemAt(i)->widget()->setVisible((std::string(it->get_name())== StringID));
}
}
}
layouts: std::vector holding Gtk::Boxes.
itemAt is a pseudo method, (QT method) to access Gtk::Box at (i).
Gtk::Box is not the right abstraction. Every operation on widgets is relative to other widgets present in the container. If you want control over children at a specific location in your container, I would suggest moving from Gtk::Box to Gtk::Grid, which has special methods to do what you need. For example, you could use:
Widget* Gtk::Grid::get_child_at(int left,
int top
)
See the reference for more information.

Photoshop scripting - Close all except first document

I'm trying to make a photoshop script that closes all documents without saving except for the first document. The first document will be a psd/psdc, the rest will be images
Currently I have the below code, this closes all documents
while (app.documents.length > 0) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
I've tried modifying it the same way I've done with a previous script, but it closes random documents, and not even all of them, it can leave 5-6 documents open
for (var i = 1; i < app.documents.length; i++) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
Can anyone point me in the right direction
Just use the inverted loop (so the docs are closed from the last to the first) and address them by the reference from the documents array, not by active document:
for (var i = documents.length - 1; i >= 1; i--) {
documents[i].close(SaveOptions.DONOTSAVECHANGES)
}

inDesign JSX scripted add of heading and content into textFrame

I'm attempting to use inDesign JSX scripts to insert the following data into a document:
data = [{heading:"Heading 1", content: ["Some content"]},
{heading:"Heading 2", content: ["Some other content with", "Multiple paragraphs"]}]
The data has to be placed into a single TextFrame, but have different styling on the heading and content.
The only way I can see to add the text is in one go via the textFrame.contents variable:
allContent = "";
headingParagraphs = []; // keep track of which paragraphs are headings
paragraph = 0;
for (var i = 0; i < data.length; i++) {
allContent += data.heading + "\r"; // Use a newline to split the paragraph
headingParagraphs.push(paragraph);
paragraph++;
for (var j = 0; j < data.content.length; j++) {
allContent += data.content[j] + "\r"; // Use a newline to split the paragraph
paragraph++;
}
}
textFrame.contents = allContent; // all data is in, but all text is styled the same
Then once the data is in, I iterate the paragraphs and add some style to the headings:
for (var i = 0; i < textFrame.paragraphs.count(); i++) {
if (headingParagraphs.indexOf(i) != -1) { // this is a heading paragraph
textFrame.paragraphs[i].pointSize = 20;
}
}
This works fine for small data sets that fit on one page, but once the contents gets bigger than the frame, paragraphs only returns visible paragraphs. And if I follow on to a new textFrame, paragraphs get split and the headingParagraphs[] array no longer lines up.
Ideally I'd like to append to the contents and set styles before I append the next content - but the API docs aren't very clear on how you might do that (if at all)
// Pseudo code:
for all sections:
append the heading to the frame, split to next page if needed
style all the *new* paragraphs as headings
for all section contents
append the content to the frame, split to next page if needed
style any *new* paragraphs as normal content
Is there a way to achieve this using either an append function or some other way to assign headings to the right place after content has been added? Perhaps special characters in the content to define style?
Your longer text gets messed up because currently you are working inside a single text frame. As soon as the text runs out of this one frame, you can't refer to them as this frame's "owned" paragraphs anymore. Use parentStory instead, as it points to the whole story, inside one text frame or spanning more than one. It also keeps on working if the text gets overset.
So if you have a starting frame called textFrame, set a new variable story to textFrame.parentStory and use that to add text.
As for adding text to this frame(/story): indeed, there is no fast way to add formatted text. Setting contents only works for long swathes with the same formatting. One way I've used is to write INX formatted text to a temporary file and importing that. It's slow for short fragments, but larger stories (up to several hundreds of pages) can be created very efficiently in Javascript itself, and then importing it into ID is .. well, it aint fast but faster than trying to do it "manually".
The other way is to add contents one paragraph at a time. The trick is to set formatting and add your text to story.insertionPoints[-1]. This, in a particularly handy notation, refers to the very last text insertion point of the story. You can think of an insertion point as "the text cursor"; you can 'apply' formatting to it, and any text added will then have this formatting as well.
Your code snippet reworked to add one data item at a time:
for (var i = 0; i < data.length; i++)
{
story.insertionPoints[-1].pointSize = 20;
story.insertionPoints[-1].contents = data[i].heading + "\r"; // Use a newline to split the paragraph
story.insertionPoints[-1].pointSize = 10;
for (var j = 0; j < data[i].content.length; j++)
{
story.insertionPoints[-1].contents = data[i].content[j] + "\r"; // Use a newline to split the paragraph
}
}
One thing to note is that you cannot temporarily override the pointSize here. If you set it to your larger size, you must also set it back to the original size again (the '10' in my snippet).
Can I convince you to look in to using paragraph styles? With paragraph styles, you'd have something like
hdrStyle = app.activeDocument.paragraphStyles.item("Header");
textStyle = app.activeDocument.paragraphStyles.item("Text");
for (var i = 0; i < data.length; i++)
{
story.insertionPoints[-1].contents = data[i].heading + "\r"; // Use a newline to split the paragraph
story.insertionPoints[-2].appliedParagraphStyle = hdrStyle;
for (var j = 0; j < data[i].content.length; j++)
{
story.insertionPoints[-1].contents = data[i].content[j] + "\r"; // Use a newline to split the paragraph
story.insertionPoints[-2].appliedParagraphStyle = textStyle;
}
}
Note that it's worth here to invert inserting contents and applying formatting. This is so any previous 'temporary' formatting gets cleared; applying a paragraph style this way overrides any and all local overrides. As you have to apply the style to the previous paragraph (the one before the hard return you just inserted), you would use insertionPoints[-2] here.
The advantages of using styles over local formatting are countless. You can apply all formatting you want with a single command, safely remove all local overridden formatting, and change any part of the formatting globally if you are not satisfied with it, rather than having to re-run your script with slightly different settings.

Programatically updating underlying data in Slickgrid

I have 6 textboxes at the top of the screen that update an entire column(one textbox per column) based on any changes. I was selecting the columns based on their class (.l#). Here is the code (issues to follow):
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = [".l1", ".l7", ".l8", ".l9"];
var fields = $(bound[id]);
for (var i = 0; i < fields.length; i++)
{
fields[i].innerHTML = $(ctrl).val();
}
};
which is bound to the keyup event for the text areas. Issues are:
1) initially fields.length was -1 as I didn't want to put data in the "add new
row" section at the bottom. However, when running it, I noticed the
final "real" record wasn't being populated. Also, when stepping through, I
noticed that the "new row" field was before the "last row" field.
2) when doing it this way, it is purely superficial: if I double click the field,
the real data hasn't been changed.
so in the grand scheme of things, I know that I was doing it wrong. I'm assuming it involves updating the data and then forcing a render, but I'm not certain.
Figured out how to do it. Modified the original code this way:
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = ['title1', 'title2', 'title3', 'title4'];
var field = bound[id];
for (var i = 0; i < dataView.getLength(); i++)
{
var item = dataView.getItem(i);
item[field] = $(ctrl).val();
dataView.updateItem(i, item);
}
grid.invalidate();
};
I have 6 textboxes (item1-item6) that "bind" to fields in the sense that if I change data in a textbox, it updates all of the rows and any new rows added also have this data.
Parts where the two issues can be explained this way:
1) to work around that, though still it would be a presentational fix and not a real updating of the underlying data, one could force it to ignore if it had the active class attached. Extra work, and not in the "real" direction one is going for (masking the field).
2) It was pretty obvious with the original implementation (though it was all I could figure out via Chrome Dev Tools that I could modify at the time) that it was merely updating a div's content and not actually interacting with the data underneath. Would look nice, and perhaps one could just pull data from the item1-item6 boxes in place of the column if it is submitted, but if someone attempts to modify the cell, they'll be looking at the real data again.

Changing the width of all columns in a DataGridView

We have a DataGridView which has 2048 columns. We must provide a way for the user to increase and decrease the width of all columns in the DataGridView.
Currently, we do the following in a button click handler:
for (int i = 0; i < dgv.Columns.Count; i++)
{
dgv.Columns[i].Width += 5;
}
But that takes a while! (around 2 seconds to be more specific). (Note: We set the ColumnHeadersHeightSizeMode property to DataGridViewColumnHeadersHeightSizeMode.DisableResizing to gain some performance, but that doesn't cut it)
Is there a faster way to achieve the column resizing?
You could try attaching a separate event to the button click for each column, something like this:
for (int i = 0; i < 500; i++)
{
DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn();
dataGridView1.Columns.Add(c);
button1.Click += (o, e) => {
c.Width = 10;
};
}
I tried this on a hunch and it looks like it works. I"m not sure though whether there are any side effects, whether or not there is a better method or even whether it would work for a non-trivial example - all my columns are empty and unbound.

Resources