1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2014-06-30 00:04:32 -04:00
parent 85594d3cdd
commit bae88e739c
2482 changed files with 198730 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
public class Rect_ref {
public Rect_ref(int x, int y, int w, int h) {this.x = x; this.y = y; this.w = w; this.h = h;}
public int X() {return x;} public Rect_ref X_(int v) {x = v; return this;} private int x;
public int Y() {return y;} public Rect_ref Y_(int v) {y = v; return this;} private int y;
public int W() {return w;} public Rect_ref W_(int v) {w = v; return this;} private int w;
public int H() {return h;} public Rect_ref H_(int v) {h = v; return this;} private int h;
public int X_max() {return x + w;}
public int Y_max() {return y + h;}
public gplx.gfui.RectAdp XtoRectAdp() {return gplx.gfui.RectAdp_.new_(x, y, w, h);}
public gplx.gfui.RectAdp XtoRectAdp_add(Rect_ref v) {return gplx.gfui.RectAdp_.new_(x + v.x, y + v.y, w + v.w, h + v.h);}
@Override public String toString() {return String_.Format("{0},{1},{2},{3}", x, y, w, h);}
public static final Rect_ref Zero = new Rect_ref(0, 0, 0, 0);
public static Rect_ref rectAdp_(gplx.gfui.RectAdp v) {return new Rect_ref(v.X(), v.Y(), v.Width(), v.Height());}
public static Rect_ref parse_(String raw) {
try {
String[] ary = String_.Split(raw, ",");
return new Rect_ref(Int_.parse_(ary[0]), Int_.parse_(ary[1]), Int_.parse_(ary[2]), Int_.parse_(ary[3]));
} catch(Exception exc) {throw Err_.parse_type_exc_(exc, Rect_ref.class, raw);}
}
}

View File

@@ -0,0 +1,213 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.html.*; import gplx.xowa.gui.menus.*; import gplx.xowa.gui.menus.dom.*;
public class Xog_html_itm implements GfoInvkAble, GfoEvObj {
private Xoa_app app;
public Xog_html_itm(Xog_tab_itm owner_tab) {
this.owner_tab = owner_tab;
app = owner_tab.Tab_mgr().Win().App();
js_cbk = new Xog_html_js_cbk(this);
Gfui_kit kit = owner_tab.Tab_mgr().Win().Kit();
cmd_sync = kit.New_cmd_sync(this); // NOTE: always use sync; async will cause some images to be "lost" in update;
cmd_async = kit.New_cmd_async(this);
ev_mgr = GfoEvMgr.new_(this);
}
public GfoEvMgr EvMgr() {return ev_mgr;} private GfoEvMgr ev_mgr;
public Xog_tab_itm Owner_tab() {return owner_tab;} private Xog_tab_itm owner_tab;
public Gfui_html Html_box() {return html_box;} private Gfui_html html_box;
public Xog_html_js_cbk Js_cbk() {return js_cbk;} private Xog_html_js_cbk js_cbk;
public GfoInvkAble Cmd_sync() {return cmd_sync;} private GfoInvkAble cmd_sync;
public GfoInvkAble Cmd_async() {return cmd_async;} private GfoInvkAble cmd_async;
public void Switch_mem(Xog_html_itm comp) {
Xog_tab_itm temp_owner_tab = owner_tab; // NOTE: reparent owner_tab, since owner_tab will be switching its html_itm
this.owner_tab = comp.owner_tab;
comp.owner_tab = temp_owner_tab;
}
public void Html_box_(Gfui_html html_box) {
this.html_box = html_box;
html_box.Html_js_cbks_add("xowa_exec", js_cbk);
}
public String Html_selected_get_src_or_empty() {return html_box.Html_doc_selected_get_src_or_empty();}
public String Html_selected_get_href_or_text() {return Html_extract_text(html_box.Html_doc_selected_get_href_or_text());}
public String Html_selected_get_text_or_href() {return Html_extract_text(html_box.Html_doc_selected_get_text_or_href());}
private String Html_extract_text(String v) {
Xoa_page page = owner_tab.Page();
String site = page.Wiki().Domain_str();
String ttl = String_.new_utf8_(page.Ttl().Full_db());
return Xog_html_itm__href_extractor.Html_extract_text(site, ttl, v);
}
public void Show(Xoa_page page) {
byte view_mode = owner_tab.View_mode();
byte[] html_src = page.Wiki().Html_mgr().Page_wtr_mgr().Gen(page, view_mode);
Html_src_(page, html_src);
if (view_mode == Xog_page_mode.Tid_read){ // used only for Xosrh test; DATE:2014-01-29
html_box.Html_doc_body_focus(); // NOTE: only focus if read so up / down will scroll box; edit / html should focus edit-box; DATE:2014-06-05
page.Root().Data_htm_(html_src);
}
}
private void Html_src_(Xoa_page page, byte[] html_src) {
html_box.Html_doc_html_(String_.new_utf8_(html_src));
}
public void Html_swap(Xog_html_itm trg_itm) {
Xog_html_itm src_itm = this;
Gfui_html src_html = html_box;
Gfui_html trg_html = trg_itm.html_box;
Xog_html_js_cbk src_js_cbk = js_cbk;
Xog_html_js_cbk trg_js_cbk = trg_itm.js_cbk;
src_itm.html_box = trg_html;
trg_itm.html_box = src_html;
src_itm.js_cbk = trg_js_cbk;
trg_itm.js_cbk = src_js_cbk;
}
public byte[] Get_elem_value_for_edit_box_as_bry() {return Bry_.new_utf8_(this.Get_elem_value_for_edit_box());}
public String Get_elem_value_for_edit_box() {return html_box.Html_elem_atr_get_str(Elem_id__xowa_edit_data_box, Gfui_html.Atr_value);}
public String Get_elem_value(String elem_id) {return html_box.Html_elem_atr_get_str(elem_id, Gfui_html.Atr_value);}
public void Html_img_update(String elem_id, String elem_src, int elem_width, int elem_height) {
GfoMsg m = GfoMsg_.new_cast_(Invk_html_img_update).Add("elem_id", elem_id).Add("elem_src", elem_src).Add("elem_width", elem_width).Add("elem_height", elem_height);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_img_update, m);
} Object guard = new Object();
public void Html_elem_delete(String elem_id) {
GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_delete).Add("elem_id", elem_id);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_delete, m);
}
public void Html_atr_set(String elem_id, String atr_key, String atr_val) {
GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set, m);
}
public void Html_elem_atr_set_append(String elem_id, String atr_key, String atr_val) {
GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_atr_set_append).Add("elem_id", elem_id).Add("atr_key", atr_key).Add("atr_val", atr_val);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_atr_set_append, m);
}
public void Html_elem_replace_html(String id, String html) {
GfoMsg m = GfoMsg_.new_cast_(Invk_html_elem_replace_html).Add("id", id).Add("html", html);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_elem_replace_html, m);
}
public void Html_gallery_packed_exec() {
if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // do not exec unless active;
GfoMsg m = GfoMsg_.new_cast_(Invk_html_gallery_packed_exec);
GfoInvkAble_.InvkCmd_msg(cmd_sync, Invk_html_gallery_packed_exec, m);
module_packed_done = true;
}
private boolean module_packed_done = false;
public void Tab_selected(Xoa_page page) {
if ( page.Html_data().Module_mgr().Itm_gallery().Enabled()
&& !module_packed_done
) {
this.Html_gallery_packed_exec();
}
}
public void Scroll_page_by_bmk_gui() {GfoInvkAble_.InvkCmd(cmd_async, Invk_scroll_page_by_bmk);}
private void Scroll_page_by_bmk() {
if (!String_.Eq(owner_tab.Tab_key(), owner_tab.Tab_mgr().Active_tab().Tab_key())) return; // only set html page position on active tab; otherwise, page "scrolls down" mysteriously on unseen tab; DATE:2014-05-02
String html_doc_pos = owner_tab.Page().Html_data().Bmk_pos();
if (html_doc_pos == null) {
String auto_focus_id = app.Gui_mgr().Html_mgr().Auto_focus_id();
if (String_.Len_eq_0(auto_focus_id)) return; // don't focus anything
if (String_.Eq(auto_focus_id, " first_anchor")) // NOTE: HTML 4/5 do not allow space as id; XOWA using space here to create a unique_key that will never collide with any id
html_box.Html_doc_body_focus(); // NOTE: will focus body if content-editable, or first_anchor otherwise
else
html_box.Html_elem_focus(auto_focus_id);
}
else if (String_.Eq(html_doc_pos, gplx.xowa.gui.history.Xog_history_itm.Html_doc_pos_toc)) // NOTE: special case to handle TOC clicks; DATE:2013-07-17
Scroll_page_by_id("toc");
else
html_box.Html_window_vpos_(html_doc_pos);
}
public void Scroll_page_by_id_gui(String id) {GfoInvkAble_.InvkCmd_val(cmd_async, Invk_scroll_page_by_id, id);}
private boolean Scroll_page_by_id(String id) {
return (id == null)
? false
: html_box.Html_elem_scroll_into_view(app.Url_converter_id().Encode_str(id));
}
public void Js_enabled_(boolean v) {
html_box.Html_js_enabled_(v);
}
private void When_menu_detected() {
Xoa_gui_mgr gui_mgr = app.Gui_mgr(); Gfui_kit kit = gui_mgr.Kit();
Xog_popup_mnu_mgr popup_mnu_mgr = gui_mgr.Menu_mgr().Popup();
Xog_mnu_grp popup_mnu = popup_mnu_mgr.Html_page();
if (String_.Len_gt_0(this.Html_selected_get_src_or_empty()))
popup_mnu = popup_mnu_mgr.Html_file();
else if (String_.Len_gt_0(this.Html_selected_get_text_or_href()))
popup_mnu = popup_mnu_mgr.Html_link();
kit.Set_mnu_popup(html_box, popup_mnu.Under_mnu());
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_html_img_update)) html_box.Html_elem_img_update(m.ReadStr("elem_id"), m.ReadStr("elem_src"), m.ReadInt("elem_width"), m.ReadInt("elem_height"));
else if (ctx.Match(k, Invk_html_elem_atr_set)) html_box.Html_elem_atr_set(m.ReadStr("elem_id"), m.ReadStr("atr_key"), m.ReadStr("atr_val"));
else if (ctx.Match(k, Invk_html_elem_atr_set_append)) html_box.Html_elem_atr_set_append(m.ReadStr("elem_id"), m.ReadStr("atr_key"), m.ReadStr("atr_val"));
else if (ctx.Match(k, Invk_html_elem_delete)) html_box.Html_elem_delete(m.ReadStr("elem_id"));
else if (ctx.Match(k, Invk_html_elem_replace_html)) html_box.Html_elem_replace_html(m.ReadStr("id"), m.ReadStr("html"));
else if (ctx.Match(k, Invk_html_gallery_packed_exec)) html_box.Html_gallery_packed_exec();
else if (ctx.Match(k, Invk_scroll_page_by_bmk)) Scroll_page_by_bmk();
else if (ctx.Match(k, Invk_scroll_page_by_id)) Scroll_page_by_id(m.ReadStr("v"));
else if (ctx.Match(k, Invk_html_elem_focus)) html_box.Html_elem_focus(m.ReadStr("v"));
else if (ctx.Match(k, GfuiElemKeys.Evt_menu_detected)) When_menu_detected();
else return GfoInvkAble_.Rv_unhandled;
return this;
}
private static final String
Invk_html_gallery_packed_exec = "html_gallery_packed_exec"
, Invk_html_img_update = "html_img_update", Invk_html_elem_atr_set = "html_elem_atr_set"
, Invk_html_elem_atr_set_append = "html_elem_atr_set_append", Invk_html_elem_delete = "html_elem_delete", Invk_html_elem_replace_html = "html_elem_replace_html"
, Invk_scroll_page_by_bmk = "scroll_page_by_bmk", Invk_scroll_page_by_id = "scroll_page_by_id"
;
public static final String
Elem_id__xowa_edit_data_box = "xowa_edit_data_box"
, Elem_id__xowa_edit_rename_box = "xowa_edit_rename_box"
, Elem_id__first_heading = "firstHeading"
, Invk_html_elem_focus = "html_elem_focus"
;
}
class Xog_html_itm__href_extractor {
private static final byte Text_tid_none = 0, Text_tid_text = 1, Text_tid_href = 2;
private static final byte Href_tid_wiki = 1, Href_tid_site = 2, Href_tid_anchor = 3;
private static final byte[] File_protocol_bry = Bry_.new_ascii_("file://");
private static final int File_protocol_len = File_protocol_bry.length;
private static final ByteTrieMgr_slim href_trie = ByteTrieMgr_slim.cs_()
.Add_str_byte("/site/" , Href_tid_site)
.Add_str_byte("/wiki/" , Href_tid_wiki)
.Add_str_byte("#" , Href_tid_anchor)
;
public static String Html_extract_text(String site, String page, String text_str) {
byte[] text_bry = Bry_.new_utf8_(text_str);
int text_tid = Byte_ascii.X_to_digit(text_bry[0]);
int text_len = text_bry.length;
switch (text_tid) {
case Text_tid_none: return "";
case Text_tid_text: return String_.new_utf8_(text_bry, 2, text_len); // 2 to skip "1|"
case Text_tid_href: break; // fall through to below
default: throw Err_.unhandled(text_tid);
}
int href_bgn = 2; // 2 for length of "2|"
if (Bry_.HasAtBgn(text_bry, File_protocol_bry, 2, text_len)) {
href_bgn += File_protocol_len; // skip "file://"
}
Byte_obj_val href_tid = (Byte_obj_val)href_trie.MatchAtCur(text_bry, href_bgn, text_len);
if (href_tid != null) {
switch (href_tid.Val()) {
case Href_tid_wiki: return site + String_.new_utf8_(text_bry, href_bgn, text_len);
case Href_tid_site: return String_.new_utf8_(text_bry, href_bgn + 6, text_len); // +6 to skip "site/"
case Href_tid_anchor: return site + "/wiki/" + page + String_.new_utf8_(text_bry, href_bgn, text_len);
}
}
return String_.new_utf8_(text_bry, 2, text_len); // 2 to skip "2|"; handles "http://" text as well as any fall-thru from above
}
public static final Xog_html_itm__href_extractor _ = new Xog_html_itm__href_extractor(); Xog_html_itm__href_extractor() {}
}

