diff options
26 files changed, 593 insertions, 469 deletions
diff --git a/connectivity/inc/connectivity/dbexception.hxx b/connectivity/inc/connectivity/dbexception.hxx index 5c9f575da7c7..dbfcf5eb5747 100644 --- a/connectivity/inc/connectivity/dbexception.hxx +++ b/connectivity/inc/connectivity/dbexception.hxx @@ -150,6 +150,12 @@ public: const ::com::sun::star::uno::Any& get() const { return m_aContent; } + void clear() + { + m_aContent.clear(); + m_eType = UNDEFINED; + } + protected: void implDetermineType(); }; diff --git a/connectivity/inc/connectivity/sqlparse.hxx b/connectivity/inc/connectivity/sqlparse.hxx index 6ca31d695bd9..fb775abb480d 100644 --- a/connectivity/inc/connectivity/sqlparse.hxx +++ b/connectivity/inc/connectivity/sqlparse.hxx @@ -232,7 +232,8 @@ namespace connectivity // compares the _sFunctionName with all known function names and return the DataType of the return value static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL); - + // returns the type for a parameter in a given function name + static sal_Int32 getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos); void error(sal_Char *fmt); int SQLlex(); diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx index a6ee377e586e..d4a83249098a 100644 --- a/connectivity/source/drivers/dbase/DTable.cxx +++ b/connectivity/source/drivers/dbase/DTable.cxx @@ -368,11 +368,12 @@ void ODbaseTable::fillColumns() cType[0] = aDBFColumn.db_typ; cType[1] = 0; aTypeName = ::rtl::OUString::createFromAscii(cType); +OSL_TRACE("column type: %c",aDBFColumn.db_typ); switch (aDBFColumn.db_typ) { case 'C': - eType = DataType::CHAR; + eType = DataType::VARCHAR; aTypeName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VARCHAR")); break; case 'F': diff --git a/connectivity/source/drivers/file/FStatement.cxx b/connectivity/source/drivers/file/FStatement.cxx index 2692f02d7614..72ad91dbfa73 100644 --- a/connectivity/source/drivers/file/FStatement.cxx +++ b/connectivity/source/drivers/file/FStatement.cxx @@ -639,7 +639,7 @@ void OStatement_Base::GetAssignValues() aColumnNameList.push_back(pCol->getTokenValue()); } } - if(!aColumnNameList.size()) + if ( aColumnNameList.empty() ) throwFunctionSequenceException(*this); // Werte ... @@ -652,10 +652,10 @@ void OStatement_Base::GetAssignValues() if (! SQL_ISTOKEN(pValuesOrQuerySpec->getChild(0),VALUES)) throwFunctionSequenceException(*this); - OSL_ENSURE(pValuesOrQuerySpec->count() == 2,"OResultSet: pValuesOrQuerySpec->count() != 2"); + OSL_ENSURE(pValuesOrQuerySpec->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4"); // Liste von Werten - OSQLParseNode * pInsertAtomCommalist = pValuesOrQuerySpec->getChild(1); + OSQLParseNode * pInsertAtomCommalist = pValuesOrQuerySpec->getChild(2); OSL_ENSURE(pInsertAtomCommalist != NULL,"OResultSet: pInsertAtomCommalist darf nicht NULL sein!"); OSL_ENSURE(pInsertAtomCommalist->count() > 0,"OResultSet: pInsertAtomCommalist <= 0"); @@ -665,40 +665,22 @@ void OStatement_Base::GetAssignValues() for (sal_uInt32 i = 0; i < pInsertAtomCommalist->count(); i++) { pRow_Value_Const = pInsertAtomCommalist->getChild(i); // row_value_constructor - if(pRow_Value_Const->count() == 3) // '(' row_value_const_list ')' + OSL_ENSURE(pRow_Value_Const != NULL,"OResultSet: pRow_Value_Const darf nicht NULL sein!"); + if(SQL_ISRULE(pRow_Value_Const,parameter)) { - pRow_Value_Const = pRow_Value_Const->getChild(1); // row_value_const_list - OSL_ENSURE(pRow_Value_Const != NULL,"OResultSet: pRow_Value_Const darf nicht NULL sein!"); - if(SQL_ISRULE(pRow_Value_Const,parameter)) - { - if(pRow_Value_Const->count() == aColumnNameList.size()) - ParseAssignValues(aColumnNameList,pRow_Value_Const,nIndex++); // kann nur ein Columnname vorhanden sein pro Schleife - else - { -// aStatus.Set(SQL_STAT_ERROR, -// String::CreateFromAscii("S1000"), -// aStatus.CreateErrorMessage(String(SdbResId(STR_STAT_SYNTAX_ERROR))), -// 0, String() ); - throwFunctionSequenceException(*this); - } - } - else if(pRow_Value_Const->isToken()) - ParseAssignValues(aColumnNameList,pRow_Value_Const,static_cast<xub_StrLen>(i)); - else - { - if(pRow_Value_Const->count() == aColumnNameList.size()) - { - for (sal_uInt32 j = 0; j < pRow_Value_Const->count(); ++j) - ParseAssignValues(aColumnNameList,pRow_Value_Const->getChild(j),nIndex++); - } - else - throwFunctionSequenceException(*this); - } + ParseAssignValues(aColumnNameList,pRow_Value_Const,nIndex++); // kann nur ein Columnname vorhanden sein pro Schleife } + else if(pRow_Value_Const->isToken()) + ParseAssignValues(aColumnNameList,pRow_Value_Const,static_cast<xub_StrLen>(i)); else { - // aStatus.SetStatementTooComplex(); - throwFunctionSequenceException(*this); + if(pRow_Value_Const->count() == aColumnNameList.size()) + { + for (sal_uInt32 j = 0; j < pRow_Value_Const->count(); ++j) + ParseAssignValues(aColumnNameList,pRow_Value_Const->getChild(j),nIndex++); + } + else + throwFunctionSequenceException(*this); } } } diff --git a/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx b/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx index 11863be3b8bf..b0341a3fd564 100644 --- a/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx +++ b/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx @@ -616,7 +616,8 @@ Reference< XResultSet > java_sql_DatabaseMetaData::impl_callResultSetMethodWithS const ::rtl::OUString* _pOptionalAdditionalString ) { bool bCatalog = _rCatalog.hasValue(); - ::rtl::OUString sCatalog( ::comphelper::getString( _rCatalog ) ); + ::rtl::OUString sCatalog; + _rCatalog >>= sCatalog; bool bSchema = _rSchemaPattern.toChar() != '%'; diff --git a/connectivity/source/drivers/jdbc/ResultSet.cxx b/connectivity/source/drivers/jdbc/ResultSet.cxx index e78488ffbba3..4728586ad4d0 100644 --- a/connectivity/source/drivers/jdbc/ResultSet.cxx +++ b/connectivity/source/drivers/jdbc/ResultSet.cxx @@ -261,7 +261,7 @@ sal_Int64 SAL_CALL java_sql_ResultSet::getLong( sal_Int32 columnIndex ) throw(SQ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_ResultSet::getLong" ); static jmethodID mID(NULL); jlong (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallLongMethod; - return callMethodWithIntArg<jlong>(pCallMethod,"getLong","(I)L",mID,columnIndex); + return callMethodWithIntArg<jlong>(pCallMethod,"getLong","(I)J",mID,columnIndex); } // ------------------------------------------------------------------------- diff --git a/connectivity/source/parse/sqlbison.y b/connectivity/source/parse/sqlbison.y index a42c3cb2302c..b25f7c8fb2a4 100644 --- a/connectivity/source/parse/sqlbison.y +++ b/connectivity/source/parse/sqlbison.y @@ -107,7 +107,7 @@ static connectivity::OSQLInternalNode* newNode(const sal_Char* pNewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - + OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(pNewValue, eNodeType, nNodeID); } @@ -115,7 +115,7 @@ static connectivity::OSQLInternalNode* newNode(const ::rtl::OString& _NewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - + OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID); } @@ -123,7 +123,7 @@ static connectivity::OSQLInternalNode* newNode(const ::rtl::OUString& _NewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - + OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID); } @@ -676,15 +676,12 @@ manipulative_statement_list: ; ***/ -/*sql: - {$$ = SQL_NEW_LISTRULE;} - ; -*/ sql_not: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_NOT ; - /* manipulative statements */ + +/* manipulative statements */ sql: manipulative_statement ; @@ -767,10 +764,12 @@ insert_statement: $$->append($5);} ; values_or_query_spec: - SQL_TOKEN_VALUES table_value_const_list + SQL_TOKEN_VALUES '(' table_value_const_list ')' {$$ = SQL_NEW_RULE; $$->append($1); - $$->append($2); + $$->append($2 = newNode("(", SQL_NODE_PUNCTUATION)); + $$->append($3); + $$->append($4 = newNode(")", SQL_NODE_PUNCTUATION)); } ; @@ -792,18 +791,14 @@ row_value_const_list: ; row_value_constructor: row_value_constructor_elem - | '(' row_value_const_list ')' +/* | '(' row_value_const_list ')' { $$ = SQL_NEW_RULE; $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION)); $$->append($2); $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION)); } -/* | subquery - { - $$ = SQL_NEW_RULE; - $$->append($1); - }*/ + */ ; row_value_constructor_elem: value_exp /*[^')']*/ @@ -1053,47 +1048,16 @@ truth_value: ; boolean_primary: predicate - | '(' search_condition ')' - { + | '(' search_condition ')' + { // boolean_primary: rule 2 $$ = SQL_NEW_RULE; $$->append($1 = newNode("(", SQL_NODE_PUNCTUATION)); $$->append($2); $$->append($3 = newNode(")", SQL_NODE_PUNCTUATION)); } - ; - -boolean_test: - boolean_primary - | boolean_primary SQL_TOKEN_IS sql_not truth_value - { - $$ = SQL_NEW_RULE; - $$->append($1); - $$->append($2); - $$->append($3); - $$->append($4); - } - ; -boolean_factor: - boolean_test - | SQL_TOKEN_NOT boolean_test - { - $$ = SQL_NEW_RULE; - $$->append($1); - $$->append($2); - } - ; -boolean_term: - boolean_factor - | boolean_term SQL_TOKEN_AND boolean_factor - { - $$ = SQL_NEW_RULE; - $$->append($1); - $$->append($2); - $$->append($3); - } | row_value_constructor_elem /*[^')' ',']*/ { - if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck())// boolean_primary: rule 3 { $$ = SQL_NEW_RULE; sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$1); @@ -1115,54 +1079,43 @@ boolean_term: else YYERROR; } - | boolean_term SQL_TOKEN_AND literal - { - if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) - { - $$ = SQL_NEW_RULE; - $$->append($1); - $$->append($2); - sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$3); - if(nErg < 1) - { - delete $$; - if(nErg) - YYERROR; - else - YYABORT; - } - } - else - YYERROR; + ; +boolean_test: + boolean_primary + | boolean_primary SQL_TOKEN_IS sql_not truth_value + { + $$ = SQL_NEW_RULE; + $$->append($1); + $$->append($2); + $$->append($3); + $$->append($4); } - | boolean_term SQL_TOKEN_AND SQL_TOKEN_STRING + ; +boolean_factor: + boolean_test + | SQL_TOKEN_NOT boolean_test + { // boolean_factor: rule 1 + $$ = SQL_NEW_RULE; + $$->append($1); + $$->append($2); + } + ; +boolean_term: + boolean_factor + | boolean_term SQL_TOKEN_AND boolean_factor { - if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) - { - $$ = SQL_NEW_RULE; - $$->append($1); - $$->append($2); - sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$3); - if(nErg < 1) - { - delete $$; - if(nErg) - YYERROR; - else - YYABORT; - } - } - else - YYERROR; - + $$ = SQL_NEW_RULE; // boolean_term: rule 1 + $$->append($1); + $$->append($2); + $$->append($3); } ; search_condition: boolean_term | search_condition SQL_TOKEN_OR boolean_term { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // search_condition $$->append($1); $$->append($2); $$->append($3); @@ -1182,14 +1135,14 @@ predicate: comparison_predicate: row_value_constructor comparison row_value_constructor { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // comparison_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); } | comparison row_value_constructor { - if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // comparison_predicate: rule 2 { $$ = SQL_NEW_RULE; sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildPredicateRule($$,$2,$1); @@ -1221,7 +1174,7 @@ comparison: ; between_predicate: row_value_constructor sql_not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor - {$$ = SQL_NEW_RULE; + {$$ = SQL_NEW_RULE; // between_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); @@ -1231,7 +1184,7 @@ between_predicate: } | sql_not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor { - if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // between_predicate: rule 2 { $$ = SQL_NEW_RULE; @@ -1258,7 +1211,7 @@ between_predicate: like_predicate: row_value_constructor SQL_TOKEN_NOT SQL_TOKEN_LIKE string_value_exp opt_escape { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // like_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); @@ -1267,7 +1220,7 @@ like_predicate: } | row_value_constructor SQL_TOKEN_LIKE string_value_exp opt_escape { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // like_predicate: rule 2 $$->append($1); $$->append($2); $$->append($3); @@ -1275,7 +1228,7 @@ like_predicate: } | row_value_constructor SQL_TOKEN_NOT SQL_TOKEN_LIKE value_exp_primary opt_escape { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // like_predicate: rule 3 $$->append($1); $$->append($2); $$->append($3); @@ -1284,7 +1237,7 @@ like_predicate: } | row_value_constructor SQL_TOKEN_LIKE value_exp_primary opt_escape { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // like_predicate: rule 4 $$->append($1); $$->append($2); $$->append($3); @@ -1292,7 +1245,7 @@ like_predicate: } | sql_not SQL_TOKEN_LIKE string_value_exp opt_escape { - if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // like_predicate: rule 5 { OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME)); @@ -1314,7 +1267,7 @@ like_predicate: } | sql_not SQL_TOKEN_LIKE value_exp_primary opt_escape { - if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // like_predicate: rule 6 { OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME)); @@ -1355,7 +1308,7 @@ opt_escape: test_for_null: row_value_constructor SQL_TOKEN_IS sql_not truth_value { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE; // test_for_null: rule 1 $$->append($1); $$->append($2); $$->append($3); @@ -1363,7 +1316,7 @@ test_for_null: } | SQL_TOKEN_IS sql_not truth_value { - if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())// test_for_null: rule 2 { OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME)); @@ -1393,15 +1346,15 @@ in_predicate_value: in_predicate: row_value_constructor sql_not SQL_TOKEN_IN in_predicate_value { - $$ = SQL_NEW_RULE; + $$ = SQL_NEW_RULE;// in_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); $$->append($4); } - | sql_not SQL_TOKEN_IN in_predicate_value + | sql_not SQL_TOKEN_IN in_predicate_value { - if ( xxx_pGLOBAL_SQLPARSER->inPredicateCheck() ) + if ( xxx_pGLOBAL_SQLPARSER->inPredicateCheck() )// in_predicate: rule 2 { OSQLParseNode* pColumnRef = newNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQL_NODE_NAME)); @@ -3132,7 +3085,7 @@ user: SQL_TOKEN_NAME sql: search_condition /* checking predicats */ { - if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) + if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // sql: rule 1 { $$ = $1; if ( SQL_ISRULE($$,search_condition) ) @@ -3143,7 +3096,9 @@ sql: } else YYERROR; - }; + } + | '(' sql ')' /* checking predicats */ + ; %% diff --git a/connectivity/source/parse/sqliterator.cxx b/connectivity/source/parse/sqliterator.cxx index 56f63de5ce14..42778d6a7ed0 100644 --- a/connectivity/source/parse/sqliterator.cxx +++ b/connectivity/source/parse/sqliterator.cxx @@ -1493,6 +1493,20 @@ void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode } if ( bNotFound ) { + sal_Int32 nType = DataType::VARCHAR; + OSQLParseNode* pParent = _pColumnRef ? _pColumnRef->getParent() : NULL; + if ( pParent && (SQL_ISRULE(pParent,general_set_fct) || SQL_ISRULE(pParent,set_fct_spec)) ) + { + const sal_uInt32 nCount = _pColumnRef->count(); + sal_uInt32 i = 0; + for(; i < nCount;++i) + { + if ( _pColumnRef->getChild(i) == _pParseNode ) + break; + } + nType = ::connectivity::OSQLParser::getFunctionParameterType( pParent->getChild(0)->getTokenID(), i+1); + } + ::rtl::OUString aNewColName( getUniqueColumnName( sParameterName ) ); OParseColumn* pColumn = new OParseColumn(aNewColName, @@ -1501,7 +1515,7 @@ void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode ColumnValue::NULLABLE_UNKNOWN, 0, 0, - DataType::VARCHAR, + nType, sal_False, sal_False, isCaseSensitive() ); diff --git a/connectivity/source/parse/sqlnode.cxx b/connectivity/source/parse/sqlnode.cxx index 76c6c69d269c..e134d7a757c4 100644 --- a/connectivity/source/parse/sqlnode.cxx +++ b/connectivity/source/parse/sqlnode.cxx @@ -2616,6 +2616,113 @@ sal_Int32 OSQLParser::getFunctionReturnType(const ::rtl::OUString& _sFunctionNam return nType; } +// ----------------------------------------------------------------------------- +sal_Int32 OSQLParser::getFunctionParameterType(sal_uInt32 _nTokenId, sal_uInt32 _nPos) +{ + sal_Int32 nType = DataType::VARCHAR; + + if(_nTokenId == SQL_TOKEN_CHAR) nType = DataType::INTEGER; + else if(_nTokenId == SQL_TOKEN_INSERT) + { + if ( _nPos == 2 || _nPos == 3 ) + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_LEFT) + { + if ( _nPos == 2 ) + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_LOCATE) + { + if ( _nPos == 3 ) + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_LOCATE_2) + { + if ( _nPos == 3 ) + nType = DataType::INTEGER; + } + else if( _nTokenId == SQL_TOKEN_REPEAT || _nTokenId == SQL_TOKEN_RIGHT ) + { + if ( _nPos == 2 ) + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_SPACE ) + { + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_SUBSTRING) + { + if ( _nPos != 1 ) + nType = DataType::INTEGER; + } + else if(_nTokenId == SQL_TOKEN_DATEDIFF) + { + if ( _nPos != 1 ) + nType = DataType::TIMESTAMP; + } + else if(_nTokenId == SQL_TOKEN_DATEVALUE) + nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_DAYNAME) + nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_DAYOFMONTH) + nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_DAYOFWEEK) + nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_DAYOFYEAR) + nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_EXTRACT) nType = DataType::VARCHAR; + else if(_nTokenId == SQL_TOKEN_HOUR) nType = DataType::TIME; + else if(_nTokenId == SQL_TOKEN_MINUTE) nType = DataType::TIME; + else if(_nTokenId == SQL_TOKEN_MONTH) nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_MONTHNAME) nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_NOW) nType = DataType::TIMESTAMP; + else if(_nTokenId == SQL_TOKEN_QUARTER) nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_SECOND) nType = DataType::TIME; + else if(_nTokenId == SQL_TOKEN_TIMESTAMPADD) nType = DataType::TIMESTAMP; + else if(_nTokenId == SQL_TOKEN_TIMESTAMPDIFF) nType = DataType::TIMESTAMP; + else if(_nTokenId == SQL_TOKEN_TIMEVALUE) nType = DataType::TIMESTAMP; + else if(_nTokenId == SQL_TOKEN_WEEK) nType = DataType::DATE; + else if(_nTokenId == SQL_TOKEN_YEAR) nType = DataType::DATE; + + else if(_nTokenId == SQL_TOKEN_ABS) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ACOS) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ASIN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ATAN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ATAN2) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_CEILING) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_COS) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_COT) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_DEGREES) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_EXP) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_FLOOR) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_LOGF) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_LOG) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_LOG10) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_LN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_MOD) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_PI) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_POWER) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_RADIANS) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_RAND) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ROUND) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_ROUNDMAGIC) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_SIGN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_SIN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_SQRT) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_TAN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_TRUNCATE) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_COUNT) nType = DataType::INTEGER; + else if(_nTokenId == SQL_TOKEN_MAX) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_MIN) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_AVG) nType = DataType::DOUBLE; + else if(_nTokenId == SQL_TOKEN_SUM) nType = DataType::DOUBLE; + + else if(_nTokenId == SQL_TOKEN_LOWER) nType = DataType::VARCHAR; + else if(_nTokenId == SQL_TOKEN_UPPER) nType = DataType::VARCHAR; + + return nType; +} // ----------------------------------------------------------------------------- const SQLError& OSQLParser::getErrorHelper() const diff --git a/connectivity/source/resource/conn_shared_res.src b/connectivity/source/resource/conn_shared_res.src index c9e54b740252..92b3e5814f4e 100644 --- a/connectivity/source/resource/conn_shared_res.src +++ b/connectivity/source/resource/conn_shared_res.src @@ -292,23 +292,23 @@ String STR_OPERATOR_TOO_COMPLEX }; String STR_QUERY_INVALID_LIKE_COLUMN { - Text [ en-US ] = "The query can not be executed. The 'LIKE' can only be used with a column name."; + Text [ en-US ] = "The query can not be executed. You cannot use 'LIKE' with columns of this type."; }; String STR_QUERY_INVALID_LIKE_STRING { - Text [ en-US ] = "The query can not be executed. The 'LIKE' can only be used with a string argument."; + Text [ en-US ] = "The query can not be executed. 'LIKE' can be used with a string argument only."; }; String STR_QUERY_NOT_LIKE_TOO_COMPLEX { - Text [ en-US ] = "The query can not be executed. The 'NOT LIKE' is too complex."; + Text [ en-US ] = "The query can not be executed. The 'NOT LIKE' condition is too complex."; }; String STR_QUERY_LIKE_WILDCARD { - Text [ en-US ] = "The query can not be executed. The 'LIKE' statement contains wildcard in the middle."; + Text [ en-US ] = "The query can not be executed. The 'LIKE' condition contains wildcard in the middle."; }; String STR_QUERY_LIKE_WILDCARD_MANY { - Text [ en-US ] = "The query can not be executed. The 'LIKE' statement contains too many wildcards."; + Text [ en-US ] = "The query can not be executed. The 'LIKE' condition contains too many wildcards."; }; String STR_INVALID_COLUMNNAME { diff --git a/svx/inc/svx/msocximex.hxx b/svx/inc/svx/msocximex.hxx index 679845827867..a32179a43eb4 100644 --- a/svx/inc/svx/msocximex.hxx +++ b/svx/inc/svx/msocximex.hxx @@ -230,7 +230,7 @@ class SVX_DLLPUBLIC OCX_Control { public: OCX_Control(UniString sN, OCX_Control* parent = NULL ) : nWidth( 0 ), nHeight( 0 ), mnLeft(0), mnTop(0), - mnStep(0), mnBackColor(0x8000000FL), mnForeColor(0), mnTabPos(0), sName(sN), pDocSh(0), + mnStep(0), mnBackColor(0x8000000FL), mnForeColor(0), mnTabPos(0), mbVisible(true), sName(sN), pDocSh(0), bSetInDialog(FALSE), mpParent( parent ) {} sal_Bool FullRead(SotStorageStream *pS) { @@ -287,6 +287,7 @@ public: sal_Int32 mnBackColor; sal_Int32 mnForeColor; sal_uInt16 mnTabPos; + bool mbVisible; UniString sName; UniString msToolTip; OCX_FontData aFontData; @@ -483,7 +484,7 @@ public: }; struct ContainerRecord { - ContainerRecord():nTop(0), nLeft(0), nSubStorageId(0), nSubStreamLen(0), nTabPos(0), nTypeIdent(0) {} + ContainerRecord():nTop(0), nLeft(0), nSubStorageId(0), nSubStreamLen(0), nTabPos(0), nTypeIdent(0), bVisible( true ) {} ::rtl::OUString cName; ::rtl::OUString controlTip; @@ -494,6 +495,7 @@ struct ContainerRecord sal_uInt32 nSubStreamLen; sal_uInt16 nTabPos; sal_uInt16 nTypeIdent; + bool bVisible; }; typedef std::vector<OCX_Control*>::iterator CtrlIterator; diff --git a/svx/inc/svx/sdr/contact/viewobjectcontactofunocontrol.hxx b/svx/inc/svx/sdr/contact/viewobjectcontactofunocontrol.hxx index 7a40c25511e4..10e194973f48 100644 --- a/svx/inc/svx/sdr/contact/viewobjectcontactofunocontrol.hxx +++ b/svx/inc/svx/sdr/contact/viewobjectcontactofunocontrol.hxx @@ -89,18 +89,6 @@ namespace sdr { namespace contact { */ void setControlDesignMode( bool _bDesignMode ) const; - /** determines whether the instance belongs to a given OutputDevice - @precond - The instance knows the device it belongs to, or can determine it. - If this is not the case, you will notice an assertion, and the method will - return false. - */ - bool belongsToDevice( const OutputDevice* _pDevice ) const; - - /** positions the control for subsequent paint operations - */ - void positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const; - /** callback from impl class to react on changes of properties form the XControlModel */ void propertyChange(); diff --git a/svx/inc/svx/sdr/primitive2d/svx_primitivetypes2d.hxx b/svx/inc/svx/sdr/primitive2d/svx_primitivetypes2d.hxx index b788cfa69d7b..bf3ceedc689e 100644 --- a/svx/inc/svx/sdr/primitive2d/svx_primitivetypes2d.hxx +++ b/svx/inc/svx/sdr/primitive2d/svx_primitivetypes2d.hxx @@ -57,6 +57,7 @@ #define PRIMITIVE2D_ID_OVERLAYHATCHRECTANGLEPRIMITIVE (PRIMITIVE2D_ID_RANGE_SVX| 18) #define PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE (PRIMITIVE2D_ID_RANGE_SVX| 19) #define PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE (PRIMITIVE2D_ID_RANGE_SVX| 20) +#define PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 16) ////////////////////////////////////////////////////////////////////////////// diff --git a/svx/source/cui/macropg.src b/svx/source/cui/macropg.src index 84fdb5c1af7f..0de8a8c5e1dd 100644 --- a/svx/source/cui/macropg.src +++ b/svx/source/cui/macropg.src @@ -234,11 +234,11 @@ String RID_SVXSTR_EVENT_PAGECOUNTCHANGE }; String RID_SVXSTR_EVENT_SUBCOMPONENT_OPENED { - Text = "Loaded a sub component" ; + Text [ en-US ] = "Loaded a sub component" ; }; String RID_SVXSTR_EVENT_SUBCOMPONENT_CLOSED { - Text = "Closed a sub component" ; + Text [ en-US ] = "Closed a sub component" ; }; String RID_SVXSTR_EVENT_APPROVEPARAMETER { diff --git a/svx/source/fmcomp/fmgridif.cxx b/svx/source/fmcomp/fmgridif.cxx index 80983514ede5..8f5a895e0c33 100644 --- a/svx/source/fmcomp/fmgridif.cxx +++ b/svx/source/fmcomp/fmgridif.cxx @@ -1921,7 +1921,7 @@ void FmXGridPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& V if ( 0 == PropertyName.compareToAscii( FM_PROP_TEXTLINECOLOR ) ) { - ::Color aTextLineColor(::comphelper::getINT32(Value)); + ::Color aTextLineColor( bVoid ? COL_TRANSPARENT : ::comphelper::getINT32( Value ) ); if (bVoid) { pGrid->SetTextLineColor(); diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx index d6cd4f2d2bae..ad645992d53d 100644 --- a/svx/source/fmcomp/gridcell.cxx +++ b/svx/source/fmcomp/gridcell.cxx @@ -55,6 +55,7 @@ #include <com/sun/star/util/XNumberFormatsSupplier.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> #ifndef _COM_SUN_STAR_SCRTIP_XEVENTATTACHERMANAGER_HPP_ #include <com/sun/star/script/XEventAttacherManager.hpp> #endif @@ -90,9 +91,9 @@ using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::form; -using ::com::sun::star::util::XNumberFormatter; using ::com::sun::star::util::XNumberFormatter; +namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior; String INVALIDTEXT = String::CreateFromAscii("###"); String OBJECTTEXT = String::CreateFromAscii("<OBJECT>"); @@ -836,22 +837,40 @@ void DbCellControl::Init( Window& rParent, const Reference< XRowSet >& _rxCursor try { // some other common properties - Reference< XPropertySet > xModel( m_rColumn.getModel() ); - Reference< XPropertySetInfo > xModelPSI; - if ( xModel.is() ) - xModelPSI = xModel->getPropertySetInfo(); + Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW ); + Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW ); - // the "readonly" state - if ( xModelPSI.is() && xModelPSI->hasPropertyByName( FM_PROP_READONLY ) ) + if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) ) { implAdjustReadOnly( xModel ); } - // the "enabled" flag - if ( xModelPSI.is() && xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) ) + if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) ) { implAdjustEnabled( xModel ); } + + if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) ) + { + sal_Int16 nWheelBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY; + OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior ); + USHORT nVclSetting = MOUSE_WHEEL_FOCUS_ONLY; + switch ( nWheelBehavior ) + { + case MouseWheelBehavior::SCROLL_DISABLED: nVclSetting = MOUSE_WHEEL_DISABLE; break; + case MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MOUSE_WHEEL_FOCUS_ONLY; break; + case MouseWheelBehavior::SCROLL_ALWAYS: nVclSetting = MOUSE_WHEEL_ALWAYS; break; + default: + OSL_ENSURE( false, "DbCellControl::Init: invalid MouseWheelBehavior!" ); + break; + } + + AllSettings aSettings = m_pWindow->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + aMouseSettings.SetWheelBehavior( nVclSetting ); + aSettings.SetMouseSettings( aMouseSettings ); + m_pWindow->SetSettings( aSettings, TRUE ); + } } catch( const Exception& ) { diff --git a/svx/source/form/fmprop.cxx b/svx/source/form/fmprop.cxx index 2cf5f158ac1f..e328e79b9514 100644 --- a/svx/source/form/fmprop.cxx +++ b/svx/source/form/fmprop.cxx @@ -189,6 +189,7 @@ namespace svxform IMPLEMENT_CONSTASCII_USTRING( FM_PROP_INPUT_REQUIRED, "InputRequired" ); IMPLEMENT_CONSTASCII_USTRING( FM_PROP_WRITING_MODE, "WritingMode" ); + IMPLEMENT_CONSTASCII_USTRING( FM_PROP_MOUSE_WHEEL_BEHAVIOR, "MouseWheelBehavior" ); } // namespace svxform diff --git a/svx/source/inc/fmprop.hrc b/svx/source/inc/fmprop.hrc index adfb73ad1dc8..3deec41981d4 100644 --- a/svx/source/inc/fmprop.hrc +++ b/svx/source/inc/fmprop.hrc @@ -182,6 +182,7 @@ namespace svxform DECLARE_CONSTASCII_USTRING( FM_PROP_FORM_OPERATIONS ); DECLARE_CONSTASCII_USTRING( FM_PROP_INPUT_REQUIRED ); DECLARE_CONSTASCII_USTRING( FM_PROP_WRITING_MODE ); + DECLARE_CONSTASCII_USTRING( FM_PROP_MOUSE_WHEEL_BEHAVIOR ); } // namespace svxform diff --git a/svx/source/msfilter/msocximex.cxx b/svx/source/msfilter/msocximex.cxx index 7308bbf221eb..7db08e229536 100644 --- a/svx/source/msfilter/msocximex.cxx +++ b/svx/source/msfilter/msocximex.cxx @@ -623,7 +623,11 @@ class ContainerRecReader pS->SeekRel( 4 ); // option flags if( nContentFlags & 0x00000010 ) - pS->SeekRel( 4 ); + { + sal_uInt32 nBitFlags = 0; + *pS >> nBitFlags; + rec.bVisible = ( ( nBitFlags & 0x02 ) == 0x02 ); + } // substream size if( nContentFlags & 0x00000020 ) *pS >> rec.nSubStreamLen; @@ -1212,6 +1216,13 @@ sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog xPropSet->setPropertyValue(WW8_ASCII2STR("Step"), aTmp); } + try + { + xPropSet->setPropertyValue(WW8_ASCII2STR("EnableVisible"), uno::makeAny( mbVisible ) ); + } + catch( uno::Exception& ) + { + } return sal_True; } @@ -3612,6 +3623,7 @@ void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream* // reflect the ms tabbing from orig MS UserForm, see below pControl->mnTabPos = rec.nTabPos; pControl->SetInDialog(true); + pControl->mbVisible = rec.bVisible; if ( mnStep ) { // If the container has a step then it should be diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index ea260f3285f7..bb7d772b3c0e 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -35,6 +35,7 @@ #include <svx/sdr/contact/displayinfo.hxx> #include <svx/sdr/properties/properties.hxx> #include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> /** === begin UNO includes === **/ #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -80,6 +81,7 @@ namespace sdr { namespace contact { using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::awt::XControl; @@ -175,7 +177,11 @@ namespace sdr { namespace contact { inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); } inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); } void setPosSize( const Rectangle& _rPosSize ) const; - void setZoom( const MapMode& _rMapMode ) const; + Rectangle + getPosSize() const; + void setZoom( const ::basegfx::B2DVector& _rScale ) const; + ::basegfx::B2DVector + getZoom() const; inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); } inline Reference< XGraphics > @@ -221,10 +227,36 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ControlHolder::setZoom( const MapMode& _rMapMode ) const + ::Rectangle ControlHolder::getPosSize() const { // no check whether we're valid, this is the responsibility of the caller - m_xControlView->setZoom( (float)double( _rMapMode.GetScaleX() ), (float)double( _rMapMode.GetScaleY() ) ); + return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const + { + // no check whether we're valid, this is the responsibility of the caller + m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() ); + } + + //-------------------------------------------------------------------- + ::basegfx::B2DVector ControlHolder::getZoom() const + { + // no check whether we're valid, this is the responsibility of the caller + + // Argh. Why does XView have a setZoom only, but not a getZoom? + Window* pWindow = VCLUnoHelper::GetWindow( m_xControlWindow ); + OSL_ENSURE( pWindow, "ControlHolder::setZoom: no implementation access!" ); + + ::basegfx::B2DVector aZoom( 1, 1 ); + if ( pWindow ) + { + const Fraction& rZoom( pWindow->GetZoom() ); + aZoom.setX( (double)rZoom ); + aZoom.setY( (double)rZoom ); + } + return aZoom; } //==================================================================== @@ -233,37 +265,13 @@ namespace sdr { namespace contact { class UnoControlContactHelper { public: - /** positions a control relative to a device - - @precond <arg>_pDevice</arg> is not <NULL/> + /** positions a control, and sets its zoom mode, using a given transformation and output device */ - static void positionControl_throw( + static void adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, - const OutputDevice* _pDevice - ); - - /** sets the zoom at a UNO control, according to a Device's MapMode - - @precond <arg>_pDevice</arg> is not <NULL/> - */ - static void setControlZoom( - const ControlHolder& _rControl, - const OutputDevice* _pDevice - ); - - /** draws a given control onto it's current XGraphics, at given coordinates - - Note that the control is not drawn onto the given device, instead you must - use ->XView::setGraphics yourself, before calling this method. The given ->OutputDevice - is only used to calculate pixel coordinates from logic coordinates - - @precond <arg>_pDevice</arg> is not <NULL/> - */ - static void drawControl( - const ControlHolder& _rControl, - const Point& _rLogicTopLeft, - const OutputDevice* _pDevice + const ::basegfx::B2DHomMatrix& _rViewTransformation, + const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ); /** disposes the given control @@ -279,50 +287,28 @@ namespace sdr { namespace contact { }; //-------------------------------------------------------------------- - void UnoControlContactHelper::positionControl_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, - const OutputDevice* _pDevice ) + void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, + const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ) { - OSL_PRECOND( _pDevice, "UnoControlContactHelper::positionControl_throw: no device -> no survival!" ); - - if ( _rControl.is() ) - { - const Rectangle aPaintRectPixel( - _pDevice->LogicToPixel( _rLogicBoundingRect.TopLeft() ), - _pDevice->LogicToPixel( _rLogicBoundingRect.GetSize() ) - ); - - _rControl.setPosSize( aPaintRectPixel ); - } - } - - //-------------------------------------------------------------------- - void UnoControlContactHelper::setControlZoom( const ControlHolder& _rControl, const OutputDevice* _pDevice ) - { - OSL_PRECOND( _pDevice, "UnoControlContactHelper::setControlZoom: no device -> no survival!" ); - OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::setControlZoom: illegal control!" ); - - if ( _rControl.is() ) - _rControl.setZoom( _pDevice->GetMapMode() ); - } - - //-------------------------------------------------------------------- - void UnoControlContactHelper::drawControl( const ControlHolder& _rControl, const Point& _rLogicTopLeft, - const OutputDevice* _pDevice ) - { - OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::drawControl: invalid control!" ); + OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" ); if ( !_rControl.is() ) return; - try - { - _rControl.draw( - _pDevice->LogicToPixel( _rLogicTopLeft ) - ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } + // transform the logic bound rect, using the view transformation, to pixel coordinates + ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() ); + aTopLeft *= _rViewTransformation; + ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() ); + aBottomRight *= _rViewTransformation; + + const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() ); + _rControl.setPosSize( aPaintRectPixel ); + + // determine the scale from the current view transformation, and the normalization matrix + ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization ); + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX ); + _rControl.setZoom( aScale ); } //-------------------------------------------------------------------- @@ -402,40 +388,7 @@ namespace sdr { namespace contact { } //==================================================================== - //= DummyPageViewAccess - //==================================================================== - /** is a ->IPageViewAccess implementation which defaults all attribute access, and thus can be - operated without an actual ->SdrPageView - */ - class DummyPageViewAccess : public IPageViewAccess - { - public: - virtual bool isDesignMode() const; - virtual Reference< XControlContainer > - getControlContainer( const OutputDevice& _rDevice ) const; - virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; - }; - - //-------------------------------------------------------------------- - bool DummyPageViewAccess::isDesignMode() const - { - return true; - } - - //-------------------------------------------------------------------- - Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const - { - return Reference< XControlContainer >(); - } - - //-------------------------------------------------------------------- - bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const - { - return true; - } - - //==================================================================== - //= DummyPageViewAccess + //= InvisibleControlViewAccess //==================================================================== /** is a ->IPageViewAccess implementation which can be used to create an invisble control for an arbitrary device @@ -510,7 +463,7 @@ namespace sdr { namespace contact { Reference< XContainer > m_xContainer; /// the output device for which the control was created - OutputDevice const* m_pOutputDeviceForWindow; + const OutputDevice* m_pOutputDeviceForWindow; /// flag indicating whether the control is currently visible bool m_bControlIsVisible; @@ -527,6 +480,8 @@ namespace sdr { namespace contact { /// is the control currently in design mode? mutable ViewControlMode m_eControlDesignMode; + ::basegfx::B2DHomMatrix m_aZoomLevelNormalization; + public: ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ); @@ -549,17 +504,13 @@ namespace sdr { namespace contact { */ bool getUnoObject( SdrUnoObj*& _out_rpObject ) const; - /** ensures that we have an XControl which can be painted onto the given display - */ - bool ensureControl( const DisplayInfo& _rDisplayInfo ); - /** ensures that we have an ->XControl Must only be called if a control is needed when no DisplayInfo is present, yet. - For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both can only be - obtained from a ->DisplayInfo struct, or alternatively a ->ObjectContactOfPageView. So, if - our (anti-impl's) object contact is not a ->ObjectContactOfPageView, this method fill fail. + For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained + from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView, + this method fill fail. Failure of this method will be reported via an assertion in a non-product version. */ @@ -572,22 +523,16 @@ namespace sdr { namespace contact { inline const ControlHolder& getExistentControl() const { return m_aControl; } - /** positions our XControl according to the geometry settings in the SdrUnoObj, - and sets proper zoom settings according to our device + inline bool + hasControl() const { return m_aControl.is(); } + + /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given + transformation, and sets proper zoom settings according to our device @precond ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/> - @tolerant - If the preconditions are not met, nothing is done at all */ - void positionAndZoomControl() const; - - /** positions the control for a paint onto a given device - - If we do not (yet) have a control, or the control does not belong to the - device for which a paint is requested, no positioning happens. - */ - void positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const; + void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const; /** determines whether or not our control is printable @@ -626,6 +571,13 @@ namespace sdr { namespace contact { struct GuardAccess { friend class VOCGuard; private: GuardAccess() { } }; ::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; } + const ViewContactOfUnoControl& + getViewContact() const + { + ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" ); + return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() ); + } + protected: ~ViewObjectContactOfUnoControl_Impl(); @@ -797,10 +749,11 @@ namespace sdr { namespace contact { This method cares for this, by retrieving the very original OutputDevice. */ - const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const; + static const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ); + const OutputDevice& imp_getPageViewDevice_nothrow() const; private: - ViewObjectContactOfUnoControl_Impl(); // never implemented + ViewObjectContactOfUnoControl_Impl(); // never implemented ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented }; @@ -812,18 +765,65 @@ namespace sdr { namespace contact { */ class VOCGuard { - const ViewObjectContactOfUnoControl_Impl& m_rImpl; - ::osl::MutexGuard m_aMutexGuard; + private: + ::osl::MutexGuard m_aMutexGuard; public: VOCGuard( const ViewObjectContactOfUnoControl_Impl& _rImpl ) - :m_rImpl( _rImpl ) - ,m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) + :m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) { } }; //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BasePrimitive2D + { + private: + typedef ::drawinglayer::primitive2d::BasePrimitive2D BasePrimitive2D; + + protected: + virtual ::drawinglayer::primitive2d::Primitive2DSequence + get2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::drawinglayer::primitive2d::Primitive2DSequence + createLocalDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::basegfx::B2DRange + getB2DRange( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + public: + LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl ) + :m_pVOCImpl( _pVOCImpl ) + { + ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." ); + getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation ); + } + + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + // declare unique ID for this primitive class + DeclPrimitrive2DIDBlock() + + static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ); + + private: + ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl; + /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand + (since the data the calculation is based on might have changed then), but need to calc + it at construction time, and remember it. + */ + ::basegfx::B2DHomMatrix m_aTransformation; + }; + + //==================================================================== //= ViewObjectContactOfUnoControl_Impl //==================================================================== DBG_NAME( ViewObjectContactOfUnoControl_Impl ) @@ -834,10 +834,20 @@ namespace sdr { namespace contact { ,m_bControlIsVisible( false ) ,m_bIsDesignModeListening( false ) ,m_eControlDesignMode( eUnknown ) + ,m_aZoomLevelNormalization() { DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL ); DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" ); - } + + const OutputDevice& rPageViewDevice( imp_getPageViewDevice_nothrow() ); + m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation(); + + ::basegfx::B2DHomMatrix aScaleNormalization; + MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() ); + aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() ); + aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() ); + m_aZoomLevelNormalization *= aScaleNormalization; + } //-------------------------------------------------------------------- ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl() @@ -898,27 +908,21 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl_Impl::positionControlForPaint( const DisplayInfo& /* #i74769# _rDisplayInfo*/ ) const - { - if ( !m_aControl.is() ) - return; - - positionAndZoomControl(); - } - - //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl() const + void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const { - OSL_PRECOND( m_pOutputDeviceForWindow && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); - if ( !m_pOutputDeviceForWindow || !m_aControl.is() ) + OSL_PRECOND( ( m_pOutputDeviceForWindow != NULL ) && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); + if ( ( m_pOutputDeviceForWindow == NULL ) || !m_aControl.is() ) return; try { SdrUnoObj* pUnoObject( NULL ); if ( getUnoObject( pUnoObject ) ) - UnoControlContactHelper::positionControl_throw( m_aControl, pUnoObject->GetLogicRect(), m_pOutputDeviceForWindow ); - UnoControlContactHelper::setControlZoom( m_aControl, m_pOutputDeviceForWindow ); + { + UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization ); + } + else + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" ); } catch( const Exception& ) { @@ -927,37 +931,6 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl_Impl::ensureControl( const DisplayInfo& /*_rDisplayInfo*/ ) - { - OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); - if ( impl_isDisposed_nofail() ) - return false; - - const OutputDevice* pDeviceForControl( NULL ); - - // if we're working for a page view, use the respective OutputDevice at the proper - // PaintWindow. The DisplayInfo might only contain a temporary (virtual) device, which - // is dangerous to remember - // 2006-10-24 / #i70604# / frank.schoenheit@sun.com - ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); - if ( pPageViewContact ) - pDeviceForControl = &imp_getPageViewDevice_nothrow( *pPageViewContact ); - - if ( !pDeviceForControl && pPageViewContact) - pDeviceForControl = pPageViewContact->TryToGetOutputDevice(); - - DBG_ASSERT( pDeviceForControl, "ViewObjectContactOfUnoControl_Impl::ensureControl: no output device!" ); - if ( !pDeviceForControl ) - return false; - - SdrPageView* pPageView = m_pAntiImpl->GetObjectContact().TryToGetSdrPageView(); - - ::std::auto_ptr< IPageViewAccess > pPVAccess; - pPVAccess.reset( pPageView ? (IPageViewAccess*)new SdrPageViewAccess( *pPageView ) : (IPageViewAccess*)new DummyPageViewAccess() ); - return impl_ensureControl_nothrow( *pPVAccess, *pDeviceForControl ); - } - - //-------------------------------------------------------------------- bool ViewObjectContactOfUnoControl_Impl::ensureControl() { OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); @@ -977,13 +950,21 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const + const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow() const + { + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + ENSURE_OR_THROW( pPageViewContact, "need a ObjectContactOfPageView." ); + return imp_getPageViewDevice_nothrow( *pPageViewContact ); + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) { // if the PageWindow has a patched PaintWindow, use the original PaintWindow // this ensures that our control is _not_ re-created just because somebody // (temporarily) changed the window to paint onto. // #i72429# / 2007-02-20 / frank.schoenheit@sun.com - const SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); + SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); if ( rPageWindow.GetOriginalPaintWindow() ) return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice(); @@ -1001,7 +982,7 @@ namespace sdr { namespace contact { // Somebody requested a control for a new device, which means either of // - our PageView's paint window changed since we were last here // - we don't belong to a page view, and are simply painted onto different devices - // The first sounds strange (doens't it?), the second means we could perhaps + // The first sounds strange (doens't it?), the second means we could perhaps // optimize this in the future - there is no need to re-create the control every time, // is it? // #i74523# / 2007-02-15 / frank.schoenheit@sun.com @@ -1063,44 +1044,37 @@ namespace sdr { namespace contact { bool bSuccess = false; try { - do - { - const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); + const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); - Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); - if ( xFactory.is() ) - { - _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY ); - } - DBG_ASSERT( _out_rControl.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control could be created!" ); - if ( !_out_rControl.is() ) - break; - - // knit the model and the control - _out_rControl.setModel( xControlModel ); + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW ); - UnoControlContactHelper::positionControl_throw( _out_rControl, _rUnoObject.GetLogicRect(), &_rDevice ); + // knit the model and the control + _out_rControl.setModel( xControlModel ); - // proper zoom - UnoControlContactHelper::setControlZoom( _out_rControl, &_rDevice ); + // proper geometry + UnoControlContactHelper::adjustControlGeometry_throw( + _out_rControl, + _rUnoObject.GetLogicRect(), + _rDevice.GetViewTransformation(), + _rDevice.GetInverseViewTransformation() + ); - // #107049# set design mode before peer is created, - // this is also needed for accessibility - _out_rControl.setDesignMode( _rPageView.isDesignMode() ); + // #107049# set design mode before peer is created, + // this is also needed for accessibility + _out_rControl.setDesignMode( _rPageView.isDesignMode() ); - // adjust the initial visibility according to the visibility of the layer - // 2003-06-03 - #110592# - fs@openoffice.org - impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); + // adjust the initial visibility according to the visibility of the layer + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); - // add the control to the respective control container - // #108327# do this last - Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); - if ( xControlContainer.is() ) - xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); + // add the control to the respective control container + // #108327# do this last + Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); + if ( xControlContainer.is() ) + xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); - bSuccess = true; - } - while ( false ); + bSuccess = true; } catch( const Exception& ) { @@ -1411,15 +1385,20 @@ namespace sdr { namespace contact { if ( !xNewControl.is() ) return; + ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." ); + DBG_ASSERT( xNewControl->getModel() == m_aControl.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" ); // another model should - in the drawing layer - also imply another SdrUnoObj, which // should also result in new ViewContact, and thus in new ViewObjectContacts impl_switchControlListening_nothrow( false ); + ControlHolder aNewControl( xNewControl ); + aNewControl.setZoom( m_aControl.getZoom() ); + aNewControl.setPosSize( m_aControl.getPosSize() ); + aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() ); + m_aControl = xNewControl; - positionAndZoomControl(); - m_aControl.setDesignMode( impl_isControlDesignMode_nothrow() ); m_bControlIsVisible = m_aControl.isVisible(); impl_switchControlListening_nothrow( true ); @@ -1449,30 +1428,96 @@ namespace sdr { namespace contact { } } + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl_Impl::belongsToDevice( const OutputDevice* _pDevice ) const + bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - DBG_ASSERT( _pDevice, "ViewObjectContactOfUnoControl_Impl::belongsToDevice: invalid device!" ); + if ( !BasePrimitive2D::operator==( rPrimitive ) ) + return false; - OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::belongsToDevice: already disposed!" ); - if ( impl_isDisposed_nofail() ) + const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive ); + if ( !pRHS ) return false; - if ( m_pOutputDeviceForWindow ) - { - if ( _pDevice == m_pOutputDeviceForWindow ) - return true; + if ( m_pVOCImpl != pRHS->m_pVOCImpl ) return false; - } - ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); - if ( pPageViewContact ) - return ( _pDevice == &imp_getPageViewDevice_nothrow( *pPageViewContact ) ); + if ( m_aTransformation != pRHS->m_aTransformation ) + return false; - DBG_ERROR( "ViewObjectContactOfUnoControl_Impl::belongsToDevice: could not determine the device I belong to!" ); - return false; + return true; + } + + //-------------------------------------------------------------------- + void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ) + { + // Do use model data directly to create the correct geometry. Do NOT + // use getBoundRect()/getSnapRect() here; tese will use the sequence of + // primitives themselves in the long run. + const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + const basegfx::B2DRange aRange( + aSdrGeoData.Left(), + aSdrGeoData.Top(), + aSdrGeoData.Right(), + aSdrGeoData.Bottom() + ); + + _out_Transformation.identity(); + _out_Transformation.set( 0, 0, aRange.getWidth() ); + _out_Transformation.set( 1, 1, aRange.getHeight() ); + _out_Transformation.set( 0, 2, aRange.getMinX() ); + _out_Transformation.set( 1, 2, aRange.getMinY() ); + } + + //-------------------------------------------------------------------- + ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const + { + ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 ); + aRange.transform( m_aTransformation ); + return aRange; + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + if ( m_pVOCImpl->hasControl() ) + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + return BasePrimitive2D::get2DDecomposition( _rViewInformation ); + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::createLocalDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + // force control here to make it a VCL ChildWindow. Will be fetched + // and used below by getExistentControl() + m_pVOCImpl->ensureControl(); + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + + // get needed data + const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() ); + Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() ); + const ControlHolder& rControl( m_pVOCImpl->getExistentControl() ); + + // check if we already have an XControl. + if ( !xControlModel.is() || !rControl.is() ) + // use the default mechanism. This will create a ControlPrimitive2D without + // handing over a XControl. If not even a XControlModel exists, it will + // create the SdrObject fallback visualisation + return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); + + // create a primitive and hand over the existing xControl. This will + // allow the primitive to not need to create another one on demand. + const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D( + m_aTransformation, xControlModel, rControl.getControl() ) ); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); } + //-------------------------------------------------------------------- + ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D ) + //==================================================================== //= ViewObjectContactOfUnoControl //==================================================================== @@ -1522,20 +1567,6 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - void ViewObjectContactOfUnoControl::positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const - { - VOCGuard aGuard( *m_pImpl ); - - // ensure we have a control. If we don't, then the Drawing Layer might be tempted to - // never draw the complete form layer. - // #i75095# / 2007-03-05 / frank.schoenheit@sun.com - m_pImpl->ensureControl( _rDisplayInfo ); - - // position the control - m_pImpl->positionControlForPaint( _rDisplayInfo ); - } - - //-------------------------------------------------------------------- void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const { VOCGuard aGuard( *m_pImpl ); @@ -1582,70 +1613,32 @@ namespace sdr { namespace contact { } //-------------------------------------------------------------------- - bool ViewObjectContactOfUnoControl::belongsToDevice( const OutputDevice* _pDevice ) const + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const { - VOCGuard aGuard( *m_pImpl ); - return m_pImpl->belongsToDevice( _pDevice ); + if ( m_pImpl->isDisposed() ) + // our control already died. + // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance + // disposed the control though it doesn't own it. So, /me thinks we should not bother here. + return drawinglayer::primitive2d::Primitive2DSequence();
+
+ ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) ); + return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 ); } //-------------------------------------------------------------------- - drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const - { - // force control here to make it a VCL ChildWindow. Will be fetched - // and used below by getExistentControl() - m_pImpl->ensureControl(); - m_pImpl->positionControlForPaint(rDisplayInfo); - - // get needed data - const ViewContactOfUnoControl& rViewContactOfUnoControl(static_cast< const ViewContactOfUnoControl& >(GetViewContact())); - Reference< XControlModel > xControlModel(rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel()); - const ControlHolder& rControl(m_pImpl->getExistentControl()); - - // check if we already have a XControl. - if(xControlModel.is() && rControl.is()) - { - // create a primitive and hand over the existing xControl. This will - // allow the primitive to not need to create another one on demand. - // Do use model data directly to create the correct geometry. Do NOT - // use getBoundRect()/getSnapRect() here; tese will use the sequence of - // primitives themselves in the long run. - const Rectangle aUnoControlModelData(rViewContactOfUnoControl.GetSdrUnoObj().GetGeoRect()); - const basegfx::B2DRange aRange(aUnoControlModelData.Left(), aUnoControlModelData.Top(), aUnoControlModelData.Right(), aUnoControlModelData.Bottom()); - - // create object transform - basegfx::B2DHomMatrix aTransform; - aTransform.set(0, 0, aRange.getWidth()); - aTransform.set(1, 1, aRange.getHeight()); - aTransform.set(0, 2, aRange.getMinX()); - aTransform.set(1, 2, aRange.getMinY()); - - // create control primitive with existing XControl - const drawinglayer::primitive2d::Primitive2DReference xRetval(new drawinglayer::primitive2d::ControlPrimitive2D( - aTransform, xControlModel, rControl.getControl())); - - return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); - } - else - { - // use the default mechanism. This will create a ControlPrimitive2D without - // handing over a XControl. If not even a XControlModel exists, it will - // create the SdrObject fallback visualisation - return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); - } - } - void ViewObjectContactOfUnoControl::propertyChange() { // graphical invalidate at all views ActionChanged(); // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel - // since e.g. background color has changed and existing decompositions are evtl. no + // since e.g. background color has changed and existing decompositions are possibly no // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator== // since it only has a uno reference to the XControlModel flushPrimitive2DSequence(); } + //-------------------------------------------------------------------- void ViewObjectContactOfUnoControl::ActionChanged() { // call parent diff --git a/xmloff/source/forms/elementexport.cxx b/xmloff/source/forms/elementexport.cxx index 0769798159c4..d3dc170e58d5 100644 --- a/xmloff/source/forms/elementexport.cxx +++ b/xmloff/source/forms/elementexport.cxx @@ -529,15 +529,15 @@ namespace xmloff { static sal_Int32 nBooleanPropertyAttributeIds[] = { // attribute flags - CCA_CURRENT_SELECTED, CCA_DISABLED, CCA_DROPDOWN, CCA_PRINTABLE, CCA_READONLY, CCA_SELECTED, CCA_TAB_STOP + CCA_CURRENT_SELECTED, CCA_DISABLED, CCA_DROPDOWN, CCA_PRINTABLE, CCA_READONLY, CCA_SELECTED, CCA_TAB_STOP, CCA_ENABLEVISIBLE }; static const ::rtl::OUString* pBooleanPropertyNames[] = { // property names - &PROPERTY_STATE, &PROPERTY_ENABLED, &PROPERTY_DROPDOWN, &PROPERTY_PRINTABLE, &PROPERTY_READONLY, &PROPERTY_DEFAULT_STATE, &PROPERTY_TABSTOP + &PROPERTY_STATE, &PROPERTY_ENABLED, &PROPERTY_DROPDOWN, &PROPERTY_PRINTABLE, &PROPERTY_READONLY, &PROPERTY_DEFAULT_STATE, &PROPERTY_TABSTOP, &PROPERTY_ENABLEVISIBLE }; static sal_Bool nBooleanPropertyAttrFlags[] = { // attribute defaults - BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE | BOOLATTR_INVERSE_SEMANTICS, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_VOID + BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE | BOOLATTR_INVERSE_SEMANTICS, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_VOID, BOOLATTR_DEFAULT_FALSE }; #if OSL_DEBUG_LEVEL > 0 sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]); diff --git a/xmloff/source/forms/formattributes.cxx b/xmloff/source/forms/formattributes.cxx index da5f3207ddda..0c2431590b63 100644 --- a/xmloff/source/forms/formattributes.cxx +++ b/xmloff/source/forms/formattributes.cxx @@ -60,6 +60,7 @@ namespace xmloff case CCA_CURRENT_SELECTED: return "current-selected"; case CCA_CURRENT_VALUE: return "current-value"; case CCA_DISABLED: return "disabled"; + case CCA_ENABLEVISIBLE: return "visible"; case CCA_DROPDOWN: return "dropdown"; case CCA_FOR: return "for"; case CCA_IMAGE_DATA: return "image-data"; diff --git a/xmloff/source/forms/formattributes.hxx b/xmloff/source/forms/formattributes.hxx index 5d55948be328..eba2855d3b5e 100644 --- a/xmloff/source/forms/formattributes.hxx +++ b/xmloff/source/forms/formattributes.hxx @@ -69,6 +69,7 @@ namespace xmloff #define CCA_VALUE 0x00200000 #define CCA_ORIENTATION 0x00400000 #define CCA_VISUAL_EFFECT 0x00800000 + #define CCA_ENABLEVISIBLE 0x01000000 // flags for database control atttributes #define DA_BOUND_COLUMN 0x00000001 diff --git a/xmloff/source/forms/strings.hxx b/xmloff/source/forms/strings.hxx index 2e525829fa1a..59413ed0b924 100644 --- a/xmloff/source/forms/strings.hxx +++ b/xmloff/source/forms/strings.hxx @@ -115,6 +115,7 @@ namespace xmloff XMLFORM_CONSTASCII_STRING( PROPERTY_TABSTOP, "Tabstop" ); XMLFORM_CONSTASCII_STRING( PROPERTY_STATE, "State" ); XMLFORM_CONSTASCII_STRING( PROPERTY_ENABLED, "Enabled" ); + XMLFORM_CONSTASCII_STRING( PROPERTY_ENABLEVISIBLE, "EnableVisible" ); XMLFORM_CONSTASCII_STRING( PROPERTY_MAXTEXTLENGTH, "MaxTextLen" ); XMLFORM_CONSTASCII_STRING( PROPERTY_LINECOUNT, "LineCount" ); XMLFORM_CONSTASCII_STRING( PROPERTY_TABINDEX, "TabIndex" ); diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx index 6e5f91f7f741..9535d8a46c1a 100644 --- a/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx +++ b/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx @@ -33,6 +33,7 @@ #include "exp_share.hxx" #include <rtl/ustrbuf.hxx> +#include <tools/diagnose_ex.h> #include <com/sun/star/awt/CharSet.hpp> #include <com/sun/star/awt/FontFamily.hpp> @@ -996,6 +997,24 @@ void ElementDescriptor::readDefaults( bool supportPrintable ) OSL_ENSURE( 0, "unexpected property type for \"Enabled\": not bool!" ); } + sal_Bool bVisible = sal_True; + try + { + if (_xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("EnableVisible") ) ) >>= bVisible) + { + + // only write out the non default case + if (! bVisible) + { + addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":visible") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("false") ) ); + } + } + } + catch( Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } // force writing of pos/size a = _xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("PositionX") ) ); if (a.getValueTypeClass() == TypeClass_LONG) diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx index f02b9d46b2aa..78b2fed46673 100644 --- a/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx +++ b/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx @@ -33,6 +33,7 @@ #include "imp_share.hxx" #include <osl/diagnose.h> +#include <tools/diagnose_ex.h> #include <osl/mutex.hxx> #include <rtl/ustrbuf.hxx> @@ -1612,6 +1613,23 @@ void ImportContext::importDefaults( OUString( RTL_CONSTASCII_USTRINGPARAM("Enabled") ), makeAny( sal_False ) ); } + sal_Bool bVisible = sal_True; + if (getBoolAttr( + &bVisible, OUString( RTL_CONSTASCII_USTRINGPARAM("visible") ), + xAttributes, _pImport->XMLNS_DIALOGS_UID ) && !bVisible) + { + try + { + + _xControlModel->setPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("EnableVisible") ), makeAny( sal_False ) ); + } + catch( Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + if (!importLongProperty( nBaseX, OUString( RTL_CONSTASCII_USTRINGPARAM("PositionX") ), OUString( RTL_CONSTASCII_USTRINGPARAM("left") ), |