/* * HistoryStorageList.java * * Created on 1 Май 2007 г., 15:06 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package jimm.history; // #sijapp cond.if modules_HISTORY is "true" # import jimm.cl.SysTextList; import jimmui.Clipboard; import jimmui.view.form.Form; import jimmui.view.form.FormListener; import jimmui.view.text.TextList; import jimmui.view.text.TextListModel; import jimmui.view.text.*; import java.util.*; import javax.microedition.rms.*; import jimm.*; // #sijapp cond.if modules_FILES="true"# // #sijapp cond.end# import jimmui.view.*; import jimmui.view.base.*; import jimmui.view.menu.*; import jimm.util.JLocale; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; import jimm.comm.*; import jimmui.view.text.TextListController; // Visual messages history list public final class HistoryStorageList extends VirtualList implements Runnable, FormListener, TextListExCommands { // list UIN private HistoryStorage history; // Controls for finding text private Form frmFind; private static final int tfldFind = 1000; private static final int find_backwards = 1010; private static final int find_case_sensitiv = 1011; private static final int NOT_FOUND = 1; private static final int CACHE_SIZE = 50; private Hashtable<Integer, CachedRecord> cachedRecords = new Hashtable<Integer, CachedRecord>(); private Thread searching = null; private MenuModel msgMenu = new MenuModel(); private TextList msg = new TextList(null); // #sijapp cond.if modules_FILES="true"# private HistoryExport export = null; // #sijapp cond.end# // Constructor public HistoryStorageList(HistoryStorage storage) { super(JLocale.getString("history")); history = storage; history.openHistory(); int size = getSize(); if (0 != size) { setCurrentItemIndex(size - 1); } } void closeHistoryView() { clearCache(); history.closeHistoryView(); searching = null; } public int getHistorySize() { return history.getHistorySize(); } private CachedRecord getCachedRecord(int num) { Integer key = new Integer(num); CachedRecord cachedRec = (CachedRecord)cachedRecords.get(key); if (null == cachedRec) { trimCache(); cachedRec = history.getRecord(num); if (null != cachedRec) { cachedRecords.put(key, cachedRec); } } return cachedRec; } private void trimCache() { if (cachedRecords.size() > CACHE_SIZE) { cachedRecords.clear(); } } // Clears cache before hiding history list private void clearCache() { cachedRecords.clear(); Jimm.gc(); } protected void onCursorMove() { CachedRecord record = getCachedRecord(getCurrItem()); if (null != record) { setCaption(record.from + " " + record.date); } } protected void doJimmAction(int action) { switch (action) { case NativeCanvas.JIMM_SELECT: showMessText().show(); return; case NativeCanvas.JIMM_BACK: back(); closeHistoryView(); return; case NativeCanvas.JIMM_MENU: showMenu(getMenu()); return; } switch (action) { case MENU_GOTO_URL: SysTextList.gotoURL(getCachedRecord(getCurrItem()).text); break; case MENU_SELECT: showMessText().show(); break; case MENU_FIND: if (null == frmFind) { frmFind = UIBuilder.createForm("find", "find", "back", this); frmFind.addTextField(tfldFind, "text_to_find", "", 64); frmFind.addCheckBox(find_backwards, "find_backwards", true); frmFind.addCheckBox(find_case_sensitiv, "find_case_sensitiv", false); } frmFind.remove(NOT_FOUND); frmFind.show(); break; case MENU_CLEAR: MenuModel menu = new MenuModel(); menu.addItem("currect_contact", MENU_DEL_CURRENT); menu.addItem("all_contact_except_this", MENU_DEL_ALL_EXCEPT_CUR); menu.addItem("all_contacts", MENU_DEL_ALL); menu.setActionListener(new Binder(this)); showMenu(menu); break; case MENU_DEL_CURRENT: history.removeHistory(); clearCache(); restore(); break; case MENU_DEL_ALL_EXCEPT_CUR: history.clearAll(true); restore(); break; case MENU_DEL_ALL: history.clearAll(false); clearCache(); restore(); break; case MENU_COPY_TEXT: int index = getCurrItem(); if (-1 == index) return; CachedRecord record = getCachedRecord(index); if (null == record) return; Clipboard.setClipBoardText((record.type == 0), record.from, record.date, record.text); restore(); break; case MENU_INFO: RecordStore rs = history.getRS(); try { String sb = JLocale.getString("hist_cur") + ": " + getSize() + "\n" + JLocale.getString("hist_size") + ": " + (rs.getSize() / 1024) + "\n" + JLocale.getString("hist_avail") + ": " + (rs.getSizeAvailable() / 1024) + "\n"; new Popup(this, sb).show(); } catch (Exception ignored) { } break; // #sijapp cond.if modules_FILES="true"# case MENU_EXPORT: export = new HistoryExport(this); export.export(history); break; case MENU_EXPORT_ALL: export = new HistoryExport(this); export.export(null); break; // #sijapp cond.end# } } public void onContentMove(TextListModel sender, int direction) { moveInList(direction); } private static final int MENU_SELECT = 0; private static final int MENU_FIND = 1; private static final int MENU_CLEAR = 2; private static final int MENU_DEL_CURRENT = 40; private static final int MENU_DEL_ALL_EXCEPT_CUR = 41; private static final int MENU_DEL_ALL = 42; private static final int MENU_COPY_TEXT = 3; private static final int MENU_INFO = 4; private static final int MENU_EXPORT = 5; private static final int MENU_EXPORT_ALL = 6; private static final int MENU_GOTO_URL = 7; protected MenuModel getMenu() { MenuModel menu = new MenuModel(); if (getSize() > 0) { menu.addItem("select", MENU_SELECT); menu.addEllipsisItem("find", MENU_FIND); menu.addEllipsisItem("clear", MENU_CLEAR); menu.addItem("copy_text", MENU_COPY_TEXT); menu.addItem("history_info", MENU_INFO); // #sijapp cond.if modules_FILES="true"# if (jimm.modules.fs.FileSystem.isSupported()) { menu.addItem("export", MENU_EXPORT); //menu.addItem("exportall", MENU_EXPORT_ALL); } // #sijapp cond.end# } menu.setActionListener(new Binder(this)); return menu; } // Moves on next/previous message in list and shows message text private void moveInList(int offset) { setCurrentItemIndex(getCurrItem() + offset); showMessText().restore(); } public void run() { Thread it = Thread.currentThread(); searching = it; // search String text = frmFind.getTextFieldValue(tfldFind); int textIndex = find(text, getCurrItem(), frmFind.getCheckBoxValue(find_case_sensitiv), frmFind.getCheckBoxValue(find_backwards)); if (0 <= textIndex) { setCurrentItemIndex(textIndex); restore(); } else if (searching == it) { frmFind.addString(NOT_FOUND, text + "\n" + JLocale.getString("not_found")); } } private int find(String text, int fromIndex, boolean caseSens, boolean back) { Thread it = Thread.currentThread(); int size = history.getHistorySize(); if ((fromIndex < 0) || (fromIndex >= size)) return -1; if (!caseSens) text = StringUtils.toLowerCase(text); int step = back ? -1 : +1; int updater = 100; for (int index = fromIndex; ; index += step) { if ((index < 0) || (index >= size)) break; CachedRecord record = history.getRecord(index); String searchText = caseSens ? record.text : StringUtils.toLowerCase(record.text); if (searchText.indexOf(text) != -1) { return index; } if (0 != updater) { updater--; } else { updater = 100; try { Thread.sleep(100); } catch (Exception ignored) { } if (it != searching) { return -1; } } } return -1; } public void formAction(Form form, boolean apply) { if (apply) { frmFind.remove(NOT_FOUND); new Thread(this).start(); } else { searching = null; restore(); } } // Show text message of current message of messages list private TextList showMessText() { if (getCurrItem() >= getSize()) return null; CachedRecord record = history.getRecord(getCurrItem()); msg.setCaption(record.from); msg.getTextContent().setUpdateListener(this); msgMenu.clean(); msgMenu.addItem("copy_text", MENU_COPY_TEXT); if (record.containsUrl()) { msgMenu.addItem("goto_url", MENU_GOTO_URL); } msgMenu.setActionListener(new Binder(this)); msg.lock(); msg.getTextContent().setAllToTop(); TextListModel msgText = new TextListModel(); Parser parser = msgText.createNewParser(false); parser.addText(record.date + ":", THEME_TEXT, FONT_STYLE_BOLD); parser.doCRLF(); parser.addTextWithSmiles(record.text, THEME_TEXT, FONT_STYLE_PLAIN); msgText.addPar(parser); msg.setController(new TextListController(msgMenu, -1)); msg.setModel(msgText); return msg; } // returns size of messages history list protected final int getSize() { return getHistorySize(); } protected void paint(GraphicsEx g) { super.paint(g); // #sijapp cond.if modules_FILES="true"# HistoryExport he = export; if (null != he) { int progressHeight = getDefaultFont().getHeight(); int y = (getClientHeight() - 2 * progressHeight) / 2; int w = getWidth(); g.setClip(0, 0, getWidth(), getHeight()); g.setThemeColor(CanvasEx.THEME_BACKGROUND); g.fillRect(0, y - 1, w, progressHeight * 2 + 1); g.setThemeColor(CanvasEx.THEME_TEXT); g.drawRect(0, y - 1, w, progressHeight * 2 + 1); g.setFont(getDefaultFont()); g.drawString(he.contact, 2, y, w - 4, progressHeight); g.fillRect(0, y + progressHeight, w * he.currentMessage / he.messageCount, progressHeight); } // #sijapp cond.end# } protected void drawItemData(GraphicsEx g, int index, int x1, int y1, int w, int h, int skip, int to) { CachedRecord record = getCachedRecord(index); if ((null == record) || (null == record.getShortText())) return; Font font = getDefaultFont(); g.setFont(font); g.setThemeColor((record.type == 0) ? THEME_CHAT_INMSG : THEME_CHAT_OUTMSG); g.drawString(record.getShortText(), x1, y1 + (h - font.getHeight()) / 2, Graphics.TOP | Graphics.LEFT); } protected int getItemHeight(int itemIndex) { return Math.max(CanvasEx.minItemHeight, getDefaultFont().getHeight()); } public void select(Select select, MenuModel model, int cmd) { } // #sijapp cond.if modules_FILES="true"# void exportDone() { export = null; invalidate(); } // #sijapp cond.end# } // #sijapp cond.end#