View File

@@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import org.junit.*;
public class Xog_html_itm_tst {
@Before public void init() {fxt.Clear();} private Xog_html_itm_fxt fxt = new Xog_html_itm_fxt();
@Test public void Extract_href__text() {
fxt.Test_extract_href("0|" , "");
fxt.Test_extract_href("1|selected_text" , "selected_text");
fxt.Test_extract_href("2|http://a.org" , "http://a.org");
}
@Test public void Extract_href__file() {
fxt.Test_extract_href("2|file:///site/en.wiktionary.org/wiki/Page_1" , "en.wiktionary.org/wiki/Page_1");
fxt.Test_extract_href("2|file:///wiki/Page_2" , "en.wikipedia.org/wiki/Page_2");
fxt.Test_extract_href("2|file://#anchor" , "en.wikipedia.org/wiki/Page_0#anchor");
}
@Test public void Extract_href__internal() { //
fxt.Test_extract_href("2|/site/en.wiktionary.org/wiki/Page_1" , "en.wiktionary.org/wiki/Page_1");
fxt.Test_extract_href("2|/wiki/Page_2" , "en.wikipedia.org/wiki/Page_2");
fxt.Test_extract_href("2|#anchor" , "en.wikipedia.org/wiki/Page_0#anchor");
}
}
class Xog_html_itm_fxt {
public void Clear() {
cur_wiki = "en.wikipedia.org";
cur_page = "Page_0";
}
public String Cur_wiki() {return cur_wiki;} public Xog_html_itm_fxt Cur_wiki_(String v) {cur_wiki = v; return this;} private String cur_wiki;
public String Cur_page() {return cur_page;} public Xog_html_itm_fxt Cur_page_(String v) {cur_page = v; return this;} private String cur_page;
public void Test_extract_href(String text_str, String expd) {
Tfds.Eq(expd, Xog_html_itm__href_extractor.Html_extract_text(cur_wiki, cur_page, text_str));
}
}

View File

