All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.qt.uic.CustomWidgetsInfo Maven / Gradle / Ivy

The newest version!
/****************************************************************************
**
** Copyright (C) 2009-2024 Dr. Peter Droste, Omix Visualization GmbH & Co. KG. All rights reserved.
**
** This file is part of Qt Jambi.
**
** $BEGIN_LICENSE$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** 
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
** $END_LICENSE$

**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package io.qt.uic;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import io.qt.core.QMetaMethod;
import io.qt.core.QMetaMethod.MethodType;
import io.qt.core.QMetaObject;
import io.qt.core.QPair;
import io.qt.uic.java.WriteImports;
import io.qt.uic.ui4.DomCustomWidget;
import io.qt.uic.ui4.DomCustomWidgets;
import io.qt.uic.ui4.DomUI;

/**
 * @hidden
 */
public class CustomWidgetsInfo extends TreeWalker{
	
	public DomCustomWidget customWidget(String name)
    { return m_customWidgets.get(name); }
	
	@Override
	public void acceptUI(DomUI node)
	{
	    m_customWidgets.clear();

	    if (node.elementCustomWidgets()!=null)
	        acceptCustomWidgets(node.elementCustomWidgets());
	}

	@Override
	public void acceptCustomWidgets(DomCustomWidgets node)
	{
	    super.acceptCustomWidgets(node);
	}

	@Override
	public void acceptCustomWidget(DomCustomWidget node)
	{
	    if (node.elementClass().isEmpty())
	        return;

	    m_customWidgets.put(node.elementClass(), node);
	}

	public final boolean _extends(String classNameIn, String baseClassName)
	{
	    if (Objects.equals(classNameIn, baseClassName))
	        return true;

	    String className = classNameIn;
	    DomCustomWidget c = customWidget(className);
	    while (c!=null) {
	        String _extends = c.elementExtends();
	        if (Objects.equals(className, _extends)) // Faulty legacy custom widget entries exist.
	            return false;
	        if (Objects.equals(_extends, baseClassName))
	            return true;
	        className = _extends;
	        c = customWidget(className);
	    }
	    return false;
	}

	public final boolean extendsOneOf(String classNameIn, List baseClassNames)
	{
	    if (baseClassNames.contains(classNameIn))
	        return true;

	    String className = classNameIn;
	    DomCustomWidget c = customWidget(className);
	    while (c!=null) {
	        String _extends = c.elementExtends();
	        if (Objects.equals(className, _extends)) // Faulty legacy custom widget entries exist.
	            return false;
	        if (baseClassNames.contains(_extends))
	            return true;
	        className = _extends;
	        c = customWidget(className);
	    }
	    return false;
	}

	public final boolean isCustomWidgetContainer(String className)
	{
		DomCustomWidget dcw = m_customWidgets.getOrDefault(className, null);
	    if (dcw!=null)
	        if (dcw.hasElementContainer())
	            return dcw.elementContainer() != 0;
	    return false;
	}
	
	/**
	 * @hidden
	 */
	public static class MethodInfo{
		private MethodInfo(QMetaMethod metaMethod, Method method, boolean isAmbiguous) {
			this.metaMethod = metaMethod;
			this.method = method;
			this.isAmbiguous = isAmbiguous;
		}
		public final QMetaMethod metaMethod;
		public final Method method;
		public final boolean isAmbiguous;
	}

	public final MethodInfo methodInfo(String className, String signature, boolean isSignal)
	{
		String javaCassName;
		if(WriteImports.m_classToPackage.containsKey(className)) {
			javaCassName = WriteImports.m_classToPackage.get(className);
			if(javaCassName==null || javaCassName.isEmpty())
				javaCassName = className;
			else if(javaCassName.endsWith("*"))
				javaCassName = javaCassName.replace("*", className);
		}else {
			javaCassName = className;
			DomCustomWidget customWidget = customWidget(javaCassName);
			if(customWidget!=null) {
				if(javaCassName.contains("::"))
					javaCassName = javaCassName.replace("::", ".");
		    	else if(customWidget.hasElementHeader()) {
		    		if(!customWidget.elementHeader().text().toLowerCase().endsWith(".h"))
		    			javaCassName = customWidget.elementHeader().text().replace("::", ".");
		    	}
			}
		}
		try {
			Class javaClass = Class.forName(javaCassName);
			QMetaObject mo = QMetaObject.forType(javaClass);
			QMetaMethod matchingMetaMethod = null;
			Set reflectedMethods = new HashSet<>();
			List metaMethods = new ArrayList<>();
			int parenPos = signature.indexOf('(');
			String functionName = signature.substring(0, parenPos);
			for(QMetaMethod mtd : mo.methods()) {
				if(isSignal && mtd.methodType()!=MethodType.Signal)
					continue;
				if(mtd.name().toString().equals(functionName)) {
					metaMethods.add(mtd);
					try {
						reflectedMethods.add(mtd.toReflectedMethod());
					}catch(Throwable t) {}
					if(mtd.cppMethodSignature().toString().equals(signature)) {
						matchingMetaMethod = mtd;
					}
				}
			}
			List methods = new ArrayList<>();
			if(!isSignal) {
				for(Method method : javaClass.getMethods()) {
					if(!reflectedMethods.contains(method) && method.getName().equals(functionName)) {
						methods.add(method);
					}
				}
			}
			if(metaMethods.size() + methods.size()==1) {
				if(metaMethods.size()==1)
					return new MethodInfo(metaMethods.get(0), null, false);
				else
					return new MethodInfo(null, methods.get(0), false);
			}else
				return new MethodInfo(matchingMetaMethod, null, true);
		}catch(ClassNotFoundException t) {
			Logger.getLogger("qtjambi.uic").log(Level.WARNING, "Unable to load class "+javaCassName+". Please make sure to add it to UIC's classpath.", t);
		}catch(Throwable t) {}
	    return new MethodInfo(null, null, false);
	}
	
	public final String realClassName(String className)
	{
	    if ("Line".equals(className))
	        return "QFrame";
	    DomCustomWidget dcw = m_customWidgets.getOrDefault(className, null);
	    if (dcw!=null) {
	    	className = dcw.elementClass();
	    	String[] namespaces = className.split("::");
		    if (namespaces.length>0) {
		    	className = namespaces[namespaces.length-1];
		    }
	    }
	    return className;
	}

	public final String customWidgetAddPageMethod(String name)
	{
		DomCustomWidget dcw = m_customWidgets.getOrDefault(name, null);
	    if (dcw!=null)
	        return dcw.elementAddPageMethod();
	    return "";
	}

	@SuppressWarnings({ "unchecked" })
	private static QPair addPageMethods[] = new QPair[]{
	        new QPair<>("QStackedWidget", "addWidget"),
			new QPair<>("QToolBar", "addWidget"),
			new QPair<>("QDockWidget", "setWidget"),
			new QPair<>("QScrollArea", "setWidget"),
			new QPair<>("QSplitter", "addWidget"),
			new QPair<>("QMdiArea", "addSubWindow")
	    };
	// add page methods for simple containers taking only the widget parameter
	public final String simpleContainerAddPageMethod(String name)
	{
	    for (QPair m : addPageMethods) {
	        if (_extends(name, m.first))
	            return m.second;
	    }
	    return "";
	}

	private final Map m_customWidgets = new TreeMap<>();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy