What is the alternative to getActionView() before API level11 in android? - android-actionbar

getActionView() for action bar was introduced in API 11, If I want backward compatibility what is the alternative for getActionView() ?
e.g.
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_bar_menu, menu);
final MenuItem item = menu.findItem(R.id.menuitem);
item.getActionView() //Works from API level 11
return true;
}

You can use MenuItemCompat.getActionView(MenuItem menuItem) from the support library to get the action view on pre 11 API.

#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_activity_actions, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
// Configure the search info and add any event listeners
...
return super.onCreateOptionsMenu(menu);
}
See http://developer.android.com/guide/topics/ui/actionbar.html for details

For backwards compatibility you can use either ActionBarCompat or ActionBarScherlock. In both cases you can use the method getActionView(). You have to be sure that the import, in the first case is from the compatibility library ( android.support.v4.view.MenuItemCompat). If
you use ActionBarSherlock you have to import com.actionbarsherlock.view.MenuItem. Then you should be ok using item.getActionView().
Old
Since August 2013, and I pray people down-voting to take a look. You have to be sure that the OP's question date import, Android introduced in the first case is from the compatibility library ( ActionBarCompactandroid.support.v4.view.MenuItemCompat). Even though If you use ActionBarSherlock is still a valid choice, an option is moving towards ActionBarCompact.
So another option is to use it, and of course, all the importsyou have to came from the support library, e.g. android.supportimport com.v4actionbarsherlock.view.MenuItemCompatMenuItem. Then you should be ok using item.getActionView().

Related

Eclipse CDT: Problems with extension point CIndexer