@@ -0,0 +1,187 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.threads.*; import gplx.xowa.xtns.pfuncs.ifs.*;
public class Xog_html_js_cbk implements GfoInvkAble {
private Xoa_app app;
private Xog_html_itm html_itm;
private Xop_root_tkn root = new Xop_root_tkn();
private Bry_bfr bfr = Bry_bfr.reset_(255);
public Xog_html_js_cbk(Xog_html_itm html_itm) {this.html_itm = html_itm; this.app = html_itm.Owner_tab().Tab_mgr().Win().App();}
private String Xowa_exec_test(GfoMsg m) { // concat args with pipe; EX: xowa_exec('proc', 'arg0', 'arg1'); -> proc|arg0|arg1
bfr.Clear();
bfr.Add_str(m.Key());
int len = m.Args_count();
for (int i = 0; i < len; i++)
bfr.Add_str("|").Add_str(m.Args_getAt(i).Val_to_str_or_empty());
return bfr.XtoStrAndClear();
}
private String[] Xowa_exec_test_as_array(GfoMsg m) {// return args as array; EX: xowa_exec('proc', 'arg0', 'arg1'); -> proc,arg0,arg1
bfr.Clear();
int len = m.Args_count();
String[] rv = new String[len + 1];
rv[0] = Invk_xowa_exec_test_as_array;
for (int i = 0; i < len; i++)
rv[i + 1] = Object_.XtoStr_OrEmpty(m.ReadValAt(i));
return rv;
}
private String Parse_to_html(GfoMsg m) {
Xoa_page page = html_itm.Owner_tab().Page();
Xow_wiki wiki = page.Wiki();
Xop_ctx ctx = wiki.Ctx();
boolean old_para_enabled = ctx.Para().Enabled();
byte[] raw = Bry_.new_utf8_(m.Args_getAt(0).Val_to_str_or_empty());
boolean para_enabled = m.Args_count() < 2 ? false : Bool_.parse_(m.Args_getAt(1).Val_to_str_or_empty());
try {
wiki.Ctx().Para().Enabled_(para_enabled);
wiki.Parser().Parse_text_to_wdom(root, wiki.Ctx(), wiki.Ctx().Tkn_mkr(), raw, 0);
byte[] data = root.Data_mid();
wiki.Html_mgr().Html_wtr().Write_all(bfr, wiki.Ctx(), data, root);
return bfr.XtoStrAndClear();
}
finally {
wiki.Ctx().Para().Enabled_(old_para_enabled);
}
}
private String Get_page(GfoMsg m) {
Xow_wiki wiki = html_itm.Owner_tab().Page().Wiki();
try {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, m.Args_getAt(0).Val_to_bry());
Xoa_page page = wiki.Data_mgr().Get_page(ttl, false);
return String_.new_utf8_(page.Data_raw());
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String Popups_get_async_bgn(GfoMsg m) {
try {
byte[] js_cbk = m.Args_getAt(0).Val_to_bry();
byte[] href_bry = m.Args_getAt(1).Val_to_bry();
return html_itm.Owner_tab().Page().Wiki().Html_mgr().Module_mgr().Popup_mgr().Get_async_bgn(js_cbk, href_bry);
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String Popups_get_html(GfoMsg m) {
try {
int popups_id = Int_.X_by_double_(Double_.cast_(m.Args_getAt(0).Val()));
byte[] href_bry = m.Args_getAt(1).Val_to_bry();
return html_itm.Owner_tab().Page().Wiki().Html_mgr().Module_mgr().Popup_mgr().Show_init(href_bry, popups_id);
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String[] Get_title_meta(Xow_wiki wiki, byte[] ttl) {
Pfunc_ifexist.Exists(tmp_page, wiki.Ctx(), ttl);
return String_.Ary(tmp_page.Exists() ? "1" : "0", Int_.XtoStr(tmp_page.Id()), Int_.XtoStr(tmp_page.Ns_id()), String_.new_utf8_(tmp_page.Ttl_wo_ns()), Bool_.XtoStr_lower(tmp_page.Type_redirect()), tmp_page.Modified_on().XtoStr_fmt("yyyy-MM-dd HH:mm:ss"), Int_.XtoStr(tmp_page.Text_len()));
} private static final Xodb_page tmp_page = Xodb_page.tmp_();
private String[][] Get_titles_meta(GfoMsg m) {
Xow_wiki wiki = html_itm.Owner_tab().Page().Wiki();
try {
byte[][] ttls = Bry_.Split(Bry_.new_utf8_((String)m.ReadValAt(0)), Byte_ascii.NewLine);
int ttls_len = ttls.length;
String[][] rv = new String[ttls_len][];
for (int i = 0; i < ttls_len; i++) {
byte[] ttl = ttls[i];
rv[i] = Get_title_meta(wiki, ttl);
}
return rv;
} catch (Exception e) {Err_.Noop(e); return null;}
}
private boolean Get_title_exists(Xow_wiki wiki, byte[] ttl) {
return Pfunc_ifexist.Exists(tmp_page, wiki.Ctx(), ttl);
}
private String[] Get_titles_exists(GfoMsg m) {
Xow_wiki wiki = html_itm.Owner_tab().Page().Wiki();
try {
byte[][] ttls = Bry_.Ary_obj((Object[])m.ReadValAt(0));
int ttls_len = ttls.length;
String[] rv = new String[ttls_len];
for (int i = 0; i < ttls_len; i++) {
byte[] ttl = ttls[i];
rv[i] = Get_title_exists(wiki, ttl) ? "1" : "0";
}
return rv;
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String Get_search_suggestions(GfoMsg m) {
Xow_wiki wiki = html_itm.Owner_tab().Page().Wiki();
byte[] search_str = Bry_.new_utf8_((String)m.ReadValAt(0));
byte[] cbk_func = Bry_.new_utf8_((String)m.ReadValAt(1));
app.Gui_mgr().Search_suggest_mgr().Search(wiki, search_str, cbk_func);
return "";
}
private String[] Wikidata_get_label(GfoMsg m) {
try {
ThreadAdp_.Sleep(10); // slow down calls to prevent random crashing in XulRunner; DATE:2014-04-23
gplx.xowa.xtns.wdatas.Wdata_wiki_mgr wdata_mgr = app.Wiki_mgr().Wdata_mgr();
wdata_mgr.Wdata_wiki().Init_assert(); // NOTE: must assert else ns_mgr won't load Property
int len = m.Args_count();
if (len < 1) return null;
byte[][] langs = Bry_.Split(m.Args_getAt(0).Val_to_bry(), Byte_ascii.Semic);
int langs_len = langs.length;
String[] rv = new String[len - 1];
for (int i = 1; i < len; i++) {
try {
byte[] ttl_bry = m.Args_getAt(i).Val_to_bry();
gplx.xowa.xtns.wdatas.Wdata_doc page = wdata_mgr.Pages_get(ttl_bry); if (page == null) continue;
for (int j = 0; j < langs_len; j++) {
byte[] lang_key = langs[j];
if (Bry_.Eq(lang_key, Wikidata_get_label_xowa_ui_lang))
lang_key = app.Sys_cfg().Lang();
byte[] val_bry = null;
if (Bry_.Eq(lang_key, Wikidata_get_label_xowa_title))
val_bry = ttl_bry;
else {
val_bry = page.Label_list_get(lang_key);
}
if (val_bry == null) continue;
rv[i - 1] = String_.new_utf8_(val_bry);
break;
}
} catch (Exception e) {Err_.Noop(e); rv[i] = null;}
finally {}
}
return rv;
} catch (Exception e) {Err_.Noop(e); return null;}
}
private String Scripts_exec(GfoMsg m) {
Object rv = null;
try {
rv = app.Gfs_mgr().Run_str(m.Args_getAt(0).Val_to_str_or_empty());
}
catch (Exception e) {Err_.Noop(e); return null;}
return Object_.XtoStr_OrEmpty(rv);
}
private static final byte[] Wikidata_get_label_xowa_ui_lang = Bry_.new_ascii_("xowa_ui_lang"), Wikidata_get_label_xowa_title = Bry_.new_ascii_("xowa_title");
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_parse_to_html)) return Parse_to_html(m);
else if (ctx.Match(k, Invk_wikidata_get_label)) return Wikidata_get_label(m);
else if (ctx.Match(k, Invk_get_page)) return Get_page(m);
else if (ctx.Match(k, Invk_popups_get_async_bgn)) return Popups_get_async_bgn(m);
else if (ctx.Match(k, Invk_popups_get_html)) return Popups_get_html(m);
else if (ctx.Match(k, Invk_scripts_exec)) return Scripts_exec(m);
else if (ctx.Match(k, Invk_get_search_suggestions)) return Get_search_suggestions(m);
else if (ctx.Match(k, Invk_get_titles_meta)) return Get_titles_meta(m);
else if (ctx.Match(k, Invk_get_titles_exists)) return Get_titles_exists(m);
else if (ctx.Match(k, Invk_get_current_url)) return String_.new_utf8_(html_itm.Owner_tab().Page().Url().Raw());
else if (ctx.Match(k, Invk_xowa_exec_test)) return Xowa_exec_test(m);
else if (ctx.Match(k, Invk_xowa_exec_test_as_array))return Xowa_exec_test_as_array(m);
else return GfoInvkAble_.Rv_unhandled;
}
public static final String Invk_parse_to_html = "parse_to_html", Invk_wikidata_get_label = "wikidata_get_label", Invk_get_page = "get_page", Invk_scripts_exec = "scripts_exec"
, Invk_get_search_suggestions = "get_search_suggestions", Invk_get_titles_meta = "get_titles_meta", Invk_get_titles_exists = "get_titles_exists", Invk_get_current_url = "get_current_url"
, Invk_xowa_exec_test = "xowa_exec_test", Invk_xowa_exec_test_as_array = "xowa_exec_test_as_array"
, Invk_popups_get_async_bgn = "popups_get_async_bgn"
, Invk_popups_get_html = "popups_get_html"
;
}

View File

@@ -0,0 +1,45 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import org.junit.*; import gplx.xowa.xtns.wdatas.*;
public class Xog_html_js_cbk_tst {
@Before public void init() {fxt.Clear();} private Xog_html_js_cbk_fxt fxt = new Xog_html_js_cbk_fxt();
@Test public void Get_title() {
fxt.Fxt().Init_page_create("exists");
fxt.Test_get_title("exists", "1" , "0" , Int_.XtoStr(Int_.MinValue), "Exists", "false", "0001-01-01 00:00:00", "0");
fxt.Test_get_title("absent", "0", "-1", Int_.XtoStr(Int_.MinValue), null , "false", "0001-01-01 00:00:00", "0");
}
}
class Xog_html_js_cbk_fxt {
public void Clear() {
fxt = new Xop_fxt();
Xoa_app_fxt.Init_gui(fxt.App());
} private Xop_fxt fxt;
public Xop_fxt Fxt() {return fxt;}
public void Test_get_title(String ttl, Object... expd) {
Xoa_app app = fxt.App();
Xow_wiki wiki = fxt.Wiki();
Xoa_page page = Xoa_page.test_(wiki, Xoa_ttl.parse_(wiki, Bry_.new_ascii_("mock_page")));
Xog_tab_itm tab = app.Gui_mgr().Browser_win().Active_tab();
tab.Page_(page);
Xog_html_js_cbk exec = tab.Html_itm().Js_cbk();
GfoMsg msg = GfoMsg_.new_cast_(Xog_html_js_cbk.Invk_get_titles_meta).Add("ttl", ttl);
String[][] actl = (String[][])GfoInvkAble_.InvkCmd_msg(exec, Xog_html_js_cbk.Invk_get_titles_meta, msg);
Tfds.Eq_ary_str(expd, actl[0]);
}
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import org.junit.*; import gplx.xowa.xtns.wdatas.*;
public class Xog_html_js_cbk_wdata_labels_tst {
@Before public void init() {fxt.Init();} Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt();
@Test public void Basic() {
fxt.Init_pages_add(fxt.page_bldr_("q1").Label_add("en", "en_q1").Xto_page_doc());
fxt.Init_pages_add(fxt.page_bldr_("q2").Label_add("en", "en_q2").Xto_page_doc());
fxt.Init_pages_add(fxt.page_bldr_("Property:P1").Label_add("en", "en_property_p1").Xto_page_doc());
Tst_wikidata_label_get(String_.Ary("en", "q1", "q2", "Property:P1"), String_.Ary("en_q1", "en_q2", "en_property_p1"));
}
@Test public void Outliers() {
fxt.Init_pages_add(fxt.page_bldr_("q1").Label_add("en", "en_q1").Label_add("de", "de_q1").Xto_page_doc());
Tst_wikidata_label_get(String_.Ary("fr", "q1"), String_.Ary((String)null));
Tst_wikidata_label_get(String_.Ary("de", "q1"), String_.Ary("de_q1"));
Tst_wikidata_label_get(String_.Ary("xowa_title", "q1"), String_.Ary("q1"));
Tst_wikidata_label_get(String_.Ary("xowa_ui_lang", "q1"), String_.Ary("en_q1"));
Tst_wikidata_label_get(String_.Ary("fr;de", "q1"), String_.Ary("de_q1"));
}
@Test public void Escaped() { // PURPOSE: \t should be escaped; EX:wd.q:2; DATE:2014-04-23
Wdata_doc d = doc_("q1", String_.Concat_lines_nl
( "{ 'entity':['item',1]"
, ", 'label':"
, " { 'en':'\\ta'" // NOTE: json literally has "\t", not (char)8
, " }"
, "}"
));
fxt.Init_pages_add(d);
Tst_wikidata_label_get(String_.Ary("en", "q1"), String_.Ary("\ta"));
}
private Wdata_doc doc_(String qid, String src) {
gplx.json.Json_doc doc = gplx.json.Json_doc.new_apos_(src);
Xoa_app app = Xoa_app_fxt.app_();
Wdata_doc rv = new Wdata_doc(Bry_.new_ascii_(qid), app.Wiki_mgr().Wdata_mgr(), doc);
return rv;
}
private void Tst_wikidata_label_get(String[] args, String[] expd) {
Xoa_app_fxt.Init_gui(fxt.App());
Xog_html_js_cbk exec = fxt.App().Gui_mgr().Browser_win().Active_html_itm().Js_cbk();
GfoMsg msg = GfoMsg_.new_cast_(Xog_html_js_cbk.Invk_wikidata_get_label);
int args_len = args.length;
for (int i = 0; i < args_len; i++)
msg.Add("v", args[i]);
String[] actl = (String[])GfoInvkAble_.InvkCmd_msg(exec, Xog_html_js_cbk.Invk_wikidata_get_label, msg);
Tfds.Eq_ary_str(expd, actl);
}
}

View File

@@ -0,0 +1,109 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.xowa.gui.views.*;
public class Xog_layout implements GfoInvkAble {
public Xog_layout() {
go_bwd_btn.Owner_(this);
go_fwd_btn.Owner_(this);
url_box.Owner_(this);
url_exec_btn.Owner_(this);
find_close_btn.Owner_(this);
search_box.Owner_(this);
search_exec_btn.Owner_(this);
html_box.Owner_(this);
find_box.Owner_(this);
prog_box.Owner_(this);
note_box.Owner_(this);
main_win.Owner_(this);
}
public Xog_layout_box Go_fwd_btn() {return go_fwd_btn;} private Xog_layout_box go_fwd_btn = new Xog_layout_box();
public Xog_layout_box Go_bwd_btn() {return go_bwd_btn;} private Xog_layout_box go_bwd_btn = new Xog_layout_box();
public Xog_layout_box Url_box() {return url_box;} private Xog_layout_box url_box = new Xog_layout_box();
public Xog_layout_box Url_exec_btn() {return url_exec_btn;} private Xog_layout_box url_exec_btn = new Xog_layout_box();
public Xog_layout_box Find_close_btn() {return find_close_btn;} private Xog_layout_box find_close_btn = new Xog_layout_box();
public Xog_layout_box Search_box() {return search_box;} private Xog_layout_box search_box = new Xog_layout_box();
public Xog_layout_box Search_exec_btn() {return search_exec_btn;} private Xog_layout_box search_exec_btn = new Xog_layout_box();
public Xog_layout_box Html_box() {return html_box;} private Xog_layout_box html_box = new Xog_layout_box();
public Xog_layout_box Find_box() {return find_box;} private Xog_layout_box find_box = new Xog_layout_box();
public Xog_layout_box Find_fwd_btn() {return find_fwd_btn;} private Xog_layout_box find_fwd_btn = new Xog_layout_box();
public Xog_layout_box Find_bwd_btn() {return find_bwd_btn;} private Xog_layout_box find_bwd_btn = new Xog_layout_box();
public Xog_layout_box Prog_box() {return prog_box;} private Xog_layout_box prog_box = new Xog_layout_box();
public Xog_layout_box Note_box() {return note_box;} private Xog_layout_box note_box = new Xog_layout_box();
public Xog_layout_box Browser_win() {return main_win;} private Xog_layout_box main_win = new Xog_layout_box();
public void Find_show() {
Visible_(true, win.Find_box(), win.Find_bwd_btn(), win.Find_fwd_btn(), win.Find_close_btn());
GfuiTextBox find_box = win.Find_box();
find_box.Focus();
int text_len = String_.Len(find_box.Text());
if (text_len > 0) { // if text exists, select it; GUI:Firefox
find_box.SelBgn_set(0);
find_box.SelLen_set(text_len);
}
}
public void Find_close() {
Visible_(false, win.Find_box(), win.Find_bwd_btn(), win.Find_fwd_btn(), win.Find_close_btn());
win.Active_html_box().Focus();
}
private void Visible_(boolean v, GfuiElem... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
ary[i].Visible_set(v);
}
public void Init(Xog_win_itm win) {
this.win = win;
go_bwd_btn.Adj_text(win.Go_bwd_btn());
go_fwd_btn.Adj_text(win.Go_fwd_btn());
url_box.Adj_text(win.Url_box());
url_exec_btn.Adj_text(win.Url_exec_btn());
find_close_btn.Adj_text(win.Find_close_btn());
search_box.Adj_text(win.Search_box());
search_exec_btn.Adj_text(win.Search_exec_btn());
find_box.Adj_text(win.Find_box());
find_fwd_btn.Adj_text(win.Find_fwd_btn());
find_bwd_btn.Adj_text(win.Find_bwd_btn());
prog_box.Adj_text(win.Prog_box());
note_box.Adj_text(win.Info_box());
Visible_(false, win.Find_box(), win.Find_bwd_btn(), win.Find_fwd_btn(), win.Find_close_btn());
} private Xog_win_itm win;
public int Box_height_calc(Gfui_kit kit, GfuiElem url_box) {
if (box_height > 0) return box_height;
float font_height = kit.Calc_font_height(url_box, "I");
box_height = (int)(font_height * 2);
return box_height;
} private int box_height = 0;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_go_fwd_btn)) return go_fwd_btn;
else if (ctx.Match(k, Invk_go_bwd_btn)) return go_bwd_btn;
else if (ctx.Match(k, Invk_url_box)) return url_box;
else if (ctx.Match(k, Invk_url_exec_btn)) return url_exec_btn;
else if (ctx.Match(k, Invk_find_close_btn)) return find_close_btn;
else if (ctx.Match(k, Invk_search_box)) return search_box;
else if (ctx.Match(k, Invk_search_exec_btn)) return search_exec_btn;
else if (ctx.Match(k, Invk_html_box)) return html_box;
else if (ctx.Match(k, Invk_find_box)) return find_box;
else if (ctx.Match(k, Invk_find_fwd_btn)) return find_fwd_btn;
else if (ctx.Match(k, Invk_find_bwd_btn)) return find_bwd_btn;
else if (ctx.Match(k, Invk_prog_box)) return prog_box;
else if (ctx.Match(k, Invk_note_box)) return note_box;
else if (ctx.Match(k, Invk_main_win)) return main_win;
else return GfoInvkAble_.Rv_unhandled;
}
static final String Invk_coord_mode_ = "coord_mode_", Invk_go_fwd_btn = "go_fwd_btn", Invk_go_bwd_btn = "go_bwd_btn", Invk_url_box = "url_box", Invk_search_box = "search_box", Invk_html_box = "html_box", Invk_find_box = "find_box", Invk_prog_box = "prog_box", Invk_note_box = "note_box"
, Invk_main_win = "main_win", Invk_find_fwd_btn = "find_fwd_btn", Invk_find_bwd_btn = "find_bwd_btn", Invk_url_exec_btn = "url_exec_btn", Invk_search_exec_btn = "search_exec_btn", Invk_find_close_btn = "find_close_btn";
}

View File

@@ -0,0 +1,83 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*;
public class Xog_layout_box implements GfoInvkAble {
public GfoInvkAble Owner() {return owner;} public Xog_layout_box Owner_(GfoInvkAble v) {owner = v; return this;} GfoInvkAble owner;
public int X_abs() {return x_abs;} public Xog_layout_box X_abs_(int v) {x_abs = v; return this;} private int x_abs = Int_.MinValue;
public int Y_abs() {return y_abs;} public Xog_layout_box Y_abs_(int v) {y_abs = v; return this;} private int y_abs = Int_.MinValue;
public int W_abs() {return w_abs;} public Xog_layout_box W_abs_(int v) {w_abs = v; return this;} private int w_abs = Int_.MinValue;
public int H_abs() {return h_abs;} public Xog_layout_box H_abs_(int v) {h_abs = v; return this;} private int h_abs = Int_.MinValue;
public int X_rel() {return x_rel;} public Xog_layout_box X_rel_(int v) {x_rel = v; return this;} private int x_rel = Int_.MinValue;
public int Y_rel() {return y_rel;} public Xog_layout_box Y_rel_(int v) {y_rel = v; return this;} private int y_rel = Int_.MinValue;
public int W_rel() {return w_rel;} public Xog_layout_box W_rel_(int v) {w_rel = v; return this;} private int w_rel = Int_.MinValue;
public int H_rel() {return h_rel;} public Xog_layout_box H_rel_(int v) {h_rel = v; return this;} private int h_rel = Int_.MinValue;
public String Text() {return text;} public Xog_layout_box Text_(String v) {text = v; return this;} private String text;
public String Font_name() {return font_name;} public Xog_layout_box Font_name_(String v) {font_name = v; return this;} private String font_name;
public float Font_size() {return font_size;} public Xog_layout_box Font_size_(float v) {font_size = v; return this;} float font_size = Float_.NaN;
public FontStyleAdp Font_style() {return font_style;} public Xog_layout_box Font_style_(FontStyleAdp v) {font_style = v; return this;} FontStyleAdp font_style;
public byte Mode() {return mode;} public Xog_layout_box Mode_(byte v) {mode = v; return this;} private byte mode = Mode_rel;
public void Adj_size(Rect_ref rect) {
if (w_abs > -1) rect.W_(w_abs); if (w_rel != Int_.MinValue) rect.W_(w_rel + rect.W());
if (h_abs > -1) rect.H_(h_abs); if (h_rel != Int_.MinValue) rect.H_(h_rel + rect.H());
}
public void Adj_pos(Rect_ref rect) {
if (x_abs > -1) rect.X_(x_abs); if (x_rel != Int_.MinValue) rect.X_(x_rel + rect.X());
if (y_abs > -1) rect.Y_(y_abs); if (y_rel != Int_.MinValue) rect.Y_(y_rel + rect.Y());
}
public void Adj_text(GfuiElem elem) {
if (text != null) elem.Text_(text);
if (font_name != null || !Float_.IsNaN(font_size) || font_style != null)
elem.TextMgr().Font_(Font_make(font_name, font_size, font_style));
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_x_abs_)) x_abs = m.ReadInt("v");
else if (ctx.Match(k, Invk_y_abs_)) y_abs = m.ReadInt("v");
else if (ctx.Match(k, Invk_w_abs_)) w_abs = m.ReadInt("v");
else if (ctx.Match(k, Invk_h_abs_)) h_abs = m.ReadInt("v");
else if (ctx.Match(k, Invk_x_rel_)) x_rel = m.ReadInt("v");
else if (ctx.Match(k, Invk_y_rel_)) y_rel = m.ReadInt("v");
else if (ctx.Match(k, Invk_w_rel_)) w_rel = m.ReadInt("v");
else if (ctx.Match(k, Invk_h_rel_)) h_rel = m.ReadInt("v");
else if (ctx.Match(k, Invk_size_abs_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 2, null); if (ary != null) {w_abs = ary[0]; h_abs = ary[1];}}
else if (ctx.Match(k, Invk_size_rel_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 2, null); if (ary != null) {w_rel = ary[0]; h_rel = ary[1];}}
else if (ctx.Match(k, Invk_pos_abs_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 2, null); if (ary != null) {x_abs = ary[0]; y_abs = ary[1];}}
else if (ctx.Match(k, Invk_pos_rel_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 2, null); if (ary != null) {x_rel = ary[0]; y_rel = ary[1];}}
else if (ctx.Match(k, Invk_rect_abs_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 4, null); if (ary != null) {w_abs = ary[0]; h_abs = ary[1]; x_abs = ary[2]; y_abs = ary[3];}}
else if (ctx.Match(k, Invk_rect_rel_)) {int[] ary = Int_.Ary_parse(m.ReadStr("v"), 4, null); if (ary != null) {w_rel = ary[0]; h_rel = ary[1]; x_rel = ary[2]; y_rel = ary[3];}}
else if (ctx.Match(k, Invk_text_)) text = m.ReadStr("v");
else if (ctx.Match(k, Invk_font_name_)) font_name = m.ReadStr("v");
else if (ctx.Match(k, Invk_font_size_)) font_size = m.ReadFloat("v");
else if (ctx.Match(k, Invk_font_style_)) font_style = FontStyleAdp_.parse_(m.ReadStr("v"));
else if (ctx.Match(k, Invk_mode_)) mode = String_.Eq(m.ReadStr("v"), "abs") ? Mode_abs : Mode_rel;
else if (ctx.Match(k, Invk_owner)) return owner;
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final byte Mode_abs = 0, Mode_rel = 1;
static final String Invk_x_abs_ = "x_abs_", Invk_y_abs_ = "y_abs_", Invk_w_abs_ = "w_abs_", Invk_h_abs_ = "h_abs_", Invk_x_rel_ = "x_rel_", Invk_y_rel_ = "y_rel_", Invk_w_rel_ = "w_rel_", Invk_h_rel_ = "h_rel_"
, Invk_size_abs_ = "size_abs_", Invk_pos_abs_ = "pos_abs_", Invk_rect_abs_ = "rect_abs_", Invk_size_rel_ = "size_rel_", Invk_pos_rel_ = "pos_rel_", Invk_rect_rel_ = "rect_rel_"
, Invk_text_ = "text_"
, Invk_font_name_ = "font_name_", Invk_font_size_ = "font_size_", Invk_font_style_ = "font_style_", Invk_mode_ = "mode_", Invk_owner = "owner";
FontAdp Font_make(String font_name, float font_size, FontStyleAdp font_style) {
String new_font_name = font_name == null ? "Arial" : font_name;
float new_font_size = Float_.IsNaN(font_size) ? 8 : font_size;
FontStyleAdp new_font_style = font_style == null ? FontStyleAdp_.Plain : font_style;
return FontAdp.new_(new_font_name, new_font_size, new_font_style);
}
}

View File

@@ -0,0 +1,254 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.threads.*; import gplx.gfui.*; import gplx.xowa.gui.history.*; import gplx.xowa.gui.bnds.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.cfgs2.*;
public class Xog_tab_itm implements GfoInvkAble {
private Xog_win_itm win; private Xocfg_tab_mgr cfg_tab_mgr;
public Xog_tab_itm(Xog_tab_mgr tab_mgr, Gfui_tab_itm_data tab_data) {
this.tab_mgr = tab_mgr; this.tab_data = tab_data;
this.win = tab_mgr.Win(); this.cfg_tab_mgr = win.App().Cfg_regy ().App().Gui_mgr().Tab_mgr();
html_itm = new Xog_html_itm(this);
cmd_sync = win.Kit().New_cmd_sync(this);
}
public GfoInvkAble Cmd_sync() {return cmd_sync;} private GfoInvkAble cmd_sync;
public void Make_html_box(int uid, Gfui_tab_itm tab_box, Xog_win_itm win, GfuiElem owner) {
this.tab_box = tab_box;
Xoa_app app = win.App(); Xoa_gui_mgr gui_mgr = win.Gui_mgr(); Gfui_kit kit = win.Kit();
Gfui_html html_box = kit.New_html("html_box" + Int_.XtoStr(uid), owner);
html_box.Html_js_enabled_(gui_mgr.Html_mgr().Javascript_enabled());
html_box.Html_invk_src_(win);
html_itm.Html_box_(html_box);
if (app.Mode() == Xoa_app_.Mode_gui) { // NOTE: only run for gui; will cause firefox addon to fail; DATE:2014-05-03
html_box.Html_doc_html_(""); // NOTE: must set source, else control will be empty, and key events will not be raised; DATE:2014-04-30
IptBnd_.ipt_to_(IptCfg_.Null, html_box, this, "popup", IptEventType_.MouseDown, IptMouseBtn_.Right);
GfoEvMgr_.SubSame(html_box, GfuiElemKeys.Evt_menu_detected, html_itm);
gui_mgr.Bnd_mgr().Bind(Xog_bnd_box_.Tid_browser_html, html_box);
if (!Env_.Mode_testing())
kit.Set_mnu_popup(html_box, gui_mgr.Menu_mgr().Popup().Html_page().Under_mnu());
}
}
public void Switch_mem(Xog_tab_itm comp) {
html_itm.Switch_mem(comp.html_itm); // switch html_itm.owner_tab reference only
Xog_html_itm temp_html_itm = html_itm; // switch .html_itm, since the underlying CTabFolder has reparented the control
this.html_itm = comp.html_itm;
comp.html_itm = temp_html_itm;
Xoa_page temp_page = page; // switch .page, since its underlying html_box has changed and .page must reflect html_box
this.page = comp.page;
comp.page = temp_page;
page.Tab_(this); comp.Page().Tab_(comp);
byte temp_view_mode = view_mode; // switch .view_mode to match .page
this.view_mode = comp.view_mode;
comp.view_mode = temp_view_mode;
Xog_history_mgr temp_history_mgr = history_mgr; // switch .history_mgr along with .page
this.history_mgr = comp.history_mgr;
comp.history_mgr = temp_history_mgr;
}
public Gfui_tab_itm_data Tab_data() {return tab_data;} private Gfui_tab_itm_data tab_data;
public String Tab_key() {return tab_data.Key();}
public int Tab_idx() {return tab_data.Idx();} public void Tab_idx_(int v) {tab_data.Idx_(v);}
public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr;
public Gfui_tab_itm Tab_box() {return tab_box;} private Gfui_tab_itm tab_box;
public boolean Tab_is_loading() {return tab_is_loading;} private boolean tab_is_loading;
public Xog_html_itm Html_itm() {return html_itm;} private Xog_html_itm html_itm;
public Gfui_html Html_box() {return html_itm.Html_box();}
public Xoa_page Page() {return page;}
public void Page_(Xoa_page page) {Page_(true, page);}
public void Page_(boolean update_ui, Xoa_page page) {
this.page = page;
if (update_ui) {
this.Tab_name_();
tab_box.Tab_tip_text_(String_.new_utf8_(page.Url().X_to_full()));
}
} private Xoa_page page;
public void Tab_name_() {
byte[] tab_name = page.Html_data().Custom_name();
if (tab_name == null) tab_name = page.Ttl().Full_txt();
Tab_name_(String_.new_utf8_(tab_name));
}
public void Tab_name_(String tab_name) {
Xocfg_tab_btn_mgr cfg_tab_btn_mgr = cfg_tab_mgr.Btn_mgr();
tab_name = Xog_tab_itm_.Tab_name_min(tab_name, cfg_tab_btn_mgr.Text_min_chars());
tab_name = Xog_tab_itm_.Tab_name_max(tab_name, cfg_tab_btn_mgr.Text_max_chars());
tab_box.Tab_name_(tab_name);
}
public Xog_history_mgr History_mgr() {return history_mgr;} private Xog_history_mgr history_mgr = new Xog_history_mgr();
public byte View_mode() {return view_mode;} public Xog_tab_itm View_mode_(byte v) {view_mode = v; return this;} private byte view_mode = Xog_page_mode.Tid_read;
public void Pin_toggle() {
}
public void Show_url_bgn(Xoa_url url) {
this.tab_is_loading = true;
Xoa_app app = win.App(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
Xoa_page page = Xoa_page.Empty;
if ( url.Anchor_str() != null // url has anchor
&& url.Eq_page(page.Url()) // url has same page_name as existing page
&& url.Args().length == 0) { // url has no args; needed for Category:A?from=b#mw-pages
html_itm.Scroll_page_by_id_gui(url.Anchor_str()); // skip page_load and jump to anchor
return;
}
if (win.Page__async__working(url)) return;
app.Gui_mgr().Search_suggest_mgr().Cancel(); // cancel pending search_suggest calls
app.Log_wtr().Queue_enabled_(true);
usr_dlg.Clear();
Xow_wiki wiki = url.Wiki();
wiki.Init_assert(); // NOTE: assert wiki.Init before parsing; needed b/c lang (with lang-specific ns) is only loaded on init, and parse Xoa_ttl.parse_ will fail below; EX:pt.wikipedia.org/wiki/Wikipedia:P<>gina principal
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, url.Page_bry());
if (ttl == null) {usr_dlg.Prog_one("", "", "title is invalid: ~{0}", String_.new_utf8_(url.Raw())); return;}
usr_dlg.Prog_one("", "", "loading: ~{0}", String_.new_utf8_(ttl.Raw()));
this.Html_box().Html_js_eval_script("xowa_popups_hide_all();");
app.Thread_mgr().Page_load_mgr().Add_at_end(new Load_page_wkr(this, wiki, url, ttl)).Run();
}
public void Show_url_loaded(Xoa_page page) {
Xow_wiki wiki = page.Wiki(); Xoa_url url = page.Url(); Xoa_ttl ttl = page.Ttl();
Xoa_app app = wiki.App(); Gfo_usr_dlg usr_dlg = app.Usr_dlg();
try {
wiki.Ctx().Cur_page_(page);
if (page.Missing()) {
if (wiki.Db_mgr().Save_mgr().Create_enabled()) {
page = Xoa_page.create_(wiki, ttl);
view_mode = Xog_page_mode.Tid_edit;
history_mgr.Add(page); // NOTE: must put new_page on stack so that pressing back will pop new_page, not previous page
Xog_tab_itm_read_mgr.Show_page(this, page, false);
}
else {
if (page.Redirect_list().Count() > 0)
usr_dlg.Prog_many("", "", "could not find: ~{0} (redirected from ~{1})", String_.new_utf8_(page.Url().Page_bry()), String_.new_utf8_((byte[])page.Redirect_list().FetchAt(0)));
else {
if (ttl.Ns().Id_file())
usr_dlg.Prog_one("", "", "commons.wikimedia.org must be installed in order to view the file. See [[Help:Wikis/Commons]]: ~{0}", String_.new_utf8_(url.Raw()));
else
usr_dlg.Prog_one("", "", "could not find: ~{0}", String_.new_utf8_(url.Raw()));
}
}
app.Log_wtr().Queue_enabled_(false);
return;
}
if (!page.Redirected()) page.Url_(url); // NOTE: handle redirect from commons
if (page.Ttl().Anch_bgn() != Bry_.NotFound) page.Url().Anchor_bry_(page.Ttl().Anch_txt()); // NOTE: occurs when page is a redirect to an anchor; EX: w:Duck race -> Rubber duck#Races
history_mgr.Add(page);
Xog_tab_itm_read_mgr.Show_page(this, page, true);
if (app.Api_root().Usr().History().Enabled()) app.User().History_mgr().Add(page);
usr_dlg.Prog_none("", "", "rendering html");
// win.Page__async__bgn(this);
app.Thread_mgr().File_load_mgr().Add_at_end(new Load_files_wkr(this)).Run();
}
finally {
app.Thread_mgr().Page_load_mgr().Resume();
this.tab_is_loading = false;
}
}
@gplx.Internal protected void Show_url_failed(Load_page_wkr wkr) {
try {
Xog_tab_itm_read_mgr.Show_page_err(win, this, wkr.Wiki(), wkr.Url(), wkr.Ttl(), wkr.Exc());
} finally {
wkr.Wiki().App().Thread_mgr().Page_load_mgr().Resume();
}
}
public void Async() {
if (page == null) return; // TEST: occurs during Xog_win_mgr_tst
Xow_wiki wiki = page.Wiki(); Xoa_app app = wiki.App(); Xog_win_itm win_itm = tab_mgr.Win(); Gfo_usr_dlg usr_dlg = win_itm.Usr_dlg();
app.Usr_dlg().Log_many("", "", "page.async: url=~{0}", page.Url().X_to_full_str_safe());
if (page.Url().Anchor_str() != null) html_itm.Scroll_page_by_id_gui(page.Url().Anchor_str());
if (usr_dlg.Canceled()) {usr_dlg.Prog_none("", "", ""); app.Log_wtr().Queue_enabled_(false); return;}
int xfer_len = 0;
xfer_len = page.File_queue().Count();
String page_ttl_str = String_.new_utf8_(page.Ttl().Raw());
if (xfer_len > 0){
usr_dlg.Prog_one("", "", "downloading images: ~{0}", xfer_len);
try {page.File_queue().Exec(gplx.xowa.files.Xof_exec_tid.Tid_wiki_page, usr_dlg, wiki, page);}
catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.image: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));}
}
xfer_len = page.File_math().Count();
if (xfer_len > 0){
try {
usr_dlg.Prog_one("", "", "generating math: ~{0}", xfer_len);
for (int i = 0; i < xfer_len; i++) {
if (usr_dlg.Canceled()) {usr_dlg.Prog_none("", "", ""); app.Log_wtr().Queue_enabled_(false); return;}
gplx.xowa.xtns.math.Xof_math_itm itm = (gplx.xowa.xtns.math.Xof_math_itm)page.File_math().FetchAt(i);
String queue_msg = usr_dlg.Prog_many("", "", "generating math ~{0} of ~{1}: ~{2}", i + ListAdp_.Base1, xfer_len, String_.new_utf8_(itm.Math()));
app.File_mgr().Math_mgr().MakePng(itm.Math(), itm.Hash(), itm.Png_url(), queue_msg);
gplx.gfui.SizeAdp size = app.File_mgr().Img_mgr().Wkr_query_img_size().Exec(itm.Png_url());
html_itm.Html_img_update("xowa_math_img_" + itm.Id(), itm.Png_url().To_http_file_str(), size.Width(), size.Height());
html_itm.Html_elem_delete("xowa_math_txt_" + itm.Id());
}
page.File_math().Clear();
}
catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.math: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));}
}
if (page.Html_cmd_mgr().Count() > 0) {
try {page.Html_cmd_mgr().Exec(app, page);}
catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.cmds: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));}
}
try {
Xop_lnki_logger_redlinks_wkr redlinks_wkr = new Xop_lnki_logger_redlinks_wkr(win_itm, page);
ThreadAdp_.invk_(redlinks_wkr, gplx.xowa.parsers.lnkis.redlinks.Xop_lnki_logger_redlinks_wkr.Invk_run).Start();
usr_dlg.Prog_none("", "imgs.done", "");
} catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.redlinks: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));}
try {app.File_mgr().Cache_mgr().Compress_check();}
catch (Exception e) {usr_dlg.Warn_many("", "", "page.thread.cache: page=~{0} err=~{1}", page_ttl_str, Err_.Message_gplx_brief(e));}
app.Log_wtr().Queue_enabled_(false);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_show_url_loaded_swt)) this.Show_url_loaded((Xoa_page)m.ReadObj("v"));
else if (ctx.Match(k, Invk_show_url_failed_swt)) this.Show_url_failed((Load_page_wkr)m.ReadObj("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final String Invk_show_url_loaded_swt = "show_url_loaded_swt", Invk_show_url_failed_swt = "show_url_failed_swt";
}
class Load_page_wkr implements Gfo_thread_wkr {
private Xog_tab_itm tab;
public Load_page_wkr(Xog_tab_itm tab, Xow_wiki wiki, Xoa_url url, Xoa_ttl ttl) {this.tab = tab; this.wiki = wiki; this.url = url; this.ttl = ttl;}
public String Name() {return "xowa.load_page_wkr";}
public boolean Resume() {return false;}
public Xow_wiki Wiki() {return wiki;} private Xow_wiki wiki;
public Xoa_url Url() {return url;} private Xoa_url url;
public Xoa_ttl Ttl() {return ttl;} private Xoa_ttl ttl;
public Exception Exc() {return exc;} private Exception exc;
public void Exec() {
try {
Xoa_app app = wiki.App();
app.Usr_dlg().Log_many("", "", "page.load: url=~{0}", url.X_to_full_str_safe());
if (Env_.System_memory_free() < app.Sys_cfg().Free_mem_when()) // check if low in memory
app.Free_mem(false); // clear caches (which will clear bry_bfr_mk)
else // not low in memory
app.Utl_bry_bfr_mkr().Clear(); // clear bry_bfr_mk only; NOTE: call before page parse, not when page is first added, else threading errors; DATE:2014-05-30
Xoa_page page = wiki.GetPageByTtl(url, ttl, tab);
GfoInvkAble_.InvkCmd_val(tab.Cmd_sync(), Xog_tab_itm.Invk_show_url_loaded_swt, page);
}
catch (Exception e) {
this.exc = e;
GfoInvkAble_.InvkCmd_val(tab.Cmd_sync(), Xog_tab_itm.Invk_show_url_failed_swt, this);
}
}
}
class Load_files_wkr implements Gfo_thread_wkr {
private Xog_tab_itm tab;
public Load_files_wkr(Xog_tab_itm tab) {this.tab = tab;}
public String Name() {return "xowa.load_files_wkr";}
public boolean Resume() {return true;}
public void Exec() {
try {tab.Async();}
catch (Exception e) {
tab.Tab_mgr().Win().App().Usr_dlg().Warn_many("error while running file wkr; page=~{0} err=~{1}", tab.Page().Url().X_to_full_str(), Err_.Message_gplx_brief(e));
}
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
public class Xog_tab_itm_ {
public static String Tab_name_min(String name, int min) {
int name_len = String_.Len(name);
return min == Tab_name_min_disabled || name_len > min ? name : name + String_.Repeat(" ", min - name_len);
}
public static String Tab_name_max(String name, int max) {
int name_len = String_.Len(name);
return max == Tab_name_max_disabled || name_len <= max ? name : String_.Mid(name, 0, max) + "...";
}
public static final int Tab_name_min_disabled = -1, Tab_name_max_disabled = -1;
public static final Xog_tab_itm Null = null;
}

View File

@@ -0,0 +1,123 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.xowa.html.*;
public class Xog_tab_itm_edit_mgr {
public static void Save(Xog_tab_itm tab, boolean quick_save) {
if (tab.View_mode() != Xog_page_mode.Tid_edit) return; // exit if not edit; handles ctrl+s being pressed on read/html modes
Xoa_page page = tab.Page(); Xow_wiki wiki = page.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
byte[] new_text = Get_new_text(tab);
if (page.Edit_mode() == Xoa_page_.Edit_mode_create) {
wiki.Db_mgr().Save_mgr().Data_create(page.Ttl(), new_text);
page.Edit_mode_update_(); // set to update so that next save does not try to create
}
else
wiki.Db_mgr().Save_mgr().Data_update(page, new_text);
Invalidate(wiki);
page.Data_raw_(new_text);
wiki.ParsePage_root(page, true); // refresh html
win_itm.Usr_dlg().Prog_one("", "", "saved page ~{0}", String_.new_utf8_(page.Ttl().Full_txt_raw())); // NOTE: show message after ParsePage_root, b/c ParsePage_root will flash "Loading page"; DATE:2014-05-17
if (!quick_save) { // full_save; save page and go to read mode
page.Html_data().Edit_preview_(Bry_.Empty);
Xoa_page stack_page = tab.History_mgr().Cur_page(wiki); // NOTE: must be to CurPage() else changes will be lost when going Bwd,Fwd
stack_page.Data_raw_(page.Data_raw()); // NOTE: overwrite with "saved" changes
stack_page.Wiki().ParsePage_root(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
win_itm.Page__mode_(Xog_page_mode.Tid_read);
win_itm.Page__async__bgn(tab);
}
}
public static void Preview(Xog_tab_itm tab) {
if (tab.View_mode() != Xog_page_mode.Tid_edit) return; // exit if not edit; handles preview somehow being called?
Xoa_page page = tab.Page(); Xow_wiki wiki = page.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
Xog_html_itm html_itm = tab.Html_itm();
byte[] new_text = Get_new_text(tab);
Xoa_page new_page = Xoa_page.new_(wiki, page.Ttl());
new_page.Revision_data().Id_(page.Revision_data().Id()); // NOTE: page_id needed for sqlite (was not needed for xdat)
new_page.Data_raw_(new_text);
wiki.ParsePage_root(new_page, true); // refresh html
tab.Page_(new_page);
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_m001();
Xoh_page_wtr_wkr wkr = wiki.Html_mgr().Page_wtr_mgr().Wkr(Xog_page_mode.Tid_read);
wkr.Page_(new_page);
wkr.XferAry(tmp_bfr, 0);
byte[] new_html = tmp_bfr.Mkr_rls().XtoAryAndClear();
new_page.Html_data().Edit_preview_(new_html);
Invalidate(wiki);
win_itm.Page__mode_(Xog_page_mode.Tid_edit);
html_itm.Scroll_page_by_id_gui(Xog_html_itm.Elem_id__first_heading);// NOTE: was originally directly; changed to call on thread; DATE:2014-05-03
win_itm.Page__async__bgn(tab); // NOTE: needed to show images during preview; DATE:2014-06-21
}
public static void Rename(Xog_tab_itm tab) {
if (tab.View_mode() != Xog_page_mode.Tid_edit) return; // exit if not edit; handles ctrl+r being pressed
Xoa_page page = tab.Page(); Xow_wiki wiki = page.Wiki(); Xog_win_itm win_itm = tab.Tab_mgr().Win();
if (Bry_.Eq(page.Ttl().Page_db(), wiki.Props().Main_page())) {
win_itm.Usr_dlg().Warn_many("", "", "The Main Page cannot be renamed");
return;
}
byte[] new_text = Bry_.new_utf8_(tab.Html_itm().Get_elem_value(Xog_html_itm.Elem_id__xowa_edit_rename_box));
if (Bry_.Len_eq_0(new_text)) return; // no ttl given; exit
new_text = Xoa_ttl.Replace_spaces(new_text); // ttls cannot have spaces; only underscores
Xoa_ttl new_ttl = Xoa_ttl.parse_(wiki, new_text);
int new_ns_id = new_ttl.Ns().Id();
if (new_ns_id != Xow_ns_.Id_main) {
win_itm.Usr_dlg().Warn_many("", "", "The new page name must remain in the same namespace");
return;
}
wiki.Db_mgr().Save_mgr().Data_rename(page, new_ns_id, new_text);
page.Ttl_(Xoa_ttl.parse_(wiki, Bry_.Add(page.Ttl().Ns().Name_db_w_colon(), new_text)));
win_itm.Page__mode_(Xog_page_mode.Tid_read);
win_itm.Usr_dlg().Prog_one("", "", "renamed page to {0}", String_.new_utf8_(page.Ttl().Full_txt_raw()));
}
public static void Focus(Xog_win_itm win, String elem_focus_id) {
Gfui_html html_box = win.Active_html_box();
html_box.Focus();
html_box.Html_elem_focus(elem_focus_id);
}
public static void Debug(Xog_win_itm win, byte view_tid) {
Xog_tab_itm tab = win.Tab_mgr().Active_tab(); Xoa_page page = tab.Page();
Xow_wiki wiki = page.Wiki(); Xop_ctx ctx = wiki.Ctx();
ctx.Defn_trace().Clear(); // TODO: move_me
ctx.Defn_trace_(Xot_defn_trace_dbg._);
Xoa_ttl ttl = page.Ttl();
Xoa_page new_page = Xoa_page.new_(page.Wiki(), ttl);
byte[] data = tab.Html_itm().Get_elem_value_for_edit_box_as_bry();
new_page.Data_raw_(data);
wiki.ParsePage_root(new_page, true);
Bry_bfr bfr = win.App().Utl_bry_bfr_mkr().Get_m001();
bfr.Add(new_page.Root().Root_src());
wiki.Ctx().Defn_trace().Print(data, bfr);
new_page.Data_raw_(bfr.Mkr_rls().XtoAryAndClear());
byte old = tab.View_mode();
tab.View_mode_(view_tid);
Xog_tab_itm_read_mgr.Show_page(tab, new_page, false);
tab.History_mgr().Add(new_page);
tab.View_mode_(old);
}
private static void Invalidate(Xow_wiki wiki) {// invalidate everything on updates; especially needed for page transclusion; {{/my_subpage}} DATE:2014-04-10
gplx.xowa.xtns.scribunto.Scrib_core.Core_invalidate();
wiki.Cache_mgr().Free_mem_all();
}
private static byte[] Get_new_text(Xog_tab_itm tab) {
byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry();
rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25
return rv;
}
}

View File

@@ -0,0 +1,111 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.threads.*;
import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.gui.history.*;
public class Xog_tab_itm_read_mgr {
public static void Async(Xog_tab_itm tab) {tab.Async();}
public static void Show_page(Xog_tab_itm tab, Xoa_page new_page, boolean reset_to_read) {Show_page(tab, new_page, reset_to_read, false, false, Xog_history_stack.Nav_fwd);}
public static void Show_page(Xog_tab_itm tab, Xoa_page new_page, boolean reset_to_read, boolean new_page_is_same, boolean show_is_err, byte history_nav_type) {
if (reset_to_read) tab.View_mode_(Xog_page_mode.Tid_read);
if (new_page.Url().Action_is_edit()) tab.View_mode_(Xog_page_mode.Tid_edit);
Xoa_page cur_page = tab.Page(); Xog_html_itm html_itm = tab.Html_itm(); Gfui_html html_box = html_itm.Html_box();
Xoa_app app = cur_page.App(); Xog_win_itm win = tab.Tab_mgr().Win();
if (cur_page != null && !new_page_is_same) { // if new_page_is_same, don't update DocPos; will "lose" current position
cur_page.Html_data().Bmk_pos_(html_box.Html_window_vpos());
tab.History_mgr().Update_html_doc_pos(cur_page, history_nav_type); // HACK: old_page is already in stack, but need to update its hdoc_pos
}
win.Usr_dlg().Prog_none("", "", "locating images");
try {tab.Html_itm().Show(new_page);}
catch (Exception e) {
if (show_is_err) { // trying to show error page, but failed; don't show again, else recursion until out of memory; TODO:always load error page; no reason it should fail; WHEN:html_skin; DATE:2014-06-08
String new_page_url = new_page.Url().X_to_full_str_safe();
String err_msg = "fatal error trying to load error page; page=" + new_page_url;
app.Usr_dlg().Warn_many("", "", err_msg);
app.Gui_mgr().Kit().Ask_ok("", "", err_msg);
return;
}
else
Show_page_err(win, tab, new_page.Wiki(), new_page.Url(), new_page.Ttl(), e);
return;
}
tab.Page_(new_page);
if (tab == tab.Tab_mgr().Active_tab())
Update_selected_tab(app, win, new_page.Url(), new_page.Ttl());
Xol_font_info lang_font = new_page.Wiki().Lang().Gui_font();
if (lang_font.Name() == null) lang_font = app.Gui_mgr().Win_cfg().Font();
Xog_win_itm_.Font_update(tab.Tab_mgr().Win(), lang_font);
tab.Tab_mgr().Tab_mgr().Focus();
html_box.Focus();
win.Usr_dlg().Prog_none("", "", ""); // blank out status bar
if (tab.View_mode() == Xog_page_mode.Tid_read)
html_itm.Scroll_page_by_bmk_gui();
else
GfoInvkAble_.InvkCmd_val(tab.Html_itm().Cmd_async(), Xog_html_itm.Invk_html_elem_focus, Xog_html_itm.Elem_id__xowa_edit_data_box); // NOTE: must be async, else won't work; DATE:2014-06-05
}
public static void Update_selected_tab_blank(Xoa_app app, Xog_win_itm win) {Update_selected_tab(app, win, null, null);} // called when all tabs are null
public static void Update_selected_tab(Xoa_app app, Xog_win_itm win, Xoa_url url, Xoa_ttl ttl) {
String url_str = "", win_str = Win_text_blank;
if (url != null && ttl != null) {
try {url_str = app.Url_parser().Build_str(url);}
catch (Exception e) { // HACK: failed pages will have a null wiki; for now, catch and ignore; DATE:2014-06-22
app.Usr_dlg().Warn_many("", "", "failed to build url: url=~{0}, err=~{1}", String_.new_utf8_(url.Raw()), Err_.Message_gplx(e));
url_str = String_.new_utf8_(ttl.Full_txt());
}
win_str = String_.new_utf8_(Bry_.Add(ttl.Full_txt(), Win_text_suffix_page));
}
win.Url_box().Text_(url_str);
win.Win_box().Text_(win_str);
}
private static final byte[] Win_text_suffix_page = Bry_.new_ascii_(" - XOWA"); private static final String Win_text_blank = "XOWA";
public static void Show_page_err(Xog_win_itm win, Xog_tab_itm tab, Xow_wiki wiki, Xoa_url url, Xoa_ttl ttl, Exception e) {
String err_msg = String_.Format("page_load fail: page={0} err={1}", String_.new_utf8_(url.Raw()), Err_.Message_gplx(e));
win.Usr_dlg().Warn_many("", "", err_msg);
win.App().Log_wtr().Queue_enabled_(false);
Xoa_page fail_page = wiki.Data_mgr().Get_page(ttl, false);
tab.View_mode_(Xog_page_mode.Tid_edit);
Update_selected_tab(win.App(), win, url, ttl);
Show_page(tab, fail_page, false, false, true, Xog_history_stack.Nav_fwd);
win.Win_box().Text_(err_msg);
}
public static void Launch(Xog_win_itm win) {
Xoa_app app = win.App();
Gfo_log_bfr log_bfr = app.Log_bfr();
log_bfr.Add("app.launch.page.bgn");
Xow_wiki home_wiki = app.User().Wiki();
Xoa_page launch_page = Xog_tab_itm_read_mgr.Launch_page(win, home_wiki, app.Sys_cfg().Launch_url());
if (launch_page.Missing())
launch_page = Xog_tab_itm_read_mgr.Launch_page(win, home_wiki, Xoa_sys_cfg.Launch_url_dflt);
log_bfr.Add("app.launch.page.show");
Xog_tab_itm tab = win.Active_tab();
Xog_tab_itm_read_mgr.Show_page(tab, launch_page, false);
tab.History_mgr().Add(launch_page);
tab.Html_itm().Html_box().Focus(); //this.Html_box().Html_doc_body_focus(); // focus the html_box so wheel scroll works; DATE:2013-02-08
app.Gui_wtr().Prog_none("", "", "");
log_bfr.Add("app.launch.page.end");
app.Gui_wtr().Log_wtr().Log_msg_to_session_direct(log_bfr.Xto_str());
}
private static Xoa_page Launch_page(Xog_win_itm win, Xow_wiki home_wiki, String launch_str) {
Xoa_url launch_url = Xoa_url_parser.Parse_url(win.App(), home_wiki, launch_str);
Xow_wiki launch_wiki = launch_url.Wiki();
Xoa_ttl launch_ttl = Xoa_ttl.parse_(launch_wiki, launch_url.Page_bry());
Xoa_page rv = launch_wiki.GetPageByTtl(launch_url, launch_ttl).Url_(launch_url); // FUTURE: .Url_() should not be called (needed for anchor); EX: en.wikipedia.org/Earth#Biosphere
win.Active_page_(rv); // set to blank page
return rv;
}
}

View File

@@ -0,0 +1,247 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.xowa.cfgs2.*;
public class Xog_tab_mgr implements GfoEvObj {
private OrderedHash tab_regy = OrderedHash_.new_(); private int tab_uid = 0;
public Xog_tab_mgr(Xog_win_itm win) {
this.win = win;
ev_mgr = GfoEvMgr.new_(this);
}
public GfoEvMgr EvMgr() {return ev_mgr;} private GfoEvMgr ev_mgr;
public Xog_win_itm Win() {return win;} private Xog_win_itm win;
public Gfui_tab_mgr Tab_mgr() {return tab_mgr;} private Gfui_tab_mgr tab_mgr;
public void Init_by_kit(Gfui_kit kit) {
tab_mgr = kit.New_tab_mgr("xowa.tab_mgr", win.Win_box());
active_tab = Xog_tab_itm_.Null;
tab_mgr.Btns_selected_color_(ColorAdp_.White);
tab_mgr.Btns_unselected_color_(ColorAdp_.LightGray);
GfoEvMgr_.SubSame_many(tab_mgr, this, Gfui_tab_mgr.Evt_tab_selected, Gfui_tab_mgr.Evt_tab_closed, Gfui_tab_mgr.Evt_tab_switched);
Xocfg_tab_btn_mgr btn_mgr = win.App().Cfg_regy().App().Gui_mgr().Tab_mgr().Btn_mgr();
Btns_place_on_top_(btn_mgr.Place_on_top());
Btns_curved_(btn_mgr.Curved());
Btns_close_visible_(btn_mgr.Close_visible());
Btns_unselected_close_visible_(btn_mgr.Unselected_close_visible());
Btns_height_(btn_mgr.Height());
GfoEvMgr_.SubSame_many(btn_mgr, this
, Xocfg_tab_btn_mgr.Evt_place_on_top_changed, Xocfg_tab_btn_mgr.Evt_height_changed, Xocfg_tab_btn_mgr.Evt_curved_changed
, Xocfg_tab_btn_mgr.Evt_close_visible_changed, Xocfg_tab_btn_mgr.Evt_unselected_close_visible_changed
, Xocfg_tab_btn_mgr.Evt_text_min_chars_changed, Xocfg_tab_btn_mgr.Evt_text_max_chars_changed
, Xocfg_tab_btn_mgr.Evt_hide_if_one_changed
);
}
public Xog_tab_itm Active_tab() {return active_tab;} private Xog_tab_itm active_tab;
public Xog_tab_itm Active_tab_assert() {
if (active_tab == Xog_tab_itm_.Null) this.Tabs_new_dflt(false, true); // update_ui=false; create dflt tab, but do not update name; will be updated later by whatever loads page
return active_tab;
}
public boolean Active_tab_is_null() {return active_tab == Xog_tab_itm_.Null;}
private void Btns_place_on_top_(boolean v) {tab_mgr.Btns_place_on_top_(v);}
private void Btns_curved_(boolean v) {tab_mgr.Btns_curved_(v);}
private void Btns_height_(int v) {tab_mgr.Btns_height_(v);}
private void Btns_close_visible_(boolean v) {tab_mgr.Btns_close_visible_(v);}
private void Btns_unselected_close_visible_(boolean v) {tab_mgr.Btns_unselected_close_visible_(v);}
private void Btns_text_recalc() {
int len = this.Tabs_len();
for (int i = 0; i < len; i++) {
Xog_tab_itm tab_itm = this.Tabs_get_at(i);
tab_itm.Tab_name_();
}
}
public int Tabs_len() {return tab_regy.Count();}
public void Tabs_new_init() {
this.Tabs_new(true, true);
}
public Xog_tab_itm Tabs_get_at(int i) {return (Xog_tab_itm)tab_regy.FetchAt(i);}
public Xog_tab_itm Tabs_new_dflt() {return Tabs_new_dflt(false);}
public Xog_tab_itm Tabs_new_dflt(boolean focus) {return Tabs_new_dflt(false, focus);}
public Xog_tab_itm Tabs_new_dflt(boolean update_ui, boolean focus) {
boolean active_tab_is_null = this.Active_tab_is_null();
Xow_wiki cur_wiki = active_tab_is_null ? win.App().User().Wiki() : active_tab.Page().Wiki();
Xog_tab_itm rv = Tabs_new(focus, active_tab_is_null);
Xoa_ttl ttl = Xoa_ttl.parse_(cur_wiki, gplx.xowa.specials.xowa.default_tab.Default_tab_page.Ttl_full_bry);
Xoa_url url = Xoa_url_parser.Parse_from_url_bar(win.App(), cur_wiki, ttl.Full_db_as_str());
rv.Page_(update_ui, Xoa_page.new_(cur_wiki, ttl));
rv.Show_url_bgn(url);
return rv;
}
private Xog_tab_itm Tabs_new(boolean focus, boolean active_tab_is_null) {
String tab_key = "tab_" + Int_.XtoStr(tab_uid++); int tab_idx = tab_regy.Count();
Gfui_tab_itm_data tab_data = new Gfui_tab_itm_data(tab_key, tab_idx);
Xog_tab_itm rv = new Xog_tab_itm(this, tab_data);
Gfui_tab_itm tab_box = tab_mgr.Tabs_add(tab_data);
rv.Make_html_box(tab_uid, tab_box, win, tab_mgr);
tab_box.Subs_add(rv.Html_itm().Html_box());
tab_regy.Add(tab_key, rv);
if ( focus
|| active_tab_is_null // NOTE: must select 1st tab, else nothing will show in tab box
) {
tab_mgr.Tabs_select_by_idx(rv.Tab_idx());
active_tab = rv;
}
Tabs_hide_if_one_chk();
return rv;
}
public void Tabs_new_dupe(boolean focus) {
if (this.Active_tab_is_null()) return;
String url = active_tab.Page().Url().X_to_full_str();
Tabs_new_dflt(focus);
win.Page__navigate_by_url_bar(url);
}
public void Tabs_javascript_enabled_(boolean v) {
int len = tab_regy.Count();
for (int i = 0; i < len; i++) {
Xog_tab_itm tab = Tabs_get_by_idx_or_warn(i);
tab.Html_itm().Js_enabled_(v);
}
}
private void Tabs_selected(String key) {
Xog_tab_itm tab = Tabs_get_by_key_or_warn(key); if (tab == null) return;
active_tab = tab;
Xoa_page page = tab.Page();
Xog_tab_itm_read_mgr.Update_selected_tab(win.App(), win, page.Url(), page.Ttl());
tab.Html_itm().Tab_selected(page);
}
public void Tabs_close_cur() {
if (this.Active_tab_is_null()) return;
tab_mgr.Tabs_close_by_idx(active_tab.Tab_idx());
}
public void Tabs_close_others() {this.Tabs_close_to_bgn(); this.Tabs_close_to_end();}
public void Tabs_close_to_bgn() {if (Active_tab_is_null()) return; Tabs_close_rng(0 , active_tab.Tab_idx());}
public void Tabs_close_to_end() {if (Active_tab_is_null()) return; Tabs_close_rng(active_tab.Tab_idx() + 1 , tab_regy.Count());}
public void Tabs_close_rng(int bgn, int end) {
for (int i = bgn; i < end; i++)
tab_mgr.Tabs_close_by_idx(bgn);
}
public void Tabs_close_undo() {
if (closed_undo_list.Count() == 0) return;
String url = (String)ListAdp_.Pop(closed_undo_list);
Tabs_new_dflt(true);
win.Page__navigate_by_url_bar(url);
}
private ListAdp closed_undo_list = ListAdp_.new_();
private void Tabs_closed(String key) {
Xog_tab_itm itm = Tabs_get_by_key_or_warn(key); if (itm == null) return;
closed_undo_list.Add(itm.Page().Url().X_to_full_str());
tab_regy.Del(key);
if (tab_regy.Count() == 0) {
active_tab = Xog_tab_itm_.Null;
Xog_tab_itm_read_mgr.Update_selected_tab_blank(win.App(), win);
}
else
Tabs_recalc_idx();
Tabs_hide_if_one_chk();
}
private Xog_tab_itm Tabs_get_by_key_or_warn(String key) {
Xog_tab_itm rv = (Xog_tab_itm)tab_regy.Fetch(key); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; key={0}", key);
return rv;
}
private Xog_tab_itm Tabs_get_by_idx_or_warn(int idx) {
Xog_tab_itm rv = (Xog_tab_itm)tab_regy.FetchAt(idx); if (rv == null) win.App().Usr_dlg().Warn_many("", "", "tab.selected could not find tab; idx={0}", idx);
return rv;
}
private void Tabs_recalc_idx() {
int len = tab_regy.Count();
for (int i = 0; i < len; i++) {
Xog_tab_itm itm = Tabs_get_by_idx_or_warn(i);
itm.Tab_idx_(i);
}
}
public void Tabs_select(boolean fwd) {
if (this.Active_tab_is_null()) return;
int new_idx = TabBox_.Cycle(fwd, active_tab.Tab_idx(), tab_regy.Count());
tab_mgr.Tabs_select_by_idx(new_idx);
}
public void Tabs_select_by_idx(int v) {
if (v >= tab_regy.Count()) return;
tab_mgr.Tabs_select_by_idx(v);
}
public void Tabs_move(boolean fwd) {
if (this.Active_tab_is_null()) return;
int src_idx = active_tab.Tab_idx();
int trg_idx = TabBox_.Cycle(fwd, src_idx, tab_regy.Count());
tab_mgr.Tabs_switch(src_idx, trg_idx);
}
private void Tabs_switched(String src_key, String trg_key) {
Xog_tab_itm src_itm = Tabs_get_by_key_or_warn(src_key);
Xog_tab_itm trg_itm = Tabs_get_by_key_or_warn(trg_key);
src_itm.Switch_mem(trg_itm);
active_tab = trg_itm; // NOTE: src_itm initiated switch, but trg_itm is now active b/c everything in src_itm has now been reparented to trg_itm; DATE:2014-05-12
}
public void Tabs_new_link(boolean focus, String link) {
if (String_.Len_eq_0(link)) {
if (this.Active_tab_is_null()) return;
link = active_tab.Html_itm().Html_selected_get_text_or_href();
}
if (String_.Len_eq_0(link)) {win.App().Usr_dlg().Prog_many("", "", "no link or text selected"); return;}
Tabs_new_link(link, focus);
}
public void Tabs_new_link(String link, boolean focus) {
Xow_wiki wiki = active_tab.Page().Wiki();
Xoa_url url = Xoa_url_parser.Parse_from_url_bar(win.App(), wiki, link); // NOTE: link must be of form domain/wiki/page; DATE:2014-05-27
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, url.Page_bry());
Xog_tab_itm new_tab = Tabs_new(focus, false);
new_tab.Page_(false, Xoa_page.new_(wiki, ttl));
new_tab.Tab_name_(String_.new_utf8_(Xoa_ttl.Replace_unders(url.Page_bry())));
new_tab.Show_url_bgn(url);
if (focus)
tab_mgr.Tabs_select_by_idx(new_tab.Tab_idx());
}
private void Tabs_hide_if_one_chk() {
gplx.xowa.cfgs2.Xocfg_tab_btn_mgr btn_mgr = win.App().Cfg_regy().App().Gui_mgr().Tab_mgr().Btn_mgr();
if (!btn_mgr.Hide_if_one()) return;
if (tab_regy.Count() > 1) {
if (tab_mgr.Btns_height() != btn_mgr.Height())
Btns_height_(btn_mgr.Height());
}
else {
if (tab_mgr.Btns_height() != 0)
Btns_height_(0);
}
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_tabs_new_dflt__at_dflt__focus_y)) Tabs_new_dflt(Bool_.Y);
else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_n)) Tabs_new_link(Bool_.N, m.ReadStrOr("v", null));
else if (ctx.Match(k, Invk_tabs_new_link__at_dflt__focus_y)) Tabs_new_link(Bool_.Y, m.ReadStrOr("v", null));
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_selected)) Tabs_selected(m.ReadStr("key"));
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_closed)) Tabs_closed(m.ReadStr("key"));
else if (ctx.Match(k, Gfui_tab_mgr.Evt_tab_switched)) Tabs_switched(m.ReadStr("src"), m.ReadStr("trg"));
else if (ctx.Match(k, Invk_tabs_close_cur)) Tabs_close_cur();
else if (ctx.Match(k, Invk_tabs_select_bwd)) Tabs_select(Bool_.N);
else if (ctx.Match(k, Invk_tabs_select_fwd)) Tabs_select(Bool_.Y);
else if (ctx.Match(k, Invk_tabs_switch_cur_bwd)) Tabs_move(Bool_.N);
else if (ctx.Match(k, Invk_tabs_switch_cur_fwd)) Tabs_move(Bool_.Y);
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_place_on_top_changed)) Btns_place_on_top_(m.ReadBool("v"));
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_curved_changed)) Btns_curved_(m.ReadBool("v"));
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_height_changed)) Btns_height_(m.ReadInt("v"));
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_close_visible_changed)) Btns_close_visible_(m.ReadBool("v"));
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_unselected_close_visible_changed)) Btns_unselected_close_visible_(m.ReadBool("v"));
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_text_min_chars_changed)) Btns_text_recalc();
else if (ctx.Match(k, Xocfg_tab_btn_mgr.Evt_text_max_chars_changed)) Btns_text_recalc();
else return GfoInvkAble_.Rv_unhandled;
return this;
}
public static final String
Invk_tabs_select_fwd = "tabs_select_fwd" , Invk_tabs_select_bwd = "tabs_select_bwd"
, Invk_tabs_switch_cur_fwd = "tabs_switch_cur_fwd" , Invk_tabs_switch_cur_bwd = "tabs_switch_cur_bwd"
, Invk_tabs_new_dflt__at_dflt__focus_y = "tabs_new_dflt__at_dflt__focus_y"
, Invk_tabs_new_link__at_dflt__focus_n = "tabs_new_link__at_dflt__focus_n"
, Invk_tabs_new_link__at_dflt__focus_y = "tabs_new_link__at_dflt__focus_y"
, Invk_tabs_close_cur = "tabs_close_cur"
;
}

