55// Qt
66#include < QFile>
77#include < QStringListModel>
8+ #include < QMetaObject>
9+ #include < QMetaMethod>
10+ #include < QMetaProperty>
811
912#include < wobjectimpl.h>
1013W_OBJECT_IMPL (QJSCompleter)
1114
1215QJSCompleter::QJSCompleter(QObject *parent) : QCompleter(parent)
1316{
1417 // Setting up JavaScript types
15- QStringList list;
16-
1718 Q_INIT_RESOURCE (qcodeeditor_resources);
1819 QFile fl (" :/languages/js.xml" );
1920
@@ -33,12 +34,73 @@ QJSCompleter::QJSCompleter(QObject *parent) : QCompleter(parent)
3334 for (auto &&key : keys)
3435 {
3536 auto names = language.names (key);
36- list .append (names);
37+ m_baseCompletions .append (names);
3738 }
3839
39- setModel (new QStringListModel (list, this ));
40+ m_model = new QStringListModel (this );
41+ setModel (m_model);
42+ updateCompletions ();
43+
4044 setCompletionColumn (0 );
4145 setModelSorting (QCompleter::CaseInsensitivelySortedModel);
4246 setCaseSensitivity (Qt::CaseSensitive);
4347 setWrapAround (true );
4448}
49+
50+ void QJSCompleter::registerObject (const QString& name, QObject* object)
51+ {
52+ if (!object)
53+ return ;
54+
55+ // Get the meta-object for introspection
56+ const QMetaObject* metaObj = object->metaObject ();
57+
58+ // Extract all properties
59+ m_registeredCompletions.reserve (metaObj->propertyCount () + metaObj->methodCount ());
60+ for (int i = 0 ; i < metaObj->propertyCount (); ++i)
61+ {
62+ m_registeredCompletions.append (QStringLiteral (" %1.%2" ).arg (name, metaObj->property (i).name ()));
63+ }
64+
65+ // Extract all methods (slots, signals, and invokable methods)
66+ for (int i = 0 ; i < metaObj->methodCount (); ++i)
67+ {
68+ QMetaMethod method = metaObj->method (i);
69+ auto methodName = method.name ();
70+
71+ // Skip internal Qt methods
72+ if (methodName.startsWith (" _q_" ))
73+ continue ;
74+ if (methodName.startsWith (" destroyed" ) || methodName.startsWith (" deleteLater" ))
75+ continue ;
76+
77+ m_registeredCompletions.append (QStringLiteral (" %1.%2" ).arg (name, methodName));
78+ }
79+
80+ updateCompletions ();
81+ }
82+
83+ void QJSCompleter::unregisterObject (const QString& name)
84+ {
85+ // Remove all completions that start with "name."
86+ QString prefix = name + " ." ;
87+ m_registeredCompletions.erase (
88+ std::remove_if (m_registeredCompletions.begin (), m_registeredCompletions.end (),
89+ [&prefix](const QString& completion) {
90+ return completion.startsWith (prefix);
91+ }),
92+ m_registeredCompletions.end ()
93+ );
94+
95+ updateCompletions ();
96+ }
97+
98+ void QJSCompleter::updateCompletions ()
99+ {
100+ QStringList allCompletions = m_baseCompletions;
101+ allCompletions.append (m_registeredCompletions);
102+ allCompletions.removeDuplicates ();
103+
104+ if (m_model)
105+ m_model->setStringList (allCompletions);
106+ }
0 commit comments