Problem 1: I can't find org.eclipse.cdt.core.index.IIndexer
From the API:
API Information: Plug-ins that want to extend this extension point must implement org.eclipse.cdt.core.index.IIndexer interface.
Is the API Information incorrect/deprecated? Which interface should be implemented if not IIndexer?
Problem 2: I can install my own Indexer in CDT version 6.8 (eclipse 2019-06) but not in version 6.5 (eclipse 2018-09), though I don't see the difference in the plugin code.
More Details:
My Indexer class:
#SuppressWarnings("restriction")
public class MyIndexer extends PDOMFastIndexer {
public static final String ID = "de.blub.MyIndexer";
#Override
public String getID() {
return ID;
}
#Override
public IPDOMIndexerTask createTask(ITranslationUnit[] added, ITranslationUnit[] changed,
ITranslationUnit[] removed) {
if (...) {
return new MyIndexerTask(added, changed, removed, this, true);
} else {
return super.createTask(added, changed, removed);
}
}
The plugin.xml
<extension
id="org.eclipse.cdt.core.fastIndexer"
name="My Indexer"
point="org.eclipse.cdt.core.CIndexer">
<run
class="de.blub.MyIndexer">
</run>
The MANIFEST.MF File lists org.eclipse.cdt.core in the Require-Bundle section without bundle-version. Of course the cdt plugin has different versions:
In Eclipse 2019-06:
Eclipse CDT C/C++ Development Tools Core 6.8.1.201907021957 org.eclipse.cdt.core
In Eclipse 2018-09:
Eclipse CDT C/C++ Development Tools Core 6.5.0.201811180605 org.eclipse.cdt.core
This code is from org.eclipse.cdt.internal.core.pdom.PDOMManager:
private IPDOMIndexer newIndexer(String indexerId, Properties props) throws CoreException {
IPDOMIndexer indexer = null;
// Look up in extension point
IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
if (indexerExt != null) {
IConfigurationElement[] elements = indexerExt.getConfigurationElements();
for (IConfigurationElement element : elements) {
if ("run".equals(element.getName())) { //$NON-NLS-1$
try {
indexer = (IPDOMIndexer) element.createExecutableExtension("class"); //$NON-NLS-1$
indexer.setProperties(props);
} catch (CoreException e) {
CCorePlugin.log(e);
}
break;
}
}
}
// Unknown index, default to the null one
if (indexer == null)
indexer = new PDOMNullIndexer();
return indexer;
}
The code is the same for both cdt versions. indexer becomes a PDOMFastIndexer in eclipse 2018-09, but a MyIndexer in 2019-06.
One difference I could see is that in RegistryObjectManager
private Object basicGetObject(int id, byte type) {
Object result = cache.get(id);
if (result != null)
return result;
...
}
An id is used to get the correct ConfigurationElement (result) from a cache object, which I don't really understand how it is built up. However, the returned ConfigurationElement contains a field propertiesAnsValues which is incorrect in the one case (org.eclipse.cdt.internal.core.pdom.indexer.PDOMFastIndexer instead of de.blub.MyIndexer).
How can I fix that to have my own indexer in eclipse 2018-09, too?
Please also note my Problem 1. Because if the API description is correct, it means I'm trying to install my indexer the wrong way and need to do something to 'see' the IIndexer interface.
According to the schema definition, the class you need to derive from is IPDOMIndexer (which you're already doing). You can also tell this from the PDOMManager code you quoted, which casts the result of createExecutableExtension() to IPDOMIndexer.
(The comment saying to use org.eclipse.cdt.core.index.IIndexer is indeed out of date. Based on a brief look, that interface hasn't existed since at least 2005. Patches to update the extension point documentation are welcome.)
As for your second problem, I believe it's because you're using id="org.eclipse.cdt.core.fastIndexer" for your extension, which is already in use by one of CDT's built-in indexers. The id needs to identify your extension uniquely (so you can make it something like myproject.MyIndexer.)

Sitecore IsPageEditor and IsExperienceEditor

We are currently writing a module for Sitecore and have ran into a problem.
We have a pipeline in which we do the following check:
if (Sitecore.Context.PageMode.IsExperienceEditor)
{
return;
}
The problem is that one of our clients are running and older version of Sitecore (8.0 update 5) where the property IsExperienceEditor does not exist yet. See Sitecore release notes for next update where it is introduced.
To quickly fix the error we used the older deprecated property which is this:
if (Sitecore.Context.PageMode.IsPageEditor)
{
return;
}
Now the question is, is there any way in which we can test for the Sitecore version so we can have backwards compatibility in the module?
You can use the code which is executed in Sitecore in background of both properties mentioned by you:
if (Sitecore.Context.Site.DisplayMode == Sitecore.Sites.DisplayMode.Edit)
{
return;
}
I know that using Sitecore.Context.PageMode.IsExperienceEditor (or Sitecore.Context.PageMode.IsPageEditor) is more elegant, but in a situation when you need to support both old and new Sitecore versions, that's sounds like a good option.
The deprecated property of IsPageEditor is still present specifically for the purpose of backward compatibility. IsExperienceEditor is just a renamed property that does the same thing that IsPageEditor does.
However you can check for the existence of a property like this:
public static bool HasProperty(this object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName) != null;
}
Another option is to make two different versions of the module, if the implementation becomes significantly different for the different versions of Sitecore.

A descendant of TStyledPresentationProxy has not been registered for class

I have a custom grid control that inherits from TGrid called TFmGrid. This control was working fine in Rad Studio 10 Seattle Update One. I recently upgraded to 10.1 Berlin and started noticing this error message showing up on my TFmGrid controls both when I run the application and in the designer:
A descendant of TStyledPresentationProxy has not been registered for class TFmGrid. Maybe it is necessary to add the FMX.Grid.Style module to the uses section
The image below shows how the error message shows up on my grid controls:
I started by doing as the message suggests, and adding #include <FMX.Grid.Style.hpp> to the header file of my TFmGrid control, however this seems to have done nothing.
So as far as trying to register a decendant of TStyledPresentationProxy I am not exactly sure where to start. I found this documentation about a method which:
Attempts to register the presentation proxy class with the specified name or the specified combination of control class and control type.
So I assume I need to use this method or at least something similar, but I don't understand how I am supposed to go about calling this method.
But then that brings up the question of WHERE do I call this code?
My custom control has a method in its namespace called Register() which I believe was autogenerated by the IDE when the control was created:
namespace Fmgridu
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TFmGrid)};
RegisterComponents(L"Kalos FM Controls", classes, 0);
}
}
Do I need to call something in there to register a decendant of TStyledPresentationProxy? What is the proper way to go about this?
Just override virtual method DefinePresentationName in you TfmGrid and return name of presentation name for grid:
function TfmGrid.DefinePresentationName: string;
begin
Result := 'Grid-' + GetPresentationSuffix;
end;
Fm registers presentation by string name and uses class name for it, so if you create new component (based on existed) you automatically change classname, so system cannot find presentation for you. There are two solution:
Said that you will use presentation from TGrid (DefinePresentationName)
Register existed presentation for you class (look at the initialization section of FMX.Grid.Style.pas)
P.S. Year ago i wrote article about it in common eNew approach of development of FireMonkey control “Control – Model – Presentation”. Part 1 I hope it will help you
It's simple :
Just put "StyleBook" component to your form
I had the same issue with a test component I was developing.
Complementing Yaroslav Brovin's speech, I solved the problem by adding the class register in the initialization and finalization clauses at the end of the unit, like this:
initialization
TPresentationProxyFactory.Current.Register(<COMPONENT CLASSNAME HERE>, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
finalization
TPresentationProxyFactory.Current.Unregister(<COMPONENT CLASSNAME HERE>, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
In my case looks like this:
initialization
TPresentationProxyFactory.Current.Register(TSGrid, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
finalization
TPresentationProxyFactory.Current.Unregister(TSGrid, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
PS: Don't forget to declare the FMX.Presentation.Factory,
FMX.Presentation.Style and FMX.Grid.Style units in the uses clause

Sitecore Glass Mapper always null

I am using Sitecore Glass Mapper for a new project I'm setting up.
We are using Sitecore 7.2, latest version of Team Development for Sitecore (TDS) code generation and the latest version of glass.
The code I am trying to execute:
var b = new SitecoreContext();
var c = b.GetCurrentItem<T01_Homepage>();
b is not null. c is null.
var d = b.GetItem<T01_Homepage>("path")
d is null.
I added my assembly in GlassMapperScCustom:
public static IConfigurationLoader[] GlassLoaders(){
var attributes = new AttributeConfigurationLoader(new[] { "Company.Framework.Websites.Corporate", "Company.Framework.Core", "Company.Framework.Common" });
return new IConfigurationLoader[] { attributes };
}
When I look into b.GlassContext.TypeConfigurations all my models are there.
I figured it could be a language issue because the site is in dutch and maybe the wrong language would be resolved incorrectly. This was also not the case.
I disabled WebActivator and added the GlassMapperSc.Start() in my Global.asax Application_Start method.
We are also using Autofac as DI framework. But without it, it still isn't working as you can see above. Also when I create my own custom models without TDS code generation the result of GetCurrentItem<T> is null.
Does anyone have an idea how I can fix this?
Did you check your Sites.config and the default language for this website? There could be a difference between the language which is defined in your Sitecore languages folder and your configuration.
I had a similar problem with one of my projects where I changed the Sitecore.Context.Language to "nl" instead of "nl-NL". The glass mapper will return null, but Sitecore.Context.Database.GetItem will return an object in this case.
Most of the times it is a language issue. The mapper returns a null object when you do not have versions in the current or given language.
What can be confusing is that Sitecore.Context.Database.GetItem returns an object, even if it does not have a version in the current language. Be sure to check that item.Versions has any.
Some things you may try (this didn't fit in the comments field)
1) Confirm that the related fields in the Sitecore Item object contain values (so Sitecore.Context.Item for your "c" var and Sitecore.Context.Database.GetItem("path") for your "d" var)
2) Try to encapsulate the GetItem/GetCurrentItem call in a VersionCountDisabler, like this:
T01_Homepage model = null;
using (new VersionCountDisabler())
{
var context = new SitecoreContext();
model = context.GetItem<T01_Homepage>("path");
}
// Do you have data in model now?
3) Try to encapsulate the same call with a SecurityDisabler. Just to confirm it's not a security issue.
4) If you still don't know what it is, please update your question with some (simplified) code for your model.

CRecordset::snapshot doesn't work in VS2012 anymore - what's the alternative?

Apparently, in VS2012, SQL_CUR_USE_ODBC is deprecated. [Update: it appears that the cursors library has been removed from VS2012 entirely].
MFC's CDatabase doesn't use it anymore (whereas it was the default for VS2010 and earlier versions of MFC), but instead uses SQL_CUR_USE_DRIVER.
Unfortunately, SQL_CUR_USE_DRIVER doesn't work properly with the Jet ODBC driver (we're interacting with an Access database). The driver initially claims to support positional operations (but not positional updates), but when an attempt is made to actually query the database, all concurrency models fail until the MFC library drops down to read-only interaction with the database (which is not going to fly for us).
Questions
Is this MS's latest attempt to force devs to move away from Jet based datasources and migrate to SQL Express (or the like)?
Is there another modality that we should be using to interact with our Access databases through VS 2012 versions of MFC/ODBC?(1)
See also:
http://social.msdn.microsoft.com/Forums/kk/vcmfcatl/thread/acd84294-c2b5-4016-b4d9-8953f337f30c
Update: Looking at the various options, it seems that the cursor library has been removed from VS2012's ODBC library. Combined with the fact that Jet doesn't correctly support positional updates(2), it makes "snapshot" mode unusable. It does appear to support "dynaset" as long as the underlying tables have a primary key. Unkeyed tables are incompatible with "dynaset" mode(3). So - I can stick with VS 2010, or I can change my tables to include an autonumber or something similar in order to ensure a pkey is available so I can use dynaset mode for the recordsets.
(1) e.g. should we be using a different open type for CRecordset? We currently use CRecordset::snapshot. But I've never really understood the various modes snapshot, dynamic, dynaset. A quick set of "try each" has failed to get a working updatable interface to our access database...
(2) it claims to when queried initially, but then returns errors for all concurrency modes that it previously claimed to support
(3) "dynamic" is also out, since Jet doesn't support it at all (from what I can tell from my tests).
I found a solution that appears to work. I overrode OpenEx the exact same way VS 2012 has it because we need that to call the child version of AllocConnect since it is not virtual in the parent. I also overrode AllocConnect as mentioned. In the derived version of CDatabase, try the following code:
MyCDatabase.h
BOOL OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions = 0);
void AllocConnect(DWORD dwOptions);
MyCDatabase.cpp
BOOL MyCDatabase::OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions)
{
ENSURE_VALID(this);
ENSURE_ARG(lpszConnectString == NULL || AfxIsValidString(lpszConnectString));
ENSURE_ARG(!(dwOptions & noOdbcDialog && dwOptions & forceOdbcDialog));
// Exclusive access not supported.
ASSERT(!(dwOptions & openExclusive));
m_bUpdatable = !(dwOptions & openReadOnly);
TRY
{
m_strConnect = lpszConnectString;
DATA_BLOB connectBlob;
connectBlob.pbData = (BYTE *)(LPCTSTR)m_strConnect;
connectBlob.cbData = (DWORD)(AtlStrLen(m_strConnect) + 1) * sizeof(TCHAR);
if (CryptProtectData(&connectBlob, NULL, NULL, NULL, NULL, 0, &m_blobConnect))
{
SecureZeroMemory((BYTE *)(LPCTSTR)m_strConnect, m_strConnect.GetLength() * sizeof(TCHAR));
m_strConnect.Empty();
}
// Allocate the HDBC and make connection
AllocConnect(dwOptions);
if(!CDatabase::Connect(dwOptions))
return FALSE;
// Verify support for required functionality and cache info
VerifyConnect();
GetConnectInfo();
}
CATCH_ALL(e)
{
Free();
THROW_LAST();
}
END_CATCH_ALL
return TRUE;
}
void MyCDatabase::AllocConnect(DWORD dwOptions)
{
CDatabase::AllocConnect(dwOptions);
dwOptions = dwOptions | CDatabase::useCursorLib;
// Turn on cursor lib support
if (dwOptions & useCursorLib)
{
::SQLSetConnectAttr(m_hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER)SQL_CUR_USE_ODBC, 0);
// With cursor library added records immediately in result set
m_bIncRecordCountOnAdd = TRUE;
}
}
Please note that you do not want to pass in useCursorLab to OpenEx at first, you need to override it in the hacked version of AllocConnect.
Also note that this is just a hack but it appears to work. Please test all your code to be sure it works as expected but so far it works OK for me.
If anyone else runs into this issue, here's what seems to be the answer:
For ODBC to an Access database, connect using CDatabase mydb; mydb.OpenEx(.., 0), so that you ask the system not to load the cursor library.
Then for the recordsets, use dynaset CMyRecordset myrs; myrs.Open(CRecordset::dynaset, ...).
Finally, you must make sure that your tables have a primary key in order to use dynasets (keysets).
Derive CDatabase and override OpenEx. In your derived class CMyDatabase, replace the call to AllocConnect to MyAllocConnect. Obviously, your MyAllocConnect function should call SQLSetConnectOption with the desired parameter:
// Turn on cursor lib support
if (dwOptions & useCursorLib)
{
AFX_SQL_SYNC(::SQLSetConnectOption(m_hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_ODBC));
// With cursor library added records immediately in result set
m_bIncRecordCountOnAdd = TRUE;
}
Then use your CMyDatabase class instead of CDatabase for all your queries.