View File

@@ -0,0 +1,306 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.threads.*; import gplx.gfui.*; import gplx.xowa.gui.*; import gplx.xowa.gui.history.*; import gplx.xowa.xtns.math.*; import gplx.xowa.files.*;
import gplx.xowa.gui.urls.*; import gplx.xowa.gui.views.*;
import gplx.xowa.parsers.lnkis.redlinks.*;
public class Xog_win_itm implements GfoInvkAble, GfoEvObj {
private GfoInvkAble sync_cmd;
public Xog_win_itm(Xoa_app app, Xoa_gui_mgr gui_mgr) {
this.app = app; this.gui_mgr = gui_mgr;
this.tab_mgr = new Xog_tab_mgr(this);
}
public Gfui_kit Kit() {return kit;} private Gfui_kit kit;
public Xoa_gui_mgr Gui_mgr() {return gui_mgr;} private Xoa_gui_mgr gui_mgr;
public GfuiWin Win_box() {return win_box;} private GfuiWin win_box;
public GfuiBtn Go_bwd_btn() {return go_bwd_btn;} private GfuiBtn go_bwd_btn;
public GfuiBtn Go_fwd_btn() {return go_fwd_btn;} private GfuiBtn go_fwd_btn;
public GfuiTextBox Url_box() {return url_box;} private GfuiTextBox url_box;
public GfuiBtn Url_exec_btn() {return url_exec_btn;} private GfuiBtn url_exec_btn;
public GfuiTextBox Search_box() {return search_box;} private GfuiTextBox search_box;
public GfuiBtn Search_exec_btn() {return search_exec_btn;} private GfuiBtn search_exec_btn;
public GfuiTextBox Find_box() {return find_box;} private GfuiTextBox find_box;
public GfuiBtn Find_close_btn() {return find_close_btn;} private GfuiBtn find_close_btn;
public GfuiBtn Find_fwd_btn() {return find_fwd_btn;} private GfuiBtn find_fwd_btn;
public GfuiBtn Find_bwd_btn() {return find_bwd_btn;} private GfuiBtn find_bwd_btn;
public GfuiTextBox Prog_box() {return prog_box;} private GfuiTextBox prog_box;
public GfuiTextBox Info_box() {return info_box;} private GfuiTextBox info_box;
public GfoEvMgr EvMgr() {if (evMgr == null) evMgr = GfoEvMgr.new_(this); return evMgr;} private GfoEvMgr evMgr;
public Xoa_app App() {return app;} private Xoa_app app;
public Xog_tab_mgr Tab_mgr() {return tab_mgr;} private Xog_tab_mgr tab_mgr;
public Xog_tab_itm Active_tab() {return tab_mgr.Active_tab();}
public Xoa_page Active_page() {return tab_mgr.Active_tab().Page();} public void Active_page_(Xoa_page v) {tab_mgr.Active_tab().Page_(v);}
public Xog_html_itm Active_html_itm() {return tab_mgr.Active_tab().Html_itm();}
public Gfui_html Active_html_box() {return tab_mgr.Active_tab().Html_itm().Html_box();}
public Xog_resizer Resizer() {return resizer;} private Xog_resizer resizer = new Xog_resizer();
public Gfo_usr_dlg Usr_dlg() {return app.Usr_dlg();}
public void Refresh_win_size() {
if (win_box != null) // NOTE: will be null when html box adjustment pref is set and application is starting
resizer.Exec_win_resize(app, win_box.Width(), win_box.Height());
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_link_click)) Win__link_click();
else if (ctx.Match(k, Invk_link_print)) Xog_win_itm__prog_href_mgr.Print(this);
else if (ctx.Match(k, Gfui_html.Evt_link_hover)) Xog_win_itm__prog_href_mgr.Hover(app, this.Active_page(), m.ReadStr("v"));
else if (ctx.Match(k, Gfui_html.Evt_location_changed)) Win__link_clicked(m.ReadStr("v"));
else if (ctx.Match(k, Gfui_html.Evt_location_changing)) Page__navigate_by_internal_href(m.ReadStr("v"), tab_mgr.Active_tab());
else if (ctx.Match(k, Gfui_html.Evt_win_resized)) Refresh_win_size();
else if (ctx.Match(k, Invk_page_refresh)) Page__refresh();
else if (ctx.Match(k, Invk_page_async_exec)) Xog_tab_itm_read_mgr.Async((Xog_tab_itm)m.ReadObj("v"));
else if (ctx.Match(k, Invk_page_view_read)) Page__mode_(Xog_page_mode.Tid_read);
else if (ctx.Match(k, Invk_page_view_edit)) Page__mode_(Xog_page_mode.Tid_edit);
else if (ctx.Match(k, Invk_page_view_html)) Page__mode_(Xog_page_mode.Tid_html);
else if (ctx.Match(k, Invk_page_edit_save)) Xog_tab_itm_edit_mgr.Save(tab_mgr.Active_tab(), Bool_.N);
else if (ctx.Match(k, Invk_page_edit_save_draft)) Xog_tab_itm_edit_mgr.Save(tab_mgr.Active_tab(), Bool_.Y);
else if (ctx.Match(k, Invk_page_edit_preview)) Xog_tab_itm_edit_mgr.Preview(tab_mgr.Active_tab());
else if (ctx.Match(k, Invk_page_edit_rename)) Xog_tab_itm_edit_mgr.Rename(tab_mgr.Active_tab());
else if (ctx.Match(k, Invk_page_edit_focus_box)) Xog_tab_itm_edit_mgr.Focus(this, Xog_html_itm.Elem_id__xowa_edit_data_box);
else if (ctx.Match(k, Invk_page_edit_focus_first)) Xog_tab_itm_edit_mgr.Focus(this, Xog_html_itm.Elem_id__first_heading);
else if (ctx.Match(k, Invk_page_dbg_html)) Xog_tab_itm_edit_mgr.Debug(this, Xog_page_mode.Tid_html);
else if (ctx.Match(k, Invk_page_dbg_wiki)) Xog_tab_itm_edit_mgr.Debug(this, Xog_page_mode.Tid_edit);
else if (ctx.Match(k, Invk_page_goto)) Page__navigate_by_url_bar(m.ReadStr("v"));
else if (ctx.Match(k, Invk_page_goto_recent)) Page__navigate_by_url_bar(app.User().History_mgr().Get_at_last(app));
else if (ctx.Match(k, Invk_history_bwd)) {Page__navigate_by_history(Bool_.N);}
else if (ctx.Match(k, Invk_history_fwd)) {Page__navigate_by_history(Bool_.Y);}
else if (ctx.Match(k, Invk_app_exit)) App__exit();
else if (ctx.Match(k, Invk_eval)) App__eval(m.ReadStr("cmd"));
else if (ctx.Match(k, Invk_page_async_cancel_wait)) Page__async__cancel__wait();
else if (ctx.Match(k, Invk_page_async_restart)) Page__async__restart();
else if (ctx.Match(k, Invk_search)) Page__navigate_by_search();
else if (ctx.Match(k, Invk_window_font_changed)) Xog_win_itm_.Font_update(this, (Xol_font_info)m.CastObj("font"));
else if (ctx.Match(k, Invk_app)) return app;
else if (ctx.Match(k, Invk_page)) return this.Active_page();
else if (ctx.Match(k, Invk_wiki)) return this.Active_page().Wiki();
else return GfoInvkAble_.Rv_unhandled;
return this;
}
private static final String
Invk_page_async_exec = "page_async_exec"
, Invk_page_async_cancel_wait = "page_async_cancel_wait", Invk_page_async_restart = "page_async_restart"
;
public static final String
Invk_app = "app", Invk_wiki = "wiki", Invk_page = "page", Invk_shortcuts = "shortcuts"
, Invk_link_click = "link_click", Invk_link_print = "link_print"
, Invk_window_font_changed = "winow_font_changed"
, Invk_search = "search"
, Invk_page_view_edit = "page_view_edit", Invk_page_view_read = "page_view_read", Invk_page_view_html = "page_view_html"
, Invk_history_fwd = "history_fwd", Invk_history_bwd = "history_bwd"
, Invk_page_refresh = "page_refresh"
, Invk_page_edit_focus_box = "page_edit_focus_box", Invk_page_edit_focus_first = "page_edit_focus_first"
, Invk_page_edit_save = "page_edit_save", Invk_page_edit_save_draft = "page_edit_save_draft", Invk_page_edit_preview = "page_edit_preview", Invk_page_edit_rename = "page_edit_rename"
, Invk_page_dbg_wiki = "page_dbg_wiki", Invk_page_dbg_html = "page_dbg_html"
, Invk_app_exit = "app_exit"
, Invk_eval = "eval"
// xowa.gfs: shortcuts
, Invk_page_goto = "page_goto", Invk_page_goto_recent = "page_goto_recent"
;
private void Win__link_click() { // NOTE: only applies when content_editable=y; if n, then link_click will be handled by SwtBrowser location changed (Win__link_clicked)
Xog_tab_itm tab = tab_mgr.Active_tab(); Xoa_page page = tab.Page();
if (page.Wiki().Gui_mgr().Cfg_browser().Content_editable()) {
String href = tab.Html_itm().Html_box().Html_active_atr_get_str(Gfui_html.Atr_href, null);
if (String_.Len_eq_0(href)) return; // NOTE: href can be null for images; EX: [[File:Loudspeaker.svg|11px|link=|alt=play]]; link= basically means don't link to image
Page__navigate_by_internal_href(href, tab);
}
}
private void Win__link_clicked(String anchor_raw) {
String url = url_box.Text();
int pos = String_.FindFwd(url, gplx.xowa.html.Xoh_html_tag.Const_anchor);
if (pos != Bry_.NotFound) url = String_.Mid(url, 0, pos);
String anchor_str = Parse_evt_location_changing(anchor_raw);
byte[] anchor_bry = Bry_.new_utf8_(anchor_str);
Xog_tab_itm tab = tab_mgr.Active_tab(); Xoa_page page = tab.Page();
if (anchor_str != null) { // link has anchor
url_box.Text_(url + "#" + anchor_str); // update url box
page.Html_data().Bmk_pos_(Xog_history_itm.Html_doc_pos_toc); // HACK: anchor clicked; set docPos of curentPage to TOC (so back will go back to TOC)
tab.History_mgr().Update_html_doc_pos(page, Xog_history_stack.Nav_by_anchor); // HACK: update history_mgr; note that this must occur before setting Anchor (since Anchor will generate a new history itm)
page.Url().Anchor_bry_(anchor_bry); // update url
}
tab.History_mgr().Add(page);
app.User().History_mgr().Add(page.Url(), page.Ttl(), Bry_.Add_w_dlm(Byte_ascii.Hash, page.Url().Page_bry(), anchor_bry));
}
public void App__exit() {
if (!app.Term_cbk()) return; // NOTE: exit called by keyboard shortcut, or exit link; must call Term_cbk manually; Alt-F4/X button will call Term_cbk in closing event
app.Gui_mgr().Kit().Kit_term();
}
private void App__eval(String s) {
String snippet = this.Active_html_box().Html_elem_atr_get_str(s, Gfui_html.Atr_innerHTML);
app.Gfs_mgr().Run_str(snippet);
}
private static String Parse_evt_location_changing(String v) { // EX: about:blank#anchor -> anchor
int pos = String_.FindFwd(v, gplx.xowa.html.Xoh_html_tag.Const_anchor);
return pos == Bry_.NotFound
? null
: String_.Mid(v, pos + 1);
}
public void Page__mode_(byte new_mode_tid) {
Xog_tab_itm tab = tab_mgr.Active_tab(); Xoa_page page = tab.Page();
if ( new_mode_tid == Xog_page_mode.Tid_read // used to be && cur_view_tid == Edit; removed clause else redlinks wouldn't show when going form html to read (or clicking read multiple times) DATE: 2013-11-26;
&& !page.Missing() // if new page, don't try to reload
) {
// NOTE: if moving from "Edit" to "Read", reload page (else Preview changes will still show); NOTE: do not call Exec_page_reload / Exec_page_refresh, which will fire redlinks code
page = tab_mgr.Active_tab().History_mgr().Cur_page(page.Wiki()); // NOTE: must set to CurPage() else changes will be lost when going Bwd,Fwd
tab.Page_(page);
page.Wiki().ParsePage_root(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
Xoa_url url = page.Url();
if (url.Args_exists(Xoa_url_parser.Bry_arg_action, Xoa_url_parser.Bry_arg_action_edit)) // url has ?action=edit
app.Url_parser().Parse(url, url.X_to_full()); // remove all query args; handle (1) s.w:Earth?action=edit; (2) click on Read; DATE:2014-03-06
}
tab.View_mode_(new_mode_tid);
if (page.Missing()) return;
Xog_tab_itm_read_mgr.Show_page(tab, page, false);
// Exec_page_refresh(); // commented out; causes lnke to show as [2] instead of [1] when saving page; EX: [http://a.org b] DATE:2014-04-24
}
public void Page__navigate_by_search() {Page__navigate_by_url_bar(app.Gui_mgr().Win_cfg().Search_box_fmtr().Bld_str_many(search_box.Text()));}
public void Page__navigate_by_url_bar(String href) {
Xog_tab_itm tab = tab_mgr.Active_tab_assert();
Xoa_url url = Xoa_url_parser.Parse_from_url_bar(app, tab.Page().Wiki(), href);
tab.Show_url_bgn(url);
}
private void Page__navigate_by_internal_href(String href, Xog_tab_itm tab) { // NOTE: different from Navigate_by_url_bar in that it handles "file:///" and other @gplx.Internal protected formats; EX: "/site/", "about:blank"; etc..
Xoa_url url = Xog_url_wkr.Exec_url(this, href);
if (url != Xog_url_wkr.Rslt_handled)
tab.Show_url_bgn(url);
}
public void Page__navigate_by_history(boolean fwd) {
Xog_tab_itm tab = tab_mgr.Active_tab();
if (tab == Xog_tab_itm_.Null) return;
Xoa_page cur_page = tab.Page();
Xoa_page new_page = tab.History_mgr().Go_by_dir(cur_page.Wiki(), fwd);
if (new_page.Missing()) return;
byte history_nav_type = fwd ? Xog_history_stack.Nav_fwd : Xog_history_stack.Nav_bwd;
boolean new_page_is_same = Bry_.Eq(cur_page.Ttl().Full_txt(), new_page.Ttl().Full_txt());
Xog_tab_itm_read_mgr.Show_page(tab, new_page, true, new_page_is_same, false, history_nav_type);
Page__async__bgn(tab);
}
public void Page__reload() {
Xog_tab_itm tab = tab_mgr.Active_tab();
Xoa_page page = tab.History_mgr().Cur_page(tab.Page().Wiki()); // NOTE: must set to CurPage() else changes will be lost when going Bwd,Fwd
tab.Page_(page);
page.Wiki().ParsePage_root(page, true); // NOTE: must reparse page if (a) Edit -> Read; or (b) "Options" save
Page__refresh();
}
public void Page__refresh() {
Xog_tab_itm tab = tab_mgr.Active_tab(); Xoa_page page = tab.Page(); Xog_html_itm html_itm = tab.Html_itm();
page.Html_data().Bmk_pos_(html_itm.Html_box().Html_window_vpos());
html_itm.Show(page);
if (page.Url().Anchor_str() == null)
html_itm.Scroll_page_by_bmk_gui();
else
html_itm.Scroll_page_by_id_gui(page.Url().Anchor_str());
Page__async__bgn(tab);
}
public void Page__async__bgn(Xog_tab_itm tab) {
page__async__thread = ThreadAdp_.invk_msg_(this, GfoMsg_.new_cast_(Invk_page_async_exec).Add("v", tab)).Start();
} private ThreadAdp page__async__thread = ThreadAdp.Null;
public boolean Page__async__working(Xoa_url url) {
if (page__async__thread.IsAlive()) { // cancel pending image downloads
page__async__restart_url = url;
this.Usr_dlg().Canceled_y_();
app.File_mgr().Download_mgr().Download_wkr().Download_xrg().Prog_cancel_y_();
ThreadAdp_.invk_(this, Invk_page_async_cancel_wait).Start();
return true;
}
return false;
}
private void Page__async__cancel__wait() {
while (page__async__thread.IsAlive()) {
ThreadAdp_.Sleep(10);
}
this.Active_page().File_queue().Clear();
this.Usr_dlg().Canceled_n_(); // NOTE: must mark "uncanceled", else one cancelation will stop all future downloads; DATE:2014-05-04
GfoInvkAble_.InvkCmd(sync_cmd, Invk_page_async_restart);
}
private void Page__async__restart() {
tab_mgr.Active_tab().Show_url_bgn(page__async__restart_url);
} private Xoa_url page__async__restart_url;
public void Lang_changed(Xol_lang lang) {
Xoa_app app = gui_mgr.App();
Xog_win_itm_.Update_tiptext(app, go_bwd_btn , Xol_msg_itm_.Id_xowa_window_go_bwd_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, go_fwd_btn , Xol_msg_itm_.Id_xowa_window_go_fwd_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, url_box , Xol_msg_itm_.Id_xowa_window_url_box_tooltip);
Xog_win_itm_.Update_tiptext(app, url_exec_btn , Xol_msg_itm_.Id_xowa_window_url_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, search_box , Xol_msg_itm_.Id_xowa_window_search_box_tooltip);
Xog_win_itm_.Update_tiptext(app, search_exec_btn , Xol_msg_itm_.Id_xowa_window_search_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, find_close_btn , Xol_msg_itm_.Id_xowa_window_find_close_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, find_box , Xol_msg_itm_.Id_xowa_window_find_box_tooltip);
Xog_win_itm_.Update_tiptext(app, find_bwd_btn , Xol_msg_itm_.Id_xowa_window_find_bwd_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, find_fwd_btn , Xol_msg_itm_.Id_xowa_window_find_fwd_btn_tooltip);
Xog_win_itm_.Update_tiptext(app, prog_box , Xol_msg_itm_.Id_xowa_window_prog_box_tooltip);
Xog_win_itm_.Update_tiptext(app, info_box , Xol_msg_itm_.Id_xowa_window_info_box_tooltip);
}
public byte[] App__retrieve_by_url(String url_str, String output_str) {
synchronized (App__retrieve__lock) {
boolean output_html = String_.Eq(output_str, "html");
Xoa_url url = new Xoa_url();
byte[] url_bry = Bry_.new_utf8_(url_str);
Xow_wiki home_wiki = app.User().Wiki();
Xoa_ttl ttl = Xoa_ttl.parse_(home_wiki, Xoa_page_.Main_page_bry); // NOTE: must be Main_Page, not "" else Firefox Addon will fail; DATE:2014-03-13
Xoa_page new_page = Xoa_page.new_(home_wiki, ttl);
this.Active_page_(new_page);
url = Xoa_url_parser.Parse_url(url, app, new_page.Wiki(), url_bry, 0, url_bry.length, true);
new_page.Url_(url);
return App__retrieve_by_href(url, output_html);
}
} private Object App__retrieve__lock = new Object();
public byte[] App__retrieve_by_href(String href, boolean output_html) {return App__retrieve_by_href(Xog_url_wkr.Exec_url(this, href), output_html);} // NOTE: used by drd
private byte[] App__retrieve_by_href(Xoa_url url, boolean output_html) {
if (url == null) return Bry_.new_ascii_("missing");
Xoa_ttl ttl = Xoa_ttl.parse_(url.Wiki(), url.Page_bry());
Xoa_page new_page = url.Wiki().GetPageByTtl(url, ttl);
if (new_page.Missing()) {return Bry_.Empty;}
Xog_tab_itm tab = tab_mgr.Active_tab();
tab.Page_(new_page);
tab.History_mgr().Add(new_page);
byte[] rv = output_html
? url.Wiki().Html_mgr().Page_wtr_mgr().Gen(new_page, tab.View_mode())
: new_page.Data_raw()
;
if (app.Shell().Fetch_page_exec_async())
app.Gui_mgr().Browser_win().Page__async__bgn(tab);
return rv;
}
public void Init_by_kit(Gfui_kit kit) {
this.kit = kit;
win_box = kit.New_win_app("win");
sync_cmd = win_box.Kit().New_cmd_sync(this);
Io_url img_dir = app.User().Fsys_mgr().App_img_dir().GenSubDir_nest("window", "chrome");
FontAdp ui_font = app.Gui_mgr().Win_cfg().Font().XtoFontAdp();
go_bwd_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "go_bwd_btn", "go_bwd.png" );
go_fwd_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "go_fwd_btn", "go_fwd.png" );
url_box = Xog_win_itm_.new_txt(app, kit, win_box, ui_font, "url_box" , true);
url_exec_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "url_exec_btn", "url_exec.png" );
search_box = Xog_win_itm_.new_txt(app, kit, win_box, ui_font, "search_box" , true);
search_exec_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "search_exec_btn", "search_exec.png" );
find_close_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "find_close_btn", "find_close.png" );
find_box = Xog_win_itm_.new_txt(app, kit, win_box, ui_font, "find_box" , true);
find_fwd_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "find_fwd_btn", "find_fwd.png" );
find_bwd_btn = Xog_win_itm_.new_btn(app, kit, win_box, img_dir, "find_bwd_btn", "find_bwd.png" );
prog_box = Xog_win_itm_.new_txt(app, kit, win_box, ui_font, "prog_box" , false);
info_box = Xog_win_itm_.new_txt(app, kit, win_box, ui_font, "note_box" , false);
tab_mgr.Init_by_kit(kit);
this.Lang_changed(app.User().Lang());
GfoEvMgr_.SubSame_many(this, this, Gfui_html.Evt_location_changed, Gfui_html.Evt_location_changing, Gfui_html.Evt_link_hover);
GfoEvMgr_.SubSame(win_box, Gfui_html.Evt_win_resized, this);
GfoEvMgr_.Sub(app.Gui_mgr().Win_cfg().Font(), Xol_font_info.Font_changed, this, Invk_window_font_changed);
if ( !Env_.Mode_testing()
&& app.Mode() == Xoa_app_.Mode_gui) // only run for gui; do not run for tcp/http server; DATE:2014-05-03
app.Usr_dlg().Ui_wkr_(new Gfo_usr_dlg_ui_swt(kit, prog_box, info_box, info_box, app.Gui_mgr().Win_cfg()));
}
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*; import gplx.xowa.gui.bnds.*; import gplx.xowa.gui.cmds.*;
public class Xog_win_itm_ {
public static void Show_win(Xog_win_itm win) {
Xoa_app app = win.App(); GfuiWin win_box = win.Win_box();
win_box.Focus_able_(false);
win_box.BackColor_(ColorAdp_.White);
win.Tab_mgr().Tab_mgr().BackColor_(ColorAdp_.White);
app.User().Cfg_mgr().Startup_mgr().Window_mgr().Init_window(win_box);
win.Resizer().Exec_win_resize(app, win_box.Width(), win_box.Height());
IconAdp.regy_loadDir_shallow(app.User().Fsys_mgr().Root_dir().GenSubDir_nest("app", "img", "win"));
win_box.Icon_(IconAdp.regy_("xowa.app"));
}
public static GfuiBtn new_btn(Xoa_app app, Gfui_kit kit, GfuiWin win, Io_url img_dir, String id, String file) {
GfuiBtn rv = kit.New_btn(id, win);
rv.Btn_img_(kit.New_img_load(img_dir.GenSubFil(file)));
return rv;
}
public static GfuiTextBox new_txt(Xoa_app app, Gfui_kit kit, GfuiWin win, FontAdp ui_font, String id, boolean border_on) {
GfuiTextBox rv = kit.New_text_box(id, win, KeyVal_.new_(GfuiTextBox.CFG_border_on_, border_on));
rv.TextMgr().Font_(ui_font);
return rv;
}
public static void Update_tiptext(Xoa_app app, GfuiElem elem, int tiptext_id) {
elem.TipText_(Xog_win_itm_.new_tiptext(app, tiptext_id));
}
public static void Font_update(Xog_win_itm win, Xol_font_info itm_font) {
FontAdp gui_font = win.Url_box().TextMgr().Font();
if (!itm_font.Eq(gui_font)) {
FontAdp new_font = itm_font.XtoFontAdp();
win.Url_box().TextMgr().Font_(new_font);
win.Find_box().TextMgr().Font_(new_font);
win.Prog_box().TextMgr().Font_(new_font);
win.Tab_mgr().Tab_mgr().TextMgr().Font_(new_font);
}
}
public static String new_tiptext(Xoa_app app, int id) {return String_.new_utf8_(app.User().Lang().Msg_mgr().Val_by_id(app.User().Wiki(), id));}
}

View File

@@ -0,0 +1,41 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.gui.views; import gplx.*; import gplx.xowa.*; import gplx.xowa.gui.*;
import gplx.gfui.*;
public class Xog_win_itm__prog_href_mgr {
private static Xoh_href tmp_href = new Xoh_href();
private static Bry_bfr tmp_bfr = Bry_bfr.reset_(512);
public static void Print(Xog_win_itm win) { // PURPOSE: print href in prog box when in content editable mode
String href = win.Active_html_box().Html_active_atr_get_str(Gfui_html.Atr_href, "");// get selected href from html_box
href = win.App().Url_converter_href().Decode_str(href); // remove url encodings
if (!String_.Eq(href, win.Prog_box().Text()))
win.Usr_dlg().Prog_direct(href);
}
public static void Hover(Xoa_app app, Xoa_page page, String href) {
Gfo_usr_dlg usr_dlg = app.Usr_dlg();
if ( String_.Len_eq_0(href) // href is null / empty; occurs when hovering over empty space
|| String_.Eq(href, "file:///")) {
usr_dlg.Prog_direct(""); // clear out previous entry
return;
}
Xow_wiki wiki = page.Wiki();
app.Href_parser().Parse(tmp_href, href, wiki, page.Ttl().Page_url());
tmp_href.Print_to_bfr(tmp_bfr, wiki.Gui_mgr().Cfg_browser().Link_hover_full());
usr_dlg.Prog_direct(tmp_bfr.XtoStrAndClear());
}
}