View Issue Details

IDProjectCategoryView StatusLast Update
0017399ScribusGeneralpublic2025-04-05 22:22
Reportertropion Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Summary0017399: Objects in groups are not accessible via the scriptplugin python API
DescriptionI suggest the attached patch
Steps To ReproduceCreate objects
Group the objects
Open the script console
Type getAllObjects()
Press F9
See that the group is returned, but not the elements of the group.

Type objectsExists('<name of obj in group>')
Press F9

See that the object is not accessible.
getGroupItems ('Group1',recursive=true)
returns all objects in Group1, but there still is no way to do anything with them.
TagsNo tags attached.
Patch

Relationships

related to 0017490 new [PATCH] Scripter: GetItem(name) should look inside of groups 
related to 0009054 assignedale Feature: Fix Hairline width 

Activities

tropion

2025-01-31 16:05

reporter  

scriptplugin.diff (5,645 bytes)   

ale

2025-02-22 11:19

manager   ~0052099

can you explain what exactly your script does?

if i understand it correctly, it's patching all the function that have an own implementation of getItem (and getItem itself) to also look inside of groups.

if it's the case, that's fine for me and i would be ready to review your patch.

i already have one remark:
shouldn't also groups in groups be explored?
this can be done by creating a stack with the items to be looped and adding the children to it, when a group is found.

tropion

2025-02-24 09:35

reporter   ~0052110

You do understand this correctly, it changes getItem and all variations of it to also look inside of groups.

Whenever a group is encountered getAllChildren() is called. That should explore groups in groups.

ale

2025-02-24 19:38

manager   ~0052112

/tmp/scriptplugin.diff:61: trailing whitespace.
        PyObject* l = PyList_New (0);
/tmp/scriptplugin.diff:80: trailing whitespace.
                                        if (it->OwnPage == pageNr)
/tmp/scriptplugin.diff:104: trailing whitespace.
                // We do not call getPageItemByName() here,
warning: 3 lines add whitespace errors.

ale

2025-02-24 21:28

manager   ~0052114

I've made a review on Gitlab:

https://gitlab.com/scribus/scribus/-/merge_requests/48

The patch seems Ok to me, just a few minor or aesthetic things that can be fixed.

ale

2025-04-05 22:16

manager   ~0052408

I'm going through this after some time... after having had again the need for modifying the properties of items in a group...

i attach a patch that, in my eyes, is slightly better.

First, i'm leaving out the changes in getAllObjects() and getPageItems().
i don't think it's a good idea to make them return all items, included the ones that are in a group.
0017052 has added getGroupItems() and it's probably better to go through all the direct items and, if you encounter a group act on its items (if the task demands for it)

Also, ReplaceColor() is now completely different. Probably no need to patch it.

My version of the patch

- adds getPageItemByNameOrNull(), which does not throw a python exception. getPageItemByName() uses and throws an exception on nullptr (or empty name).
- removes GetItem() and replace its only usage by getItemByName() (createPathText() throws the same exception anyway, when it gets nullptr; there was already a comment asking for this change)
- get ItemExists() is much simplified and by using getPageItemOrNullByName() also checks inside the groups
- use getPageItemOrNullByName() instead of ad hoc loops
- removed setSelectedItemsByName() because it's unused
- move some doxygen doc from .cpp to .h

Sadly, git messed up the diff, and the changes in getPageItemByName(), the new getPageItemOrNullByName, and the minimized ItemExists() are mixed together...
once the diff applied, the result will be like this:

PageItem* getPageItemOrNullByName(const QString& name)
{
    if (name.isEmpty())
    {
        return nullptr;
    }

    ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
    for (int i = 0; i < currentDoc->Items->count(); ++i)
    {
        PageItem* pageItem = currentDoc->Items->at(i);
        if (name == pageItem->itemName())
            return pageItem;
        if (pageItem->isGroup())
        {
            for (const auto& groupItem: pageItem->asGroupFrame()->getAllChildren())
            {
                if (name == groupItem->itemName())
                    return groupItem;
            }
        }
    }

    return nullptr;
}

PageItem* getPageItemByName(const QString& name)
{
    if (name.length() == 0)
    {
        PyErr_SetString(PyExc_ValueError, QString("Cannot accept empty name for pageitem").toLocal8Bit().constData());
        return nullptr;
    }

    PageItem* pageItem = getPageItemOrNullByName(name);

    if (pageItem == nullptr)
    {
        PyErr_SetString(NoValidObjectError, QString("Object not found").toLocal8Bit().constData());
        return nullptr;
    }

    return pageItem;
}

bool ItemExists(const QString& name)
{
    return getPageItemOrNullByName(name) != nullptr;
}

Issue History

Date Modified Username Field Change
2025-01-31 16:05 tropion New Issue
2025-01-31 16:05 tropion File Added: scriptplugin.diff
2025-02-22 10:39 ale Project Infrastructure => Scribus
2025-02-22 11:19 ale Note Added: 0052099
2025-02-24 09:35 tropion Note Added: 0052110
2025-02-24 19:38 ale Note Added: 0052112
2025-02-24 21:28 ale Note Added: 0052114
2025-04-05 12:01 ale Relationship added related to 0017490
2025-04-05 22:16 ale Note Added: 0052408
2025-04-05 22:16 ale File Added: get-page-item-by-name-in-groups.diff
2025-04-05 22:22 ale Relationship added related to 0009054