mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-21 14:15:25 -06:00
180 lines
4.4 KiB
C++
180 lines
4.4 KiB
C++
#include "ide.h"
|
|
|
|
String SearchEnginesFile()
|
|
{
|
|
return ConfigFile("search_engines.json");
|
|
}
|
|
|
|
Value LoadSearchEngines()
|
|
{
|
|
return ParseJSON(LoadFile(SearchEnginesFile()));
|
|
}
|
|
|
|
struct IconDisplay : Display {
|
|
virtual Size GetStdSize(const Value&) { return DPI(16, 16); }
|
|
virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
|
{
|
|
w.DrawRect(r, paper);
|
|
Image m = StreamRaster::LoadStringAny(q);
|
|
Point p = r.CenterPos(m.GetSize());
|
|
w.DrawImage(p.x, p.y, m);
|
|
}
|
|
};
|
|
|
|
WebSearchTab::WebSearchTab()
|
|
{
|
|
list.AddColumn("Name", 5);
|
|
list.AddColumn("URI", 5);
|
|
list.AddColumn("Icon").SetDisplay(Single<IconDisplay>());
|
|
list.Moving().RowName("search engine").Removing();
|
|
list.WhenLeftDouble = [=] { Edit(); };
|
|
list.SetLineCy(max(GetStdFontSize().cy, DPI(18)));
|
|
list.WhenBar = [&](Bar& bar) {
|
|
bool b = list.IsCursor();
|
|
bar.Add("Add search engine", IdeImg::add(), [&] { Add(); }).Key(K_INSERT);
|
|
bar.Add(b, "Edit search engine", IdeImg::pencil(), [&] { Edit(); }).Key(K_ENTER);
|
|
bar.Add(b, "Set as default engine", IdeImg::star(), [&] { Default(); });
|
|
list.StdBar(bar);
|
|
};
|
|
list.EvenRowColor();
|
|
list.ColumnWidths("104 382 30");
|
|
}
|
|
|
|
bool WebSearchTab::EditDlg(String& name, String& uri, String& ico)
|
|
{
|
|
WithWebSearchEngineLayout<TopWindow> dlg;
|
|
CtrlLayoutOKCancel(dlg, "Web search engine setup");
|
|
CtrlRetriever r;
|
|
r(dlg.name, name)(dlg.uri, uri);
|
|
if(dlg.Execute() == IDOK) {
|
|
r.Retrieve();
|
|
ico = Null;
|
|
int q = uri.Find('/', max(0, uri.FindAfter("//")));
|
|
if(q < 0)
|
|
q = uri.GetCount();
|
|
|
|
Image r;
|
|
Size wanted = DPI(16, 16);
|
|
String data = HttpRequest(uri.Mid(0, q) + "/favicon.ico").RequestTimeout(3000).Execute();
|
|
for(const Image& m : ReadIcon(data)) {
|
|
Size isz = m.GetSize();
|
|
if(isz == wanted) {
|
|
r = m;
|
|
break;
|
|
}
|
|
if(isz.cx > r.GetSize().cx)
|
|
r = m;
|
|
}
|
|
if(IsNull(r))
|
|
r = StreamRaster::LoadStringAny(data);
|
|
DDUMP(r.GetSize());
|
|
ico = IsNull(r) ? String() :
|
|
PNGEncoder().SaveString(2 * r.GetSize() == wanted ? Upscale2x(r)
|
|
: r.GetSize() == 2 * wanted ? Downscale2x(r)
|
|
: Rescale(r, wanted));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void WebSearchTab::Add()
|
|
{
|
|
String name, uri, zico;
|
|
if(EditDlg(name, uri, zico))
|
|
list.Add(name, uri, zico);
|
|
}
|
|
|
|
void WebSearchTab::Edit()
|
|
{
|
|
if(!list.IsCursor())
|
|
return;
|
|
String name = list.Get(0);
|
|
String uri = list.Get(1);
|
|
String zico = list.Get(2);
|
|
if(EditDlg(name, uri, zico)) {
|
|
list.Set(0, name);
|
|
list.Set(1, uri);
|
|
list.Set(2, zico);
|
|
}
|
|
}
|
|
|
|
void WebSearchTab::Default()
|
|
{
|
|
int i = list.GetCursor();
|
|
if(i < 0) return;
|
|
Vector<Value> v = list.GetLine(i);
|
|
list.Remove(i);
|
|
list.Insert(0, v);
|
|
list.SetCursor(0);
|
|
}
|
|
|
|
void WebSearchTab::Load()
|
|
{
|
|
for(Value se : LoadSearchEngines())
|
|
list.Add(se["Name"], se["URI"], Decode64(se["Icon"]));
|
|
}
|
|
|
|
void WebSearchTab::Save()
|
|
{
|
|
JsonArray ja;
|
|
for(int i = 0; i < list.GetCount(); i++)
|
|
ja << Upp::Json("Name", list.Get(i, 0))("URI", list.Get(i, 1))("Icon", Encode64(list.Get(i, 2)));
|
|
|
|
SaveChangedFile(SearchEnginesFile(), ja);
|
|
}
|
|
|
|
void Ide::OnlineSearchMenu(Bar& menu)
|
|
{
|
|
static Time se_tm = Null;
|
|
static Value se;
|
|
|
|
Time h = FileGetTime(SearchEnginesFile());
|
|
if(h != se_tm) {
|
|
se = LoadSearchEngines();
|
|
se_tm = h;
|
|
}
|
|
|
|
bool b = editor.IsSelection() || IsAlNum(editor.GetChar()) || editor.GetChar() == '_';
|
|
|
|
auto OnlineSearch = [=](const String& url) {
|
|
String h = url;
|
|
h.Replace("%s", UrlEncode(Nvl(editor.GetSelection(), editor.GetWord())));
|
|
LaunchWebBrowser(h);
|
|
};
|
|
|
|
auto Icon = [&](int i) {
|
|
return StreamRaster::LoadStringAny(Decode64(se[i]["Icon"]));
|
|
};
|
|
|
|
String name, uri;
|
|
Image m;
|
|
|
|
if(se.GetCount()) {
|
|
name = se[0]["Name"];
|
|
uri = se[0]["URI"];
|
|
m = Icon(0);
|
|
}
|
|
else {
|
|
name = "Google";
|
|
uri = "https://www.google.com/search?q=%s";
|
|
}
|
|
|
|
using namespace IdeKeys;
|
|
|
|
menu.Add(b, "Search on " + name, Nvl(m, CtrlImg::Network()), [=] { OnlineSearch(uri); }).Key(AK_GOOGLE);
|
|
menu.Add(b, AK_GOOGLEUPP, IdeImg::GoogleUpp(), [=] {
|
|
OnlineSearch("https://www.google.com/search?q=%s"
|
|
"&domains=www.ultimatepp.org&sitesearch=www.ultimatepp.org");
|
|
});
|
|
|
|
if(!menu.IsMenuBar() || se.GetCount() < 2)
|
|
return;
|
|
|
|
menu.Sub(b, "Search on...", [=](Bar& menu) {
|
|
for(int i = 1; i < se.GetCount(); i++) {
|
|
const String& name = se[i]["Name"];
|
|
const String& uri = se[i]["URI"];
|
|
menu.Add(b, name, Nvl(Icon(i), CtrlImg::Network()), [=] { OnlineSearch(uri); });
|
|
}
|
|
});
|
|
}
|