1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   4  *   This program is free software: you can redistribute it and/or modify 
   5  *   it under the terms of the GNU General Public License as published by 
   6  *   the Free Software Foundation, either version 3 of the License, or 
   7  *   (at your option) any later version. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19 package eu
.alefzero
.owncloud
.ui
; 
  22 import java
.io
.FileInputStream
; 
  23 import java
.io
.FileNotFoundException
; 
  24 import java
.io
.IOException
; 
  25 import java
.util
.LinkedList
; 
  26 import java
.util
.Stack
; 
  28 import android
.accounts
.Account
; 
  29 import android
.accounts
.AccountManager
; 
  30 import android
.app
.AlertDialog
; 
  31 import android
.app
.Dialog
; 
  32 import android
.app
.ListActivity
; 
  33 import android
.content
.DialogInterface
; 
  34 import android
.content
.Intent
; 
  35 import android
.content
.DialogInterface
.OnCancelListener
; 
  36 import android
.content
.res
.Configuration
; 
  37 import android
.database
.Cursor
; 
  38 import android
.graphics
.Bitmap
; 
  39 import android
.graphics
.BitmapFactory
; 
  40 import android
.graphics
.Matrix
; 
  41 import android
.net
.Uri
; 
  42 import android
.os
.Bundle
; 
  43 import android
.os
.Environment
; 
  44 import android
.support
.v4
.app
.FragmentActivity
; 
  45 import android
.support
.v4
.app
.FragmentTransaction
; 
  46 import android
.text
.TextUtils
; 
  47 import android
.util
.Log
; 
  48 import android
.view
.Menu
; 
  49 import android
.view
.MenuInflater
; 
  50 import android
.view
.MenuItem
; 
  51 import android
.view
.View
; 
  52 import android
.view
.Window
; 
  53 import android
.widget
.ImageView
; 
  54 import android
.widget
.ListView
; 
  55 import android
.widget
.TextView
; 
  56 import eu
.alefzero
.owncloud
.DbHandler
; 
  57 import eu
.alefzero
.owncloud
.R
; 
  58 import eu
.alefzero
.owncloud
.R
.id
; 
  59 import eu
.alefzero
.owncloud
.R
.layout
; 
  60 import eu
.alefzero
.owncloud
.R
.menu
; 
  61 import eu
.alefzero
.owncloud
.R
.string
; 
  62 import eu
.alefzero
.owncloud
.authenticator
.AccountAuthenticator
; 
  63 import eu
.alefzero
.owncloud
.db
.ProviderMeta
.ProviderTableMeta
; 
  64 import eu
.alefzero
.owncloud
.ui
.fragment
.FileDetail
; 
  65 import eu
.alefzero
.owncloud
.ui
.fragment
.FileList
; 
  66 import eu
.alefzero
.owncloud
.ui
.fragment
.ActionBar
; 
  67 public class FileDisplayActivity 
