bool RefactoringAssistant::acceptDrag(QDropEvent *event) const { //first check if we can accept drops at all, and if the operation // is a move within the list itself if( !acceptDrops() || !itemsMovable() || (event->source()!=viewport())) { return false; } RefactoringAssistant *me = const_cast<RefactoringAssistant*>(this); //ok, check if the move is valid QListViewItem *movingItem = 0, *afterme = 0, *parentItem = 0; me->findDrop(event->pos(), parentItem, afterme); for( movingItem = firstChild(); movingItem != 0; movingItem = movingItem->itemBelow() ) { if( movingItem->isSelected() ) break; } if(!movingItem || !parentItem) { kDebug()<<"moving/parent items not found - can't accept drag!"<<endl; return false; } UMLObject *movingObject; if( !(movingObject = me->findUMLObject(movingItem)) ) { kDebug()<<"Moving object not found in uml map!"<<movingItem->text(0)<<endl; return false; } Uml::Object_Type t = movingObject->getBaseType(); if (t != Uml::ot_Attribute && t != Uml::ot_Operation) { kDebug()<<"only operations and attributes are movable! - return false"<<endl; return false; } kDebug()<<"parent item is "<<parentItem->text(0)<<endl; UMLObject *parentObject = me->findUMLObject(parentItem); if( parentObject && dynamic_cast<UMLClassifier*>(parentObject) ) { //droping to a classifier, ok } else {//parent is not a classifier, so maybe it's a folder.. check types if( (parentItem->text(1) == "operations" && t == Uml::ot_Operation) || (parentItem->text(1) == "attributes" && t == Uml::ot_Attribute)) { parentObject = me->findUMLObject( parentItem->parent() ); } else { kDebug()<<"moving to item "<<parentItem->text(0)<<" -- "<<parentItem->text(1)<<" not valid"<<endl; return false; } } if (dynamic_cast<UMLClassifier*>(parentObject) && (t == Uml::ot_Attribute || t == Uml::ot_Operation)) { return true; } kDebug()<<"how did I get here? return false!!"<<endl; return false; }
/** * Need to overwrite this for d since we need to pick up the * d class declaration block. * Sigh. NOT optimal. The only reason that we need to have this * is so we can create the DClassDeclarationBlock. * would be better if we could create a handler interface that each * codeblock used so all we have to do here is add the handler * for "dclassdeclarationblock". */ void DClassifierCodeDocument::loadChildTextBlocksFromNode(QDomElement & root) { QDomNode tnode = root.firstChild(); QDomElement telement = tnode.toElement(); bool loadCheckForChildrenOK = false; while (!telement.isNull()) { QString nodeName = telement.tagName(); if (nodeName == QLatin1String("textblocks")) { QDomNode node = telement.firstChild(); QDomElement element = node.toElement(); // if there is nothing to begin with, then we don't worry about it loadCheckForChildrenOK = element.isNull() ? true : false; while (!element.isNull()) { QString name = element.tagName(); if (name == QLatin1String("codecomment")) { CodeComment * block = new DCodeComment(this); block->loadFromXMI(element); if (!addTextBlock(block)) { uError()<<"loadFromXMI : unable to add codeComment to :"<<this; delete block; } else { loadCheckForChildrenOK= true; } } else if (name == QLatin1String("codeaccessormethod") || name == QLatin1String("ccfdeclarationcodeblock")) { QString acctag = element.attribute(QLatin1String("tag")); // search for our method in the TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag); if (!tb || !addTextBlock(tb)) { uError()<<"loadFromXMI : unable to add codeclassfield child method to:"<<this; // DON'T delete } else { loadCheckForChildrenOK= true; } } else if (name == QLatin1String("codeblock")) { CodeBlock * block = newCodeBlock(); block->loadFromXMI(element); if (!addTextBlock(block)) { uError()<<"loadFromXMI : unable to add codeBlock to :"<<this; delete block; } else { loadCheckForChildrenOK= true; } } else if (name == QLatin1String("codeblockwithcomments")) { CodeBlockWithComments * block = newCodeBlockWithComments(); block->loadFromXMI(element); if (!addTextBlock(block)) { uError()<<"loadFromXMI : unable to add codeBlockwithcomments to:"<<this; delete block; } else { loadCheckForChildrenOK= true; } } else if (name == QLatin1String("header")) { // do nothing.. this is treated elsewhere } else if (name == QLatin1String("hierarchicalcodeblock")) { HierarchicalCodeBlock * block = newHierarchicalCodeBlock(); block->loadFromXMI(element); if (!addTextBlock(block)) { uError()<<"Unable to add hierarchicalcodeBlock to:"<<this; delete block; } else { loadCheckForChildrenOK= true; } } else if (name == QLatin1String("codeoperation")) { // find the code operation by id QString id = element.attribute(QLatin1String("parent_id"), QLatin1String("-1")); UMLObject * obj = UMLApp::app()->document()->findObjectById(Uml::ID::fromString(id)); UMLOperation * op = obj->asUMLOperation(); if (op) { CodeOperation * block = new DCodeOperation(this, op); block->loadFromXMI(element); if (addTextBlock(block)) { loadCheckForChildrenOK= true; } else { uError()<<"Unable to add codeoperation to:"<<this; block->deleteLater(); } } else { uError()<<"Unable to find operation create codeoperation for:"<<this; } } else if (name == QLatin1String("dclassdeclarationblock")) { DClassDeclarationBlock * block = getClassDecl(); block->loadFromXMI(element); if (!addTextBlock(block)) { uError()<<"Unable to add d code declaration block to:"<<this; // DON'T delete. // block->deleteLater(); } else { loadCheckForChildrenOK= true; } } else { uDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"; } node = element.nextSibling(); element = node.toElement(); } break; } tnode = telement.nextSibling(); telement = tnode.toElement(); } if (!loadCheckForChildrenOK) { uWarning() << "loadChildBlocks : unable to initialize any child blocks in doc: " << getFileName() << " " << this; } }
/** * Implement abstract operation from NativeImportBase. * @return success status of operation */ bool CSharpImport::parseStmt() { const int srcLength = m_source.count(); const QString& keyword = m_source[m_srcIndex]; //uDebug() << '"' << keyword << '"'; if (keyword == "using") { return parseStmtUsing(); } if (keyword == "namespace") { return parseStmtNamespace(); } // if (keyword == "package") { // m_currentPackage = advance(); // const QString& qualifiedName = m_currentPackage; // const QStringList names = qualifiedName.split('.'); // for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it) { // QString name = (*it); // log(keyword + ' ' + name); // UMLObject *ns = Import_Utils::createUMLObject(UMLObject::ot_Package, // name, m_scope[m_scopeIndex], m_comment); // m_scope[++m_scopeIndex] = static_cast<UMLPackage*>(ns); // } // if (advance() != ";") { // uError() << "unexpected: " << m_source[m_srcIndex]; // skipStmt(); // } // return true; // } if (keyword == "class" || keyword == "interface") { return parseStmtClass(keyword); } if (keyword == "enum") { return parseStmtEnum(); } if (keyword == "static") { m_isStatic = true; return true; } // if we detected static previously and keyword is { then this is a static block if (m_isStatic && keyword == "{") { // reset static flag and jump to end of static block m_isStatic = false; return skipToClosing('{'); } if (keyword == "abstract") { m_isAbstract = true; return true; } if (keyword == "public") { m_currentAccess = Uml::Visibility::Public; return true; } if (keyword == "protected") { m_currentAccess = Uml::Visibility::Protected; return true; } if (keyword == "private") { m_currentAccess = Uml::Visibility::Private; return true; } if ((keyword == "override") || (keyword == "virtual") || (keyword == "sealed")) { //:TODO: anything to do here? return true; } if (keyword == "#") { // preprocessor directives QString ppdKeyword = advance(); uDebug() << "found preprocessor directive " << ppdKeyword; //:TODO: anything to do here? return true; } // if (keyword == "@") { // annotation // advance(); // if (m_source[m_srcIndex + 1] == "(") { // advance(); // skipToClosing('('); // } // return true; // } if (keyword == "[") { // ... advance(); skipToClosing('['); return true; } if (keyword == "}") { if (m_scopeIndex) m_klass = dynamic_cast<UMLClassifier*>(m_scope[--m_scopeIndex]); else uError() << "too many }"; return true; } // At this point, we expect `keyword' to be a type name // (of a member of class or interface, or return type // of an operation.) Up next is the name of the attribute // or operation. if (! keyword.contains(QRegExp("^\\w"))) { uError() << "ignoring " << keyword << " at " << m_srcIndex << ", " << m_source.count() << " in " << m_klass; //:TODO: ->name(); return false; } QString typeName = m_source[m_srcIndex]; typeName = joinTypename(typeName); // At this point we need a class. if (m_klass == NULL) { uError() << "no class set for " << typeName; return false; } QString name = advance(); QString nextToken; if (typeName == m_klass->name() && name == "(") { // Constructor. nextToken = name; name = typeName; typeName.clear(); } else { nextToken = advance(); } if (name.contains(QRegExp("\\W"))) { uError() << "expecting name in " << name; return false; } if (nextToken == "(") { // operation UMLOperation *op = Import_Utils::makeOperation(m_klass, name); m_srcIndex++; while (m_srcIndex < srcLength && m_source[m_srcIndex] != ")") { QString typeName = m_source[m_srcIndex]; if (typeName == "final" || typeName.startsWith("//")) { // ignore the "final" keyword and any comments in method args typeName = advance(); } typeName = joinTypename(typeName); QString parName = advance(); // the Class might not be resolved yet so resolve it if necessary UMLObject *obj = resolveClass(typeName); if (obj) { // by prepending the package, unwanted placeholder types will not get created typeName = obj->fullyQualifiedName("."); } /* UMLAttribute *att = */ Import_Utils::addMethodParameter(op, typeName, parName); if (advance() != ",") break; m_srcIndex++; } // before adding the method, try resolving the return type UMLObject *obj = resolveClass(typeName); if (obj) { // using the fully qualified name means that a placeholder type will not be created. typeName = obj->fullyQualifiedName("."); } Import_Utils::insertMethod(m_klass, op, m_currentAccess, typeName, m_isStatic, m_isAbstract, false /*isFriend*/, false /*isConstructor*/, m_comment); m_isAbstract = m_isStatic = false; // reset the default visibility m_currentAccess = m_defaultCurrentAccess; // At this point we do not know whether the method has a body or not. do { nextToken = advance(); } while (nextToken != "{" && nextToken != ";"); if (nextToken == ";") { // No body (interface or abstract) return true; } else { return skipToClosing('{'); } } // At this point we know it's some kind of attribute declaration. while(1) { while (nextToken != "," && nextToken != ";") { if (nextToken == "=") { if ((nextToken = advance()) == "new") { advance(); if ((nextToken = advance()) == "(") { skipToClosing('('); if ((nextToken = advance()) == "{") { skipToClosing('{'); } else { skipStmt(); break; } } else { skipStmt(); break; } } else { skipStmt(); break; } } else { name += nextToken; // add possible array dimensions to `name' } nextToken = advance(); if (nextToken.isEmpty()) { break; } } // try to resolve the class type, or create a placeholder if that fails UMLObject *type = resolveClass(typeName); UMLObject *o; if (type) { o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name, static_cast<UMLClassifier*>(type), m_comment, m_isStatic); } else { o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name, typeName, m_comment, m_isStatic); } // UMLAttribute *attr = static_cast<UMLAttribute*>(o); if (nextToken != ",") { // reset the modifiers m_isStatic = m_isAbstract = false; break; } name = advance(); nextToken = advance(); } // reset visibility to default m_currentAccess = m_defaultCurrentAccess; if (m_srcIndex < m_source.count()) { if (m_source[m_srcIndex] != ";") { uError() << "ignoring trailing items at " << name; skipStmt(); } } else { uError() << "index out of range: ignoring statement " << name; skipStmt(); } return true; }
/** * Implement abstract operation from NativeImportBase. * @return success status of operation */ bool PythonImport::parseStmt() { const int srcLength = m_source.count(); QString keyword = m_source[m_srcIndex]; if (keyword == QLatin1String("class")) { const QString& name = advance(); UMLObject *ns = Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(), m_comment); pushScope(m_klass = ns->asUMLClassifier()); m_comment.clear(); if (advance() == QLatin1String("(")) { while (m_srcIndex < srcLength - 1 && advance() != QLatin1String(")")) { const QString& baseName = m_source[m_srcIndex]; Import_Utils::createGeneralization(m_klass, baseName); if (advance() != QLatin1String(",")) break; } } if (m_source[m_srcIndex] != QLatin1String("{")) { skipStmt(QLatin1String("{")); } log(QLatin1String("class ") + name); return true; } if (keyword == QLatin1String("@")) { const QString& annotation = m_source[++m_srcIndex]; uDebug() << "annotation:" << annotation; if (annotation == QLatin1String("staticmethod")) m_isStatic = true; return true; } if (keyword == QLatin1String("def")) { if (m_klass == 0) { // skip functions outside of a class skipBody(); return true; } if (!m_klass->hasDoc() && !m_comment.isEmpty()) { m_klass->setDoc(m_comment); m_comment = QString(); } const QString& name = advance(); // operation UMLOperation *op = Import_Utils::makeOperation(m_klass, name); if (advance() != QLatin1String("(")) { uError() << "importPython def " << name << ": expecting \"(\""; skipBody(); return true; } bool firstParam = true; while (m_srcIndex < srcLength && advance() != QLatin1String(")")) { const QString& parName = m_source[m_srcIndex]; if (firstParam) { if (parName.compare(QLatin1String("self"), Qt::CaseInsensitive) != 0) { m_isStatic = true; Import_Utils::addMethodParameter(op, QLatin1String("string"), parName); } firstParam = false; } else { /*UMLAttribute *att =*/ Import_Utils::addMethodParameter(op, QLatin1String("string"), parName); } if (advance() != QLatin1String(",")) break; } Import_Utils::insertMethod(m_klass, op, Uml::Visibility::Public, QLatin1String("string"), m_isStatic, false /*isAbstract*/, false /*isFriend*/, false /*isConstructor*/, m_comment); m_isStatic = false; int srcIndex = m_srcIndex; op->setSourceCode(skipBody()); if (!op->hasDoc() && !m_comment.isEmpty()) { op->setDoc(m_comment); m_comment = QString(); } // parse instance variables from __init__ method if (name == QLatin1String("__init__")) { int indexSave = m_srcIndex; m_srcIndex = srcIndex; advance(); keyword = advance(); while (m_srcIndex < indexSave) { if (lookAhead() == QLatin1String("=")) { parseAssignmentStmt(keyword); // skip ; inserted by lexer if (lookAhead() == QLatin1String(";")) { advance(); keyword = advance(); } } else { skipStmt(QLatin1String(";")); keyword = advance(); } } m_srcIndex = indexSave; } log(QLatin1String("def ") + name); return true; } // parse class variables if (m_klass && lookAhead() == QLatin1String("=")) { bool result = parseAssignmentStmt(keyword); log(QLatin1String("class attribute ") + keyword); return result; } if (keyword == QLatin1String("}")) { if (scopeIndex()) { m_klass = popScope()->asUMLClassifier(); } else uError() << "parsing: too many }"; return true; } return false; // @todo parsing of attributes }