Improved theide T++ (help) browser

git-svn-id: svn://ultimatepp.org/upp/trunk@454 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-09-17 12:13:43 +00:00
parent 028a3d7697
commit e6c2027cf5
15 changed files with 536 additions and 270 deletions

View file

@ -1,12 +1,121 @@
TITLE("Heap implementation")
COMPRESSED
120,156,149,88,107,143,219,54,22,253,43,4,210,166,158,68,51,213,211,150,199,221,96,147,110,131,45,138,164,64,211,162,31,6,193,154,150,105,155,59,146,232,21,169,113,156,197,230,183,239,185,36,245,242,78,18,108,48,200,140,68,242,62,206,125,29,234,46,102,223,124,19,6,225,147,240,43,255,110,255,38,118,188,45,205,251,59,153,166,249,138,199,217,234,254,151,95,151,171,103,127,157,205,211,43,146,18,65,74,178,136,146,60,75,162,52,158,227,191,40,137,226,44,78,210,40,143,151,105,158,36,121,120,91,148,92,235,247,119,101,156,231,43,58,20,7,241,147,120,145,197,209,34,205,211,60,74,22,121,140,179,113,24,198,225,34,206,162,52,201,227,236,118,43,116,241,254,142,231,201,234,217,111,115,28,74,72,19,132,135,209,60,78,23,105,28,38,97,156,66,85,148,231,105,180,200,242,100,57,159,223,22,252,104,164,170,189,46,25,69,113,180,218,68,139,21,108,254,244,233,211,77,148,134,206,130,20,194,162,48,133,169,17,222,133,105,188,136,178,101,184,204,242,40,15,19,
8,207,22,97,118,123,228,13,175,62,239,122,246,85,215,23,225,173,52,2,34,158,61,143,162,5,142,204,131,249,147,40,93,192,209,60,73,179,124,17,66,121,28,199,73,18,71,73,188,92,198,217,60,91,220,30,4,223,138,6,46,164,209,220,26,187,8,22,79,178,44,75,177,63,77,179,69,158,198,9,98,147,38,41,160,72,163,101,150,46,179,248,182,22,218,136,237,250,218,193,230,220,239,13,39,187,73,82,30,228,79,230,233,124,25,1,253,116,185,72,195,229,60,90,36,4,94,4,216,231,73,26,47,179,94,146,143,218,191,255,241,159,111,127,122,123,253,199,59,118,167,147,21,251,187,224,71,38,171,99,41,42,81,27,78,104,63,125,127,167,195,21,251,99,253,124,253,156,29,236,186,102,91,249,32,183,98,203,100,109,20,75,88,193,141,216,171,70,10,205,54,92,227,189,170,153,57,8,182,41,85,113,207,180,252,40,216,250,154,233,138,151,101,192,42,177,149,109,197,120,189,101,27,185,191,241,242,233,215,124,197,222,209,30,119,78,251,149,87,246,129,253,176,254,11,3,
132,108,115,54,66,223,176,119,109,113,240,251,24,111,4,139,252,10,107,84,91,195,180,128,105,69,54,96,9,246,98,245,168,180,150,155,82,88,115,180,91,186,97,47,139,66,53,91,89,239,25,28,81,109,195,26,161,5,111,138,67,208,9,239,244,54,226,72,107,181,177,158,85,252,159,240,215,156,153,218,117,27,91,109,1,97,63,18,82,223,59,188,248,241,88,202,194,226,168,217,236,197,50,255,150,14,12,46,94,141,221,15,167,238,91,183,240,168,8,93,43,57,253,229,21,59,242,61,185,239,197,151,39,126,214,76,124,56,138,194,104,114,97,47,12,144,61,3,228,74,53,103,182,107,84,101,237,213,103,132,189,178,18,120,41,247,53,4,206,204,1,200,224,231,216,40,23,205,205,153,29,75,110,118,170,169,152,134,72,185,147,5,123,119,214,47,201,136,223,248,201,198,12,207,175,27,33,232,113,215,214,133,117,237,210,141,159,56,130,211,91,107,19,6,65,119,126,192,72,13,188,203,113,118,220,176,223,41,28,80,44,134,152,213,138,213,194,31,48,180,66,126,29,69,179,190,
118,7,101,77,134,90,108,87,120,128,127,124,59,126,9,0,55,170,117,225,58,29,84,175,16,162,173,60,11,41,45,38,177,79,29,87,155,140,187,51,27,177,151,117,77,169,129,144,117,206,144,165,178,223,105,229,0,64,133,58,192,163,177,25,199,74,169,13,157,217,1,166,46,150,94,21,137,8,216,86,181,72,196,245,117,41,235,251,238,176,102,48,124,92,52,36,11,150,72,131,234,170,97,204,200,104,159,20,138,12,104,218,194,180,48,34,128,118,195,75,86,183,213,6,166,12,105,233,53,119,14,216,24,14,155,46,108,236,221,156,198,243,101,175,240,94,136,163,158,120,217,11,150,218,89,76,105,91,40,234,33,70,148,103,87,22,51,4,115,164,234,138,116,161,38,133,235,51,108,166,106,209,63,32,196,163,212,184,98,250,117,139,154,224,77,195,109,181,145,94,120,219,82,18,77,144,132,154,14,203,27,246,179,233,131,195,27,35,129,152,183,196,103,100,205,244,159,170,185,31,25,161,199,42,140,54,22,168,182,190,56,68,169,111,77,248,44,66,188,68,232,112,74,187,92,53,
135,134,242,178,64,69,8,146,173,71,21,14,51,41,56,0,206,46,195,169,35,229,16,229,163,139,8,165,132,160,90,194,65,106,112,61,42,182,166,236,33,96,235,156,191,98,39,105,14,148,240,27,65,208,64,45,57,189,21,67,11,153,245,15,40,15,108,248,87,43,9,161,66,105,131,157,90,52,192,73,126,116,171,14,223,2,61,14,117,91,98,209,86,250,21,76,222,77,74,212,217,196,31,184,44,57,117,87,159,110,206,223,157,197,163,211,24,244,62,92,246,54,130,250,8,203,237,56,25,142,35,153,84,93,8,54,171,4,175,125,118,77,173,132,13,170,238,66,107,247,82,246,64,205,160,181,175,128,147,106,52,21,147,22,206,139,190,27,140,33,34,75,122,247,120,73,177,59,143,2,50,246,110,236,78,223,103,189,225,56,63,150,74,145,161,236,113,125,111,234,130,120,176,21,240,255,187,56,14,230,163,78,78,51,244,173,58,57,11,187,144,78,199,60,196,25,196,144,212,29,212,41,96,123,9,187,92,207,154,118,183,174,249,218,7,42,135,192,254,229,59,226,184,33,56,44,
225,16,134,148,27,66,68,4,212,4,249,130,6,207,13,123,67,253,189,27,57,148,183,1,89,97,91,245,80,47,100,162,104,42,89,211,116,223,136,130,3,18,38,119,236,36,216,125,141,221,248,125,224,15,98,124,36,160,151,212,63,75,165,238,187,198,174,13,90,194,101,83,199,224,105,164,179,202,218,92,242,102,79,78,31,112,184,167,29,93,182,219,228,181,163,23,243,178,160,180,113,146,249,118,139,130,242,18,68,189,213,54,242,44,39,184,14,226,3,155,65,122,238,69,117,99,152,80,234,201,75,37,181,127,127,5,211,15,178,156,120,163,199,154,251,51,254,0,57,1,173,21,191,39,118,3,150,7,184,41,194,196,188,252,105,76,65,61,24,185,126,74,134,81,17,215,31,69,163,172,236,23,112,53,32,76,215,79,237,154,93,120,4,87,107,245,37,174,143,14,204,142,148,84,20,97,154,206,23,105,249,243,110,84,171,223,79,27,84,139,188,166,134,6,113,190,226,72,13,53,54,202,243,123,88,101,57,15,102,227,22,3,228,118,42,248,207,131,232,39,37,217,52,201,138,157,
164,50,113,35,192,14,50,106,167,7,81,208,16,153,204,97,219,41,208,230,250,6,23,140,102,192,248,148,119,115,24,114,22,70,225,138,136,219,173,162,58,26,36,118,45,78,67,5,168,13,170,142,210,224,146,169,205,92,3,30,177,47,116,173,183,202,8,63,100,31,153,200,159,157,234,67,125,194,157,199,170,254,214,247,60,74,1,115,82,158,43,75,204,65,162,244,84,137,99,137,158,143,52,130,168,243,64,163,156,79,157,158,215,132,112,48,234,165,190,251,245,179,250,17,150,4,86,15,153,53,170,155,98,224,181,245,156,66,214,210,15,114,123,100,182,87,198,161,230,2,66,108,200,66,135,202,57,170,198,122,247,56,20,99,198,82,138,157,233,114,108,215,199,149,178,187,226,53,246,88,82,188,254,142,150,214,223,17,171,38,132,81,81,198,78,243,157,22,246,36,238,82,200,38,186,145,12,234,72,155,107,46,118,98,82,172,221,126,252,245,34,137,131,201,214,81,34,184,184,131,246,205,116,187,49,13,47,108,246,78,111,83,87,158,134,74,127,235,48,148,160,74,110,93,26,120,
210,108,217,37,229,252,103,120,40,218,1,146,19,73,107,21,80,86,218,141,143,208,63,91,74,180,136,141,193,215,201,35,153,37,235,162,177,105,70,141,9,0,72,227,90,205,137,69,1,61,184,113,231,83,166,47,227,74,61,116,165,224,88,31,113,127,42,210,78,6,9,0,109,1,199,178,110,124,158,242,58,162,221,91,68,130,173,18,155,43,23,238,249,171,231,27,119,47,245,50,166,151,79,234,139,54,43,126,96,243,44,11,211,238,22,250,242,136,203,211,7,137,11,7,181,63,109,214,215,59,57,46,206,46,64,190,167,232,33,211,223,184,11,26,69,190,217,243,26,65,181,133,52,39,147,139,67,91,67,233,236,34,39,166,189,192,222,177,6,138,49,64,233,39,177,157,60,32,178,110,234,122,94,211,143,96,220,101,31,164,106,125,8,190,66,247,81,239,83,250,125,25,124,18,72,52,187,104,49,54,29,65,69,45,147,170,45,182,55,114,211,118,84,166,114,92,19,55,86,116,236,154,234,185,191,104,151,234,212,15,220,48,205,109,205,251,203,252,136,24,19,238,52,253,205,73,
136,110,35,124,115,87,189,36,11,195,48,112,167,8,177,145,26,40,221,55,234,164,189,168,254,160,161,220,6,35,192,68,181,99,12,54,62,240,178,21,30,96,91,212,22,52,130,150,224,148,48,232,67,87,71,61,44,227,46,246,197,57,20,116,2,122,246,51,253,100,210,71,203,137,38,6,100,191,71,96,135,229,45,228,150,13,173,155,42,86,22,125,186,176,169,226,36,208,160,163,249,63,106,48,179,62,57,175,0,131,224,166,67,218,95,2,182,254,26,254,74,238,247,162,25,179,13,255,165,231,139,29,97,200,247,74,52,123,247,113,197,174,118,105,105,13,238,83,14,251,106,241,97,98,31,70,37,110,247,255,195,88,187,105,87,161,191,194,172,129,99,218,50,233,172,36,176,208,43,20,120,113,119,241,183,252,91,59,130,213,221,164,65,122,218,210,226,215,95,185,105,223,219,95,127,239,184,212,240,105,68,11,43,0,92,249,216,13,146,49,15,187,228,214,190,131,0,189,233,167,171,215,195,24,219,56,100,45,232,163,22,50,6,207,242,181,179,187,59,142,191,186,32,188,91,196,
168,160,194,241,113,126,144,141,65,23,244,159,121,198,215,221,209,7,144,209,247,143,9,105,255,194,103,14,207,92,236,29,150,152,36,189,118,103,163,249,250,218,241,205,182,238,96,234,134,73,163,10,16,202,27,123,27,112,5,213,8,211,54,8,196,212,78,100,58,36,249,123,132,27,214,29,144,239,255,11,93,173,175,92,
topic "Heap implementation";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,2#27521748481378242620020725143825:desc]
[a83;*R6 $$3,0#31310162474203024125188417583966:caption]
[l288;i1121;b17;O9;~~~.1408;2 $$4,0#10431211400427159095818037425705:param]
[i448;a25;kKO9;*@(64)2 $$5,0#37138531426314131252341829483370:item]
[*+117 $$6,6#14700283458701402223321329925657:header]
[l416;2 $$7,7#55548704457842300043401641954952:nested`-desc]
[l288;i448;a25;kO9;*2 $$8,8#64691275497409617375831514634295:nested`-class]
[{_}%EN-US
[s3; Heap implementation&]
[s0; U`+`+ heap is divided into 3 categories based on the block size
`- small, medium and big.&]
[s0; &]
[s6; Small blocks&]
[s0; Blocks <`= 256 bytes. Such blocks are 16 bytes rounded, so there
is 16 possible sizes there. According to our research, blocks
<`= 256 represent the majority of blocks used in C`+`+/U`+`+
applications (>98% of all blocks).&]
[s0; &]
[s0; Small blocks are allocated in 4KB pages. U`+`+ always expects
to get any memory from the system 4KB aligned (this is provided
by platform specific SysAllocRaw and SysFreeRaw functions).&]
[s0; &]
[s0; Each 4KB pages is dedicated to single block size. Therefore
there is no need to store any per`-block information; instead
informations about the whole block is stored in the 32 bytes
header at the beginning of 4KB page. This header stores pointer
to the list of free blocks in the page, double`-link pointers
for the block so that it can be stored in allocator structures,
total number of blocks in the 4KB page and number of free blocks
in 4KB page.&]
[s0; &]
[s0; Allocator keeps the list of 4KB page is that are completely
used (no free blocks) in 16 element (one element per block size)
sFull array of lists, using double`-linked pointers. It stores
partially used pages in sWork 16 elements array of litst and
unused pages in sFree list.&]
[s0; &]
[s0; Allocator also uses per`-thread cache of small blocks. In this
cache, up to 32 blocks for each of 16 block sizes is cached (linked)
without being really deallocated (deallocation requires costly
serialization using critical section). If there is no block available
in the cache for allocation, 16 blocks are allocated and put
into the cache at once (means that serialization is only used
once per 16 allocations in the worst case). If block is deallocated
and there is already 32 blocks in the cache, 16 blocks from the
cache are deallocated within single serialization event (means
that serialization is only used once per 16 deallocations in
the worst case).&]
[s0; &]
[s0; Now the critical implementation detail is how, given the pointer
to the block in the Free, the header of 4KB page and that way
the size of block is decided. More specifically, how is small
block determined, because if we know we have small block, we
can look at the start of 4KB page. The trick is that larger than
256 bytes block are always placed at the address that ends with
8 in hex (is 8 bytes aligned and 16 bytes misaligned), while
small blocks are always 16 bytes aligned. That makes test simple
`- blocks whose address `& 8 is nonzero are >256, if `&8 is zero
we have small block and can look at the beginning of 4KB page
to get more info.&]
[s0; &]
[s0; If allocation/deallocation runs out of cache, the real work
has to be done:&]
[s0; &]
[s0; When allocating small block, first sWork list is checked for
the block. If no available, sFree list is checked to get free
block, if even that is empty, new block is obtained from the
system (using SysAllocRaw). Note that allocator keeps the number
of free blocks in the header. Implementation detail: there are
two possibilities how free blocks can be recorded in the block
header. First, there is a single`-linked list of free blocks.
Second, for blocks that are initially free (got from sFree or
system), portion of free blocks in the 4KB page is left out of
free list and managed by `'free`' member `- the offset of last
such free block in page. If this offset is >32, free block is
obtained using it (subtracting the block size). This is used
to avoid the need to link all free blocks in the page when getting
new free page.&]
[s0; &]
[s0; When freeing, number of free blocks in 4KB page is incremented.
If it is now 1, it means block has to be moved from sFull to
sWork. If it now equals the total number of blocks in page, 4KB
page moves to sFree.&]
[s0; &]
[s0; &]
[s6; Medium blocks &]
[s0; Blocks >256 and < 65504 bytes. Approximate best`-fit allocator
is used for these blocks. Memory is organized in 64KB chunks
(obtained using SysAllocRaw). Each allocated block has header
with its size and the size of previous block.&]
[s0; &]
[s0; Allocator keeps an array of lists of free blocks of particular
sizes. Size distribution is mostly exponential, blocks lower
than 2048 are rounded up to 32 bytes, between 2048 and about
35000, rounding exponentially grows up to 2048 and then stays
at this value. Each such size has its index in the array of free
blocks.&]
[s0; &]
[s0; When allocating, index is decided based on the size and array
is searched starting with that index to obtain the smallest free
block (best`-fit) greater than required size. Bigger blocks are
divided.&]
[s0; &]
[s0; When freeing, allocator merges the freed block with previous
or next free block if any.&]
[s0; &]
[s0; Note that master header of 64KB blocks and all operations are
designed so that resulting pointers are NOT 16 byte aligned (see
description of small blocks).&]
[s0; &]
[s0; &]
[s6; Big blocks&]
[s0; For blocks bigger than 65504 bytes, allocator simply uses SysAllocRaw
to directly obtain virtual memory. It stores information about
the block in the header at the beginning of block, also makeing
block 16`-bytes unaligned in the process. Free then returns virtual
memory back to the system.&]
[s0; ]

View file

@ -15,7 +15,7 @@ void HelpWindow::FinishText(RichText& text)
bool HelpWindow::GoTo0(const String& link)
{
if(IsNull(link))
if(IsNull(link) || current_link == link)
return false;
Topic t = AcquireTopic(link);
SetBar();
@ -28,6 +28,7 @@ bool HelpWindow::GoTo0(const String& link)
view.Pick(txt, zoom);
view.GotoLabel(label, true);
tree.FindSetCursor(topic);
current_link = link;
return true;
}
return false;
@ -139,7 +140,6 @@ bool HelpWindow::Key(dword key, int count)
void HelpWindow::ClearTree()
{
tree_view.Zoom(1);
tree.Clear();
}
@ -178,6 +178,19 @@ void HelpWindow::TreeCursor()
GoTo(~tree);
}
void HelpWindow::CurrentOrHome()
{
if(~tree != current_link) {
if(tree.FindSetCursor(current_link))
return;
for(int i = 0; i < tree.GetLineCount(); i++) {
Value k = tree.Get(tree.GetItemAtLine(i));
if(!IsNull(k) && tree.FindSetCursor(k))
break;
}
}
}
HelpWindow::HelpWindow()
{
tree_view.Horz(tree, view);
@ -194,10 +207,11 @@ HelpWindow::HelpWindow()
SetZoom();
view.Margins(Rect(12, 12, 2, 2));
SetRect(Ctrl::GetWorkArea().Deflated(80));
tree <<= THISBACK(TreeCursor);
tree.WhenSel = THISBACK(TreeCursor);
tree.NoRoot();
Icon(CtrlImg::help());
SetBar();
tree.BackPaint();
}
END_UPP_NAMESPACE

View file

@ -163,6 +163,7 @@ private:
Index<String> tree_ndx;
String topic;
String label;
String current_link;
bool GoTo0(const String& link);
void Back();
@ -189,9 +190,11 @@ public:
void SortTree(int id = 0);
void FinishTree();
void OpenDeep(int id = 0);
void CurrentOrHome();
String GetCurrent() const { return topic; }
String GetCurrentLabel() const { return label; }
String GetCurrentLink() const { return current_link; }
typedef HelpWindow CLASSNAME;

View file

@ -276,10 +276,10 @@ void RichTextView::GotoLabel(const String& lbl, bool dohighlight)
sb = f[i].py.y;
if(dohighlight)
highlight = f[i].pos;
Refresh();
break;
}
}
Refresh();
}
void RichTextView::Clear()

View file

@ -367,6 +367,16 @@ void TreeCtrl::ReLine(int itemi, int level, Size& sz)
RemoveCtrls(m.child[i]);
}
void TreeCtrl::SyncAfterSync(Ptr<Ctrl> restorefocus)
{
if(treesize != sb.GetTotal()) {
sb.SetTotal(treesize);
Refresh();
}
SyncCtrls(true, restorefocus);
SyncInfo();
}
void TreeCtrl::SyncTree()
{
if(!dirty)
@ -389,16 +399,11 @@ void TreeCtrl::SyncTree()
ReLine(0, 0, treesize);
treesize.cy = max(0, treesize.cy);
treesize.cx += levelcx;
if(treesize != sb.GetTotal()) {
sb.SetTotal(treesize);
Refresh();
}
cursor = -1;
dirty = false;
if(cursorid >= 0)
SetCursor(cursorid, false, false, false);
SyncCtrls(true, restorefocus);
PostCallback(PTEBACK(SyncInfo));
PostCallback(PTEBACK1(SyncAfterSync, restorefocus));
}
void TreeCtrl::SyncCtrls(bool add, Ctrl *restorefocus)

View file

@ -147,6 +147,7 @@ private:
void GatherSel(int id, Vector<int>& sel) const;
void DoClick(Point p, dword flags, bool down);
void SyncInfo();
void SyncAfterSync(Ptr<Ctrl> restorefocus);
protected:
virtual void SetOption(int id);

99
uppsrc/ide/About.cpp Normal file
View file

@ -0,0 +1,99 @@
#include "ide.h"
#ifdef PLATFORM_WIN32
#include "shellapi.h"
#endif
#define TOPICFILE <ide/app.tpp/all.i>
#include <Core/topic_group.h>
Size MakeLogo(Ctrl& parent, Array<Ctrl>& ctrl)
{
Image logo = IdeImg::logo();
Size isz = logo.GetSize();
ImageCtrl& l = ctrl.Create<ImageCtrl>();
Label& v = ctrl.Create<Label>();
Label& v1 = ctrl.Create<Label>();
l.SetImage(logo);
Size sz = Size(isz.cx, isz.cy + 80);
v = IDE_VERSION;
v.LeftPos(300, 100).TopPos(90, 40);
if(sizeof(void *) == 8) {
v = IDE_VERSION " (64 bit)";
v.RightPos(3, Ctrl::MINSIZE).TopPos(90, 40);
}
l.Add(v);
v.SetFont(Arial(20));
v.SetInk(Blend(Gray, Blue));
v1 = Format("%d`KB", MemoryUsedKb());
v1.LeftPos(300, 100).BottomPos(20, 12);
v1.SetFont(Arial(10));
l.Add(v1);
parent.Add(ctrl.Create<StaticRect>().Color(White).SizePos());
parent.Add(l.TopPos(0, isz.cy).LeftPos(0, isz.cx));
parent.Add(ctrl.Create<StaticRect>().Color(Blue).LeftPos(2, isz.cx - 4).TopPos(isz.cy, 1));
RichTextView& w = ctrl.Create<RichTextView>();
w.SetQTF(GetTopic("ide/app/Sponsor$en-us"));
w.PageWidth(2900);
w.NoSb();
w.SetFrame(NullFrame());
parent.Add(w.TopPos(isz.cy + 3, 99).LeftPos(0, isz.cx));
return sz;
}
struct Splash : Ctrl {
Array<Ctrl> ctrl;
Splash() {
SetRect(GetWorkArea().CenterRect(MakeLogo(*this, ctrl) + 2));
SetFrame(BlackFrame());
}
};
void HideSplash()
{
if(Single<Splash>().IsOpen())
Single<Splash>().Close();
}
void ShowSplash()
{
Single<Splash>().PopUp(NULL, false, false);
SetTimeCallback(750, callback(HideSplash));
}
bool IsSplashOpen()
{
return Single<Splash>().IsOpen();
}
struct AboutDlg : TopWindow {
Array<Ctrl> ctrl;
RichTextView about;
typedef AboutDlg CLASSNAME;
virtual bool Key(dword key, int) {
if(key == K_ALT_M)
MemoryProfileInfo();
return false;
}
AboutDlg() {
Size isz = MakeLogo(*this, ctrl);
SetRect(0, 0, 1000, isz.cy);
about.SetQTF(GetTopic("ide/app/About$en-us"), Zoom(130, 1024));
about.SetZoom(Zoom(1, 1));
about.RightPos(0, 1000 - isz.cx).VSizePos();
about.HMargins(4);
about.SetFrame(NullFrame());
Background(PaintRect(ColorDisplay(), SColorPaper()));
Add(about);
Title("About TheIDE");
}
};
void Ide::About()
{
AboutDlg().Execute();
}

View file

@ -217,17 +217,21 @@ struct TopicInfo : Moveable<TopicInfo> {
Vector<int> words;
};
String GetTopicPath(const TopicLink& link);
String GetTopicPath(const String& link);
void SyncRefs();
void SyncTopicFile(const RichText& text, const String& link, const String& path,
const String& title);
void SyncTopicFile(const String& link, const String& path);
void SyncTopicFile(const String& link);
String GetTopicTitle(const String& link);
void InvalidateTopicInfoPath(const String& path);
Vector<String> GetRefLinks(const String& ref);
int TopicWordIndex(const String& w);
bool MatchTopicLink(const String& link, const Vector<int>& query);
int MatchWord(const Vector<int>& w, const String& pattern);
bool MatchTopicLink(const String& link, const Vector<String>& query);
#define LAYOUTFILE <ide/Browser/Topic.lay>
#include <CtrlCore/lay.h>
@ -296,6 +300,7 @@ protected:
static String lasttemplate;
static int lastlang;
static bool allfonts;
static int serial;
struct FileInfo {
Time time;

View file

@ -16,6 +16,20 @@ bool ParseTopicFileName(const String& fn, String& topic, int& lang)
return lang;
}
String GetTopicPath(const TopicLink& tl)
{
if(IsNull(tl.package))
return Null;
return AppendFileName(
AppendFileName(PackageDirectory(tl.package), tl.group + ".tpp"),
tl.topic + ".tpp");
}
String GetTopicPath(const String& link)
{
return GetTopicPath(ParseTopicLink(link));
}
Topic ReadTopic(const char *text)
{
Topic topic;

View file

@ -109,11 +109,11 @@ void TopicEditor::Load(const String& fn)
title.ClearModify();
}
int sSerial = 0;
int TopicEditor::serial;
int TopicEditor::GetSerial()
{
return sSerial;
return serial;
}
void TopicEditor::SaveTopic()
@ -141,7 +141,7 @@ void TopicEditor::SaveTopic()
return;
String r = WriteTopic((String)~title, editor.Get());
if(LoadFile(topicpath) != r) {
sSerial++;
serial++;
SaveFile(topicpath, r);
if(FileExists(AppendFileName(grouppath, "all.i")))
SaveFile(ForceExt(topicpath, ".tppi"), WriteTopicI((String)~title, editor.Get()));

View file

@ -1,5 +1,7 @@
#include "Browser.h"
#define LLOG(x) // DLOG(x)
Index<String>& ref_link()
{
static Index<String> x;
@ -58,25 +60,24 @@ struct ScanTopicIterator : RichText::Iterator {
Index<int> words;
Index<String> ref;
virtual bool operator()(int pos, const RichPara& para)
virtual bool operator()(int pos, const RichPara& para)// A++ bug here....
{
if(!IsNull(para.format.label)) {
AddLinkRef(link, para.format.label);
ref.FindAdd(para.format.label);
}
for(int i = 0; i < para.part.GetCount(); i++)
if(para.part[i].IsText()) {
const wchar *s = para.part[i].text;
for(;;) {
while(!IsLetter(*s) && *s)
while(!IsLetter(*s) && !IsDigit(*s) && *s)
s++;
if(*s == '\0')
break;
WStringBuffer wb;
while(IsLetter(*s))
wb.Cat(ToLower(*s++));
words.FindAdd(TopicWordIndex(FromUnicode(wb)));
StringBuffer sb;
while(IsLetter(*s) || IsDigit(*s))
sb.Cat(ToAscii(ToLower(*s++)));
words.FindAdd(TopicWordIndex(sb));
}
}
return false;
@ -95,6 +96,8 @@ String TopicCacheName(const char *path)
return AppendFileName(cfg, ForceExt(Filter(path, NoSlashDot), ".tdx"));
}
const char *tdx_version = "tdx version 2.0";
void SyncTopicFile(const RichText& text, const String& link, const String& path, const String& title)
{
ClearLinkRef(link);
@ -103,25 +106,28 @@ void SyncTopicFile(const RichText& text, const String& link, const String& path,
sti.link = link;
text.Iterate(sti);
TopicInfo& ti = topic_info().GetAdd(link);
TopicInfo& ti = topic_info().GetPut(link);
ti.title = title;
ti.path = path;
ti.time = FileGetTime(path);
ti.words = sti.words.PickKeys();
Sort(ti.words);
FileOut out(TopicCacheName(path));
out << tdx_version << "\n";
out << title << '\n';
for(int i = 0; i < sti.ref.GetCount(); i++)
out << sti.ref[i] << '\n';
out << '\n';
const Index<String>& ws = TopicWords();
for(int i = 0; i < ti.words.GetCount(); i++)
out << TopicIndexWord(ti.words[i]) << '\n';
out << ws[ti.words[i]] << '\n';
}
void SyncTopicFile(const String& link, const String& path)
void SyncTopicFile(const String& link)
{
TopicInfo& ti = topic_info().GetAdd(link);
String path = GetTopicPath(link);
LLOG("SyncTopicFile " << link << " path: " << path);
TopicInfo& ti = topic_info().GetPut(link);
Time tm = FileGetTime(path);
if(ti.path == ":ide:" || ti.path == path && ti.time == tm)
return;
@ -129,6 +135,9 @@ void SyncTopicFile(const String& link, const String& path)
if(FileGetTime(fn) > tm) {
ClearLinkRef(link);
FileIn in(fn);
if(in) {
String s = in.GetLine();
if(s == tdx_version) {
ti.title = in.GetLine();
ti.words.Clear();
ti.path = path;
@ -148,10 +157,20 @@ void SyncTopicFile(const String& link, const String& path)
Sort(ti.words);
return;
}
}
}
Topic tp = ReadTopic(LoadFile(path));
SyncTopicFile(ParseQTF(tp.text), link, path, tp.title);
}
void InvalidateTopicInfoPath(const String& path)
{
VectorMap<String, TopicInfo>& t = topic_info();
for(int i = 0; i < t.GetCount(); i++)
if(t[i].path == path)
t.Unlink(i);
}
void SyncRefsDir(const char *dir, const String& rel, Progress& pi)
{
for(FindFile pff(AppendFileName(dir, "*.*")); pff; pff.Next()) {
@ -171,7 +190,7 @@ void SyncRefsDir(const char *dir, const String& rel, Progress& pi)
tl.topic = GetFileTitle(ft.GetName());
String link = TopicLinkString(tl);
pi.SetText("Indexing topic " + tl.topic);
SyncTopicFile(link, path);
SyncTopicFile(link);
}
}
}
@ -203,18 +222,32 @@ Vector<String> GetRefLinks(const String& ref)
String GetTopicTitle(const String& link)
{
SyncTopicFile(link);
int q = topic_info().Find(link);
return q >= 0 ? topic_info()[q].title : Null;
}
bool MatchTopicLink(const String& link, const Vector<int>& query)
int MatchWord(const Vector<int>& w, const String& pattern)
{
const Index<String>& ws = TopicWords();
for(int i = 0; i < w.GetCount(); i++) {
String wrd = ws[w[i]];
if(wrd.GetCount() >= pattern.GetCount() && memcmp(wrd, pattern, pattern.GetCount()) == 0)
return i;
}
return -1;
}
bool MatchTopicLink(const String& link, const Vector<String>& query)
{
// TIMING("MatchTopicLink"); _DBG_
SyncTopicFile(link);
int q = topic_info().Find(link);
if(q < 0)
return false;
TopicInfo& f = topic_info()[q];
for(int i = 0; i < query.GetCount(); i++)
if(FindIndex(f.words, query[i]) < 0)
if(MatchWord(f.words, query[i]) < 0)
return false;
return true;
}

View file

@ -253,6 +253,7 @@ void TopicEditor::NewTopic()
SaveInc();
topic.FindSetCursor(GetFileTitle(fn));
editor.SetFocus();
serial++;
}
void TopicEditor::RenameTopic()
@ -275,11 +276,14 @@ void TopicEditor::RenameTopic()
}
Flush();
FileMove(p, np);
InvalidateTopicInfoPath(p);
InvalidateTopicInfoPath(np);
Open(grouppath);
Load(np);
SaveInc();
topic.FindSetCursor(GetFileTitle(np));
editor.SetFocus();
serial++;
}
void TopicEditor::RemoveTopic()
@ -296,6 +300,7 @@ void TopicEditor::RemoveTopic()
topic.SetCursor(q);
if(q >= 0)
editor.SetFocus();
InvalidateTopicInfoPath(p);
}
void TopicEditor::SaveAsTemplate()

View file

@ -1,103 +1,5 @@
#include "ide.h"
#ifdef PLATFORM_WIN32
#include "shellapi.h"
#endif
#define TOPICFILE <ide/app.tpp/all.i>
#include <Core/topic_group.h>
Size MakeLogo(Ctrl& parent, Array<Ctrl>& ctrl)
{
Image logo = IdeImg::logo();
Size isz = logo.GetSize();
ImageCtrl& l = ctrl.Create<ImageCtrl>();
Label& v = ctrl.Create<Label>();
Label& v1 = ctrl.Create<Label>();
l.SetImage(logo);
Size sz = Size(isz.cx, isz.cy + 80);
v = IDE_VERSION;
v.LeftPos(300, 100).TopPos(90, 40);
if(sizeof(void *) == 8) {
v = IDE_VERSION " (64 bit)";
v.RightPos(3, Ctrl::MINSIZE).TopPos(90, 40);
}
l.Add(v);
v.SetFont(Arial(20));
v.SetInk(Blend(Gray, Blue));
v1 = Format("%d`KB", MemoryUsedKb());
v1.LeftPos(300, 100).BottomPos(20, 12);
v1.SetFont(Arial(10));
l.Add(v1);
parent.Add(ctrl.Create<StaticRect>().Color(White).SizePos());
parent.Add(l.TopPos(0, isz.cy).LeftPos(0, isz.cx));
parent.Add(ctrl.Create<StaticRect>().Color(Blue).LeftPos(2, isz.cx - 4).TopPos(isz.cy, 1));
RichTextView& w = ctrl.Create<RichTextView>();
w.SetQTF(GetTopic("ide/app/Sponsor$en-us"));
w.PageWidth(2900);
w.NoSb();
w.SetFrame(NullFrame());
parent.Add(w.TopPos(isz.cy + 3, 99).LeftPos(0, isz.cx));
return sz;
}
struct Splash : Ctrl {
Array<Ctrl> ctrl;
Splash() {
SetRect(GetWorkArea().CenterRect(MakeLogo(*this, ctrl) + 2));
SetFrame(BlackFrame());
}
};
void HideSplash()
{
if(Single<Splash>().IsOpen())
Single<Splash>().Close();
}
void ShowSplash()
{
Single<Splash>().PopUp(NULL, false, false);
SetTimeCallback(750, callback(HideSplash));
}
bool IsSplashOpen()
{
return Single<Splash>().IsOpen();
}
struct AboutDlg : TopWindow {
Array<Ctrl> ctrl;
RichTextView about;
typedef AboutDlg CLASSNAME;
virtual bool Key(dword key, int) {
if(key == K_ALT_M)
MemoryProfileInfo();
return false;
}
AboutDlg() {
Size isz = MakeLogo(*this, ctrl);
SetRect(0, 0, 1000, isz.cy);
about.SetQTF(GetTopic("ide/app/About$en-us"), Zoom(130, 1024));
about.SetZoom(Zoom(1, 1));
about.RightPos(0, 1000 - isz.cx).VSizePos();
about.HMargins(4);
about.SetFrame(NullFrame());
Background(PaintRect(ColorDisplay(), SColorPaper()));
Add(about);
Title("About TheIDE");
}
};
void Ide::About()
{
AboutDlg().Execute();
}
struct GatherLinksIterator : RichText::Iterator {
Index<String> link;
@ -130,16 +32,16 @@ void GatherLinks(Index<String>& link, const char *topic)
Index<String> TopicCtrl::idelink;
void TopicCtrl::ScanDirForTpp(const char *dir, Index<String>& li, Vector<int>& sdx,
const String& lng,
VectorMap<String, VectorMap<String, Vector<String> > >& map,
const String& rel)
void TopicCtrl::ScanDirForTpp(const char *dir, const String& rel,
Index<String>& donepackage, Index<String>& lang_list)
{
TopicLink tl;
for(FindFile pff(AppendFileName(dir, "*.*")); pff; pff.Next()) {
if(pff.IsFolder() && *pff.GetName() != '.') {
String pdir = AppendFileName(dir, pff.GetName());
tl.package = rel + pff.GetName();
if(donepackage.Find(tl.package) < 0) {
donepackage.Add(tl.package);
for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff; ff.Next())
if(ff.IsFolder()) {
tl.group = GetFileTitle(ff.GetName());
@ -151,68 +53,98 @@ void TopicCtrl::ScanDirForTpp(const char *dir, Index<String>& li, Vector<int>& s
String l;
if(q >= 0) {
l = ToUpper(tl.topic.Mid(q + 1));
li.FindAdd(l);
lang_list.FindAdd(l);
}
String link = TopicLinkString(tl);
if(idelink.Find(link) < 0 && MatchTopicLink(link, sdx) &&
(lng == "All" || lng == l)) {
map.GetAdd(tl.package).GetAdd(tl.group).Add(tl.topic);
map.GetAdd(tl.package).GetAdd(tl.group).FindAdd(tl.topic);
}
}
}
ScanDirForTpp(pdir, li, sdx, lng, map, tl.package + '/');
ScanDirForTpp(pdir, tl.package + '/', donepackage, lang_list);
}
}
}
int map_serial, topic_serial;
void TopicCtrl::LoadMap()
{
map.Clear();
lang_list.Clear();
Vector<String> upp = GetUppDirs();
Index<String> donepackage, lang_list;
for(int i = 0; i < upp.GetCount(); i++)
ScanDirForTpp(upp[i], String(), donepackage, lang_list);
Vector<String> l = lang_list.PickKeys();
Sort(l);
String lng = ~lang;
lang.Clear();
lang.Add("All");
for(int i = 0; i < l.GetCount(); i++)
lang.Add(l[i]);
if(lng.GetCount() && lang.Find(lng))
lang <<= lng;
else
if(lang.Find("EN-US"))
lang <<= "EN-US";
else
if(lang.GetCount())
lang.SetIndex(0);
}
const char *sTopicHome = "\3topic://ide/app/index$en-us";
void TopicCtrl::SyncDocTree()
{
if(map_serial != topic_serial) {
LoadMap();
map_serial = topic_serial;
}
Vector<String> ss = Split((String)~search, ' ');
Vector<int> sdx;
Vector<String> sdx;
for(int i = 0; i < ss.GetCount(); i++)
sdx.Add(TopicWordIndex(ToUtf8(ToLower(FromUtf8(ss[i])))));
sdx.Add(ToUtf8(ToLower(FromUtf8(ss[i]))));
ClearTree();
String hdx = "topic://ide/app/index$en-us";
String hdx = sTopicHome + 1;
if(idelink.GetCount() == 0)
GatherLinks(idelink, hdx);
int ide = AddTree(0, IdeImg::Package(), "\3" + hdx, "TheIDE help");
for(int i = 0; i < idelink.GetCount(); i++)
if(idelink[i] != hdx && MatchTopicLink(idelink[i], sdx))
int ide;
bool idefirst = true;
if(MatchTopicLink(hdx, sdx)) {
ide = AddTree(0, IdeImg::Package(), "\3" + hdx, "TheIDE help");
idefirst = false;
}
for(int i = 0; i < idelink.GetCount(); i++) {
if(idelink[i] != hdx && MatchTopicLink(idelink[i], sdx)) {
if(idefirst) {
ide = AddTree(0, IdeImg::Package(), "\3" + hdx, "TheIDE help");
idefirst = false;
}
AddTree(ide, TopicImg::Topic(), "\3" + idelink[i], GetTopic(idelink[i]).title);
}
}
Index<String> used;
const Workspace& wspc = GetIdeWorkspace();
for(int i = 0; i < wspc.GetCount(); i++)
used.Add(wspc[i]);
VectorMap<String, VectorMap<String, Vector<String> > > map;
Vector<String> upp = GetUppDirs();
int usid;
bool usedfirst = true;
int otid;
bool otherfirst = true;
String lng = ~lang;
lang.Clear();
lang.Add("All");
Index<String> li;
for(int i = 0; i < upp.GetCount(); i++)
ScanDirForTpp(upp[i], li, sdx, lng, map, String());
Vector<String> sli = li.PickKeys();
Sort(sli);
for(int i = 0; i < sli.GetCount(); i++)
lang.Add(sli[i]);
if(lang.Find(lng))
lang <<= lng;
int usid = AddTree(0, IdeImg::Package(), Null, "Used packages");
int otid = AddTree(0, IdeImg::Package(), Null, "Other packages");
for(int i = 0; i < map.GetCount(); i++) {
TopicLink tl;
tl.package = map.GetKey(i);
int pid = AddTree(used.Find(tl.package) >= 0 ? usid : otid,
TopicImg::Package(), Null, tl.package);
VectorMap<String, Vector<String> >& package = map[i];
for(int i = 0; i < package.GetCount(); i++) {
tl.group = package.GetKey(i);
bool packagefirst = true;
int pid;
VectorMap<String, Index<String> >& group = map[i];
for(int i = 0; i < group.GetCount(); i++) {
tl.group = group.GetKey(i);
if(all || tl.group == "src" || tl.group == "srcdoc" || tl.group == "srcimp") {
String n = tl.group;
if(n == "src")
@ -221,10 +153,40 @@ void TopicCtrl::SyncDocTree()
n = "Documents";
if(n == "srcimp")
n = "Implementation";
int gid = AddTree(pid, Null, "\1" + tl.group, n);
Vector<String> group = package[i];
for(int i = 0; i < group.GetCount(); i++) {
tl.topic = group[i];
int gid;
bool groupfirst = true;
const Index<String>& topic = group[i];
for(int i = 0; i < topic.GetCount(); i++) {
tl.topic = topic[i];
int q = tl.topic.ReverseFind('$');
String l;
if(q >= 0)
l = ToUpper(tl.topic.Mid(q + 1));
String link = TopicLinkString(tl);
if(idelink.Find(link) < 0 && MatchTopicLink(link, sdx) && (lng == "All" || lng == l)) {
int pd;
if(used.Find(tl.package) >= 0) {
if(usedfirst) {
usid = AddTree(0, IdeImg::Package(), Null, "Used packages");
usedfirst = false;
}
pd = usid;
}
else {
if(otherfirst) {
otid = AddTree(0, IdeImg::Package(), Null, "Other packages");
otherfirst = false;
}
pd = otid;
}
if(packagefirst) {
pid = AddTree(pd, TopicImg::Package(), Null, tl.package);
packagefirst = false;
}
if(groupfirst) {
gid = AddTree(pid, Null, Null, n);
groupfirst = false;
}
String p = TopicLinkString(tl);
String t = GetTopicTitle(p);
AddTree(gid, TopicImg::Topic(), p, t);
@ -232,12 +194,18 @@ void TopicCtrl::SyncDocTree()
}
}
}
}
if(!idefirst)
SortTree(ide);
if(!usedfirst)
SortTree(usid);
if(!otherfirst)
SortTree(otid);
FinishTree();
if(sdx.GetCount())
if(sdx.GetCount()) {
OpenDeep();
CurrentOrHome();
}
}
Vector<String> GetTypeRefLinks(const String& t, String &label)
@ -262,22 +230,19 @@ Topic TopicCtrl::AcquireTopic(const String& t)
internal = (byte)*topic < 32;
if(*topic == '\3')
return GetTopic(topic.Mid(1));
if(*topic == '\1') {
/* if(*topic == '\1') {
Topic t;
t.title = "Summary";
String group = topic.Mid(1);
const Workspace& wspc = GetIdeWorkspace();
for(int i = 0; i < wspc.GetCount(); i++) {
String package = wspc[i];
String path = AppendFileName(AppendFileName(PackageDirectory(wspc[i]), group + ".tpp"), "index$en-us.tpp");
if(FileExists(path)) {
t.text << "[R5* " << wspc[i] << "]&" << ReadTopic(LoadFile(path)).text << "&&&";
}
}
return t;
}
if(*topic == '\2')
topic = topic.Mid(1);
int q = group.Find('\2');
String package = group.Mid(q + 1);
group.Trim(q);
String path = AppendFileName(AppendFileName(PackageDirectory(package), group + ".tpp"),
"index$en-us.tpp");
if(FileExists(path))
return ReadTopic(LoadFile(path));
return Topic();
}*/
if(topic[0] == ':' && topic[1] == ':') {
String lbl;
Vector<String> link = GetTypeRefLinks(topic, lbl);
@ -451,21 +416,16 @@ void TopicCtrl::SShow()
void TopicCtrl::Search()
{
if(issearch) {
search <<= Null;
issearch = false;
}
else {
search.AddHistory(20);
issearch = true;
}
int l, h;
search.GetSelection(l, h);
SyncDocTree();
SetBar();
search.SetFocus();
search.SetSelection(l, h);
}
void TopicCtrl::SearchWord(const String& s)
{
issearch = false;
search <<= s;
Search();
}
@ -499,6 +459,11 @@ bool TopicCtrl::Key(dword key, int count)
return HelpWindow::Key(key, count);
}
void TopicCtrl::FocusSearch()
{
search.SetFocus();
}
void TopicCtrl::BarEx(Bar& bar)
{
bar.Gap();
@ -506,12 +471,10 @@ void TopicCtrl::BarEx(Bar& bar)
bar.Add("All topics", IdeImg::HelpAll(), THISBACK(All))
.Check(all);
bar.Gap(HorzLayoutZoom(30));
bar.Add(search_label, HorzLayoutZoom(50));
bar.Add(search, HorzLayoutZoom(300));
bar.Add("Full text search", IdeImg::HelpSearch(), THISBACK(Search))
.Check(issearch);
bar.Add("Highlight search keywords in topic", IdeImg::ShowWords(), THISBACK(ShowWords))
.Check(showwords);
bar.AddKey(K_CTRL_F, THISBACK(FocusSearch));
/* bar.Add("Highlight search keywords in topic", IdeImg::ShowWords(), THISBACK(ShowWords))
.Check(showwords);*/
bar.Add(!internal && GetCurrent().StartsWith("topic:"),
IdeImg::show(), THISBACK(SShow));
bar.GapRight();
@ -522,9 +485,12 @@ void TopicCtrl::BarEx(Bar& bar)
void TopicCtrl::Serialize(Stream& s)
{
int version = 2;
int version = 3;
s / version;
search.SerializeList(s);
if(version < 3) {
WithDropChoice<EditString> dummy;
dummy.SerializeList(s);
}
if(version >= 1)
s % showwords;
if(version >= 2)
@ -552,10 +518,11 @@ struct HelpModule : public IdeModule {
}
virtual IdeDesigner *CreateDesigner(Ide *ide, const char *path, byte cs) {
if(IsHelpName(path)) {
topic_serial++;
GetRefLinks("");
if(ide->doc.GetCurrent().IsEmpty()) {
ide->doc.SyncDocTree();
ide->doc.GoTo(Nvl(recent_topic, "\3topic://ide/app/index$en-us"));
ide->doc.GoTo(Nvl(recent_topic, sTopicHome));
}
HelpDes *d = new HelpDes;
d->topic = &ide->doc;
@ -572,17 +539,24 @@ INITBLOCK {
RegisterIdeModule(Single<HelpModule>());
}
int CharFilterTopicSearch(int c)
{
if(c == ' ') return c;
c = CharFilterDefaultToUpperAscii(c);
return IsAlNum(c) ? c : 0;
}
TopicCtrl::TopicCtrl()
{
Icon(IdeImg::doc());
search_label = "Search: ";
showwords = issearch = all = false;
lang.Add("All");
lang.Add("EN-US");
lang <<= "EN-US";
showwords = true;
all = false;
lang <<= THISBACK(Lang);
lang.Tip("Language"),
search.NullText("Search", StdFont().Italic(), SColorDisabled());
search.Tip("Full text search");
search <<= THISBACK(Search);
search.SetFilter(CharFilterTopicSearch);
internal = true;
}
@ -596,7 +570,7 @@ void Ide::ShowTopics()
if(doc_serial != TopicEditor::GetSerial()) {
GetRefLinks("");
doc.SyncDocTree();
doc.GoTo("\3topic://ide/app/index$en-us");
doc.GoTo(sTopicHome);
doc_serial = TopicEditor::GetSerial();
}
EditFile(HELPNAME);
@ -607,7 +581,7 @@ void Ide::SearchTopics()
String s = editor.GetWord();
GetRefLinks("");
doc.SyncDocTree();
doc.GoTo("\3topic://ide/app/index$en-us");
doc.GoTo(sTopicHome);
EditFile(HELPNAME);
if(s.GetLength())
doc.SearchWord(s);

View file

@ -262,23 +262,26 @@ public:
virtual void FinishText(RichText& text);
private:
EditString search;
DropList lang;
bool internal;
bool showwords, all;
VectorMap<String, VectorMap<String, Index<String> > > map;
Index<String> lang_list;
static Index<String> idelink;
void OpenTopic();
void Search();
void ShowWords();
void All();
void Lang();
void SShow();
void ScanDirForTpp(const char *dir, Index<String>& li, Vector<int>& sdx, const String& lng,
VectorMap<String, VectorMap<String, Vector<String> > >& map,
const String& rel);
Label search_label;
WithDropChoice<EditString> search;
DropList lang;
bool internal;
bool showwords, issearch, all;
static Index<String> idelink;
void ScanDirForTpp(const char *dir, const String& rel, Index<String>& donepackage,
Index<String>& lang_list);
void LoadMap();
void FocusSearch();
public:
Callback WhenTopic;

View file

@ -47,6 +47,7 @@ file
Install.cpp,
idebar.cpp,
idewin.cpp,
About.cpp,
Help.cpp,
Util.cpp,
Macro.cpp,