extends FragmentActivity 
{ 
  68   private DbHandler mDBHandler
; 
  69   private Stack
<String
> mParents
; 
  70   private LinkedList
<String
> mPath
; 
  71   private Account mAccount
; 
  72   private Cursor mCursor
; 
  73   private boolean mIsDisplayingFile
; 
  75   private static final int DIALOG_CHOOSE_ACCOUNT 
= 0; 
  78   public void onCreate(Bundle savedInstanceState
) { 
  79     super.onCreate(savedInstanceState
); 
  80     getWindow().requestFeature(Window
.FEATURE_NO_TITLE
); 
  81     setContentView(R
.layout
.files
); 
  83     FragmentTransaction ft 
= getSupportFragmentManager().beginTransaction(); 
  84     //ft.add(R.id.actionBar, new ActionBar()); 
  85     ft
.add(R
.id
.fileList
, new FileList()); 
  86     if (getResources().getConfiguration().orientation 
== Configuration
.ORIENTATION_LANDSCAPE
) { 
  87       ft
.add(R
.id
.fileDetail
, new FileDetail()); 
  91     /*getSupportFragmentManager().beginTransaction().add(arg0, arg1); 
  92     FileList fl = new FileList(); 
  93     ft.add(R.id.fileList, fl); 
  98     if (savedInstanceState != null) { 
  99       mParents = (Stack<String>)savedInstanceState.getSerializable("parentsStack"); 
 100       mIsDisplayingFile = savedInstanceState.getBoolean("isDisplayingFile"); 
 101       mPath = (LinkedList<String>)savedInstanceState.getSerializable("path"); 
 103       mParents = new Stack<String>(); 
 104       mPath = new LinkedList<String>(); 
 105       mIsDisplayingFile = false; 
 108     mDBHandler = new DbHandler(getBaseContext()); 
 109     requestWindowFeature(Window.FEATURE_NO_TITLE); 
 110     setContentView(R.layout.main); 
 112     AccountManager accMan = AccountManager.get(this); 
 113     Account[] accounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); 
 115     if (accounts.length == 0) { 
 116       // using string value since in API7 this constatn is not defined 
 117       // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS 
 118       // and Settings.EXTRA_AUTHORITIES 
 119       Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS"); 
 120       intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE}); 
 121       startActivity(intent); 
 122     } else if (accounts.length > 1) { 
 123       showDialog(DIALOG_CHOOSE_ACCOUNT); 
 125       mAccount = accounts[0]; 
 131   public boolean onOptionsItemSelected(MenuItem item
) { 
 132     switch (item
.getItemId()) { 
 133       case R
.id
.settingsItem 
: 
 134         Intent i 
= new Intent(this, Preferences
.class); 
 142   protected Dialog 
onCreateDialog(int id
) { 
 144       case DIALOG_CHOOSE_ACCOUNT
: 
 145         return createChooseAccountDialog(); 
 147         throw new IllegalArgumentException("Unknown dialog id: " + id
); 
 152   public boolean onCreateOptionsMenu(Menu menu
) { 
 153     MenuInflater inflater 
= getMenuInflater(); 
 154     inflater
.inflate(R
.menu
.menu
, menu
); 
 158   private Dialog 
createChooseAccountDialog() { 
 159     final AccountManager accMan 
= AccountManager
.get(this); 
 160     CharSequence
[] items 
= new CharSequence
[accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
).length
]; 
 162     for (Account a 
: accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
)) { 
 166     AlertDialog
.Builder builder 
= new AlertDialog
.Builder(this); 
 167     builder
.setTitle(R
.string
.common_choose_account
); 
 168     builder
.setCancelable(true
); 
 169     builder
.setItems(items
, new DialogInterface
.OnClickListener() { 
 170         public void onClick(DialogInterface dialog
, int item
) { 
 171             mAccount 
= accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
)[item
]; 
 176     builder
.setOnCancelListener(new OnCancelListener() { 
 177       public void onCancel(DialogInterface dialog
) { 
 178         FileDisplayActivity
.this.finish(); 
 181     AlertDialog alert 
= builder
.create(); 
 186   //public void onBackPressed() { 
 187     /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1); 
 188     if (mIsDisplayingFile) { 
 189       mIsDisplayingFile = false; 
 190       setContentView(R.layout.main); 
 191       pl = (PathLayout) findViewById(R.id.pathLayout1); 
 193       if (mParents.empty()) { 
 194         uri = ProviderTableMeta.CONTENT_URI; 
 196         uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()); 
 198       mCursor = managedQuery(uri, 
 200                              ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", 
 201                              new String[]{mAccount.name}, null); 
 203       if (mCursor.moveToFirst()) { 
 204         String s = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)); 
 205         for (String str : s.split("/")) { 
 206           if (!TextUtils.isEmpty(str)) 
 207             pl.push(DisplayUtils.HtmlDecode(str)); 
 210       getListView().setAdapter(new FileListListAdapter(mCursor, this));       
 211       getListView().invalidate(); 
 214     if (mParents.size()==0) { 
 215       super.onBackPressed(); 
 217     } else if (mParents.size() == 1) { 
 221       mCursor = managedQuery(ProviderTableMeta.CONTENT_URI, 
 223           ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", 
 224           new String[]{mAccount.name}, 
 230       mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()), 
 232           ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", 
 233           new String[]{mAccount.name}, 
 237     setListAdapter(new FileListListAdapter(mCursor, this)); 
 238     getListView().invalidate();*/ 
 242 /*  protected void onListItemClick(ListView l, View v, int position, long id) { 
 243     super.onListItemClick(l, v, position, id); 
 244     /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1); 
 245     if (!mCursor.moveToPosition(position)) { 
 246       throw new IndexOutOfBoundsException("Incorrect item selected"); 
 248     if (!mIsDisplayingFile) { 
 249       if (mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) { 
 250         String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)); 
 251         String dirname = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)); 
 252         pl.push(DisplayUtils.HtmlDecode(dirname)); 
 253         mPath.addLast(DisplayUtils.HtmlDecode(dirname)); 
 255         mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, id_), 
 257                                ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", 
 258                                new String[]{mAccount.name}, null); 
 259         setListAdapter(new FileListListAdapter(mCursor, this)); 
 261         mIsDisplayingFile = true; 
 262         setContentView(R.layout.file_display); 
 263         String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)); 
 264         mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, id_), 
 269         mCursor.moveToFirst(); 
 271         TextView tv = (TextView) findViewById(R.id.textView1); 
 272         tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME))); 
 274         tv = (TextView) findViewById(R.id.textView2); 
 275         tv.setText(DisplayUtils.convertMIMEtoPrettyPrint(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)))); 
 277         tv = (TextView) findViewById(R.id.textView3); 
 278         tv.setText(DisplayUtils.bitsToHumanReadable(mCursor.getLong(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)))); 
 280         tv = (TextView) findViewById(R.id.textView4); 
 281         tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_MODIFIED))); 
 282         if (!TextUtils.isEmpty(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH))) && 
 283             mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).matches("image/*")) { 
 284           ImageView iv = (ImageView) findViewById(R.id.imageView1); 
 285           Bitmap bmp = BitmapFactory.decodeFile(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH))); 
 286           Matrix m = new Matrix(); 
 288           if (bmp.getWidth() > bmp.getHeight()) { 
 289             scale = (float) (200./bmp.getWidth()); 
 291             scale = (float) (200./bmp.getHeight()); 
 293           m.postScale(scale, scale); 
 294           Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true); 
 295           iv.setImageBitmap(newBmp); 
 297         setListAdapter(new FileListActionListAdapter(mCursor, this, mAccount)); 
 299       getListView().invalidate(); 
 301         Intent i = (Intent) getListAdapter().getItem(position); 
 302         if (i.hasExtra("toDownload")) { 
 304           Intent intent = new Intent(this, FileDownloader.class); 
 305           intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/"+((TextView)findViewById(R.id.textView1)).getText().toString()); 
 306           intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount); 
 307           startService(intent); 
 309           if (i.getBooleanExtra("toDownload", false)) { 
 310             startActivityForResult(i, 200); 
 319   private void populateFileList() { 
 320     if (mParents
.empty()) { 
 321       mCursor 
= getContentResolver().query(ProviderTableMeta
.CONTENT_URI
, 
 323                                            ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?", 
 324                                            new String
[]{mAccount
.name
}, 
 327       mCursor 
= getContentResolver().query(Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, mParents
.peek()), 
 329                                            ProviderTableMeta
.FILE_ACCOUNT_OWNER 
+ "=?", 
 330                                            new String
[]{mAccount
.name
}, null
); 
 331       if (!mIsDisplayingFile
) { 
 332         //PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1); 
 333         //for (String s : mPath) { 
 338 //    setListAdapter(new FileListListAdapter(mCursor, this)); 
 339 //    getListView().invalidate(); 
 343   /*protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
 344     super.onActivityResult(requestCode, resultCode, data); 
 348   protected void onSaveInstanceState(Bundle outState) { 
 349     super.onSaveInstanceState(outState); 
 350     outState.putSerializable("parentsStack", mParents); 
 351     outState.putSerializable("path", mPath); 
 352     outState.putBoolean("isDisplayingFile", mIsDisplayingFile);