Skip to content

Commit

Permalink
Much improved source files viewer.
Browse files Browse the repository at this point in the history
Use wxScintilla for display. Basic syntax highlighting is included.
Current line is highlighted in much better way. Full file is included,
with line numbers.

Fixes #346.
  • Loading branch information
vslavik committed Apr 5, 2010
1 parent 3f0eece commit 3020ded
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 84 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Version 1.5 (not yet released)
- fixed possible transaction memory database corruption (#337, #352)
- added instructions on how to install additional spellchecker dictionaries
- added sorting by different criteria (#256, #239)
- improved source files viewer (#346)


Version 1.4.6
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ esac

AM_PATH_WXCONFIG([2.8.7],
[WXFOUND=1], [WXFOUND=0],
[xrc,html,xml,adv,core], [--unicode])
[xrc,stc,html,xml,adv,core], [--unicode])

if test "$WXFOUND" != 1; then
AC_MSG_ERROR([
Expand Down
2 changes: 1 addition & 1 deletion deps
Submodule deps updated from e96abe to bd43a9
216 changes: 163 additions & 53 deletions src/fileviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@
#include <wx/wxprec.h>

#include "fileviewer.h"

#include <wx/filename.h>
#include <wx/log.h>
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/choice.h>
#include <wx/textfile.h>
#include <wx/config.h>
#include <wx/sizer.h>
#include <wx/settings.h>
#include <wx/listctrl.h>

#define NEIGHBOUR_SIZE 40
#include <wx/fontenum.h>
#include <wx/stc/stc.h>

FileViewer::FileViewer(wxWindow *parent,
const wxString& basePath,
Expand All @@ -50,7 +51,6 @@ FileViewer::FileViewer(wxWindow *parent,
wxPanel *panel = new wxPanel(this, -1);
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
panel->SetSizer(sizer);
panel->Layout();

wxSizer *barsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(barsizer, wxSizerFlags().Expand().Border());
Expand All @@ -66,12 +66,11 @@ FileViewer::FileViewer(wxWindow *parent,
choice->Append(references[i]);
choice->SetSelection(startAt);

m_list = new wxListCtrl(panel, -1, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER |
wxSUNKEN_BORDER);
sizer->Add(m_list, 1, wxEXPAND);

ShowReference(m_references[startAt]);
m_text = new wxStyledTextCtrl(panel, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxBORDER_THEME);
SetupTextCtrl();
sizer->Add(m_text, 1, wxEXPAND);

wxConfigBase *cfg = wxConfig::Get();
int width = cfg->Read(_T("fileviewer/frame_w"), 600);
Expand All @@ -88,14 +87,158 @@ FileViewer::FileViewer(wxWindow *parent,
topsizer->Add(panel, wxSizerFlags(1).Expand());
SetSizer(topsizer);
Layout();

ShowReference(m_references[startAt]);
}


FileViewer::~FileViewer()
{
wxSize sz = GetClientSize();
wxPoint pos = GetPosition();
wxConfigBase *cfg = wxConfig::Get();
cfg->Write(_T("fileviewer/frame_w"), (long)sz.x);
cfg->Write(_T("fileviewer/frame_h"), (long)sz.y);
cfg->Write(_T("fileviewer/frame_x"), (long)pos.x);
cfg->Write(_T("fileviewer/frame_y"), (long)pos.y);
}


void FileViewer::SetupTextCtrl()
{
wxStyledTextCtrl& t = *m_text;

wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);

#ifdef __WXGTK__
font.SetFaceName(_T("monospace"));
#else
static const wxChar *s_monospaced_fonts[] = {
#ifdef __WXMSW__
_T("Consolas"),
_T("Lucida Console"),
#endif
#ifdef __WXOSX__
_T("Menlo"),
_T("Monaco"),
#endif
NULL
};

for ( const wxChar **f = s_monospaced_fonts; *f; ++f )
{
if ( wxFontEnumerator::IsValidFacename(*f) )
{
font.SetFaceName(*f);
break;
}
}
#endif

wxString fontspec = wxString::Format(_T("face:%s,size:%d"),
font.GetFaceName().c_str(),
font.GetPointSize());

// current line marker
t.MarkerDefine(1, wxSTC_MARK_BACKGROUND, wxNullColour, wxColour(255,255,0));

// set fonts
t.StyleSetSpec(wxSTC_STYLE_LINENUMBER, fontspec);
t.StyleSetSpec(wxSTC_STYLE_DEFAULT, fontspec);

// line numbers margin size:
t.SetMarginType(0, wxSTC_MARGIN_NUMBER);
t.SetMarginWidth(0,
t.TextWidth(wxSTC_STYLE_LINENUMBER, _T("9999 ")));
t.SetMarginWidth(1, 0);
t.SetMarginWidth(2, 3);

// set syntax highlighter styling
const wxString STRING(_T("fore:#16bc16"));
const wxString COMMENT(_T("fore:#808080"));

t.StyleSetSpec(wxSTC_C_STRING, STRING);
t.StyleSetSpec(wxSTC_C_COMMENT, COMMENT);
t.StyleSetSpec(wxSTC_C_COMMENTLINE, COMMENT);

t.StyleSetSpec(wxSTC_P_STRING, STRING);
t.StyleSetSpec(wxSTC_P_COMMENTLINE, COMMENT);
t.StyleSetSpec(wxSTC_P_COMMENTBLOCK, COMMENT);

t.StyleSetSpec(wxSTC_LUA_STRING, STRING);
t.StyleSetSpec(wxSTC_LUA_LITERALSTRING, STRING);
t.StyleSetSpec(wxSTC_LUA_COMMENT, COMMENT);
t.StyleSetSpec(wxSTC_LUA_COMMENTLINE, COMMENT);

t.StyleSetSpec(wxSTC_HPHP_HSTRING, STRING);
t.StyleSetSpec(wxSTC_HPHP_SIMPLESTRING, STRING);
t.StyleSetSpec(wxSTC_HPHP_COMMENT, COMMENT);
t.StyleSetSpec(wxSTC_HPHP_COMMENTLINE, COMMENT);

t.StyleSetSpec(wxSTC_TCL_COMMENT, COMMENT);
t.StyleSetSpec(wxSTC_TCL_COMMENTLINE, COMMENT);
t.StyleSetSpec(wxSTC_TCL_BLOCK_COMMENT, COMMENT);

#if wxCHECK_VERSION(2,9,0)
t.StyleSetSpec(wxSTC_PAS_STRING, STRING);
t.StyleSetSpec(wxSTC_PAS_COMMENT, COMMENT);
t.StyleSetSpec(wxSTC_PAS_COMMENT2, COMMENT);
t.StyleSetSpec(wxSTC_PAS_COMMENTLINE, COMMENT);
#endif
}


int FileViewer::GetLexer(const wxString& ext)
{
struct LexerInfo
{
const char *ext;
int lexer;
};

static const LexerInfo s_lexer[] = {
{ "c", wxSTC_LEX_CPP },
{ "cpp", wxSTC_LEX_CPP },
{ "cc", wxSTC_LEX_CPP },
{ "cxx", wxSTC_LEX_CPP },
{ "h", wxSTC_LEX_CPP },
{ "hxx", wxSTC_LEX_CPP },
{ "hpp", wxSTC_LEX_CPP },
{ "py", wxSTC_LEX_PYTHON },
{ "htm", wxSTC_LEX_HTML },
{ "html", wxSTC_LEX_HTML },
{ "php", wxSTC_LEX_PHPSCRIPT },
{ "xml", wxSTC_LEX_XML },
{ "pas", wxSTC_LEX_PASCAL },
{ NULL, -1 }
};

wxString e = ext.Lower();

for ( const LexerInfo *i = s_lexer; i->ext; ++i )
{
if ( e == wxString::FromAscii(i->ext) )
return i->lexer;
}

return wxSTC_LEX_NULL;
}


void FileViewer::ShowReference(const wxString& ref)
{
wxPathFormat pathfmt = ref.Contains(_T('\\')) ? wxPATH_WIN : wxPATH_UNIX;
wxFileName filename(ref.BeforeLast(_T(':')), pathfmt);
filename.MakeAbsolute(m_basePath);

if ( !filename.IsFileReadable() )
{
wxLogError(_("Error opening file %s!"), filename.GetFullPath().c_str());
return;
}

m_current = ref;

// support GNOME's xml2po's extension to references in the form of
// filename:line(xml_node):
wxString linenumStr = ref.AfterLast(_T(':')).BeforeFirst(_T('('));
Expand All @@ -104,54 +247,21 @@ void FileViewer::ShowReference(const wxString& ref)
if (!linenumStr.ToLong(&linenum))
linenum = 0;

wxTextFile textf(filename.GetFullPath());
m_text->SetReadOnly(false);
m_text->LoadFile(filename.GetFullPath());
m_text->SetLexer(GetLexer(filename.GetExt()));
m_text->SetReadOnly(true);

textf.Open();
if (!textf.IsOpened())
{
wxLogError(_("Error opening file %s!"), filename.GetFullPath().c_str());
return;
}

int top = wxMax(1, linenum - NEIGHBOUR_SIZE),
bottom = wxMin(linenum + NEIGHBOUR_SIZE, (int)textf.GetLineCount());

m_list->ClearAll();
m_list->InsertColumn(0, _T("#"), wxLIST_FORMAT_RIGHT);
m_list->InsertColumn(1, _("Line"));
m_text->MarkerDeleteAll(1);
m_text->MarkerAdd(linenum, 1);

for (int i = top; i < bottom; i++)
{
wxString linenum(wxString::Format(_T("%i "), i));
wxString linetxt = textf[i-1];
// FIXME: this is not correct
linetxt.Replace(_T("\t"), _T(" "));
m_list->InsertItem(i - top, linenum);
m_list->SetItem(i - top, 1, linetxt);
}

m_list->SetColumnWidth(0, wxLIST_AUTOSIZE);
m_list->SetColumnWidth(1, wxLIST_AUTOSIZE);
// Center the highlighted line:
int lineHeight = m_text->TextHeight(linenum);
int linesInWnd = m_text->GetSize().y / lineHeight;
m_text->ScrollToLine(wxMax(0, linenum - linesInWnd/2));

m_list->SetItemState(linenum - top,
wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
m_list->EnsureVisible(wxMax(0, linenum - top - 5));
m_list->EnsureVisible(wxMin(linenum - top + 5, bottom - top - 1));
m_list->EnsureVisible(linenum - top);

m_current = ref;
}

FileViewer::~FileViewer()
{
wxSize sz = GetClientSize();
wxPoint pos = GetPosition();
wxConfigBase *cfg = wxConfig::Get();
cfg->Write(_T("fileviewer/frame_w"), (long)sz.x);
cfg->Write(_T("fileviewer/frame_h"), (long)sz.y);
cfg->Write(_T("fileviewer/frame_x"), (long)pos.x);
cfg->Write(_T("fileviewer/frame_y"), (long)pos.y);
}


BEGIN_EVENT_TABLE(FileViewer, wxFrame)
Expand Down
61 changes: 33 additions & 28 deletions src/fileviewer.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* This file is part of Poedit (http://www.poedit.net)
*
* Copyright (C) 1999-2005 Vaclav Slavik
* Copyright (C) 1999-2010 Vaclav Slavik
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand All @@ -27,43 +27,48 @@
#define _FILEVIEWER_H_

#include <wx/frame.h>

class WXDLLIMPEXP_FWD_CORE wxListCtrl;
class WXDLLIMPEXP_FWD_CORE wxStyledTextCtrl;


/** This class implements frame that shows part of file
surrounding specified line (40 lines in both directions).
*/
class FileViewer : public wxFrame
{
public:
/** Ctor.
\param basePath base directory that all entries in
\i references are relative to
\param references array of strings in format \i filename:linenum
that lists all occurences of given string
\param openAt number of the \i references entry to show
by default
*/
FileViewer(wxWindow *parent, const wxString& basePath,
const wxArrayString& references, size_t openAt);
~FileViewer();

/// Shows given reference, i.e. loads the file
void ShowReference(const wxString& ref);
public:
/** Ctor.
\param basePath base directory that all entries in
\i references are relative to
\param references array of strings in format \i filename:linenum
that lists all occurences of given string
\param openAt number of the \i references entry to show
by default
*/
FileViewer(wxWindow *parent, const wxString& basePath,
const wxArrayString& references, size_t openAt);
~FileViewer();

bool FileOk() { return !m_current.empty(); }

private:
wxString m_basePath;
wxArrayString m_references;
wxString m_current;

wxListCtrl *m_list;

void OnChoice(wxCommandEvent &event);
DECLARE_EVENT_TABLE();
};
/// Shows given reference, i.e. loads the file
void ShowReference(const wxString& ref);

bool FileOk() { return !m_current.empty(); }

private:
void SetupTextCtrl();
int GetLexer(const wxString& extension);

private:
wxString m_basePath;
wxArrayString m_references;
wxString m_current;

wxStyledTextCtrl *m_text;

void OnChoice(wxCommandEvent &event);
void OnEditFile(wxCommandEvent &event);
DECLARE_EVENT_TABLE();
};

#endif // _FILEVIEWER_H_
3 changes: 3 additions & 0 deletions win32/poedit.bkl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
<define>USE_TRANSMEM</define>
<define>$(DB_DEFINE)</define>

<include>$(WX_DIR)/contrib/include</include>

<include>$(DB_INCLUDE_PATH)</include>
<lib-path>$(DB_LIB_PATH)</lib-path>
<include>$(BOOST_PATH)</include>
Expand Down Expand Up @@ -149,6 +151,7 @@ $(TAB)$(WXRC) -v -c -o compiled_xrc.cpp $(XRC_FILES)
$(substituteFromDict(WX_DEBUG, {'1':'on','0':'off'}))
</debug-runtime-libs>

<wx-lib>stc</wx-lib>
<wx-lib>xrc</wx-lib>
<wx-lib>adv</wx-lib>
<wx-lib>html</wx-lib>
Expand Down
Loading

0 comments on commit 3020ded

Please sign in to comment.