From: David A. Velasco Date: Thu, 19 Feb 2015 10:01:00 +0000 (+0100) Subject: Merge branch 'master' into develop X-Git-Tag: oc-android-1.7.1_signed^2~48 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/ec6b9d7c70deb50152bfab5cb5f25c9a2dde28e7?hp=ae1bd1b6a158ea61230fea8822fd42eab358f467 Merge branch 'master' into develop --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fd92d3d6..780875b7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -18,8 +18,8 @@ along with this program. If not, see . --> + android:versionCode="10700000" + android:versionName="1.7.0" xmlns:android="http://schemas.android.com/apk/res/android"> @@ -86,9 +86,7 @@ android:name=".ui.activity.Preferences" android:theme="@style/Theme.ownCloud" > - - - + diff --git a/oc_jb_workaround/AndroidManifest.xml b/oc_jb_workaround/AndroidManifest.xml index 478e3c42..18ffb4c0 100644 --- a/oc_jb_workaround/AndroidManifest.xml +++ b/oc_jb_workaround/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="0100021" + android:versionName="1.0.21" > + android:footerDividersEnabled="false" + android:visibility="visible" > - + + + + + + - + diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index d8d4eb00..49d6c3c7 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -258,5 +258,4 @@ كلمة مرور خاطئة اختيار الأمان - مُشارك diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index c597659a..fef7c367 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -277,5 +277,4 @@ inzibatçınızla əlaqə saxlayasınız. Hesablar Hesab əlavə et Yalnış şifrə - yayımlanmış diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index a2861bae..49e04b49 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -268,5 +268,4 @@ বেছে নিন সরাতে ব্যার্থ হলো। ফাইলটি রয়েছে কিনা দেখুন। নিরাপত্তা - ভাগাভাগিকৃত diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 9dcb1c6f..d0cd67a4 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -274,5 +274,4 @@ Contrasenya incorrecta Escull Seguretat - compartit diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index fd1ea10b..3cc5171a 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -298,7 +298,4 @@ správce systému. Zabezpečení Cesta pro nahrávání videí Stažení adresáře %1$s nemohlo být dokončeno - sdílené - s vámi - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index f4d57618..4852e565 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -297,7 +297,4 @@ Sikkerhed Sti til videoupload Download af %1$s mappe kunne ikke fuldføres - delt - med dig - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index bf25dc28..59f63695 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -299,7 +299,4 @@ Sicherheit Verzeichnis zum Hochladen der Videos Herunterladen des %1$s - Ordners konnte nicht abgeschlossen werden - geteilt - Mit Ihnen - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 254094e6..fdc369c8 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -299,7 +299,4 @@ Sicherheit Verzeichnis zum Hochladen der Videos Herunterladen des %1$s - Ordners konnte nicht abgeschlossen werden - geteilt - Mit Dir - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 6faffba9..8fbc0e0f 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -299,7 +299,4 @@ Ασφάλεια Διαδρομή Μεταφόρτωσης Βίντεο Η λήψη του φακέλου %1$s δεν ολοκληρώθηκε με επιτυχία. - μοιρασμένο - με εσένα - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5288af42..9b303212 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -299,7 +299,4 @@ Security Upload Video Path Download of %1$s folder could not be completed - shared - with you - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-eo/strings.xml b/res/values-eo/strings.xml index 4c604f03..faf45252 100644 --- a/res/values-eo/strings.xml +++ b/res/values-eo/strings.xml @@ -194,5 +194,4 @@ Malĝusta pasvorto Elekti Sekuro - kunhavigita diff --git a/res/values-es-rAR/strings.xml b/res/values-es-rAR/strings.xml index 6100a407..3baeea20 100644 --- a/res/values-es-rAR/strings.xml +++ b/res/values-es-rAR/strings.xml @@ -249,5 +249,4 @@ Clave incorrecta Elegir Seguridad - compartido diff --git a/res/values-es-rMX/strings.xml b/res/values-es-rMX/strings.xml index 57584635..a760bfec 100644 --- a/res/values-es-rMX/strings.xml +++ b/res/values-es-rMX/strings.xml @@ -219,5 +219,4 @@ Contraseña incorrecta Seleccionar Seguridad - compartido diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml index 84636cc7..e7ac96be 100644 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@ -298,5 +298,4 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi selle faili liigutamiseks Kohesed üleslaadimised Turvalisus - jagatud diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 142e71b4..0140c07a 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -240,5 +240,4 @@ رمز عبور اشتباه است انتخاب کردن امنیت - اشتراک گذاشته شده diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml index 52732578..ae5c4850 100644 --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@ -276,6 +276,4 @@ Tämän tiedoston tai kansion siirtoa yrittäessä tapahtui virhe Välittömät lähetykset Tietoturva - jaettu - kanssasi diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml index e8d11114..ff42f941 100644 --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@ -253,5 +253,4 @@ Mozgatás Válasszon Biztonság - Megosztott diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index eb2df51e..1b0dd761 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -294,5 +294,4 @@ untuk memindahkan berkas ini Unggah Cepat Keamanan - dibagikan diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 9cca628e..a4d161a2 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -299,7 +299,4 @@ Protezione Percorso di caricamento video Lo scaricamento della cartella %1$s non può essere completato - condiviso - con te - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml index 62cb40c8..5d4db25f 100644 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@ -300,7 +300,4 @@ セキュリティ 動画のアップロードパス %1$s のフォルダのダウンロードが完了しませんでした。 - 共有中 - あなたと - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index e6cbb501..f1ad81e8 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -298,7 +298,4 @@ 보안 동영상 업로드 경로 %1$s 폴더를 다운로드할 수 없습니다 - 공유됨 - 나와 - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml index b8c3bb15..76e0e523 100644 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@ -250,5 +250,4 @@ Neteisingas slaptažodis Pasirinkite Saugumas - bendrinamas diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 23c36119..2ce829c4 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -130,5 +130,4 @@ Погрешна лозинка Избери Безбедност - споделен diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 482a2794..240a7134 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -302,7 +302,5 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar Beveiliging Upload Video Pad Download van %1$s map kon niet worden voltooid - gedeeld - met u - %1$s %2$s >>%3$s<< %4$s + %1$s deelde \"%2$s\" met u diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 5d015e81..5135951f 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -299,7 +299,4 @@ Segurança Enviar o Caminho do Vídeo Baixar %1$s da pasta não pode ser completado - compartilhado - com você - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 0c98373e..a9bb306b 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -300,7 +300,4 @@ Безопасность Путь для загрузки Видео Загрузка папки %1$s не может быть завершена - общие - с вами - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-sk-rSK/strings.xml b/res/values-sk-rSK/strings.xml index 04ff6208..8e993d74 100644 --- a/res/values-sk-rSK/strings.xml +++ b/res/values-sk-rSK/strings.xml @@ -299,7 +299,4 @@ Zabezpečenie Cesta pre nahrávanie videí Sťahovanie %1$s priečinka nebolo dokončené - zdieľané - s vami - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 7c1b7ffc..02918e8a 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -77,5 +77,4 @@ Fjalëkalim i gabuar Zgjidh Siguria - Ndarë diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 254ed65e..f44afacc 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -298,7 +298,4 @@ Direktuppladning Säkerhet Uppladdnings-sökväg för video - delad - med dig - %1$s %2$s >>%3$s<< %4$s diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 8a0664e5..3b1ac5e0 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -299,7 +299,5 @@ Güvenlik Video Yükleme Yolu %1$s klasörün indirilmesi tamamlanamadı - paylaşılan - sizinle - %1$s %2$s >>%3$s<< %4$s + %1$s sizinle \"%2$s\" paylaştı diff --git a/res/values-ug/strings.xml b/res/values-ug/strings.xml index abee26e6..12a54928 100644 --- a/res/values-ug/strings.xml +++ b/res/values-ug/strings.xml @@ -44,5 +44,4 @@ ھېساباتلار بىخەتەرلىك - ھەمبەھىرلەنگەن diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 8141cc97..28123e0a 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -298,5 +298,4 @@ 安全 视频上传路径 %1$s 文件夹的下载无法完成 - 分享 diff --git a/res/values/strings.xml b/res/values/strings.xml index 914681b4..296a8e0e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -326,8 +326,6 @@ Upload Video Path Download of %1$s folder could not be completed - shared - with you - %1$s %2$s >>%3$s<< %4$s + %1$s shared \"%2$s\" with you diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index df4e21b1..8d7182d7 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -1020,12 +1020,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { dismissDialog(WAIT_DIALOG_TAG); if (result.isIdPRedirection()) { - String url = result.getRedirectedLocation(); String targetUrl = mServerInfo.mBaseUrl + AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType); // Show dialog - SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(url, targetUrl); + SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(targetUrl, targetUrl); dialog.show(getSupportFragmentManager(), SAML_DIALOG_TAG); mAuthStatusIcon = 0; diff --git a/src/com/owncloud/android/authentication/SsoWebViewClient.java b/src/com/owncloud/android/authentication/SsoWebViewClient.java index b90ab85b..2aaecb43 100644 --- a/src/com/owncloud/android/authentication/SsoWebViewClient.java +++ b/src/com/owncloud/android/authentication/SsoWebViewClient.java @@ -1,5 +1,5 @@ /* ownCloud Android client application - * Copyright (C) 2012-2013 ownCloud Inc. + * Copyright (C) 2012-2015 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -124,7 +124,7 @@ public class SsoWebViewClient extends WebViewClient { view.setVisibility(View.GONE); CookieManager cookieManager = CookieManager.getInstance(); final String cookies = cookieManager.getCookie(url); - Log_OC.d(TAG, "Cookies: " + cookies); + //Log_OC.d(TAG, "Cookies: " + cookies); if (mListenerHandler != null && mListenerRef != null) { // this is good idea because onPageFinished is not running in the UI thread mListenerHandler.post(new Runnable() { @@ -141,22 +141,14 @@ public class SsoWebViewClient extends WebViewClient { } } - - @Override - public void doUpdateVisitedHistory (WebView view, String url, boolean isReload) { - Log_OC.d(TAG, "doUpdateVisitedHistory : " + url); - } - @Override public void onReceivedSslError (final WebView view, final SslErrorHandler handler, SslError error) { - Log_OC.d(TAG, "onReceivedSslError : " + error); + Log_OC.e(TAG, "onReceivedSslError : " + error); // Test 1 X509Certificate x509Certificate = getX509CertificateFromError(error); boolean isKnownServer = false; if (x509Certificate != null) { - Log_OC.d(TAG, "------>>>>> x509Certificate " + x509Certificate.toString()); - try { isKnownServer = NetworkUtils.isCertInKnownServersStore((Certificate) x509Certificate, mContext); } catch (Exception e) { @@ -201,36 +193,4 @@ public class SsoWebViewClient extends WebViewClient { ((AuthenticatorActivity)mContext).createAuthenticationDialog(view, handler); } - @Override - public WebResourceResponse shouldInterceptRequest (WebView view, String url) { - Log_OC.d(TAG, "shouldInterceptRequest : " + url); - return null; - } - - @Override - public void onLoadResource (WebView view, String url) { - Log_OC.d(TAG, "onLoadResource : " + url); - } - - @Override - public void onReceivedLoginRequest (WebView view, String realm, String account, String args) { - Log_OC.d(TAG, "onReceivedLoginRequest : " + realm + ", " + account + ", " + args); - } - - @Override - public void onScaleChanged (WebView view, float oldScale, float newScale) { - Log_OC.d(TAG, "onScaleChanged : " + oldScale + " -> " + newScale); - super.onScaleChanged(view, oldScale, newScale); - } - - @Override - public void onUnhandledKeyEvent (WebView view, KeyEvent event) { - Log_OC.d(TAG, "onUnhandledKeyEvent : " + event); - } - - @Override - public boolean shouldOverrideKeyEvent (WebView view, KeyEvent event) { - Log_OC.d(TAG, "shouldOverrideKeyEvent : " + event); - return false; - } } diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java index feedc11c..cd7afa62 100644 --- a/src/com/owncloud/android/files/services/FileDownloader.java +++ b/src/com/owncloud/android/files/services/FileDownloader.java @@ -109,15 +109,31 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis @Override public void onCreate() { super.onCreate(); + Log_OC.d(TAG, "Creating service"); mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - HandlerThread thread = new HandlerThread("FileDownloaderThread", - Process.THREAD_PRIORITY_BACKGROUND); + HandlerThread thread = new HandlerThread("FileDownloaderThread", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper, this); mBinder = new FileDownloaderBinder(); } + + /** + * Service clean up + */ + @Override + public void onDestroy() { + Log_OC.v(TAG, "Destroying service" ); + mBinder = null; + mServiceHandler = null; + mServiceLooper.quit(); + mServiceLooper = null; + mNotificationManager = null; + super.onDestroy(); + } + + /** * Entry point to add one or several files to the queue of downloads. * @@ -126,6 +142,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis */ @Override public int onStartCommand(Intent intent, int flags, int startId) { + Log_OC.d(TAG, "Starting command with id " + startId); + if ( !intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_FILE) ) { @@ -342,11 +360,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis Iterator it = requestedDownloads.iterator(); while (it.hasNext()) { String next = it.next(); - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Handling download file " + next);*/ mService.downloadFile(next); } } + Log_OC.d(TAG, "Stopping after command with id " + msg.arg1); mService.stopSelf(msg.arg1); } } diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 386f1857..6f77a9c1 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -161,7 +161,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe @Override public void onCreate() { super.onCreate(); - Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size()); + Log_OC.d(TAG, "Creating service"); mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); @@ -171,6 +171,21 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } /** + * Service clean up + */ + @Override + public void onDestroy() { + Log_OC.v(TAG, "Destroying service" ); + mBinder = null; + mServiceHandler = null; + mServiceLooper.quit(); + mServiceLooper = null; + mNotificationManager = null; + super.onDestroy(); + } + + + /** * Entry point to add one or several files to the queue of uploads. * * New uploads are added calling to startService(), resulting in a call to @@ -179,6 +194,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe */ @Override public int onStartCommand(Intent intent, int flags, int startId) { + Log_OC.d(TAG, "Starting command with id " + startId); + if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE) || !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) { Log_OC.e(TAG, "Not enough information provided in intent"); @@ -467,6 +484,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe mService.uploadFile(it.next()); } } + Log_OC.d(TAG, "Stopping command after id " + msg.arg1); mService.stopSelf(msg.arg1); } } diff --git a/src/com/owncloud/android/operations/CreateShareOperation.java b/src/com/owncloud/android/operations/CreateShareOperation.java index fc44f530..6d9a253c 100644 --- a/src/com/owncloud/android/operations/CreateShareOperation.java +++ b/src/com/owncloud/android/operations/CreateShareOperation.java @@ -134,8 +134,7 @@ public class CreateShareOperation extends SyncOperation { if (file!=null) { mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink()); mSendIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(mContext.getString(R.string.subject_token), - getClient().getCredentials().getUsername(), mContext.getString(R.string.shared_subject_header), - file.getFileName(), mContext.getString(R.string.with_you_subject_header))); + getClient().getCredentials().getUsername(), file.getFileName())); file.setPublicLink(share.getShareLink()); file.setShareByLink(true); getStorageManager().saveFile(file); diff --git a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java index 4b5343b3..06760e85 100644 --- a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -440,7 +440,8 @@ public class SynchronizeFolderOperation extends SyncOperation { */ private void startContentSynchronizations(List filesToSyncContents, OwnCloudClient client) throws OperationCancelledException { - + + Log_OC.v(TAG, "Starting content synchronization... "); RemoteOperationResult contentsResult = null; for (SyncOperation op: filesToSyncContents) { if (mCancellationRequested.get()) { diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java index 2e57ada9..581a686d 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -144,6 +144,8 @@ public class OperationsService extends Service { @Override public void onCreate() { super.onCreate(); + Log_OC.d(TAG, "Creating service"); + /// First worker thread for most of operations HandlerThread thread = new HandlerThread("Operations thread", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); @@ -165,12 +167,12 @@ public class OperationsService extends Service { */ @Override public int onStartCommand(Intent intent, int flags, int startId) { - // WIP: for the moment, only SYNC_FOLDER and CANCEL_SYNC_FOLDER is expected here; + Log_OC.d(TAG, "Starting command with id " + startId); + + // WIP: for the moment, only SYNC_FOLDER is expected here; // the rest of the operations are requested through the Binder if (ACTION_SYNC_FOLDER.equals(intent.getAction())) { - /*Log_OC.v("NOW " + TAG + ", thread " + Thread.currentThread().getName(), "Received request to sync folder");*/ - if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_REMOTE_PATH)) { Log_OC.e(TAG, "Not enough information provided in intent"); return START_NOT_STICKY; @@ -186,10 +188,6 @@ public class OperationsService extends Service { Message msg = mSyncFolderHandler.obtainMessage(); msg.arg1 = startId; msg.obj = itemSyncKey; - /*Log_OC.v( - "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Sync folder " + remotePath + " added to queue" - );*/ mSyncFolderHandler.sendMessage(msg); } @@ -204,7 +202,7 @@ public class OperationsService extends Service { @Override public void onDestroy() { - //Log_OC.wtf(TAG, "onDestroy init" ); + Log_OC.v(TAG, "Destroying service" ); // Saving cookies try { OwnCloudClientManagerFactory.getDefaultSingleton(). @@ -221,10 +219,16 @@ public class OperationsService extends Service { e.printStackTrace(); } - //Log_OC.wtf(TAG, "Clear mUndispatchedFinishedOperations" ); mUndispatchedFinishedOperations.clear(); - - //Log_OC.wtf(TAG, "onDestroy end" ); + + mOperationsBinder = null; + + mOperationsHandler.getLooper().quit(); + mOperationsHandler = null; + + mSyncFolderHandler.getLooper().quit(); + mSyncFolderHandler = null; + super.onDestroy(); } @@ -276,10 +280,6 @@ public class OperationsService extends Service { * @param file A folder in the queue of pending synchronizations */ public void cancel(Account account, OCFile file) { - /*Log_OC.v( - "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Received request to cancel folder " + file.getRemotePath() - );*/ mSyncFolderHandler.cancel(account, file); } @@ -413,6 +413,7 @@ public class OperationsService extends Service { @Override public void handleMessage(Message msg) { nextOperation(); + Log_OC.d(TAG, "Stopping after command with id " + msg.arg1); mService.stopSelf(msg.arg1); } diff --git a/src/com/owncloud/android/services/SyncFolderHandler.java b/src/com/owncloud/android/services/SyncFolderHandler.java index b68d930b..02f8f7a4 100644 --- a/src/com/owncloud/android/services/SyncFolderHandler.java +++ b/src/com/owncloud/android/services/SyncFolderHandler.java @@ -86,9 +86,8 @@ class SyncFolderHandler extends Handler { @Override public void handleMessage(Message msg) { Pair itemSyncKey = (Pair) msg.obj; - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Handling sync folder " + itemSyncKey.second);*/ doOperation(itemSyncKey.first, itemSyncKey.second); + Log_OC.d(TAG, "Stopping after command with id " + msg.arg1); mService.stopSelf(msg.arg1); } @@ -98,8 +97,6 @@ class SyncFolderHandler extends Handler { */ private void doOperation(Account account, String remotePath) { - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Getting sync folder " + remotePath);*/ mCurrentSyncOperation = mPendingOperations.get(account, remotePath); if (mCurrentSyncOperation != null) { @@ -120,8 +117,6 @@ class SyncFolderHandler extends Handler { mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton(). getClientFor(ocAccount, mService); - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Executing sync folder " + remotePath);*/ result = mCurrentSyncOperation.execute(mOwnCloudClient, mStorageManager); } catch (AccountsException e) { @@ -129,9 +124,6 @@ class SyncFolderHandler extends Handler { } catch (IOException e) { Log_OC.e(TAG, "Error while trying to get authorization", e); } finally { - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Removing payload " + remotePath);*/ - mPendingOperations.removePayload(account, remotePath); mService.dispatchResultToOperationListeners(null, mCurrentSyncOperation, result); @@ -158,26 +150,17 @@ class SyncFolderHandler extends Handler { Log_OC.e(TAG, "Cannot cancel with NULL parameters"); return; } - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Removing sync folder " + file.getRemotePath());*/ Pair removeResult = mPendingOperations.remove(account, file.getRemotePath()); SynchronizeFolderOperation synchronization = removeResult.first; if (synchronization != null) { - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Canceling returned sync of " + file.getRemotePath());*/ synchronization.cancel(); } else { // TODO synchronize? if (mCurrentSyncOperation != null && mCurrentAccount != null && mCurrentSyncOperation.getRemotePath().startsWith(file.getRemotePath()) && account.name.equals(mCurrentAccount.name)) { - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Canceling current sync as descendant: " + mCurrentSyncOperation.getRemotePath());*/ mCurrentSyncOperation.cancel(); - } else { - /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Nothing else in cancelation of " + file.getRemotePath());*/ } } diff --git a/src/com/owncloud/android/ui/ExtendedListView.java b/src/com/owncloud/android/ui/ExtendedListView.java new file mode 100644 index 00000000..20bf66f2 --- /dev/null +++ b/src/com/owncloud/android/ui/ExtendedListView.java @@ -0,0 +1,79 @@ +/* ownCloud Android client application + * Copyright (C) 2012 Bartek Przybylski + * Copyright (C) 2012-2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.ui; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.widget.ListView; + +import com.owncloud.android.lib.common.utils.Log_OC; + +/** + * ListView allowing to specify the position of an item that should be centered in the visible area, if possible. + * + * The cleanest way I found to overcome the problem due to getHeight() returns 0 until the view is really drawn. + * + * @author David A. Velasco + */ +public class ExtendedListView extends ListView { + + private static final String TAG = ExtendedListView.class.getSimpleName(); + + private int mPositionToSetAndCenter = 0; + + public ExtendedListView(Context context) { + super(context); + } + + public ExtendedListView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ExtendedListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /** + * {@inheritDoc} + * + * + */ + @Override + protected void onDraw (Canvas canvas) { + super.onDraw(canvas); + if (mPositionToSetAndCenter > 0) { + Log_OC.v(TAG, "Centering around position " + mPositionToSetAndCenter); + this.setSelectionFromTop(mPositionToSetAndCenter, getHeight() / 2); + mPositionToSetAndCenter = 0; + } + } + + /** + * Public method to set the position of the item that should be centered in the visible area of the view. + * + * The position is saved here and checked in onDraw(). + * + * @param position Position (in the list of items) of the item to center in the visible area. + */ + public void setAndCenterSelection(int position) { + mPositionToSetAndCenter = position; + } + +} \ No newline at end of file diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 7e60776d..ef9de9ea 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -256,7 +256,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { setNavigationListWithFolder(file); if (!stateWasRecovered) { - Log_OC.e(TAG, "Initializing Fragments in onAccountChanged.."); + Log_OC.d(TAG, "Initializing Fragments in onAccountChanged.."); initFragmentsWithFile(); if (file.isFolder()) { startSyncFolderOperation(file, false); @@ -555,19 +555,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { } private void startSynchronization() { - Log_OC.e(TAG, "Got to start sync"); + Log_OC.d(TAG, "Got to start sync"); if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { - Log_OC.e(TAG, "Canceling all syncs for " + MainApp.getAuthority()); + Log_OC.d(TAG, "Canceling all syncs for " + MainApp.getAuthority()); ContentResolver.cancelSync(null, MainApp.getAuthority()); // cancel the current synchronizations of any ownCloud account Bundle bundle = new Bundle(); bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); - Log_OC.e(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority()); + Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority()); ContentResolver.requestSync( getAccount(), MainApp.getAuthority(), bundle); } else { - Log_OC.e(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority() + " with new API"); + Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority() + " with new API"); SyncRequest.Builder builder = new SyncRequest.Builder(); builder.setSyncAdapter(getAccount(), MainApp.getAuthority()); builder.setExpedited(true); @@ -699,7 +699,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { } finally { if (filepath == null) { - Log_OC.e(TAG, "Couldnt resolve path to file"); + Log_OC.e(TAG, "Couldn't resolve path to file"); Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG); t.show(); return; @@ -786,7 +786,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { @Override protected void onSaveInstanceState(Bundle outState) { // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved - Log_OC.e(TAG, "onSaveInstanceState() start"); + Log_OC.d(TAG, "onSaveInstanceState() start"); super.onSaveInstanceState(outState); outState.putParcelable(FileDisplayActivity.KEY_WAITING_TO_PREVIEW, mWaitingToPreview); outState.putBoolean(FileDisplayActivity.KEY_SYNC_IN_PROGRESS, mSyncInProgress); @@ -801,7 +801,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { @Override protected void onResume() { super.onResume(); - Log_OC.e(TAG, "onResume() start"); + Log_OC.d(TAG, "onResume() start"); // refresh list of files refreshListOfFilesFragment(); @@ -833,7 +833,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener { @Override protected void onPause() { - Log_OC.e(TAG, "onPause() start"); + Log_OC.d(TAG, "onPause() start"); if (mSyncBroadcastReceiver != null) { unregisterReceiver(mSyncBroadcastReceiver); //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver); diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java index d809f141..dcd4d70c 100644 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -30,6 +30,7 @@ import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; @@ -69,6 +70,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { private FileDataStorageManager mStorageManager; private Account mAccount; private ComponentsGetter mTransferServiceGetter; + private boolean mGridMode; private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM }; @@ -95,6 +97,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { // initialise thumbnails cache on background thread new ThumbnailsCacheManager.InitDiskCacheTask().execute(); + + mGridMode = false; } @Override @@ -134,8 +138,6 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { @Override public View getView(int position, View convertView, ViewGroup parent) { - boolean fileView = DisplayUtils.decideViewLayout(mFiles); - View view = convertView; OCFile file = null; LayoutInflater inflator = (LayoutInflater) mContext @@ -147,7 +149,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { // Find out which layout should be displayed ViewType viewType; - if (!fileView){ + if (!mGridMode){ viewType = ViewType.LIST_ITEM; } else if (file.isImage()){ viewType = ViewType.GRID_IMAGE; @@ -192,8 +194,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); if (!file.isFolder()) { - GridView parentList = (GridView)parent; - if (parentList.getChoiceMode() == GridView.CHOICE_MODE_NONE) { + AbsListView parentList = (AbsListView)parent; + if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) { checkBoxV.setVisibility(View.GONE); } else { if (parentList.isItemChecked(position)) { @@ -456,4 +458,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { return DisplayUtils.getRelativeDateTimeString(mContext, file.getModificationTimestamp(), DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0); } + + public void setGridMode(boolean gridMode) { + mGridMode = gridMode; + } } diff --git a/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java b/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java index 9982a96e..b61d3bf9 100644 --- a/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java @@ -121,7 +121,7 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter { lastModV.setVisibility(View.VISIBLE); lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.lastModified())); - GridViewWithHeaderAndFooter parentList = (GridViewWithHeaderAndFooter)parent; + ListView parentList = (ListView) parent; if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { checkBoxV.setVisibility(View.GONE); } else { diff --git a/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java b/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java index 76243edf..3e8a85f0 100644 --- a/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java +++ b/src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java @@ -76,7 +76,6 @@ public class SamlWebViewDialog extends SherlockDialogFragment { * @return New dialog instance, ready to show. */ public static SamlWebViewDialog newInstance(String url, String targetUrl) { - Log_OC.d(TAG, "New instance"); SamlWebViewDialog fragment = new SamlWebViewDialog(); Bundle args = new Bundle(); args.putString(ARG_INITIAL_URL, url); @@ -88,13 +87,12 @@ public class SamlWebViewDialog extends SherlockDialogFragment { public SamlWebViewDialog() { super(); - Log_OC.d(TAG, "constructor"); } @Override public void onAttach(Activity activity) { - Log_OC.d(TAG, "onAttach"); + Log_OC.v(TAG, "onAttach"); super.onAttach(activity); try { mSsoWebViewClientListener = (SsoWebViewClientListener) activity; @@ -110,7 +108,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @SuppressLint("SetJavaScriptEnabled") @Override public void onCreate(Bundle savedInstanceState) { - Log_OC.d(TAG, "onCreate, savedInstanceState is " + savedInstanceState); + Log_OC.v(TAG, "onCreate, savedInstanceState is " + savedInstanceState); super.onCreate(savedInstanceState); setRetainInstance(true); @@ -132,7 +130,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @SuppressLint("SetJavaScriptEnabled") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Log_OC.d(TAG, "onCreateView, savedInsanceState is " + savedInstanceState); + Log_OC.v(TAG, "onCreateView, savedInsanceState is " + savedInstanceState); // Inflate layout of the dialog RelativeLayout ssoRootView = (RelativeLayout) inflater.inflate(R.layout.sso_dialog, container, false); // null parent view because it will go in the dialog layout @@ -144,11 +142,6 @@ public class SamlWebViewDialog extends SherlockDialogFragment { mSsoWebView.setFocusableInTouchMode(true); mSsoWebView.setClickable(true); - CookieManager cookieManager = CookieManager.getInstance(); - cookieManager.setAcceptCookie(true); - cookieManager.removeAllCookie(); - mSsoWebView.loadUrl(mInitialUrl); - WebSettings webSettings = mSsoWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setBuiltInZoomControls(false); @@ -156,6 +149,12 @@ public class SamlWebViewDialog extends SherlockDialogFragment { webSettings.setSavePassword(false); webSettings.setUserAgentString(OwnCloudClient.USER_AGENT); webSettings.setSaveFormData(false); + + CookieManager cookieManager = CookieManager.getInstance(); + cookieManager.setAcceptCookie(true); + cookieManager.removeAllCookie(); + + mSsoWebView.loadUrl(mInitialUrl); } mWebViewClient.setTargetUrl(mTargetUrl); @@ -174,7 +173,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @Override public void onSaveInstanceState(Bundle outState) { - Log_OC.d(TAG, "onSaveInstanceState being CALLED"); + Log_OC.v(TAG, "onSaveInstanceState being CALLED"); super.onSaveInstanceState(outState); // save URLs @@ -184,7 +183,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @Override public void onDestroyView() { - Log_OC.d(TAG, "onDestroyView"); + Log_OC.v(TAG, "onDestroyView"); if ((ViewGroup)mSsoWebView.getParent() != null) { ((ViewGroup)mSsoWebView.getParent()).removeView(mSsoWebView); @@ -196,8 +195,6 @@ public class SamlWebViewDialog extends SherlockDialogFragment { Dialog dialog = getDialog(); if ((dialog != null)) { dialog.setOnDismissListener(null); - //dialog.dismiss(); - //dialog.setDismissMessage(null); } super.onDestroyView(); @@ -205,13 +202,13 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @Override public void onDestroy() { - Log_OC.d(TAG, "onDestroy"); + Log_OC.v(TAG, "onDestroy"); super.onDestroy(); } @Override public void onDetach() { - Log_OC.d(TAG, "onDetach"); + Log_OC.v(TAG, "onDetach"); mSsoWebViewClientListener = null; mWebViewClient = null; super.onDetach(); @@ -231,39 +228,39 @@ public class SamlWebViewDialog extends SherlockDialogFragment { @Override public void onStart() { - Log_OC.d(TAG, "onStart"); + Log_OC.v(TAG, "onStart"); super.onStart(); } @Override public void onStop() { - Log_OC.d(TAG, "onStop"); + Log_OC.v(TAG, "onStop"); super.onStop(); } @Override public void onResume() { - Log_OC.d(TAG, "onResume"); + Log_OC.v(TAG, "onResume"); super.onResume(); mSsoWebView.onResume(); } @Override public void onPause() { - Log_OC.d(TAG, "onPause"); + Log_OC.v(TAG, "onPause"); mSsoWebView.onPause(); super.onPause(); } @Override public int show (FragmentTransaction transaction, String tag) { - Log_OC.d(TAG, "show (transaction)"); + Log_OC.v(TAG, "show (transaction)"); return super.show(transaction, tag); } @Override public void show (FragmentManager manager, String tag) { - Log_OC.d(TAG, "show (manager)"); + Log_OC.v(TAG, "show (manager)"); super.show(manager, tag); } diff --git a/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java b/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java index 8aefec01..8b014af2 100644 --- a/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java +++ b/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java @@ -1,6 +1,6 @@ /* ownCloud Android client application * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2012-2013 ownCloud Inc. + * Copyright (C) 2012-2015 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -20,11 +20,13 @@ package com.owncloud.android.ui.fragment; import java.util.ArrayList; +import android.content.Context; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; @@ -34,8 +36,11 @@ import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragment; import com.owncloud.android.R; import com.owncloud.android.lib.common.utils.Log_OC; -import third_parties.in.srain.cube.GridViewWithHeaderAndFooter; +import com.owncloud.android.ui.ExtendedListView; import com.owncloud.android.ui.activity.OnEnforceableRefreshListener; +import com.owncloud.android.ui.adapter.FileListListAdapter; + +import third_parties.in.srain.cube.GridViewWithHeaderAndFooter; /** * TODO extending SherlockListFragment instead of SherlockFragment @@ -52,7 +57,8 @@ implements OnItemClickListener, OnEnforceableRefreshListener { private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL"; private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE"; - private SwipeRefreshLayout mRefreshLayout; + private SwipeRefreshLayout mRefreshListLayout; + private SwipeRefreshLayout mRefreshGridLayout; private SwipeRefreshLayout mRefreshEmptyLayout; private TextView mEmptyListMessage; @@ -64,67 +70,99 @@ implements OnItemClickListener, OnEnforceableRefreshListener { private OnEnforceableRefreshListener mOnRefreshListener = null; - protected GridViewWithHeaderAndFooter imageView; - - public void setListAdapter(ListAdapter listAdapter) { - imageView.setAdapter(listAdapter); - imageView.invalidate(); - } + protected AbsListView mCurrentListView; + private ExtendedListView mListView; + private View mListFooterView; + private GridViewWithHeaderAndFooter mGridView; + private View mGridFooterView; - public GridView getGridView() { - return imageView; - } + private ListAdapter mAdapter; - public void setFooterView(View footer) { - imageView.addFooterView(footer, null, false); - imageView.invalidate(); - } - public void removeFooterView(View footer) { - imageView.removeFooterView(footer); - imageView.invalidate(); + protected void setListAdapter(ListAdapter listAdapter) { + mAdapter = listAdapter; + mCurrentListView.setAdapter(listAdapter); + mCurrentListView.invalidate(); } - public int getFooterViewCount() { - return imageView.getFooterViewCount(); + protected AbsListView getListView() { + return mCurrentListView; } - - protected void switchImageView(){ - imageView.setNumColumns(GridView.AUTO_FIT); - imageView.invalidateRowHeight(); // Force to recalculate mRowHeight of imageView - imageView.invalidate(); + + + protected void switchToGridView() { + if ((mCurrentListView == mListView)) { + + mListView.setAdapter(null); + mRefreshListLayout.setVisibility(View.GONE); + + if (mAdapter instanceof FileListListAdapter) { + ((FileListListAdapter) mAdapter).setGridMode(true); + } + mGridView.setAdapter(mAdapter); + mRefreshGridLayout.setVisibility(View.VISIBLE); + + mCurrentListView = mGridView; + } } - protected void switchFileView(){ - imageView.setNumColumns(1); - imageView.invalidate(); + protected void switchToListView() { + if (mCurrentListView == mGridView) { + mGridView.setAdapter(null); + mRefreshGridLayout.setVisibility(View.GONE); + + if (mAdapter instanceof FileListListAdapter) { + ((FileListListAdapter) mAdapter).setGridMode(false); + } + mListView.setAdapter(mAdapter); + mRefreshListLayout.setVisibility(View.VISIBLE); + + mCurrentListView = mListView; + } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Log_OC.e(TAG, "onCreateView"); + Log_OC.d(TAG, "onCreateView"); View v = inflater.inflate(R.layout.list_fragment, null); - - imageView = (GridViewWithHeaderAndFooter)(v.findViewById(R.id.list_root)); - imageView.setOnItemClickListener(this); + + mListView = (ExtendedListView)(v.findViewById(R.id.list_root)); + mListView.setOnItemClickListener(this); + mListFooterView = inflater.inflate(R.layout.list_footer, null, false); + + mGridView = (GridViewWithHeaderAndFooter) (v.findViewById(R.id.grid_root)); + mGridView.setNumColumns(GridView.AUTO_FIT); + mGridView.setOnItemClickListener(this); + mGridFooterView = inflater.inflate(R.layout.list_footer, null, false); if (savedInstanceState != null) { int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION); - setReferencePosition(referencePosition); + if (mCurrentListView == mListView) { + Log_OC.v(TAG, "Setting and centering around list position " + referencePosition); + mListView.setAndCenterSelection(referencePosition); + } else { + Log_OC.v(TAG, "Setting grid position " + referencePosition); + mGridView.setSelection(referencePosition); + } } - // Pull down refresh - mRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files); - mRefreshEmptyLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files_emptyView); + // Pull-down to refresh layout + mRefreshListLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_list); + mRefreshGridLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_grid); + mRefreshEmptyLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_empty); mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view); - onCreateSwipeToRefresh(mRefreshLayout); + onCreateSwipeToRefresh(mRefreshListLayout); + onCreateSwipeToRefresh(mRefreshGridLayout); onCreateSwipeToRefresh(mRefreshEmptyLayout); - imageView.setEmptyView(mRefreshEmptyLayout); - + mListView.setEmptyView(mRefreshEmptyLayout); + mGridView.setEmptyView(mRefreshEmptyLayout); + + mCurrentListView = mListView; // list as default + return v; } @@ -154,7 +192,7 @@ implements OnItemClickListener, OnEnforceableRefreshListener { @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); - Log_OC.e(TAG, "onSaveInstanceState()"); + Log_OC.d(TAG, "onSaveInstanceState()"); savedInstanceState.putInt(KEY_SAVED_LIST_POSITION, getReferencePosition()); savedInstanceState.putIntegerArrayList(KEY_INDEXES, mIndexes); savedInstanceState.putIntegerArrayList(KEY_FIRST_POSITIONS, mFirstPositions); @@ -168,32 +206,20 @@ implements OnItemClickListener, OnEnforceableRefreshListener { * reposition the visible items in the list when the device is turned to * other position. * - * THe current policy is take as a reference the visible item in the center + * The current policy is take as a reference the visible item in the center * of the screen. * * @return The position in the list of the visible item in the center of the * screen. */ protected int getReferencePosition() { - if (imageView != null) { - return (imageView.getFirstVisiblePosition() + imageView.getLastVisiblePosition()) / 2; + if (mCurrentListView != null) { + return (mCurrentListView.getFirstVisiblePosition() + mCurrentListView.getLastVisiblePosition()) / 2; } else { return 0; } } - /** - * Sets the visible part of the list from the reference position. - * - * @param position Reference position previously returned by - * {@link LocalFileListFragment#getReferencePosition()} - */ - protected void setReferencePosition(int position) { - if (imageView != null) { - imageView.setSelection(position); - } - } - /* * Restore index and position @@ -203,20 +229,28 @@ implements OnItemClickListener, OnEnforceableRefreshListener { // needs to be checked; not every browse-up had a browse-down before int index = mIndexes.remove(mIndexes.size() - 1); - - int firstPosition = mFirstPositions.remove(mFirstPositions.size() -1); - + final int firstPosition = mFirstPositions.remove(mFirstPositions.size() -1); int top = mTops.remove(mTops.size() - 1); - - imageView.smoothScrollToPosition(firstPosition); - - // Move the scroll if the selection is not visible - int indexPosition = mHeightCell*index; - int height = imageView.getHeight(); - - if (indexPosition > height) { - imageView.smoothScrollToPosition(index); + + Log_OC.v(TAG, "Setting selection to position: " + firstPosition + "; top: " + top + "; index: " + index); + + if (mCurrentListView == mListView) { + if (mHeightCell*index <= mListView.getHeight()) { + mListView.setSelectionFromTop(firstPosition, top); + } else { + mListView.setSelectionFromTop(index, 0); + } + + } else { + if (mHeightCell*index <= mGridView.getHeight()) { + mGridView.setSelection(firstPosition); + //mGridView.smoothScrollToPosition(firstPosition); + } else { + mGridView.setSelection(index); + //mGridView.smoothScrollToPosition(index); + } } + } } @@ -227,10 +261,10 @@ implements OnItemClickListener, OnEnforceableRefreshListener { mIndexes.add(index); - int firstPosition = imageView.getFirstVisiblePosition(); + int firstPosition = mCurrentListView.getFirstVisiblePosition(); mFirstPositions.add(firstPosition); - View view = imageView.getChildAt(0); + View view = mCurrentListView.getChildAt(0); int top = (view == null) ? 0 : view.getTop() ; mTops.add(top); @@ -247,10 +281,10 @@ implements OnItemClickListener, OnEnforceableRefreshListener { @Override public void onRefresh() { - // to be @overriden - mRefreshLayout.setRefreshing(false); + mRefreshListLayout.setRefreshing(false); + mRefreshGridLayout.setRefreshing(false); mRefreshEmptyLayout.setRefreshing(false); - + if (mOnRefreshListener != null) { mOnRefreshListener.onRefresh(); } @@ -261,32 +295,18 @@ implements OnItemClickListener, OnEnforceableRefreshListener { /** - * Enables swipe gesture + * Disables swipe gesture. + * + * Sets the 'enabled' state of the refresh layouts contained in the fragment. + * + * When 'false' is set, prevents user gestures but keeps the option to refresh programatically, + * + * @param enabled Desired state for capturing swipe gesture. */ - public void enableSwipe() { - mRefreshLayout.setEnabled(true); - } - - /** - * Disables swipe gesture. It prevents manual gestures but keeps the option you show - * refreshing programmatically. - */ - public void disableSwipe() { - mRefreshLayout.setEnabled(false); - } - - /** - * It shows the SwipeRefreshLayout progress - */ - public void showSwipeProgress() { - mRefreshLayout.setRefreshing(true); - } - - /** - * It shows the SwipeRefreshLayout progress - */ - public void hideSwipeProgress() { - mRefreshLayout.setRefreshing(false); + public void setSwipeEnabled(boolean enabled) { + mRefreshListLayout.setEnabled(enabled); + mRefreshGridLayout.setEnabled(enabled); + mRefreshEmptyLayout.setEnabled(enabled); } /** @@ -317,11 +337,71 @@ implements OnItemClickListener, OnEnforceableRefreshListener { @Override public void onRefresh(boolean ignoreETag) { - mRefreshLayout.setRefreshing(false); + mRefreshListLayout.setRefreshing(false); + mRefreshGridLayout.setRefreshing(false); mRefreshEmptyLayout.setRefreshing(false); if (mOnRefreshListener != null) { mOnRefreshListener.onRefresh(ignoreETag); } } + + + protected void setChoiceMode(int choiceMode) { + mListView.setChoiceMode(choiceMode); + mGridView.setChoiceMode(choiceMode); + } + + protected void registerForContextMenu() { + registerForContextMenu(mListView); + registerForContextMenu(mGridView); + mListView.setOnCreateContextMenuListener(this); + mGridView.setOnCreateContextMenuListener(this); + } + + /** + * TODO doc + * To be called before setAdapter, or GridViewWithHeaderAndFooter will throw an exception + * + * @param enabled + */ + protected void setFooterEnabled(boolean enabled) { + if (enabled) { + if (mGridView.getFooterViewCount() == 0) { + if (mGridFooterView.getParent() != null ) { + ((ViewGroup) mGridFooterView.getParent()).removeView(mGridFooterView); + } + mGridView.addFooterView(mGridFooterView, null, false); + } + mGridFooterView.invalidate(); + + if (mListView.getFooterViewsCount() == 0) { + if (mListFooterView.getParent() != null ) { + ((ViewGroup) mListFooterView.getParent()).removeView(mListFooterView); + } + mListView.addFooterView(mListFooterView, null, false); + } + mListFooterView.invalidate(); + + } else { + mGridView.removeFooterView(mGridFooterView); + mListView.removeFooterView(mListFooterView); + } + } + + /** + * TODO doc + * @param text + */ + protected void setFooterText(String text) { + if (text != null && text.length() > 0) { + ((TextView)mListFooterView.findViewById(R.id.footerText)).setText(text); + ((TextView)mGridFooterView.findViewById(R.id.footerText)).setText(text); + setFooterEnabled(true); + + } else { + setFooterEnabled(false); + } + } + } diff --git a/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java b/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java index a20cc3c0..f8920c86 100644 --- a/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java @@ -76,12 +76,12 @@ public class LocalFileListFragment extends ExtendedListFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log_OC.i(TAG, "onCreateView() start"); View v = super.onCreateView(inflater, container, savedInstanceState); - getGridView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - disableSwipe(); // Disable pull refresh + setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); + setSwipeEnabled(false); // Disable pull-to-refresh setMessageForEmptyList(getString(R.string.local_file_list_empty)); Log_OC.i(TAG, "onCreateView() end"); return v; - } + } /** @@ -117,7 +117,7 @@ public class LocalFileListFragment extends ExtendedListFragment { } else { /// Click on a file ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox); if (checkBoxV != null) { - if (getGridView().isItemChecked(position)) { + if (getListView().isItemChecked(position)) { checkBoxV.setImageResource(android.R.drawable.checkbox_on_background); } else { checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); @@ -194,10 +194,10 @@ public class LocalFileListFragment extends ExtendedListFragment { directory = directory.getParentFile(); } - imageView.clearChoices(); // by now, only files in the same directory will be kept as selected + mCurrentListView.clearChoices(); // by now, only files in the same directory will be kept as selected mAdapter.swapDirectory(directory); if (mDirectory == null || !mDirectory.equals(directory)) { - imageView.setSelection(0); + mCurrentListView.setSelection(0); } mDirectory = directory; } @@ -210,11 +210,11 @@ public class LocalFileListFragment extends ExtendedListFragment { */ public String[] getCheckedFilePaths() { ArrayList result = new ArrayList(); - SparseBooleanArray positions = imageView.getCheckedItemPositions(); + SparseBooleanArray positions = mCurrentListView.getCheckedItemPositions(); if (positions.size() > 0) { for (int i = 0; i < positions.size(); i++) { if (positions.get(positions.keyAt(i)) == true) { - result.add(((File) imageView.getItemAtPosition(positions.keyAt(i))).getAbsolutePath()); + result.add(((File) mCurrentListView.getItemAtPosition(positions.keyAt(i))).getAbsolutePath()); } } @@ -234,7 +234,7 @@ public class LocalFileListFragment extends ExtendedListFragment { /** * Callback method invoked when a directory is clicked by the user on the files list * - * @param file + * @param directory */ public void onDirectoryClick(File directory); diff --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 5386ac8c..3b626b6e 100644 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -18,10 +18,8 @@ package com.owncloud.android.ui.fragment; import java.io.File; -import java.util.Vector; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; @@ -29,11 +27,8 @@ import android.view.ContextMenu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.TextView; -import android.view.LayoutInflater; import com.owncloud.android.R; import com.owncloud.android.datamodel.FileDataStorageManager; @@ -49,7 +44,6 @@ import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; -import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.FileStorageUtils; /** @@ -73,11 +67,13 @@ public class OCFileListFragment extends ExtendedListFragment { private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; + private final static Double THUMBNAIL_THRESHOLD = 0.5; + private FileFragment.ContainerActivity mContainerActivity; private OCFile mFile = null; private FileListListAdapter mAdapter; - private View mFooterView; + private boolean mJustFolders; private OCFile mTargetFile; @@ -125,23 +121,24 @@ public class OCFileListFragment extends ExtendedListFragment { mFile = savedInstanceState.getParcelable(KEY_FILE); } - mFooterView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate( - R.layout.list_footer, null, false); - setFooterView(mFooterView); + if (mJustFolders) { + setFooterEnabled(false); + } else { + setFooterEnabled(true); + } Bundle args = getArguments(); - boolean justFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false); + mJustFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false); mAdapter = new FileListListAdapter( - justFolders, + mJustFolders, getSherlockActivity(), mContainerActivity ); setListAdapter(mAdapter); - - registerForContextMenu(getGridView()); - getGridView().setOnCreateContextMenuListener(this); + + registerForContextMenu(); } - + /** * Saves the current listed folder. */ @@ -391,69 +388,65 @@ public class OCFileListFragment extends ExtendedListFragment { mAdapter.swapDirectory(directory, storageManager); if (mFile == null || !mFile.equals(directory)) { - imageView.setSelection(0); + mCurrentListView.setSelection(0); } mFile = directory; - Vector files = storageManager.getFolderContent(directory); - // Update Footer - TextView footerText = (TextView) mFooterView.findViewById(R.id.footerText); - footerText.setText(generateFooterText(directory)); - if (DisplayUtils.decideViewLayout(files)){ - switchImageView(); - } else { - switchFileView(); - } + updateLayout(); + } } - - private String generateFooterText(OCFile directory) { - Integer files = 0; - Integer folders = 0; - FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); - Vector mFiles = storageManager.getFolderContent(mFile); + private void updateLayout() { + if (!mJustFolders) { + int filesCount = 0, foldersCount = 0, imagesCount = 0; + int count = mAdapter.getCount(); + OCFile file; + for (int i=0; i < count ; i++) { + file = (OCFile) mAdapter.getItem(i); + if (file.isFolder()) { + foldersCount++; + } else { + filesCount++; + if (file.isImage()){ + imagesCount++; + } + } + } + // set footer text + setFooterText(generateFooterText(filesCount, foldersCount)); - for (OCFile ocFile : mFiles) { - if (ocFile.isFolder()) { - folders++; + // decide grid vs list view + if (((double)imagesCount / (double)filesCount) >= THUMBNAIL_THRESHOLD) { + switchToGridView(); } else { - files++; + switchToListView(); } } + } + private String generateFooterText(int filesCount, int foldersCount) { String output = ""; - - if (files > 0){ - if (files == 1) { - output = output + files.toString() + " " + getResources().getString(R.string.file_list_file); + if (filesCount > 0){ + if (filesCount == 1) { + output = output + filesCount + " " + getResources().getString(R.string.file_list_file); } else { - output = output + files.toString() + " " + getResources().getString(R.string.file_list_files); + output = output + filesCount + " " + getResources().getString(R.string.file_list_files); } } - if (folders > 0 && files > 0){ + if (foldersCount > 0 && filesCount > 0){ output = output + ", "; } - if (folders == 1) { - output = output + folders.toString() + " " + getResources().getString(R.string.file_list_folder); - } else if (folders > 1) { - output = output + folders.toString() + " " + getResources().getString(R.string.file_list_folders); + if (foldersCount == 1) { + output = output + foldersCount + " " + getResources().getString(R.string.file_list_folder); + } else if (foldersCount > 1) { + output = output + foldersCount + " " + getResources().getString(R.string.file_list_folders); } - // Fix for showing or not to show the footerView - if (folders == 0 && files == 0) { // If no files or folders, remove footerView for allowing - // to show the emptyList message - removeFooterView(mFooterView); - } else { // set a new footerView if there is not one for showing the number or files/folders - if (getFooterViewCount()== 0) { - ((ViewGroup)mFooterView.getParent()).removeView(mFooterView); - setFooterView(mFooterView); - } - } - return output; } - + + public void sortByName(boolean descending) { mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending); } diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index e22b6de8..999700f1 100644 --- a/src/com/owncloud/android/utils/DisplayUtils.java +++ b/src/com/owncloud/android/utils/DisplayUtils.java @@ -52,8 +52,6 @@ public class DisplayUtils { private static final String[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; - private final static Double THUMBNAIL_THRESHOLD = 0.5; - private static HashMap mimeType2HUmanReadable; static { mimeType2HUmanReadable = new HashMap(); @@ -344,30 +342,4 @@ public class DisplayUtils { return path; } - /** - * - * @param mFiles - * @return true: imageView, false: listView - */ - public static boolean decideViewLayout(Vector mFiles){ - // decide image vs. file view - double countImages = 0; - double countFiles = 0; - - for (OCFile file : mFiles){ - if (!file.isFolder()){ - countFiles++; - - if (file.isImage()){ - countImages++; - } - } - } - - if ((countImages / countFiles) >= THUMBNAIL_THRESHOLD){ - return true; - } else { - return false; - } - } } diff --git a/src/third_parties/in/srain/cube/GridViewWithHeaderAndFooter.java b/src/third_parties/in/srain/cube/GridViewWithHeaderAndFooter.java index 013181b5..508380a6 100644 --- a/src/third_parties/in/srain/cube/GridViewWithHeaderAndFooter.java +++ b/src/third_parties/in/srain/cube/GridViewWithHeaderAndFooter.java @@ -17,22 +17,28 @@ package third_parties.in.srain.cube; - import android.annotation.TargetApi; - import android.content.Context; - import android.database.DataSetObservable; - import android.database.DataSetObserver; - import android.os.Build; - import android.util.AttributeSet; - import android.util.Log; - import android.view.View; - import android.view.ViewGroup; - import android.widget.*; - - import java.lang.reflect.Field; - import java.util.ArrayList; +import android.annotation.TargetApi; +import android.content.Context; +import android.database.DataSetObservable; +import android.database.DataSetObserver; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.FrameLayout; +import android.widget.GridView; +import android.widget.ListAdapter; +import android.widget.WrapperListAdapter; + +import java.lang.reflect.Field; +import java.util.ArrayList; /** - * A {@link GridView} that supports adding header rows in a + * A {@link android.widget.GridView} that supports adding header rows in a * very similar way to {@link android.widget.ListView}. * See {@link GridViewWithHeaderAndFooter#addHeaderView(View, Object, boolean)} * See {@link GridViewWithHeaderAndFooter#addFooterView(View, Object, boolean)} @@ -52,7 +58,7 @@ public class GridViewWithHeaderAndFooter extends GridView { public View view; public ViewGroup viewContainer; /** - * The data backing the view. This is returned from {@link ListAdapter#getItem(int)}. + * The data backing the view. This is returned from {@link android.widget.ListAdapter#getItem(int)}. */ public Object data; /** @@ -151,7 +157,7 @@ public class GridViewWithHeaderAndFooter extends GridView { if (lyp != null) { v.setLayoutParams(new FrameLayout.LayoutParams(lyp.width, lyp.height)); - fl.setLayoutParams(new AbsListView.LayoutParams(lyp.width, lyp.height)); + fl.setLayoutParams(new LayoutParams(lyp.width, lyp.height)); } fl.addView(v); info.view = v; @@ -184,7 +190,7 @@ public class GridViewWithHeaderAndFooter extends GridView { if (lyp != null) { v.setLayoutParams(new FrameLayout.LayoutParams(lyp.width, lyp.height)); - fl.setLayoutParams(new AbsListView.LayoutParams(lyp.width, lyp.height)); + fl.setLayoutParams(new LayoutParams(lyp.width, lyp.height)); } fl.addView(v); info.view = v; @@ -315,9 +321,9 @@ public class GridViewWithHeaderAndFooter extends GridView { } int mColumnWidth = getColumnWidthCompatible(); View view = getAdapter().getView(numColumns * mHeaderViewInfos.size(), mViewForMeasureRowHeight, this); - AbsListView.LayoutParams p = (AbsListView.LayoutParams) view.getLayoutParams(); + LayoutParams p = (LayoutParams) view.getLayoutParams(); if (p == null) { - p = new AbsListView.LayoutParams(-1, -2, 0); + p = new LayoutParams(-1, -2, 0); view.setLayoutParams(p); } int childHeightSpec = getChildMeasureSpec( @@ -784,4 +790,52 @@ public class GridViewWithHeaderAndFooter extends GridView { mDataSetObservable.notifyChanged(); } } + + + /** + * Sets the selected item and positions the selection y pixels from the top edge of the ListView. + * (If in touch mode, the item will not be selected but it will still be positioned appropriately.) + * + * @param position Index (starting at 0) of the data item to be selected. + * @param y The distance from the top edge of the ListView (plus padding) + * that the item will be positioned. + * + * @see Original code + */ + public void setSelectionFromTop(int position, int y) { + if (getAdapter() == null) { + return; + } + + setSelection(position); + //setSelectionInt(position); + + /*if (!isInTouchMode()) { + position = super.lookForSelectablePosition(position, true); + if (position >= 0) { + setNextSelectedPositionInt(position); + } + } else { + mResurrectToPosition = position; + }*/ + + /* + if (position >= 0) { + mLayoutMode = LAYOUT_SPECIFIC; + mSpecificTop = mListPadding.top + y; + + if (mNeedSync) { + mSyncPosition = position; + mSyncRowId = getAdapter().getItemId(position); + } + + if (mPositionScroller != null) { + mPositionScroller.stop(); + } + + requestLayout(); + } + */ + } + }