mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-23 14:22:41 -06:00
ide: Xml and Json file format now shows viewer, TreeCtrl: GetOpenIds, OpenIds, Core: RegisterGlobalSerialize
git-svn-id: svn://ultimatepp.org/upp/trunk@11290 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
e43cde7556
commit
fcb8e80847
15 changed files with 493 additions and 100 deletions
|
|
@ -628,81 +628,88 @@ String FromSystemCharset(const String& src)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static VectorMap<String, String>& sGCfg()
|
||||
{
|
||||
static VectorMap<String, String> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
static StaticCriticalSection sGCfgLock;
|
||||
|
||||
static Vector<Event<> >& sGFlush()
|
||||
static VectorMap<String, String>& sGCfg()
|
||||
{
|
||||
static Vector<Event<> > m;
|
||||
return m;
|
||||
static VectorMap<String, String> h;
|
||||
return h;
|
||||
}
|
||||
|
||||
static StaticCriticalSection sGFlushLock;
|
||||
static Vector<Event<>>& sGFlush()
|
||||
{
|
||||
static Vector<Event<>> h;
|
||||
return h;
|
||||
}
|
||||
|
||||
static VectorMap<String, Event<Stream&>>& sGSerialize()
|
||||
{
|
||||
static VectorMap<String, Event<Stream&>> h;
|
||||
return h;
|
||||
}
|
||||
|
||||
void RegisterGlobalConfig(const char *name)
|
||||
{
|
||||
INTERLOCKED_(sGCfgLock) {
|
||||
ASSERT(sGCfg().Find(name) < 0);
|
||||
sGCfg().Add(name);
|
||||
}
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
ASSERT(sGCfg().Find(name) < 0);
|
||||
sGCfg().Add(name);
|
||||
}
|
||||
|
||||
void RegisterGlobalSerialize(const char *name, Event<Stream&> WhenSerialize)
|
||||
{
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
RegisterGlobalConfig(name);
|
||||
sGSerialize().Add(name, WhenSerialize);
|
||||
}
|
||||
|
||||
void RegisterGlobalConfig(const char *name, Event<> WhenFlush)
|
||||
{
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
RegisterGlobalConfig(name);
|
||||
INTERLOCKED_(sGFlushLock) {
|
||||
sGFlush().Add(WhenFlush);
|
||||
}
|
||||
sGFlush().Add(WhenFlush);
|
||||
}
|
||||
|
||||
String GetGlobalConfigData(const char *name)
|
||||
{
|
||||
INTERLOCKED_(sGCfgLock) {
|
||||
return sGCfg().GetAdd(name);
|
||||
}
|
||||
return String();
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
return sGCfg().GetAdd(name);
|
||||
}
|
||||
|
||||
void SetGlobalConfigData(const char *name, const String& data)
|
||||
{
|
||||
INTERLOCKED_(sGCfgLock) {
|
||||
sGCfg().GetAdd(name) = data;
|
||||
}
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
sGCfg().GetAdd(name) = data;
|
||||
}
|
||||
|
||||
void SerializeGlobalConfigs(Stream& s)
|
||||
{
|
||||
INTERLOCKED_(sGFlushLock) {
|
||||
for(int i = 0; i < sGFlush().GetCount(); i++)
|
||||
sGFlush()[i]();
|
||||
}
|
||||
INTERLOCKED_(sGCfgLock) {
|
||||
VectorMap<String, String>& cfg = sGCfg();
|
||||
int version = 0;
|
||||
s / version;
|
||||
int count = cfg.GetCount();
|
||||
s / count;
|
||||
for(int i = 0; i < count; i++) {
|
||||
String name;
|
||||
if(s.IsStoring())
|
||||
name = cfg.GetKey(i);
|
||||
s % name;
|
||||
int q = cfg.Find(name);
|
||||
if(q >= 0)
|
||||
s % cfg[q];
|
||||
Mutex::Lock __(sGCfgLock);
|
||||
for(int i = 0; i < sGFlush().GetCount(); i++)
|
||||
sGFlush()[i]();
|
||||
int version = 0;
|
||||
s / version;
|
||||
int count = sGCfg().GetCount();
|
||||
s / count;
|
||||
for(int i = 0; i < count; i++) {
|
||||
String name;
|
||||
if(s.IsStoring())
|
||||
name = sGCfg().GetKey(i);
|
||||
s % name;
|
||||
int q = sGCfg().Find(name);
|
||||
if(q >= 0) {
|
||||
int w = sGSerialize().Find(name);
|
||||
if(w >= 0)
|
||||
sGSerialize()[w](s);
|
||||
else
|
||||
{
|
||||
String dummy;
|
||||
s % dummy;
|
||||
}
|
||||
s % sGCfg()[q];
|
||||
}
|
||||
else {
|
||||
String dummy;
|
||||
s % dummy;
|
||||
}
|
||||
s.Magic();
|
||||
}
|
||||
s.Magic();
|
||||
}
|
||||
|
||||
AbortExc::AbortExc() :
|
||||
|
|
|
|||
|
|
@ -450,8 +450,9 @@ bool LoadFromString(T& x, const String& s) {
|
|||
return Load(x, ss);
|
||||
}
|
||||
|
||||
void RegisterGlobalConfig(const char *name) init_;
|
||||
void RegisterGlobalConfig(const char *name, Event<> WhenFlush) init_;
|
||||
void RegisterGlobalConfig(const char *name);
|
||||
void RegisterGlobalSerialize(const char *name, Event<Stream&> WhenSerialize);
|
||||
void RegisterGlobalConfig(const char *name, Event<> WhenFlush);
|
||||
|
||||
String GetGlobalConfigData(const char *name);
|
||||
void SetGlobalConfigData(const char *name, const String& data);
|
||||
|
|
|
|||
|
|
@ -165,45 +165,42 @@ serialization of all such data with single stream.&]
|
|||
[s0;0%- &]
|
||||
[s5;:RegisterGlobalConfig`(const char`*`):%- [@(0.0.255) void]_[* RegisterGlobalConfig]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 name])&]
|
||||
[s2; Registers name as global configuration key.&]
|
||||
[s7; [%-*C@3 name]-|Key.&]
|
||||
[s7; Registers name as global configuration key.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:RegisterGlobalConfig`(const char`*`,Callback`):%- [@(0.0.255) void]_[* RegisterGloba
|
||||
lConfig]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 name], [_^Callback^ Callback]_[*@3 Whe
|
||||
nFlush])&]
|
||||
[s2; Registers name as global configuration key, with flush callback.&]
|
||||
[s7; [%-*C@3 name]-|Key.&]
|
||||
[s7; [%-*C@3 WhenFlush]-|This callback is called before storing of all
|
||||
configuration keys is performed by SerializeGlobalConfigs `-
|
||||
this is useful when StoreToGlobal has to be explicitly triggered
|
||||
before storing configuration.&]
|
||||
[s5;:Upp`:`:RegisterGlobalSerialize`(const char`*`,Upp`:`:Event`<Upp`:`:Stream`&`>`):%- [@(0.0.255) v
|
||||
oid]_[* RegisterGlobalSerialize]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 name],
|
||||
[_^Upp`:`:Event^ Event]<Stream[@(0.0.255) `&]>_[*@3 WhenSerialize])&]
|
||||
[s2; Registers name as global configuration key. [%-*@3 WhenSerialize]
|
||||
is directly used to serialize data, unlike other variants of
|
||||
global config key, where data are stored / retrieved using LoadFromGlobal
|
||||
/ StoreToGlobal.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:Upp`:`:RegisterGlobalConfig`(const char`*`,Upp`:`:Event`<`>`):%- [@(0.0.255) void]_
|
||||
[* RegisterGlobalConfig]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 name],
|
||||
[_^Upp`:`:Event^ Event]<>_[*@3 WhenFlush])&]
|
||||
[s2; Registers name as global configuration key. [%-*C@3 WhenFlush]
|
||||
is called before storing of all configuration keys is performed
|
||||
by SerializeGlobalConfigs `- this is useful when StoreToGlobal
|
||||
has to be explicitly triggered before storing configuration.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:LoadFromGlobal`(T`&`,const char`*`):%- [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T
|
||||
][@(0.0.255) >]_[@(0.0.255) bool]_[* LoadFromGlobal]([*@4 T][@(0.0.255) `&]_[*@3 x],
|
||||
[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 name])&]
|
||||
[s2; Loads [%-*@3 x] from global configuration key, using smart backup
|
||||
methods provided by [^topic`:`/`/Core`/src`/SerializationUtils`$en`-us`#`:`:Load`(Callback1`<Stream`&`>`,Stream`&`)^ L
|
||||
oad].&]
|
||||
[s7; [*C@4 T]-|Type of serialized object.&]
|
||||
[s7; [%-*C@3 x]-|Reference to serialized object.&]
|
||||
[s7; [%-*C@3 name]-|Configuration key.&]
|
||||
[s7; [*/ Return value]-|true indicates success.&]
|
||||
[s2; Loads [%-*@3 x] from global configuration key [%-*@3 name].&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:StoreToGlobal`(T`&`,const char`*`):%- [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T
|
||||
][@(0.0.255) >]_[@(0.0.255) void]_[* StoreToGlobal]([*@4 T][@(0.0.255) `&]_[*@3 x],
|
||||
[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 name])&]
|
||||
[s2; Stores [@3 x] to global configuration key.&]
|
||||
[s7; [*C@4 T]-|Type of serialized object.&]
|
||||
[s7; [%-*C@3 x]-|Reference to serialized object.&]
|
||||
[s7; [%-*C@3 name]-|Configuration key.&]
|
||||
[s2; Stores [@3 x] to global configuration key [%-*C@3 name].&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:SerializeGlobalConfigs`(Stream`&`):%- [@(0.0.255) void]_[* SerializeGlobalConfigs]([_^Stream^ S
|
||||
tream][@(0.0.255) `&]_[*@3 s])&]
|
||||
[s2; Serializes all global configuration data from/to single stream.&]
|
||||
[s7; [%-*C@3 s]-|Stream.&]
|
||||
[s2; Serializes all registered global configuration data from/to
|
||||
single stream.&]
|
||||
[s3; &]
|
||||
[s0; ]]
|
||||
|
|
@ -502,6 +502,22 @@ bool TreeCtrl::IsOpen(int id) const
|
|||
return item[id].isopen;
|
||||
}
|
||||
|
||||
Vector<int> TreeCtrl::GetOpenIds() const
|
||||
{
|
||||
Vector<int> r;
|
||||
for(int id = 0; id < item.GetCount(); id++)
|
||||
if(!item[id].free && item[id].isopen)
|
||||
r.Add(id);
|
||||
return r;
|
||||
}
|
||||
|
||||
void TreeCtrl::OpenIds(const Vector<int>& ids)
|
||||
{
|
||||
for(int id : ids)
|
||||
if(IsValid(id))
|
||||
Open(id);
|
||||
}
|
||||
|
||||
void TreeCtrl::Dirty(int id)
|
||||
{
|
||||
// if(selectcount) SelClear(0);
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ public:
|
|||
bool IsOpen(int id) const;
|
||||
void Open(int id, bool open = true);
|
||||
void Close(int id) { Open(id, false); }
|
||||
Vector<int> GetOpenIds() const;
|
||||
void OpenIds(const Vector<int>& ids);
|
||||
|
||||
void OpenDeep(int id, bool open = true);
|
||||
void CloseDeep(int id) { OpenDeep(id, false); }
|
||||
|
|
|
|||
|
|
@ -289,6 +289,11 @@ t]_[*@3 id])_[@(0.0.255) const]&]
|
|||
[s2;%% Sets attributes.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TreeCtrl`:`:IsValid`(int`)const: [@(0.0.255) bool]_[* IsValid]([@(0.0.255) int]_
|
||||
[*@3 id])_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if [%-*@3 id] represents a valid node id.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TreeCtrl`:`:IsOpen`(int`)const: [@(0.0.255) bool]_[* IsOpen]([@(0.0.255) int]_[*@3 id])_
|
||||
[@(0.0.255) const]&]
|
||||
[s2;%% Tests whether item is opened.&]
|
||||
|
|
@ -304,6 +309,16 @@ all child items visible.&]
|
|||
[s2;%% Same as Open(id, false).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TreeCtrl`:`:GetOpenIds`(`)const: [_^Upp`:`:Vector^ Vector]<[@(0.0.255) int]>_
|
||||
[* GetOpenIds]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns all open node ids.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TreeCtrl`:`:OpenIds`(const Upp`:`:Vector`<int`>`&`): [@(0.0.255) void]_[* Ope
|
||||
nIds]([@(0.0.255) const]_[_^Upp`:`:Vector^ Vector]<[@(0.0.255) int]>`&_[*@3 ids])&]
|
||||
[s2;%% Opens all valid [%-*@3 ids].&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TreeCtrl`:`:OpenDeep`(int`,bool`): [@(0.0.255) void]_[* OpenDeep]([@(0.0.255) int]_[*@3 i
|
||||
d], [@(0.0.255) bool]_[*@3 open]_`=_[@(0.0.255) true])&]
|
||||
[s2;%% Opens/closes item with [%-*@3 id] and all of its child items.&]
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ struct IdePngDes : IdeIconDes {
|
|||
void Create(const char *filename);
|
||||
};
|
||||
|
||||
INITIALIZE(Img)
|
||||
|
||||
class FileHexView : public IdeDesigner, public HexView, private LRUCache<String, int64>::Maker {
|
||||
public:
|
||||
virtual int Byte(int64 addr);
|
||||
|
|
@ -59,10 +61,96 @@ public:
|
|||
~FileHexView();
|
||||
};
|
||||
|
||||
bool FileIsBinary(const char *path);
|
||||
|
||||
INITIALIZE(Img)
|
||||
INITIALIZE(Qtf)
|
||||
INITIALIZE(HexView)
|
||||
|
||||
struct IdeQtfDes : IdeDesigner, RichEditWithToolBar {
|
||||
String filename;
|
||||
|
||||
virtual String GetFileName() const { return filename; }
|
||||
virtual void Save();
|
||||
virtual void SaveEditPos();
|
||||
virtual void EditMenu(Bar& menu);
|
||||
virtual Ctrl& DesignerCtrl() { return *this; }
|
||||
|
||||
virtual void Serialize(Stream& s);
|
||||
|
||||
bool Load(const char *filename);
|
||||
void FileProperties();
|
||||
void CopyId(const String& n);
|
||||
|
||||
typedef IdeQtfDes CLASSNAME;
|
||||
|
||||
IdeQtfDes() { Extended(); }
|
||||
};
|
||||
|
||||
INITIALIZE(Qtf)
|
||||
|
||||
bool FileIsBinary(const char *path);
|
||||
|
||||
struct TreeDesPos {
|
||||
Time filetime = Null;
|
||||
Vector<int> openid;
|
||||
int cursor = -1;
|
||||
Point scroll;
|
||||
|
||||
void Serialize(Stream& s) { s % filetime % openid % cursor % scroll; }
|
||||
void Save(Time filetime, TreeCtrl& tree);
|
||||
void Restore(Time filetime, TreeCtrl& tree);
|
||||
};
|
||||
|
||||
void Save(ArrayMap<String, TreeDesPos>& pos, const String& filename, Time filetime, TreeCtrl& tree);
|
||||
void Restore(ArrayMap<String, TreeDesPos>& pos, const String& filename, Time filetime, TreeCtrl& tree);
|
||||
void Serialize(Stream& s, ArrayMap<String, TreeDesPos>& pos);
|
||||
|
||||
struct TreeViewDes : IdeDesigner, Ctrl {
|
||||
virtual String GetFileName() const { return filename; }
|
||||
virtual void Save() {}
|
||||
virtual void EditMenu(Bar& menu);
|
||||
virtual Ctrl& DesignerCtrl() { return *this; }
|
||||
virtual void RestoreEditPos();
|
||||
virtual void SaveEditPos();
|
||||
|
||||
static ArrayMap<String, TreeDesPos> pos;
|
||||
|
||||
String filename;
|
||||
Time filetime;
|
||||
TreeCtrl tree;
|
||||
FrameTop<StaticRect> errorbg;
|
||||
Label error;
|
||||
ParentCtrl data;
|
||||
|
||||
TreeViewDes();
|
||||
|
||||
void Error(const char *e);
|
||||
bool Load(const String& txt);
|
||||
|
||||
virtual String GetId() = 0;
|
||||
virtual void CopyPath() = 0;
|
||||
virtual String Load0(const String& data) = 0;
|
||||
};
|
||||
|
||||
INITIALIZE(TreeViewDes)
|
||||
|
||||
struct XmlViewDes : TreeViewDes {
|
||||
virtual String GetId() { return "XML"; }
|
||||
virtual void CopyPath();
|
||||
virtual String Load0(const String& data);
|
||||
|
||||
void Load0(int parent, XmlParser& p);
|
||||
};
|
||||
|
||||
INITIALIZE(XmlViewDes)
|
||||
|
||||
struct JsonViewDes : TreeViewDes {
|
||||
virtual String GetId() { return "JSON"; }
|
||||
virtual String Load0(const String& json);
|
||||
virtual void CopyPath();
|
||||
|
||||
int AddNode(int parent_id, const Value& id, const String& name, const Value& v);
|
||||
|
||||
JsonViewDes();
|
||||
};
|
||||
|
||||
INITIALIZE(JsonViewDes)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@ file
|
|||
Png.cpp,
|
||||
Img.cpp,
|
||||
Qtf.cpp,
|
||||
HexView.cpp;
|
||||
HexView.cpp,
|
||||
TreeDes.cpp,
|
||||
Xml.cpp,
|
||||
Json.cpp;
|
||||
|
||||
|
|
|
|||
105
uppsrc/ide/Designers/Json.cpp
Normal file
105
uppsrc/ide/Designers/Json.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include <ide/ide.h>
|
||||
|
||||
JsonViewDes::JsonViewDes()
|
||||
{
|
||||
tree.SetDisplay(QTFDisplay());
|
||||
}
|
||||
|
||||
void JsonViewDes::CopyPath()
|
||||
{
|
||||
int id = tree.GetCursor();
|
||||
String path;
|
||||
while(id) {
|
||||
Value k = tree.Get(id);
|
||||
if(!IsNull(k)) {
|
||||
if(IsNumber(k))
|
||||
path = "[" + AsString(k) + "]" + path;
|
||||
if(IsString(k))
|
||||
path = "[" + AsCString(String(k)) + "]" + path;
|
||||
}
|
||||
id = tree.GetParent(id);
|
||||
}
|
||||
WriteClipboardText(path);
|
||||
}
|
||||
|
||||
String JsonViewDes::Load0(const String& json)
|
||||
{
|
||||
String parsingError;
|
||||
|
||||
CParser p(json);
|
||||
try {
|
||||
tree.Open(AddNode(0, Null, "JSON", ParseJSON(p)));
|
||||
}
|
||||
catch(const CParser::Error& e) {
|
||||
parsingError << e;
|
||||
}
|
||||
|
||||
return parsingError;
|
||||
}
|
||||
|
||||
int JsonViewDes::AddNode(int parent_id, const Value& id, const String& name, const Value& v)
|
||||
{
|
||||
if(IsError(v)) {
|
||||
// TODO: Replace with JsonExc or something that is more accurate in this situation.
|
||||
String errorText = GetErrorText(v);
|
||||
errorText.Remove(0, errorText.Find(" ") + 1);
|
||||
throw Exc(errorText);
|
||||
}
|
||||
else
|
||||
if(v.Is<ValueMap>()) {
|
||||
ValueMap m = v;
|
||||
parent_id = tree.Add(parent_id, IdeImg::JsonStruct(), id, "[G1 [* " + name);
|
||||
for(int i = 0; i < m.GetCount(); i++)
|
||||
AddNode(parent_id, m.GetKey(i), "[@B \1" + String(m.GetKey(i)) + "\1:]", m.GetValue(i));
|
||||
}
|
||||
else
|
||||
if(v.Is<ValueArray>()) {
|
||||
parent_id = tree.Add(parent_id, IdeImg::JsonArray(), id, "[G1 [* " + name);
|
||||
for(int i = 0; i < v.GetCount(); i++)
|
||||
AddNode(parent_id, i, "[@c " + AsString(i) + ":]", v[i]);
|
||||
}
|
||||
else {
|
||||
String qtf = "[G1 [* " + name + "]";
|
||||
Image img = IdeImg::JsonNumber();
|
||||
if(IsString(v)) {
|
||||
img = IdeImg::JsonString();
|
||||
if(IsNull(v))
|
||||
qtf << "[*@g Null";
|
||||
else
|
||||
qtf << "[@r \1 " + AsCString(String(v));
|
||||
}
|
||||
else {
|
||||
if(v.Is<bool>())
|
||||
img = IdeImg::JsonBool();
|
||||
if(IsNull(v))
|
||||
qtf << "[*@g Null";
|
||||
else
|
||||
qtf << "\1 " + AsString(v);
|
||||
}
|
||||
parent_id = tree.Add(parent_id, img, id, qtf);
|
||||
}
|
||||
return parent_id;
|
||||
}
|
||||
|
||||
struct JsonDesModule : public IdeModule {
|
||||
virtual String GetID() { return "JsonDesModule"; }
|
||||
|
||||
virtual bool AcceptsFile(const char *path) {
|
||||
return ToLower(GetFileExt(path)) == ".json";
|
||||
}
|
||||
|
||||
virtual IdeDesigner *CreateDesigner(const char *path, byte) {
|
||||
if(!AcceptsFile(path))
|
||||
return NULL;
|
||||
JsonViewDes *d = new JsonViewDes;
|
||||
if(d->Load(path))
|
||||
return d;
|
||||
delete d;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
INITIALIZER(JsonViewDes)
|
||||
{
|
||||
RegisterIdeModule(Single<JsonDesModule>());
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ void IdePngDes::Load(const char *_filename)
|
|||
Clear();
|
||||
filename = _filename;
|
||||
filetime = FileGetTime(filename);
|
||||
Image m = StreamRaster::LoadFileAny(filename);
|
||||
Image m = StreamRaster::LoadFileAny(filename);
|
||||
AddImage(filename, m, false);
|
||||
SingleMode();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
#include "Designers.h"
|
||||
|
||||
struct IdeQtfDes : IdeDesigner, RichEditWithToolBar {
|
||||
String filename;
|
||||
|
||||
virtual String GetFileName() const { return filename; }
|
||||
virtual void Save();
|
||||
virtual void SaveEditPos();
|
||||
virtual void EditMenu(Bar& menu);
|
||||
virtual Ctrl& DesignerCtrl() { return *this; }
|
||||
|
||||
virtual void Serialize(Stream& s);
|
||||
|
||||
bool Load(const char *filename);
|
||||
void FileProperties();
|
||||
void CopyId(const String& n);
|
||||
|
||||
typedef IdeQtfDes CLASSNAME;
|
||||
|
||||
IdeQtfDes() { Extended(); }
|
||||
};
|
||||
|
||||
struct IdeQtfEditPos : Moveable<IdeQtfEditPos> {
|
||||
Time filetime;
|
||||
RichEdit::PosInfo pos;
|
||||
|
|
|
|||
93
uppsrc/ide/Designers/TreeDes.cpp
Normal file
93
uppsrc/ide/Designers/TreeDes.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include "Designers.h"
|
||||
|
||||
void TreeDesPos::Save(Time afiletime, TreeCtrl& tree)
|
||||
{
|
||||
filetime = afiletime;
|
||||
scroll = tree.GetScroll();
|
||||
cursor = tree.GetCursor();
|
||||
openid = tree.GetOpenIds();
|
||||
}
|
||||
|
||||
void TreeDesPos::Restore(Time afiletime, TreeCtrl& tree)
|
||||
{
|
||||
if(afiletime == filetime) {
|
||||
tree.OpenIds(openid);
|
||||
if(tree.IsValid(cursor))
|
||||
tree.SetCursor(cursor);
|
||||
tree.ScrollTo(scroll);
|
||||
}
|
||||
tree.SetFocus();
|
||||
}
|
||||
|
||||
void Serialize(Stream& s, ArrayMap<String, TreeDesPos>& pos)
|
||||
{
|
||||
int version = 0;
|
||||
s / version;
|
||||
s % pos;
|
||||
}
|
||||
|
||||
TreeViewDes::TreeViewDes()
|
||||
{
|
||||
tree.NoRoot();
|
||||
|
||||
error.SetFont(Arial(20)).SetInk(Red);
|
||||
errorbg.Height(Zy(25)).Add(error.SizePos());
|
||||
|
||||
Add(tree.SizePos());
|
||||
|
||||
tree.WhenLeftDouble = [=] { CopyPath(); };
|
||||
}
|
||||
|
||||
ArrayMap<String, TreeDesPos> TreeViewDes::pos;
|
||||
|
||||
bool TreeViewDes::Load(const String& fn)
|
||||
{
|
||||
RemoveFrame(errorbg);
|
||||
tree.Clear();
|
||||
|
||||
filename = fn;
|
||||
|
||||
FileIn in(filename);
|
||||
if(!in)
|
||||
return false;
|
||||
|
||||
filetime = in.GetTime();
|
||||
|
||||
const int limit = 20000000;
|
||||
|
||||
String txt = in.Get(limit);
|
||||
|
||||
String parsingError = Load0(txt);
|
||||
if(in.GetSize() >= limit)
|
||||
MergeWith(parsingError, ", ", "file was longer than 20MB and was truncated");
|
||||
if(parsingError.GetCount()) {
|
||||
error = String() << "XML parsing error: " << parsingError << ".";
|
||||
AddFrame(errorbg);
|
||||
}
|
||||
|
||||
return tree.GetChildCount(0);
|
||||
}
|
||||
|
||||
void TreeViewDes::EditMenu(Bar& menu)
|
||||
{
|
||||
menu.Add(tree.IsCursor(), "Copy current path to clipboard", [=] { CopyPath(); });
|
||||
}
|
||||
|
||||
void TreeViewDes::RestoreEditPos()
|
||||
{
|
||||
pos.GetAdd(filename + "\n" + GetId()).Restore(filetime, tree);
|
||||
}
|
||||
|
||||
void TreeViewDes::SaveEditPos()
|
||||
{
|
||||
pos.GetAdd(filename + "\n" + GetId()).Save(filetime, tree);
|
||||
}
|
||||
|
||||
INITIALIZER(TreeViewDes)
|
||||
{
|
||||
RegisterGlobalSerialize("TreeViewDes", [](Stream& s) {
|
||||
int version = 0;
|
||||
s / version;
|
||||
s % TreeViewDes::pos;
|
||||
});
|
||||
}
|
||||
86
uppsrc/ide/Designers/Xml.cpp
Normal file
86
uppsrc/ide/Designers/Xml.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include <ide/ide.h>
|
||||
|
||||
void XmlViewDes::CopyPath()
|
||||
{
|
||||
String path;
|
||||
int id = tree.GetCursor();
|
||||
while(id >= 0) {
|
||||
String tag = tree.Get(id);
|
||||
if(tag.GetCount())
|
||||
path = "[" + AsCString(tag) + "]" + path;
|
||||
id = tree.GetParent(id);
|
||||
}
|
||||
WriteClipboardText(path);
|
||||
}
|
||||
|
||||
String XmlViewDes::Load0(const String& data) {
|
||||
XmlParser p(data);
|
||||
|
||||
String parsingError;
|
||||
|
||||
try {
|
||||
while(!p.IsEof())
|
||||
Load0(0, p);
|
||||
}
|
||||
catch(const XmlError& e) {
|
||||
parsingError = e;
|
||||
}
|
||||
|
||||
if(!parsingError.GetCount() && !tree.GetChildCount(0))
|
||||
parsingError = "Not found any XML tags";
|
||||
|
||||
return parsingError;
|
||||
}
|
||||
|
||||
void XmlViewDes::Load0(int parent, XmlParser& p)
|
||||
{
|
||||
if(p.IsTag()) {
|
||||
String tag = p.ReadTag();
|
||||
String txt = tag;
|
||||
for(int i = 0; i < p.GetAttrCount(); i++)
|
||||
txt << ' ' << p.GetAttr(i) << "=\"" << p[i] << "\"";
|
||||
parent = tree.Add(parent, IdeImg::XmlTag(), tag, txt);
|
||||
while(!p.End()) {
|
||||
if(p.IsEof())
|
||||
throw XmlError("Unexpected end of text");
|
||||
Load0(parent, p);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(p.IsText())
|
||||
tree.Add(parent, IdeImg::XmlText(), Null, NormalizeSpaces(p.ReadText()));
|
||||
else
|
||||
if(p.IsPI())
|
||||
tree.Add(parent, IdeImg::XmlPI(), Null, NormalizeSpaces(p.ReadPI()));
|
||||
else
|
||||
if(p.IsDecl())
|
||||
tree.Add(parent, IdeImg::XmlDecl(), Null, NormalizeSpaces(p.ReadDecl()));
|
||||
else
|
||||
if(p.IsComment())
|
||||
tree.Add(parent, IdeImg::XmlComment(), Null, NormalizeSpaces(p.ReadComment()));
|
||||
else
|
||||
throw XmlError("Unexpected input");
|
||||
}
|
||||
|
||||
struct XmlDesModule : public IdeModule {
|
||||
virtual String GetID() { return "XmlDesModule"; }
|
||||
|
||||
virtual bool AcceptsFile(const char *path) {
|
||||
return ToLower(GetFileExt(path)) == ".xml";
|
||||
}
|
||||
|
||||
virtual IdeDesigner *CreateDesigner(const char *path, byte) {
|
||||
if(!AcceptsFile(path))
|
||||
return NULL;
|
||||
XmlViewDes *d = new XmlViewDes;
|
||||
if(d->Load(path))
|
||||
return d;
|
||||
delete d;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
INITIALIZER(XmlViewDes)
|
||||
{
|
||||
RegisterIdeModule(Single<XmlDesModule>());
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ void Ide::Edit(Bar& menu)
|
|||
menu.MenuSeparator();
|
||||
}
|
||||
else
|
||||
if(editastext.Find(editfile) >= 0 && IsDesignerFile(editfile)) {
|
||||
if(editastext.Find(editfile) >= 0/* && IsDesignerFile(editfile)*/) {
|
||||
menu.Add(AK_DESIGNER, THISBACK(EditUsingDesigner))
|
||||
.Help("Edit using the designer (not as text)");
|
||||
menu.MenuSeparator();
|
||||
|
|
|
|||
|
|
@ -458,12 +458,12 @@ void Ide::EditFile0(const String& path, byte charset, int spellcheck_comments, c
|
|||
|
||||
if(designer) {
|
||||
editpane.Add(designer->DesignerCtrl().SizePos());
|
||||
designer->DesignerCtrl().SetFocus();
|
||||
designer->RestoreEditPos();
|
||||
if(filetabs)
|
||||
tabs.SetAddFile(editfile);
|
||||
MakeTitle();
|
||||
SetBar();
|
||||
designer->SetFocus();
|
||||
editor.SyncNavigatorShow();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue