ide: Binary files viewer (and detection)

git-svn-id: svn://ultimatepp.org/upp/trunk@8270 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2015-03-15 14:13:59 +00:00
parent 1c2f9703f2
commit 3f25bfa2ce
18 changed files with 196 additions and 54 deletions

View file

@ -144,7 +144,7 @@ HexViewInfo::HexViewInfo()
int HexView::Byte(int64 adr)
{
return IsBadReadPtr((byte *)(uintptr_t)adr, 1) ? -1 : *(byte *)(unsigned)adr;
return 0;
}
void HexView::Paint(Draw& w)

View file

@ -3,7 +3,6 @@
#include <CtrlLib/CtrlLib.h>
NAMESPACE_UPP
#define LAYOUTFILE <HexView/HexView.lay>
@ -88,6 +87,7 @@ public:
HexView& SetFont(Font fnt);
HexView& Charset(byte chrset) { charset = chrset; Refresh(); return *this; }
HexView& FixedColumns(int c = 0) { fixed = c; Layout(); Refresh(); return *this; }
HexView& InfoMode(int m = 1) { info.SetMode(m); return *this; }
typedef HexView CLASSNAME;

View file

@ -4,3 +4,4 @@ LAYOUT(HexGotoLayout, 280, 68)
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(140, 64).TopPosZ(36, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(208, 64).TopPosZ(36, 24))
END_LAYOUT

View file

@ -1340,6 +1340,7 @@ void Ide::JumpToDefinition(const Array<CppItem>& n, int q, const String& scope)
const CppItem& pos = n[qimpl >= 0 ? qimpl : qcpp >= 0 ? qcpp : q];
String path = GetCppFile(pos.file);
editastext.RemoveKey(path);
editashex.RemoveKey(path);
if(ToLower(GetFileExt(path)) == ".lay") {
AddHistory();
EditFile(path);

View file

@ -1,6 +1,64 @@
#ifndef _ide_Designers_Designers_h_
#define _ide_Designers_Designers_h_
#include "Img.h"
#include <ide/Common/Common.h>
#include <ide/IconDes/IconDes.h>
#include <HexView/HexView.h>
struct IdeImgView : IdeDesigner, Ctrl {
Size img_sz;
Image img;
String filename;
virtual void Paint(Draw& w);
virtual String GetFileName() const { return filename; }
virtual void EditMenu(Bar& menu);
virtual void Save() {}
virtual Ctrl& DesignerCtrl() { return *this; }
typedef IdeImgView CLASSNAME;
};
struct IdePngDes : IdeIconDes {
virtual void Save();
void Load(const char *filename);
void Create(const char *filename);
};
class FileHexView : public IdeDesigner, public HexView, private LRUCache<String, int64>::Maker {
public:
virtual int Byte(int64 addr);
virtual int64 Key() const;
virtual int Make(String& object) const;
virtual String GetFileName() const { return filename; }
virtual void Save() {}
virtual void EditMenu(Bar& menu) { StdMenu(menu); }
virtual Ctrl& DesignerCtrl() { return *this; }
private:
String filename;
FileIn file;
int64 blk;
LRUCache<String, int64> cache;
enum { BLKSHIFT = 14, BLKSIZE = 1 << BLKSHIFT };
public:
void Serialize(Stream& s) { SerializeSettings(s); }
void Open(const char *path);
FileHexView();
~FileHexView();
};
bool FileIsBinary(const char *path);
#endif

View file

@ -1,8 +1,9 @@
description "Various small(er) designers (Image viewer, QTF editor, ...)\377B";
file
Img.h,
Designers.h,
Png.cpp,
Img.icpp,
Qtf.icpp;
Qtf.icpp,
HexView.icpp;

View file

@ -0,0 +1,83 @@
#include "Designers.h"
bool FileIsBinary(const char *path)
{
FileIn in(path);
if(in) {
String data = in.Get(150000);
if(*data.Last() == '\r')
data.Cat(in.Get());
const char *end = data.End();
int le = -1;
const char *s = data;
while(s < end) {
int c = (byte)*s;
if(c < 32) {
if(c == '\r') {
if(s[1] != '\n' || le == 0)
return true;
le = 1;
s += 2;
}
else
if(c == '\n') {
if(le == 1)
return true;
s++;
}
else
if(c == '\t')
s++;
else
return true;
}
else
s++;
}
}
return false;
}
int64 FileHexView::Key() const
{
return blk;
}
int FileHexView::Make(String& object) const
{
FileIn& in = const_cast<FileIn&>(file);
in.Seek(blk * FileHexView::BLKSIZE);
object = in.Get(FileHexView::BLKSIZE);
return 1;
}
int FileHexView::Byte(int64 addr)
{
blk = addr >> BLKSHIFT;
String h = cache.Get(*this);
cache.Shrink(10); // cache only 10 blocks (~150 KB)
int ii = addr & (BLKSIZE - 1);
return ii < h.GetCount() ? (byte)h[ii] : 0;
}
void FileHexView::Open(const char *path)
{
filename = path;
file.Open(path);
SetTotal(file.GetSize());
}
FileHexView::FileHexView()
{
InfoMode(2);
LoadFromGlobal(*this, "FileHexView");
}
FileHexView::~FileHexView()
{
StoreToGlobal(*this, "FileHexView");
}
INITBLOCK {
RegisterGlobalConfig("FileHexView");
}

View file

@ -1,29 +0,0 @@
#ifndef _ide_ImgDes_ImgDes_h_
#define _ide_ImgDes_ImgDes_h_
#include <ide/Common/Common.h>
#include <ide/IconDes/IconDes.h>
struct IdeImgView : IdeDesigner, Ctrl {
Size img_sz;
Image img;
String filename;
virtual void Paint(Draw& w);
virtual String GetFileName() const { return filename; }
virtual void EditMenu(Bar& menu);
virtual void Save() {}
virtual Ctrl& DesignerCtrl() { return *this; }
typedef IdeImgView CLASSNAME;
};
struct IdePngDes : IdeIconDes {
virtual void Save();
void Load(const char *filename);
void Create(const char *filename);
};
#endif

View file

@ -1,4 +1,4 @@
#include "Img.h"
#include "Designers.h"
void IdeImgView::Paint(Draw& w)
{

View file

@ -1,4 +1,4 @@
#include "Img.h"
#include "Designers.h"
void IdePngDes::Save()
{

View file

@ -1,5 +1,4 @@
#include <ide/Common/Common.h>
#include <ide/IconDes/IconDes.h>
#include "Designers.h"
struct IdeQtfDes : IdeDesigner, RichEditWithToolBar {
String filename;

View file

@ -1,9 +1,12 @@
#ifndef _ide_Designers_icpp_init_stub
#define _ide_Designers_icpp_init_stub
#define BLITZ_INDEX__ Fadb0baddbb7b757e3ed9acaca887cd9a
#define BLITZ_INDEX__ F30af27bc27b2245be0afb8cf140e0a02
#include "Img.icpp"
#undef BLITZ_INDEX__
#define BLITZ_INDEX__ F421424bc1424dfd0a7a9d53622c87987
#define BLITZ_INDEX__ F2b9cc9e34248ca7ce468509d67805881
#include "Qtf.icpp"
#undef BLITZ_INDEX__
#define BLITZ_INDEX__ F231a40d13d2e3c77ea055dcf401dd5dc
#include "HexView.icpp"
#undef BLITZ_INDEX__
#endif

View file

@ -278,6 +278,7 @@ void Ide::GoToError(const ErrorInfo& f)
return;
String file = NormalizePath(f.file);
editastext.FindAdd(file);
editashex.RemoveKey(file);
EditFile(file);
editor.SetCursor(editor.GetPos(editor.GetLineNo(f.lineno - 1), max(f.linepos - 1, 0)));
editor.CenterCursor();

View file

@ -13,6 +13,7 @@
#include <ide/LayDes/LayDes.h>
#include <ide/Debuggers/Debuggers.h>
#include <TextDiffCtrl/TextDiffCtrl.h>
#include <ide/Designers/Designers.h>
#define LAYOUTFILE <ide/ide.lay>
#include <CtrlCore/lay.h>
@ -497,6 +498,7 @@ public:
ArrayMap<String, FileData> filedata;
Index<String> editastext;
Index<String> editashex;
DropList mainconfiglist;
String mainconfigname;
@ -753,6 +755,7 @@ public:
void Edit(Bar& menu);
void EditAsText();
void EditAsHex();
void EditUsingDesigner();
void EditMakeTabs() { editor.MakeTabsOrSpaces(true); }
void EditMakeSpaces() { editor.MakeTabsOrSpaces(false); }

View file

@ -17,6 +17,7 @@ KEY(FINDINFILES, "Find in Files..", K_CTRL_F|K_SHIFT)
KEY(REPLACEINFILES, "Replace in Files..", K_CTRL_H|K_SHIFT)
KEY(FINDFILE, "Find file..", K_ALT_F|K_SHIFT)
KEY(EDITASTEXT, "Edit as text", K_CTRL_T)
KEY(EDITASHEX, "View as binary", 0)
KEY(DESIGNER, "Edit using the designer", K_CTRL_T)
KEY2(CUTLINE, "Cut line", K_CTRL_Y, K_CTRL_L)
KEY(DELLINE, "Delete line", 0)

View file

@ -147,9 +147,9 @@ LAYOUT(NewPackageLayout, 728, 560)
END_LAYOUT
LAYOUT(FileFormatLayout, 348, 108)
ITEM(Label, dv___0, SetLabel(t_("&Encoding")).LeftPosZ(8, 49).TopPosZ(8, 20))
ITEM(Label, dv___0, SetLabel(t_("&Encoding")).LeftPosZ(8, 64).TopPosZ(8, 20))
ITEM(DropList, charset, LeftPosZ(64, 120).TopPosZ(8, 19))
ITEM(Label, dv___2, SetLabel(t_("&Font")).LeftPosZ(8, 49).TopPosZ(32, 20))
ITEM(Label, dv___2, SetLabel(t_("&Font")).LeftPosZ(8, 76).TopPosZ(32, 20))
ITEM(DropList, font, LeftPosZ(64, 120).TopPosZ(32, 19))
ITEM(Label, dv___4, SetLabel(t_("T&ab size")).LeftPosZ(196, 48).TopPosZ(8, 19))
ITEM(EditIntSpin, tabsize, LeftPosZ(264, 50).TopPosZ(8, 19))

View file

@ -179,6 +179,8 @@ void Ide::SearchMenu(Bar& menu)
void Ide::Edit(Bar& menu)
{
if(editfile.GetCount() && editashex.Find(editfile) < 0)
menu.Add(AK_EDITASHEX, THISBACK(EditAsHex));
if(designer) {
if(FileExists(designer->GetFileName())) {
menu.Add(AK_EDITASTEXT, THISBACK(EditAsText))

View file

@ -460,20 +460,26 @@ void Ide::EditFile0(const String& path, byte charset, bool astext, const String&
editfile_isfolder = IsFolder(editfile);
svn_dirs = SvnDirs(true).GetCount(); // Perhaps not the best place, but should be ok
if(!astext && !(debugger && (PathIsEqual(path, posfile[0]) || PathIsEqual(path, posfile[0])))
&& editastext.Find(path) < 0 && !IsNestReadOnly(editfile)) {
bool candesigner = !astext && !(debugger && (PathIsEqual(path, posfile[0]) || PathIsEqual(path, posfile[0])))
&& editastext.Find(path) < 0 && !IsNestReadOnly(editfile);
if(candesigner) {
for(int i = 0; i < GetIdeModuleCount() && !designer; i++)
designer = GetIdeModule(i).CreateDesigner(this, path, charset);
if(designer) {
editpane.Add(designer->DesignerCtrl().SizePos());
designer->RestoreEditPos();
if(filetabs)
tabs.SetAddFile(editfile);
MakeTitle();
SetBar();
designer->SetFocus();
return;
}
}
if(!designer && editastext.Find(path) < 0 && (FileIsBinary(path) || editashex.Find(path) >= 0))
designer.Create<FileHexView>().Open(path);
if(designer) {
editpane.Add(designer->DesignerCtrl().SizePos());
designer->RestoreEditPos();
if(filetabs)
tabs.SetAddFile(editfile);
MakeTitle();
SetBar();
designer->SetFocus();
return;
}
tabs.SetAddFile(editfile);
@ -574,9 +580,20 @@ void Ide::TriggerAssistSync()
text_updated.KillSet(1000, THISBACK(EditFileAssistSync));
}
void Ide::EditAsHex()
{
String path = editfile;
editastext.RemoveKey(editfile);
editashex.FindPut(editfile);
byte cs = editor.GetCharset();
FlushFile();
EditFile0(path, cs);
}
void Ide::EditAsText()
{
String path = editfile;
editashex.RemoveKey(editfile);
editastext.FindPut(editfile);
byte cs = editor.GetCharset();
FlushFile();
@ -586,6 +603,7 @@ void Ide::EditAsText()
void Ide::EditUsingDesigner()
{
String path = editfile;
editashex.RemoveKey(editfile);
editastext.RemoveKey(editfile);
byte cs = editor.GetCharset();
FlushFile();