1 /* 2 Main/Home Activity 3 4 Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. 7 If a copy of the MPL was not distributed with this file, You can obtain one at 8 http://mozilla.org/MPL/2.0/. 9 */ 10 11 package com.freerdp.freerdpcore.presentation; 12 13 import android.app.AlertDialog; 14 import android.content.DialogInterface; 15 import android.content.Intent; 16 import android.content.res.Configuration; 17 import android.net.Uri; 18 import android.os.Bundle; 19 import androidx.appcompat.app.AppCompatActivity; 20 import android.text.Editable; 21 import android.text.TextWatcher; 22 import android.util.Log; 23 import android.view.ContextMenu; 24 import android.view.ContextMenu.ContextMenuInfo; 25 import android.view.Menu; 26 import android.view.MenuInflater; 27 import android.view.MenuItem; 28 import android.view.View; 29 import android.view.View.OnClickListener; 30 import android.view.View.OnCreateContextMenuListener; 31 import android.widget.AdapterView; 32 import android.widget.AdapterView.AdapterContextMenuInfo; 33 import android.widget.Button; 34 import android.widget.CheckBox; 35 import android.widget.EditText; 36 import android.widget.ListView; 37 38 import com.freerdp.freerdpcore.R; 39 import com.freerdp.freerdpcore.application.GlobalApp; 40 import com.freerdp.freerdpcore.domain.BookmarkBase; 41 import com.freerdp.freerdpcore.domain.ConnectionReference; 42 import com.freerdp.freerdpcore.domain.PlaceholderBookmark; 43 import com.freerdp.freerdpcore.domain.QuickConnectBookmark; 44 import com.freerdp.freerdpcore.utils.BookmarkArrayAdapter; 45 import com.freerdp.freerdpcore.utils.SeparatedListAdapter; 46 47 import java.util.ArrayList; 48 49 public class HomeActivity extends AppCompatActivity 50 { 51 private final static String ADD_BOOKMARK_PLACEHOLDER = "add_bookmark"; 52 private static final String TAG = "HomeActivity"; 53 private static final String PARAM_SUPERBAR_TEXT = "superbar_text"; 54 private ListView listViewBookmarks; 55 private Button clearTextButton; 56 private EditText superBarEditText; 57 private BookmarkArrayAdapter manualBookmarkAdapter; 58 private SeparatedListAdapter separatedListAdapter; 59 private PlaceholderBookmark addBookmarkPlaceholder; 60 private String sectionLabelBookmarks; 61 62 View mDecor; 63 onCreate(Bundle savedInstanceState)64 @Override public void onCreate(Bundle savedInstanceState) 65 { 66 setTitle(R.string.title_home); 67 super.onCreate(savedInstanceState); 68 setContentView(R.layout.home); 69 70 mDecor = getWindow().getDecorView(); 71 mDecor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 72 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 73 74 long heapSize = Runtime.getRuntime().maxMemory(); 75 Log.i(TAG, "Max HeapSize: " + heapSize); 76 Log.i(TAG, "App data folder: " + getFilesDir().toString()); 77 78 // load strings 79 sectionLabelBookmarks = getResources().getString(R.string.section_bookmarks); 80 81 // create add bookmark/quick connect bookmark placeholder 82 addBookmarkPlaceholder = new PlaceholderBookmark(); 83 addBookmarkPlaceholder.setName(ADD_BOOKMARK_PLACEHOLDER); 84 addBookmarkPlaceholder.setLabel( 85 getResources().getString(R.string.list_placeholder_add_bookmark)); 86 87 // check for passed .rdp file and open it in a new bookmark 88 Intent caller = getIntent(); 89 Uri callParameter = caller.getData(); 90 91 if (Intent.ACTION_VIEW.equals(caller.getAction()) && callParameter != null) 92 { 93 String refStr = ConnectionReference.getFileReference(callParameter.getPath()); 94 Bundle bundle = new Bundle(); 95 bundle.putString(BookmarkActivity.PARAM_CONNECTION_REFERENCE, refStr); 96 97 Intent bookmarkIntent = 98 new Intent(this.getApplicationContext(), BookmarkActivity.class); 99 bookmarkIntent.putExtras(bundle); 100 startActivity(bookmarkIntent); 101 } 102 103 // load views 104 clearTextButton = (Button)findViewById(R.id.clear_search_btn); 105 superBarEditText = (EditText)findViewById(R.id.superBarEditText); 106 107 listViewBookmarks = (ListView)findViewById(R.id.listViewBookmarks); 108 109 // set listeners for the list view 110 listViewBookmarks.setOnItemClickListener(new AdapterView.OnItemClickListener() { 111 public void onItemClick(AdapterView<?> parent, View view, int position, long id) 112 { 113 String curSection = separatedListAdapter.getSectionForPosition(position); 114 Log.v(TAG, "Clicked on item id " + separatedListAdapter.getItemId(position) + 115 " in section " + curSection); 116 if (curSection.equals(sectionLabelBookmarks)) 117 { 118 String refStr = view.getTag().toString(); 119 if (ConnectionReference.isManualBookmarkReference(refStr) || 120 ConnectionReference.isHostnameReference(refStr)) 121 { 122 Bundle bundle = new Bundle(); 123 bundle.putString(SessionActivity.PARAM_CONNECTION_REFERENCE, refStr); 124 125 Intent sessionIntent = new Intent(view.getContext(), SessionActivity.class); 126 sessionIntent.putExtras(bundle); 127 startActivity(sessionIntent); 128 129 // clear any search text 130 superBarEditText.setText(""); 131 superBarEditText.clearFocus(); 132 } 133 else if (ConnectionReference.isPlaceholderReference(refStr)) 134 { 135 // is this the add bookmark placeholder? 136 if (ConnectionReference.getPlaceholder(refStr).equals( 137 ADD_BOOKMARK_PLACEHOLDER)) 138 { 139 Intent bookmarkIntent = 140 new Intent(view.getContext(), BookmarkActivity.class); 141 startActivity(bookmarkIntent); 142 } 143 } 144 } 145 } 146 }); 147 148 listViewBookmarks.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { 149 @Override 150 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 151 { 152 // if the selected item is not a session item (tag == null) and not a quick connect 153 // entry (not a hostname connection reference) inflate the context menu 154 View itemView = ((AdapterContextMenuInfo)menuInfo).targetView; 155 String refStr = itemView.getTag() != null ? itemView.getTag().toString() : null; 156 if (refStr != null && !ConnectionReference.isHostnameReference(refStr) && 157 !ConnectionReference.isPlaceholderReference(refStr)) 158 { 159 getMenuInflater().inflate(R.menu.bookmark_context_menu, menu); 160 menu.setHeaderTitle(getResources().getString(R.string.menu_title_bookmark)); 161 } 162 } 163 }); 164 165 superBarEditText.addTextChangedListener(new SuperBarTextWatcher()); 166 167 clearTextButton.setOnClickListener(new OnClickListener() { 168 @Override public void onClick(View v) 169 { 170 superBarEditText.setText(""); 171 } 172 }); 173 } 174 onConfigurationChanged(Configuration newConfig)175 @Override public void onConfigurationChanged(Configuration newConfig) 176 { 177 // ignore orientation/keyboard change 178 super.onConfigurationChanged(newConfig); 179 mDecor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 180 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 181 } 182 onSearchRequested()183 @Override public boolean onSearchRequested() 184 { 185 superBarEditText.requestFocus(); 186 return true; 187 } 188 onContextItemSelected(MenuItem aItem)189 @Override public boolean onContextItemSelected(MenuItem aItem) 190 { 191 192 // get connection reference 193 AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo)aItem.getMenuInfo(); 194 String refStr = menuInfo.targetView.getTag().toString(); 195 196 // refer to http://tools.android.com/tips/non-constant-fields why we can't use switch/case 197 // here .. 198 int itemId = aItem.getItemId(); 199 if (itemId == R.id.bookmark_connect) 200 { 201 Bundle bundle = new Bundle(); 202 bundle.putString(SessionActivity.PARAM_CONNECTION_REFERENCE, refStr); 203 Intent sessionIntent = new Intent(this, SessionActivity.class); 204 sessionIntent.putExtras(bundle); 205 206 startActivity(sessionIntent); 207 return true; 208 } 209 else if (itemId == R.id.bookmark_edit) 210 { 211 Bundle bundle = new Bundle(); 212 bundle.putString(BookmarkActivity.PARAM_CONNECTION_REFERENCE, refStr); 213 214 Intent bookmarkIntent = 215 new Intent(this.getApplicationContext(), BookmarkActivity.class); 216 bookmarkIntent.putExtras(bundle); 217 startActivity(bookmarkIntent); 218 return true; 219 } 220 else if (itemId == R.id.bookmark_delete) 221 { 222 if (ConnectionReference.isManualBookmarkReference(refStr)) 223 { 224 long id = ConnectionReference.getManualBookmarkId(refStr); 225 GlobalApp.getManualBookmarkGateway().delete(id); 226 manualBookmarkAdapter.remove(id); 227 separatedListAdapter.notifyDataSetChanged(); 228 } 229 else 230 { 231 assert false; 232 } 233 234 // clear super bar text 235 superBarEditText.setText(""); 236 return true; 237 } 238 239 return false; 240 } 241 onResume()242 @Override protected void onResume() 243 { 244 super.onResume(); 245 Log.v(TAG, "HomeActivity.onResume"); 246 247 // create bookmark cursor adapter 248 manualBookmarkAdapter = new BookmarkArrayAdapter( 249 this, R.layout.bookmark_list_item, GlobalApp.getManualBookmarkGateway().findAll()); 250 251 // add add bookmark item to manual adapter 252 manualBookmarkAdapter.insert(addBookmarkPlaceholder, 0); 253 254 // attach all adapters to the separatedListView adapter and assign it to the list view 255 separatedListAdapter = new SeparatedListAdapter(this); 256 separatedListAdapter.addSection(sectionLabelBookmarks, manualBookmarkAdapter); 257 listViewBookmarks.setAdapter(separatedListAdapter); 258 259 // if we have a filter text entered cause an update to be caused here 260 String filter = superBarEditText.getText().toString(); 261 if (filter.length() > 0) 262 superBarEditText.setText(filter); 263 } 264 onPause()265 @Override protected void onPause() 266 { 267 super.onPause(); 268 Log.v(TAG, "HomeActivity.onPause"); 269 270 // reset adapters 271 listViewBookmarks.setAdapter(null); 272 separatedListAdapter = null; 273 manualBookmarkAdapter = null; 274 } 275 onBackPressed()276 @Override public void onBackPressed() 277 { 278 // if back was pressed - ask the user if he really wants to exit 279 if (ApplicationSettingsActivity.getAskOnExit(this)) 280 { 281 final CheckBox cb = new CheckBox(this); 282 cb.setChecked(!ApplicationSettingsActivity.getAskOnExit(this)); 283 cb.setText(R.string.dlg_dont_show_again); 284 285 AlertDialog.Builder builder = new AlertDialog.Builder(this); 286 builder.setTitle(R.string.dlg_title_exit) 287 .setMessage(R.string.dlg_msg_exit) 288 .setView(cb) 289 .setPositiveButton(R.string.yes, 290 new DialogInterface.OnClickListener() { 291 public void onClick(DialogInterface dialog, int which) 292 { 293 finish(); 294 } 295 }) 296 .setNegativeButton(R.string.no, 297 new DialogInterface.OnClickListener() { 298 public void onClick(DialogInterface dialog, int which) 299 { 300 dialog.dismiss(); 301 } 302 }) 303 .create() 304 .show(); 305 } 306 else 307 { 308 super.onBackPressed(); 309 } 310 } 311 onSaveInstanceState(Bundle outState)312 @Override protected void onSaveInstanceState(Bundle outState) 313 { 314 super.onSaveInstanceState(outState); 315 outState.putString(PARAM_SUPERBAR_TEXT, superBarEditText.getText().toString()); 316 } 317 onRestoreInstanceState(Bundle inState)318 @Override protected void onRestoreInstanceState(Bundle inState) 319 { 320 super.onRestoreInstanceState(inState); 321 superBarEditText.setText(inState.getString(PARAM_SUPERBAR_TEXT)); 322 } 323 onCreateOptionsMenu(Menu menu)324 @Override public boolean onCreateOptionsMenu(Menu menu) 325 { 326 MenuInflater inflater = getMenuInflater(); 327 inflater.inflate(R.menu.home_menu, menu); 328 return true; 329 } 330 onOptionsItemSelected(MenuItem item)331 @Override public boolean onOptionsItemSelected(MenuItem item) 332 { 333 334 // refer to http://tools.android.com/tips/non-constant-fields why we can't use switch/case 335 // here .. 336 int itemId = item.getItemId(); 337 if (itemId == R.id.newBookmark) 338 { 339 Intent bookmarkIntent = new Intent(this, BookmarkActivity.class); 340 startActivity(bookmarkIntent); 341 } 342 else if (itemId == R.id.appSettings) 343 { 344 Intent settingsIntent = new Intent(this, ApplicationSettingsActivity.class); 345 startActivity(settingsIntent); 346 } 347 else if (itemId == R.id.help) 348 { 349 Intent helpIntent = new Intent(this, HelpActivity.class); 350 startActivity(helpIntent); 351 } 352 else if (itemId == R.id.about) 353 { 354 Intent aboutIntent = new Intent(this, AboutActivity.class); 355 startActivity(aboutIntent); 356 } 357 358 return true; 359 } 360 361 private class SuperBarTextWatcher implements TextWatcher 362 { afterTextChanged(Editable s)363 @Override public void afterTextChanged(Editable s) 364 { 365 if (separatedListAdapter != null) 366 { 367 String text = s.toString(); 368 if (text.length() > 0) 369 { 370 ArrayList<BookmarkBase> computers_list = 371 GlobalApp.getQuickConnectHistoryGateway().findHistory(text); 372 computers_list.addAll( 373 GlobalApp.getManualBookmarkGateway().findByLabelOrHostnameLike(text)); 374 manualBookmarkAdapter.replaceItems(computers_list); 375 QuickConnectBookmark qcBm = new QuickConnectBookmark(); 376 qcBm.setLabel(text); 377 qcBm.setHostname(text); 378 manualBookmarkAdapter.insert(qcBm, 0); 379 } 380 else 381 { 382 manualBookmarkAdapter.replaceItems( 383 GlobalApp.getManualBookmarkGateway().findAll()); 384 manualBookmarkAdapter.insert(addBookmarkPlaceholder, 0); 385 } 386 387 separatedListAdapter.notifyDataSetChanged(); 388 } 389 } 390 beforeTextChanged(CharSequence s, int start, int count, int after)391 @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) 392 { 393 } 394 onTextChanged(CharSequence s, int start, int before, int count)395 @Override public void onTextChanged(CharSequence s, int start, int before, int count) 396 { 397 } 398 } 399 } 400