⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 noteeditor.scala

📁 JAVA 语言的函数式编程扩展
💻 SCALA
字号:
/*  * Copyright (C) 2007 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.google.android.notepadimport com.google.provider.NotePadimport _root_.android.app.Activityimport _root_.android.app.Activity._import _root_.android.content.{ComponentName, Context, Intent}import _root_.android.database.Cursorimport _root_.android.graphics.{Canvas, Paint, Rect}import _root_.android.net.ContentURIimport _root_.android.os.Bundleimport _root_.android.text.TextUtilsimport _root_.android.util.{AttributeSet, Log, Config}import _root_.android.view.{KeyEvent, Menu}import _root_.android.widget.EditTextimport java.util.Map/** * A generic activity for editing a note in a database.  This can be used * either to simply view a note (Intent.VIEW_ACTION), view and edit a note * (Intent.EDIT_ACTION), or create a new note (Intent.INSERT_ACTION).   */object NoteEditor {  private val TAG = "Notes"  private val NOTE_INDEX = 1  private val TITLE_INDEX = 2  private val MODIFIED_INDEX = 3  /**   * Standard projection for the interesting columns of a normal note.   */  private val PROJECTION = Array(    NotePad.Notes._ID, // 0    NotePad.Notes.NOTE, // 1    NotePad.Notes.TITLE, // 2    NotePad.Notes.MODIFIED_DATE // 3  )      // This is our state data that is stored when freezing.  private val ORIGINAL_CONTENT = "origContent"  // Identifiers for our menu items.  private val REVERT_ID = Menu.FIRST  private val DISCARD_ID = Menu.FIRST + 1  private val DELETE_ID = Menu.FIRST + 2  // The different distinct states the activity can be run in.  private val STATE_UNDEF = -1  private val STATE_EDIT = 0  private val STATE_INSERT = 1  // we need this constructor for ViewInflate  class MyEditText(context: Context, attrs: AttributeSet, params: Map)      extends EditText(context, attrs, params) {    private val mRect = new Rect()    private val mPaint = new Paint()    mPaint setStyle Paint.Style.STROKE    mPaint setColor 0xFF0000FF            override protected def onDraw(canvas: Canvas) {      val count = getLineCount()      val r = mRect      val paint = mPaint      for (i <- 0 until count) {        val baseline = getLineBounds(i, r)        canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint)      }      super.onDraw(canvas)    }  }}class NoteEditor extends Activity {  import NoteEditor._ // companion object  private var mState = STATE_UNDEF  private var mNoteOnly = false  private var mURI: ContentURI = _  private var mCursor: Cursor = null  private var mText: EditText = null  private var mOriginalContent: String = ""  override protected def onCreate(icicle: Bundle) {    super.onCreate(icicle)    val intent = getIntent()    //val type = intent.resolveType(this)    // Do some setup based on the action being performed.    val action = intent.getAction()    if (action equals Intent.EDIT_ACTION) {      // Requested to edit: set that state, and the data being edited.      mState = STATE_EDIT      mURI = intent.getData()    } else if (action equals Intent.INSERT_ACTION) {      // Requested to insert: set that state, and create a new entry      // in the container.      mState = STATE_INSERT      mURI = getContentResolver().insert(intent.getData(), null)      // If we were unable to create a new note, then just finish      // this activity.  A RESULT_CANCELED will be sent back to the      // original activity if they requested a result.      if (mURI == null) {        Log.e("Notes", "Failed to insert new note into " +              getIntent().getData())        finish()        return      }      // The new entry was created, so assume all will end well and      // set the result to be returned.      setResult(RESULT_OK, mURI.toString())    } else {      // Whoops, unknown action!  Bail.      Log.e(TAG, "Unknown action, exiting")      finish()      return    }    // Set the layout for this activity.  You can find it    // in res/layout/hello_activity.xml    setContentView(R.layout.note_editor)            // The text view for our note, identified by its ID in the XML file.    mText = findViewById(R.id.note).asInstanceOf[EditText]    // Get the note!    mCursor = managedQuery(mURI, PROJECTION, null, null)    // If an instance of this activity had previously stopped, we can    // get the original text it started with.    if (icicle != null)      mOriginalContent = icicle getString ORIGINAL_CONTENT  }  override protected def onResume() {    super.onResume()    // If we didn't have any trouble retrieving the data, it is now    // time to get at the stuff.    if (mCursor != null) {      // Make sure we are at the one and only row in the cursor.      mCursor.first()      // Modify our overall title depending on the mode we are running in.      if (mState == STATE_EDIT)        setTitle(getText(R.string.title_edit))      else if (mState == STATE_INSERT)        setTitle(getText(R.string.title_create))      // This is a little nasty: we be resumed after previously being      // paused/stopped.  We want to re-retrieve the data to make sure      // we are still accurately showing what is in the cursor...  but      // we don't want to lose any UI state like the current cursor      // position.  This trick accomplishes that.  In the future we      // should have a better API for doing this...      val curState = mText.saveState()      val note = mCursor getString NOTE_INDEX      mText setText note      mText restoreState curState      // If we hadn't previously retrieved the original text, do so      // now.  This allows the user to revert their changes.      if (mOriginalContent == null)        mOriginalContent = note    } else {      setTitle(getText(R.string.error_title))      mText setText getText(R.string.error_message)    }  }  override protected def onFreeze(outState: Bundle) {    // Save away the original text, so we still have it if the activity    // needs to be killed while paused.    outState.putString(ORIGINAL_CONTENT, mOriginalContent)  }  override protected def onPause() {    super.onPause()    // The user is going somewhere else, so make sure their current    // changes are safely saved away in the provider.  We don't need    // to do this if only editing.    if (mCursor != null) {      val text = mText.getText().toString()      val length = text.length()      // If this activity is finished, and there is no text, then we      // do something a little special: simply delete the note entry.      // Note that we do this both for editing and inserting...  it      // would be reasonable to only do it when inserting.      if (isFinishing() && (length == 0) && !mNoteOnly) {        setResult(RESULT_CANCELED)        deleteNote()        // Get out updates into the provider.      } else {        // This stuff is only done when working with a full-fledged note.        if (!mNoteOnly) {          // Bump the modification time to now.          mCursor.updateLong(MODIFIED_INDEX, System.currentTimeMillis())          // If we are creating a new note, then we want to also create          // an initial title for it.          if (mState == STATE_INSERT) {            var title = text.substring(0, Math.min(30, length))            if (length > 30) {              val lastSpace = title lastIndexOf ' '              if (lastSpace > 0)                title = title.substring(0, lastSpace)            }            mCursor.updateString(TITLE_INDEX, title)          }        }        // Write our text back into the provider.        mCursor.updateString(NOTE_INDEX, text)        // Commit all of our changes to persistent storage.  Note the        // use of managedCommitUpdates() instead of        // mCursor.commitUpdates() -- this lets Activity take care of        // requerying the new data if needed.        managedCommitUpdates(mCursor)      }    }  }  override def onCreateOptionsMenu(menu: Menu): Boolean = {    super.onCreateOptionsMenu(menu)    // Build the menus that are shown when editing.    if (mState == STATE_EDIT) {      menu.add(0, REVERT_ID, R.string.menu_revert).setShortcut(               KeyEvent.KEYCODE_0, 0, KeyEvent.KEYCODE_R)      if (!mNoteOnly)        menu.add(0, DELETE_ID, R.string.menu_delete).setShortcut(                 KeyEvent.KEYCODE_1, 0, KeyEvent.KEYCODE_D)      // Build the menus that are shown when inserting.    } else      menu.add(0, DISCARD_ID, R.string.menu_discard).setShortcut(               KeyEvent.KEYCODE_0, 0, KeyEvent.KEYCODE_D)    // If we are working on a real honest-to-ghod note, then append to the    // menu items for any other activities that can do stuff with it    // as well.  This does a query on the system for any activities that    // implement the ALTERNATIVE_ACTION for our data, adding a menu item    // for each one that is found.    if (!mNoteOnly) {      val intent = new Intent(null, getIntent().getData())      intent addCategory Intent.ALTERNATIVE_CATEGORY      menu.addIntentOptions(        Menu.ALTERNATIVE, 0,        new ComponentName(this, classOf[NoteEditor]), null,        intent, 0, null)    }    true  }  override def onOptionsItemSelected(item: Menu.Item): Boolean = {    // Handle all of the possible menu actions.    item.getId() match {      case DELETE_ID =>        deleteNote()        finish()      case DISCARD_ID =>        cancelNote()      case REVERT_ID =>        cancelNote()      case _ =>    }    super.onOptionsItemSelected(item)  }  /**   * Take care of cancelling work on a note.  Deletes the note if we   * had created it, otherwise reverts to the original text.   */  private final def cancelNote() {    if (mCursor != null) {      if (mState == STATE_EDIT) {        mCursor.updateString(NOTE_INDEX, mOriginalContent)        mCursor.commitUpdates()        mCursor.deactivate()        mCursor = null      } else if (mState == STATE_INSERT)        deleteNote()    }    setResult(RESULT_CANCELED)    finish()  }  /**   * Take care of deleting a note.  Simply deletes the entry.   */  private final def deleteNote() {    if (mCursor != null) {      mText setText ""      mCursor.deleteRow()      mCursor.deactivate()      mCursor = null    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -