aboutsummaryrefslogtreecommitdiff
path: root/src/uicmd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/uicmd.cc')
-rw-r--r--src/uicmd.cc586
1 files changed, 480 insertions, 106 deletions
diff --git a/src/uicmd.cc b/src/uicmd.cc
index 564e9957..93836735 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -15,15 +15,22 @@
#include <stdio.h>
#include <stdarg.h>
#include <math.h> /* for rint */
+
+#include <fltk/draw.h>
+#include <fltk/damage.h>
#include <fltk/Widget.h>
#include <fltk/TabGroup.h>
+#include <fltk/Tooltip.h>
-#include "dir.h"
+#include "paths.hh"
+#include "keys.hh"
#include "ui.hh"
#include "uicmd.hh"
#include "timeout.hh"
+#include "utf8.hh"
#include "menu.hh"
#include "dialog.hh"
+#include "xembed.hh"
#include "bookmark.h"
#include "history.h"
#include "msg.h"
@@ -33,6 +40,8 @@
#include "nav.h"
+#define DEFAULT_TAB_LABEL "Dillo"
+
// Handy macro
#define BW2UI(bw) ((UI*)((bw)->ui))
@@ -49,20 +58,198 @@ static char *save_dir = NULL;
using namespace fltk;
-//
-// For custom handling of keyboard
-//
+
+//----------------------------------------------------------------------------
+#define BTN_W 25
+#define BTN_H 20
+
+static int btn_x;
+
+/*
+ * Adds a tab-close button at the rightmost part
+ */
+class CustShrinkTabPager : public TabGroupPager {
+ bool btn_hl;
+ TabGroup *tg;
+public:
+ int update_positions(
+ TabGroup *g, int numchildren, int &selected,
+ int &cumulated_width, int &available_width,
+ int *tab_pos, int *tab_width);
+ virtual int which(TabGroup* g, int m_x,int m_y);
+ virtual TabGroupPager* clone() const;
+ virtual const char * mode_name() const {return "Shrink";}
+ virtual int id() const {return PAGER_SHRINK;}
+ virtual int available_width(TabGroup *g) const;
+ virtual bool draw_tabs(TabGroup* g, int selected, int* tab_pos,
+ int* tab_width) {
+ if (!tg) tg = g;
+ if (g->children() > 1) {
+ fltk::Rectangle r(btn_x,0,BTN_W,BTN_H);
+ setcolor(btn_hl ? 206 : GRAY75);
+ fillrect(r);
+ if (btn_hl) {
+ setcolor(WHITE);
+ strokerect(r);
+ }
+ setcolor(GRAY10);
+ //fltk::setfont(fltk::getfont()->bold(), fltk::getsize());
+ r.h(r.h()-2);
+ drawtext("X", r, ALIGN_CENTER);
+ return false;
+ } else {
+ // WORKAROUND: for http://fltk.org/str.php?L2062
+ // By returning true we avoid a call to TabGroup::draw_tab()
+ // in TabGroup::draw() in case we don't show the tabs.
+ return true;
+ }
+ }
+
+ void btn_highlight(bool flag) {
+ if (btn_hl != flag) {
+ btn_hl = flag;
+ if (tg)
+ tg->redraw(DAMAGE_VALUE);
+ }
+ };
+ bool btn_highlight() { return btn_hl; };
+
+ CustShrinkTabPager() : TabGroupPager() {
+ noclip(true);
+ btn_hl = false;
+ tg = NULL;
+ }
+};
+
+int CustShrinkTabPager::available_width(TabGroup *g) const
+{
+ _MSG("CustShrinkTabPager::available_width\n");
+ int w = MAX (g->w() - this->slope()-1 - BTN_W, 0);
+ btn_x = w + 6;
+ return w;
+}
+
+int CustShrinkTabPager::which(TabGroup* g, int event_x,int event_y)
+{
+ int H = g->tab_height();
+ if (!H) return -1;
+ if (H < 0) {
+ if (event_y > g->h() || event_y < g->h()+H) return -1;
+ } else {
+ if (event_y > H || event_y < 0) return -1;
+ }
+ if (event_x < 0) return -1;
+ int p[128], w[128];
+ int selected = g->tab_positions(p, w);
+ int d = (event_y-(H>=0?0:g->h()))*slope()/H;
+ for (int i=0; i<g->children(); i++) {
+ if (event_x < p[i+1]+(i<selected ? slope() - d : d)) return i;
+ }
+ return -1;
+}
+
+/*
+ * Prevents tabs from going over the close-tab button.
+ * Modified from fltk-2.0.x-r6525.
+ */
+int CustShrinkTabPager::update_positions(
+ TabGroup *g, int numchildren, int &selected,
+ int &cumulated_width, int &available_width,
+ int *tab_pos, int *tab_width)
+{
+ available_width-=BTN_W;
+
+ // uh oh, they are too big, we must move them:
+ // special case when the selected tab itself is too big, make it fill
+ // cumulated_width:
+ int i;
+
+ if (tab_width[selected] >= available_width) {
+ tab_width[selected] = available_width;
+ for (i = 0; i <= selected; i++)
+ tab_pos[i] = 0;
+ for (i = selected + 1; i <= numchildren; i++)
+ tab_pos[i] = available_width;
+ return selected;
+ }
+
+ int w2[128];
+
+ for (i = 0; i < numchildren; i++)
+ w2[i] = tab_width[i];
+ i = numchildren - 1;
+ int j = 0;
+
+ int minsize = 5;
+
+ bool right = true;
+
+ while (cumulated_width > available_width) {
+ int n; // which one to shrink
+
+ if (j < selected && (!right || i <= selected)) { // shrink a left one
+ n = j++;
+ right = true;
+ } else if (i > selected) { // shrink a right one
+ n = i--;
+ right = false;
+ } else { // no more space, start making them zero
+ minsize = 0;
+ i = numchildren - 1;
+ j = 0;
+ right = true;
+ continue;
+ }
+ cumulated_width -= w2[n] - minsize;
+ w2[n] = minsize;
+ if (cumulated_width < available_width) {
+ w2[n] = available_width - cumulated_width + minsize;
+ cumulated_width = available_width;
+ break;
+ }
+ }
+ // re-sum the positions:
+ cumulated_width = 0;
+ for (i = 0; i < numchildren; i++) {
+ cumulated_width += w2[i];
+ tab_pos[i+1] = cumulated_width;
+ }
+ return selected;
+}
+
+TabGroupPager* CustShrinkTabPager::clone() const {
+ return new CustShrinkTabPager(*this);
+}
+
+//----------------------------------------------------------------------------
+
+/*
+ * For custom handling of keyboard
+ */
class CustTabGroup : public fltk::TabGroup {
+ Tooltip *toolTip;
+ bool tooltipEnabled;
+ bool buttonPushed;
public:
CustTabGroup (int x, int y, int ww, int wh, const char *lbl=0) :
- TabGroup(x,y,ww,wh,lbl) {};
+ TabGroup(x,y,ww,wh,lbl) {
+ // The parameter pager is cloned, so free it.
+ CustShrinkTabPager *cp = new CustShrinkTabPager();
+ this->pager(cp);
+ delete cp;
+ toolTip = new Tooltip;
+ tooltipEnabled = false;
+ buttonPushed = false;
+ };
+ ~CustTabGroup() { delete toolTip; }
int handle(int e) {
// Don't focus with arrow keys
_MSG("CustTabGroup::handle %d\n", e);
- int k = event_key();
- // We're only interested in some flags
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
+ fltk::Rectangle r(btn_x,0,BTN_W,BTN_H);
if (e == KEY) {
+ int k = event_key();
+ // We're only interested in some flags
+ unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
if (k == UpKey || k == DownKey || k == TabKey) {
return 0;
} else if (k == LeftKey || k == RightKey) {
@@ -74,20 +261,77 @@ public:
return 1;
}
// Avoid focus change.
- return 0;
+ return 0;
+ }
+ } else if (e == FOCUS_CHANGE) {
+ // Update the window title
+ BrowserWindow *bw = a_UIcmd_get_bw_by_widget(selected_child());
+ const char *title = a_History_get_title(NAV_TOP_UIDX(bw), 1);
+ a_UIcmd_set_page_title(bw, title ? title : "");
+ } else if (e == MOVE) {
+ CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager();
+ if (event_inside(r) && children() > 1) {
+ /* We're inside the button area */
+ cstp->btn_highlight(true);
+ if (prefs.show_tooltip) {
+ /* Prepare the tooltip for pop-up */
+ tooltipEnabled = true;
+ /* We use parent() if available because we are returning 0.
+ * Returning without having TabGroup processing makes the
+ * popup event never reach 'this', but it reaches parent() */
+ toolTip->enter(parent() ?parent():this, r, "Close current Tab");
+ }
+ return 0; // Change focus
+ } else {
+ cstp->btn_highlight(false);
+
+ if (prefs.show_tooltip) {
+ /* Hide the tooltip or enable it again.*/
+ if (tooltipEnabled) {
+ tooltipEnabled = false;
+ toolTip->exit();
+ } else {
+ toolTip->enable();
+ }
+ }
+ }
+ } else if (e == PUSH && event_inside(r) &&
+ event_button() == 1 && children() > 1) {
+ buttonPushed = true;
+ return 1; /* non-zero */
+ } else if (e == RELEASE) {
+ if (event_inside(r) && event_button() == 1 &&
+ children() > 1 && buttonPushed) {
+ a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(selected_child()));
+ } else {
+ CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager();
+ cstp->btn_highlight(false);
}
+ buttonPushed = false;
+ } else if (e == DRAG) {
+ /* Ignore this event */
+ return 1;
}
- return TabGroup::handle(e);
+ int ret = TabGroup::handle(e);
+
+ if (e == PUSH) {
+ /* WORKAROUND: FLTK raises the window on unhandled clicks,
+ * which we do not want.
+ */
+ ret = 1;
+ }
+ return ret;
}
void remove (Widget *w) {
TabGroup::remove (w);
/* fixup resizable in case we just removed it */
- if (resizable () == w)
+ if (resizable () == w) {
if (children () > 0)
resizable (child (children () - 1));
else
resizable (NULL);
+ }
if (children () < 2)
hideLabels ();
@@ -110,11 +354,12 @@ public:
}
};
+//----------------------------------------------------------------------------
+
static void win_cb (fltk::Widget *w, void *cb_data) {
- CustTabGroup *tabs;
int choice = 0;
+ CustTabGroup *tabs = (CustTabGroup*) cb_data;
- tabs = BW2UI((BrowserWindow*) cb_data)->tabs();
if (tabs->children () > 1)
choice = a_Dialog_choice3 ("Window contains more than one tab.",
"Close all tabs", "Cancel", NULL);
@@ -155,10 +400,12 @@ void a_UIcmd_send_event_to_tabs_by_wid(int e, void *v_wid)
* Create a new UI and its associated BrowserWindow data structure.
* Use style from v_ui. If non-NULL it must be of type UI*.
*/
-BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
+BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
+ uint32_t xid, const void *vbw)
{
BrowserWindow *old_bw = (BrowserWindow*)vbw;
BrowserWindow *new_bw = NULL;
+ Window *win;
if (ww <= 0 || wh <= 0) {
// Set default geometry from dillorc.
@@ -166,7 +413,11 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
wh = prefs.height;
}
- Window *win = new Window(ww, wh);
+ if (xid)
+ win = new Xembed(xid, ww, wh);
+ else
+ win = new Window(ww, wh);
+
win->shortcut(0); // Ignore Escape
if (prefs.buffered_drawing != 2)
win->clear_double_buffer();
@@ -177,7 +428,8 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
win->add(DilloTabs);
// Create and set the UI
- UI *new_ui = new UI(0, 0, ww, wh, "Label", old_bw ? BW2UI(old_bw) : NULL);
+ UI *new_ui = new UI(0, 0, ww, wh, DEFAULT_TAB_LABEL,
+ old_bw ? BW2UI(old_bw) : NULL);
new_ui->set_status("http://www.dillo.org/");
new_ui->tabs(DilloTabs);
@@ -203,7 +455,7 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
viewport->setBufferedDrawing (true);
else
viewport->setBufferedDrawing (false);
-
+
layout->attachView (viewport);
new_ui->set_render_layout(*viewport);
@@ -217,7 +469,9 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
// Copy the layout pointer into the bw data
new_bw->render_layout = (void*)layout;
- win->callback(win_cb, new_bw);
+ win->callback(win_cb, DilloTabs);
+
+ new_ui->focus_location();
return new_bw;
}
@@ -226,7 +480,7 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh, const void *vbw)
* Create a new Tab.
* i.e the new UI and its associated BrowserWindow data structure.
*/
-BrowserWindow *UIcmd_tab_new(const void *vbw)
+static BrowserWindow *UIcmd_tab_new(const void *vbw)
{
_MSG(" UIcmd_tab_new vbw=%p\n", vbw);
@@ -239,10 +493,10 @@ BrowserWindow *UIcmd_tab_new(const void *vbw)
// WORKAROUND: limit the number of tabs because of a fltk bug
if (ui->tabs()->children() >= 127)
return a_UIcmd_browser_window_new(ui->window()->w(), ui->window()->h(),
- vbw);
+ 0, vbw);
// Create and set the UI
- UI *new_ui = new UI(0, 0, ui->w(), ui->h(), "Label", ui);
+ UI *new_ui = new UI(0, 0, ui->w(), ui->h(), DEFAULT_TAB_LABEL, ui);
new_ui->tabs(ui->tabs());
new_ui->tabs()->add(new_ui);
@@ -255,7 +509,7 @@ BrowserWindow *UIcmd_tab_new(const void *vbw)
Layout *layout = new Layout (platform);
FltkViewport *viewport = new FltkViewport (0, 0, 1, 1);
-
+
layout->attachView (viewport);
new_ui->set_render_layout(*viewport);
@@ -282,10 +536,11 @@ void a_UIcmd_close_bw(void *vbw)
Layout *layout = (Layout*)bw->render_layout;
MSG("a_UIcmd_close_bw\n");
- a_Bw_stop_clients(bw, BW_Root + BW_Img + Bw_Force);
+ a_Bw_stop_clients(bw, BW_Root + BW_Img + BW_Force);
delete(layout);
if (ui->tabs()) {
ui->tabs()->remove(ui);
+ ui->tabs()->value(ui->tabs()->children() - 1);
if (ui->tabs()->value() != -1)
ui->tabs()->selected_child()->take_focus();
else
@@ -332,7 +587,7 @@ void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
/* file URI */
ch = new_urlstr[5];
if (!ch || ch == '.') {
- url = a_Url_new(a_Dir_get_owd(), "file:");
+ url = a_Url_new(Paths::getOldWorkingDir(), "file:");
} else if (ch == '~') {
url = a_Url_new(dGethomedir(), "file:");
} else {
@@ -346,13 +601,10 @@ void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
dFree(new_urlstr);
if (url) {
- a_Nav_push(bw, url);
+ a_UIcmd_open_url(bw, url);
a_Url_free(url);
}
}
-
- /* let the rendered area have focus */
- //gtk_widget_grab_focus(GTK_BIN(bw->render_main_scroll)->child);
}
/*
@@ -360,15 +612,37 @@ void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
*/
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url)
{
- a_Nav_push(bw, url);
+ a_Nav_push(bw, url, NULL);
+ if (BW2UI(bw)->get_panelmode() == UI_TEMPORARILY_SHOW_PANELS)
+ BW2UI(bw)->set_panelmode(UI_HIDDEN);
+ a_UIcmd_focus_main_area(bw);
+}
+
+static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
+{
+ /* When opening a new BrowserWindow (tab or real window) we focus
+ * Location if we don't yet have an URL, main otherwise.
+ */
+ if (url) {
+ a_Nav_push(new_bw, url, NULL);
+ BW2UI(new_bw)->focus_main();
+ } else {
+ BW2UI(new_bw)->focus_location();
+ }
}
/*
- * Open a new URL in the given browser window
+ * Open a new URL in a new browser window
*/
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
{
- a_Nav_push_nw(bw, url);
+ int w, h;
+ BrowserWindow *new_bw;
+
+ a_UIcmd_get_wh(bw, &w, &h);
+ new_bw = a_UIcmd_browser_window_new(w, h, 0, bw);
+
+ UIcmd_open_url_nbw(new_bw, url);
}
/*
@@ -377,12 +651,11 @@ void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
{
BrowserWindow *new_bw = UIcmd_tab_new(vbw);
- if (url)
- a_Nav_push(new_bw, url);
- if (focus) {
+
+ if (focus)
BW2UI(new_bw)->tabs()->selected_child(BW2UI(new_bw));
- BW2UI(new_bw)->tabs()->selected_child()->take_focus();
- }
+
+ UIcmd_open_url_nbw(new_bw, url);
}
/*
@@ -422,7 +695,7 @@ void a_UIcmd_forw_popup(void *vbw)
*/
void a_UIcmd_home(void *vbw)
{
- a_Nav_home((BrowserWindow*)vbw);
+ a_UIcmd_open_url((BrowserWindow*)vbw, prefs.home);
}
/*
@@ -434,19 +707,44 @@ void a_UIcmd_reload(void *vbw)
}
/*
+ * Repush current URL
+ */
+void a_UIcmd_repush(void *vbw)
+{
+ a_Nav_repush((BrowserWindow*)vbw);
+}
+
+/*
+ * Zero-delay URL redirection.
+ */
+void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
+{
+ a_Nav_redirection0((BrowserWindow*)vbw, url);
+}
+
+/*
* Return a suitable filename for a given URL path.
*/
static char *UIcmd_make_save_filename(const char *pathstr)
{
size_t MaxLen = 64;
- char *FileName, *name;
- const char *dir = a_UIcmd_get_save_dir();
+ char *FileName, *newname, *o, *n;
+ const char *name, *dir = a_UIcmd_get_save_dir();
if ((name = strrchr(pathstr, '/'))) {
if (strlen(++name) > MaxLen) {
name = name + strlen(name) - MaxLen;
}
- FileName = dStrconcat(dir ? dir : "", name, NULL);
+ /* Replace %20 and ' ' with '_' in Filename */
+ o = n = newname = dStrdup(name);
+ for (int i = 0; o[i]; i++) {
+ *n++ = (o[i] == ' ') ? '_' :
+ (o[i] == '%' && o[i+1] == '2' && o[i+2] == '0') ?
+ i+=2, '_' : o[i];
+ }
+ *n = 0;
+ FileName = dStrconcat(dir ? dir : "", newname, NULL);
+ dFree(newname);
} else {
FileName = dStrconcat(dir ? dir : "", pathstr, NULL);
}
@@ -466,7 +764,7 @@ const char *a_UIcmd_get_save_dir()
*/
void a_UIcmd_set_save_dir(const char *dir)
{
- char *p;
+ const char *p;
if (dir && (p = strrchr(dir, '/'))) {
dFree(save_dir);
@@ -481,24 +779,21 @@ void a_UIcmd_set_save_dir(const char *dir)
void a_UIcmd_save(void *vbw)
{
const char *name;
- char *SuggestedName, *urlstr;
- DilloUrl *url;
+ char *SuggestedName;
+ BrowserWindow *bw = (BrowserWindow *)vbw;
+ const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
- a_UIcmd_set_save_dir(prefs.save_dir);
+ if (url) {
+ a_UIcmd_set_save_dir(prefs.save_dir);
+ SuggestedName = UIcmd_make_save_filename(URL_PATH(url));
+ name = a_Dialog_save_file("Save Page as File", NULL, SuggestedName);
+ MSG("a_UIcmd_save: %s\n", name);
+ dFree(SuggestedName);
- urlstr = a_UIcmd_get_location_text((BrowserWindow*)vbw);
- url = a_Url_new(urlstr, NULL);
- SuggestedName = UIcmd_make_save_filename(URL_PATH(url));
- name = a_Dialog_save_file("Save Page as File", NULL, SuggestedName);
- MSG("a_UIcmd_save: %s\n", name);
- dFree(SuggestedName);
- dFree(urlstr);
-
- if (name) {
- a_Nav_save_url((BrowserWindow*)vbw, url, name);
+ if (name) {
+ a_Nav_save_url(bw, url, name);
+ }
}
-
- a_Url_free(url);
}
/*
@@ -519,11 +814,19 @@ void a_UIcmd_stop(void *vbw)
MSG("a_UIcmd_stop()\n");
a_Nav_cancel_expect(bw);
- a_Bw_stop_clients(bw, BW_Root + BW_Img + Bw_Force);
+ a_Bw_stop_clients(bw, BW_Root + BW_Img + BW_Force);
a_UIcmd_set_buttons_sens(bw);
}
/*
+ * Popup the tools menu
+ */
+void a_UIcmd_tools(void *vbw, void *v_wid)
+{
+ a_Menu_tools_popup((BrowserWindow*)vbw, v_wid);
+}
+
+/*
* Open URL with dialog chooser
*/
void a_UIcmd_open_file(void *vbw)
@@ -535,7 +838,7 @@ void a_UIcmd_open_file(void *vbw)
if (name) {
url = a_Url_new(name, "file:");
- a_Nav_push((BrowserWindow*)vbw, url);
+ a_UIcmd_open_url((BrowserWindow*)vbw, url);
a_Url_free(url);
dFree(name);
}
@@ -579,11 +882,12 @@ static char *UIcmd_make_search_str(const char *str)
*/
void a_UIcmd_search_dialog(void *vbw)
{
- const char *query, *url_str;
+ const char *query;
if ((query = a_Dialog_input("Search the Web:"))) {
- url_str = UIcmd_make_search_str(query);
+ char *url_str = UIcmd_make_search_str(query);
a_UIcmd_open_urlstr(vbw, url_str);
+ dFree(url_str);
}
}
@@ -625,7 +929,7 @@ void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url)
void a_UIcmd_book(void *vbw)
{
DilloUrl *url = a_Url_new("dpi:/bm/", NULL);
- a_Nav_push((BrowserWindow*)vbw, url);
+ a_UIcmd_open_url((BrowserWindow*)vbw, url);
a_Url_free(url);
}
@@ -641,10 +945,11 @@ void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url)
/*
* Popup the page menu
*/
-void a_UIcmd_page_popup(void *vbw, const DilloUrl *url,
- bool_t has_bugs, bool_t unloaded_imgs)
+void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls)
{
- a_Menu_page_popup((BrowserWindow*)vbw, url, has_bugs, unloaded_imgs);
+ BrowserWindow *bw = (BrowserWindow*)vbw;
+ const DilloUrl *url = a_History_get_url(NAV_TOP_UIDX(bw));
+ a_Menu_page_popup(bw, url, has_bugs, v_cssUrls);
}
/*
@@ -659,9 +964,18 @@ void a_UIcmd_link_popup(void *vbw, const DilloUrl *url)
* Pop up the image menu
*/
void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
- DilloUrl *link_url)
+ DilloUrl *page_url, DilloUrl *link_url)
{
- a_Menu_image_popup((BrowserWindow*)vbw, url, loaded_img, link_url);
+ a_Menu_image_popup((BrowserWindow*)vbw, url, loaded_img, page_url,link_url);
+}
+
+/*
+ * Pop up the form menu
+ */
+void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform,
+ bool_t showing_hiddens)
+{
+ a_Menu_form_popup((BrowserWindow*)vbw, url, vform, showing_hiddens);
}
/*
@@ -682,17 +996,32 @@ void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr)
}
/*
- * Show a text window with the URL's source
+ * Ask the vsource dpi to show this URL's source
*/
-void a_UIcmd_view_page_source(const DilloUrl *url)
+void a_UIcmd_view_page_source(BrowserWindow *bw, const DilloUrl *url)
{
char *buf;
int buf_size;
+ Dstr *dstr_url;
+ DilloUrl *vs_url;
+ static int post_id = 0;
+ char tag[8];
if (a_Nav_get_buf(url, &buf, &buf_size)) {
- void *vWindow = a_Dialog_make_text_window(buf, "View Page source");
+ a_Nav_set_vsource_url(url);
+ dstr_url = dStr_new("dpi:/vsource/:");
+ dStr_append(dstr_url, URL_STR(url));
+ if (URL_FLAGS(url) & URL_Post) {
+ /* append a custom string to differentiate POST URLs */
+ post_id = (post_id < 9999) ? post_id + 1 : 0;
+ snprintf(tag, 8, "_%.4d", post_id);
+ dStr_append(dstr_url, tag);
+ }
+ vs_url = a_Url_new(dstr_url->str, NULL);
+ a_UIcmd_open_url_nt(bw, vs_url, 1);
+ a_Url_free(vs_url);
+ dStr_free(dstr_url, 1);
a_Nav_unref_buf(url);
- a_Dialog_show_text_window(vWindow);
}
}
@@ -704,9 +1033,7 @@ void a_UIcmd_view_page_bugs(void *vbw)
BrowserWindow *bw = (BrowserWindow*)vbw;
if (bw->num_page_bugs > 0) {
- void *vWindow = a_Dialog_make_text_window(bw->page_bugs->str,
- "Detected HTML errors");
- a_Dialog_show_text_window(vWindow);
+ a_Dialog_text_window(bw->page_bugs->str, "Detected HTML errors");
} else {
a_Dialog_msg("Zero detected HTML errors!");
}
@@ -805,6 +1132,40 @@ void a_UIcmd_set_scroll_by_fragment(BrowserWindow *bw, const char *f)
}
/*
+ * Pass scrolling command to dw.
+ */
+void a_UIcmd_scroll(BrowserWindow *bw, int icmd)
+{
+ Layout *layout = (Layout*)bw->render_layout;
+
+ if (layout) {
+ typedef struct {
+ KeysCommand_t keys_cmd;
+ ScrollCommand dw_cmd;
+ } mapping_t;
+
+ const mapping_t map[] = {
+ {KEYS_SCREEN_UP, SCREEN_UP_CMD},
+ {KEYS_SCREEN_DOWN, SCREEN_DOWN_CMD},
+ {KEYS_LINE_UP, LINE_UP_CMD},
+ {KEYS_LINE_DOWN, LINE_DOWN_CMD},
+ {KEYS_LEFT, LEFT_CMD},
+ {KEYS_RIGHT, RIGHT_CMD},
+ {KEYS_TOP, TOP_CMD},
+ {KEYS_BOTTOM, BOTTOM_CMD},
+ };
+ KeysCommand_t keycmd = (KeysCommand_t)icmd;
+
+ for (uint_t i = 0; i < (sizeof(map)/sizeof(mapping_t)); i++) {
+ if (keycmd == map[i].keys_cmd) {
+ layout->scroll(map[i].dw_cmd);
+ break;
+ }
+ }
+ }
+}
+
+/*
* Get location's text
*/
char *a_UIcmd_get_location_text(BrowserWindow *bw)
@@ -852,12 +1213,24 @@ void a_UIcmd_set_bug_prog(BrowserWindow *bw, int n_bug)
}
/*
- * Set the page title.
- * now it goes to the window titlebar (maybe to TAB label in the future).
+ * Set the page title in the window titlebar and tab label.
+ * (Update window titlebar for the current tab only)
*/
void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
{
- BW2UI(bw)->set_page_title(label);
+ const int size = 128;
+ char title[size];
+
+ if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->selected_child()) == bw) {
+ // This is the focused bw, set window title
+ if (snprintf(title, size, "Dillo: %s", label) >= size) {
+ uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8));
+ snprintf(title + i, 4, "...");
+ }
+ BW2UI(bw)->window()->copy_label(title);
+ BW2UI(bw)->window()->redraw_label();
+ }
+ BW2UI(bw)->set_tab_title(label);
}
/*
@@ -877,22 +1250,6 @@ void a_UIcmd_set_msg(BrowserWindow *bw, const char *format, ...)
}
/*
- * Check whether the UI has automatic image loading enabled.
- */
-bool_t a_UIcmd_get_images_enabled(BrowserWindow *bw)
-{
- return BW2UI(bw)->images_enabled();
-}
-
-/*
- * Enable/Disable automatic image loading.
- */
-void a_UIcmd_set_images_enabled(BrowserWindow *bw, int flag)
-{
- BW2UI(bw)->images_enabled(flag);
-}
-
-/*
* Set the sensitivity of back/forw/stop buttons.
*/
void a_UIcmd_set_buttons_sens(BrowserWindow *bw)
@@ -912,6 +1269,22 @@ void a_UIcmd_set_buttons_sens(BrowserWindow *bw)
}
/*
+ * Keep track of mouse pointer over a link.
+ */
+void a_UIcmd_set_pointer_on_link(BrowserWindow *bw, int flag)
+{
+ BW2UI(bw)->pointerOnLink(flag);
+}
+
+/*
+ * Is the mouse pointer over a link?
+ */
+int a_UIcmd_pointer_on_link(BrowserWindow *bw)
+{
+ return BW2UI(bw)->pointerOnLink();
+}
+
+/*
* Toggle control panel (aka. fullscreen)
*/
void a_UIcmd_fullscreen_toggle(BrowserWindow *bw)
@@ -920,23 +1293,24 @@ void a_UIcmd_fullscreen_toggle(BrowserWindow *bw)
}
/*
- * Search for next occurrence of key.
+ * Search for next/previous occurrence of key.
*/
-void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens)
+void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key,
+ int case_sens, int backwards)
{
Layout *l = (Layout *)bw->render_layout;
-
- switch (l->search(key, case_sens)) {
- case FindtextState::RESTART:
- a_UIcmd_set_msg(bw, "No further occurrences of \"%s\". "
- "Restarting from the top.", key);
- break;
- case FindtextState::NOT_FOUND:
- a_UIcmd_set_msg(bw, "\"%s\" not found.", key);
- break;
- case FindtextState::SUCCESS:
- default:
- a_UIcmd_set_msg(bw, "");
+
+ switch (l->search(key, case_sens, backwards)) {
+ case FindtextState::RESTART:
+ a_UIcmd_set_msg(bw, "No further occurrences of \"%s\". "
+ "Restarting from the top.", key);
+ break;
+ case FindtextState::NOT_FOUND:
+ a_UIcmd_set_msg(bw, "\"%s\" not found.", key);
+ break;
+ case FindtextState::SUCCESS:
+ default:
+ a_UIcmd_set_msg(bw, "");
}
}