1 /*
2  * Part of WCM Commander
3  * https://github.com/corporateshark/WCMCommander
4  * wcm@linderdaum.com
5  */
6 
7 #include "view-history.h"
8 #include "path-list.h"
9 #include "string-util.h"
10 #include "wcm-config.h"
11 #include "ltext.h"
12 #include "unicode_lc.h"
13 
14 
15 #define IS_EDIT			"IS_EDIT"
16 #define VIEW_POS			"VIEW_POS"
17 #define EDIT_FIRST_LINE	"EDIT_FIRST_LINE"
18 #define EDIT_POINT_LINE	"EDIT_POINT_LINE"
19 #define EDIT_POINT_POS	"EDIT_POINT_POS"
20 
21 #define MAX_VIEW_HISTORY_COUNT   50
22 
23 static const char ViewHistorySection[] = "ViewHistory";
24 
25 PathList g_ViewList;
26 
27 
LoadViewHistory()28 void LoadViewHistory()
29 {
30 	std::vector<std::string> List;
31 	LoadStringList( ViewHistorySection, List );
32 
33 	g_ViewList.SetStrings( List );
34 }
35 
SaveViewHistory()36 void SaveViewHistory()
37 {
38 	std::vector<std::string> List;
39 	g_ViewList.GetStrings( List );
40 
41 	SaveStringList( ViewHistorySection, List );
42 }
43 
AddFileToHistory(const int CurrIndex,const PathList::Data & Data)44 void AddFileToHistory( const int CurrIndex, const PathList::Data& Data )
45 {
46 	if ( CurrIndex != -1 )
47 	{
48 		// remove existing item
49 		g_ViewList.Remove( CurrIndex );
50 	}
51 
52 	// add item to the end of the list
53 	g_ViewList.Add( Data.name.data(), Data.conf );
54 
55 	// limit number of elements in the list
56 	while ( g_ViewList.GetCount() > MAX_VIEW_HISTORY_COUNT )
57 	{
58 		g_ViewList.Remove( 0 );
59 	}
60 }
61 
AddFileViewToHistory(const int CurrIndex,PathList::Data & Data,const int Pos)62 void AddFileViewToHistory( const int CurrIndex, PathList::Data& Data, const int Pos )
63 {
64 	// add file view properties
65 	StrConfig* Cfg = Data.conf.ptr();
66 	Cfg->Set( VIEW_POS, Pos );
67 	Cfg->Set( IS_EDIT, 0 );
68 
69 	// add new item to the end of list
70 	AddFileToHistory( CurrIndex, Data );
71 }
72 
GetCreateFileViewPosHistory(clPtr<FS> * Fs,FSPath * Path)73 int GetCreateFileViewPosHistory( clPtr<FS>* Fs, FSPath* Path )
74 {
75 	if ( !g_WcmConfig.editSavePos || !Fs || !Fs->Ptr() || !Path )
76 	{
77 		return -1;
78 	}
79 
80 	std::vector<unicode_t> Name = new_unicode_str( (*Fs)->Uri( *Path ).GetUnicode() );
81 
82 	// check if item already exists in the list
83 	const int Index = g_ViewList.FindByName( Name.data() );
84 	if ( Index != -1 )
85 	{
86 		StrConfig* Cfg = g_ViewList.GetData( Index )->conf.ptr();
87 		return Cfg->GetIntVal( VIEW_POS );
88 	}
89 
90 	// collect all needed path information
91 	PathList::Data Data;
92 	if ( PathListFSToData( Data, Fs, Path ) )
93 	{
94 		AddFileViewToHistory( -1, Data, 0 );
95 	}
96 
97 	return 0;
98 }
99 
UpdateFileViewPosHistory(const unicode_t * Name,const int Pos)100 void UpdateFileViewPosHistory( const unicode_t* Name, const int Pos )
101 {
102 	if ( !g_WcmConfig.editSavePos )
103 	{
104 		return;
105 	}
106 
107 	// check if item already exists in the list
108 	const int Index = g_ViewList.FindByName( Name );
109 	if ( Index != -1 )
110 	{
111 		// copy current data
112 		PathList::Data Data = *g_ViewList.GetData( Index );
113 
114 		// update data in the history list
115 		AddFileViewToHistory( Index, Data, Pos );
116 	}
117 }
118 
AddFileEditToHistory(const int CurrIndex,PathList::Data & Data,const int FirstLine,const int Line,const int Pos)119 void AddFileEditToHistory( const int CurrIndex, PathList::Data& Data, const int FirstLine, const int Line, const int Pos )
120 {
121 	// add file edit properties
122 	StrConfig* Cfg = Data.conf.ptr();
123 	Cfg->Set( EDIT_FIRST_LINE, FirstLine );
124 	Cfg->Set( EDIT_POINT_LINE, Line );
125 	Cfg->Set( EDIT_POINT_POS, Pos );
126 	Cfg->Set( IS_EDIT, 1 );
127 
128 	// add new item to the end of list
129 	AddFileToHistory( CurrIndex, Data );
130 }
131 
GetCreateFileEditPosHistory(clPtr<FS> * Fs,FSPath * Path,sEditorScrollCtx & Ctx)132 bool GetCreateFileEditPosHistory( clPtr<FS>* Fs, FSPath* Path, sEditorScrollCtx& Ctx )
133 {
134 	if ( !g_WcmConfig.editSavePos || !Fs || !Fs->Ptr() || !Path )
135 	{
136 		return false;
137 	}
138 
139 	std::vector<unicode_t> Name = new_unicode_str( (*Fs)->Uri( *Path ).GetUnicode() );
140 
141 	// check if item already exists in the list
142 	const int Index = g_ViewList.FindByName( Name.data() );
143 	if ( Index != -1 )
144 	{
145 		StrConfig* Cfg = g_ViewList.GetData( Index )->conf.ptr();
146 		Ctx.m_FirstLine = Cfg->GetIntVal( EDIT_FIRST_LINE );
147 		Ctx.m_Point.line = Cfg->GetIntVal( EDIT_POINT_LINE );
148 		Ctx.m_Point.pos = Cfg->GetIntVal( EDIT_POINT_POS );
149 		return true;
150 	}
151 
152 	// collect all needed path information
153 	PathList::Data Data;
154 	if ( PathListFSToData( Data, Fs, Path ) )
155 	{
156 		AddFileEditToHistory( Index, Data, 0, 0, 0 );
157 	}
158 
159 	return false;
160 }
161 
UpdateFileEditPosHistory(const unicode_t * Name,const sEditorScrollCtx & Ctx)162 void UpdateFileEditPosHistory( const unicode_t* Name, const sEditorScrollCtx& Ctx )
163 {
164 	if ( !g_WcmConfig.editSavePos )
165 	{
166 		return;
167 	}
168 
169 	// check if item already exists in the list
170 	const int Index = g_ViewList.FindByName( Name );
171 	if ( Index != -1 )
172 	{
173 		// copy current data
174 		PathList::Data Data = *g_ViewList.GetData( Index );
175 
176 		// update data in the history list
177 		AddFileEditToHistory( Index, Data, Ctx.m_FirstLine, Ctx.m_Point.line, Ctx.m_Point.pos );
178 	}
179 }
180 
181 
182 class clViewHistoryWin : public PathListWin
183 {
184 public:
clViewHistoryWin(Win * Parent,PathList & DataList)185 	clViewHistoryWin( Win* Parent, PathList& DataList )
186 		: PathListWin( Parent, DataList ) {}
187 
188 protected:
GetItemText(const PathList::Data * Data) const189 	virtual std::vector<unicode_t> GetItemText( const PathList::Data* Data ) const override
190 	{
191 		const bool IsEdit = Data->conf->GetIntVal( IS_EDIT ) != 0;
192 		return carray_cat( utf8_to_unicode( IsEdit ? "Edit: " : "View: " ).data(), Data->name.data() );
193 	}
194 };
195 
196 
197 class clViewHistoryDlg : public PathListDlg
198 {
199 private:
200 	clViewHistoryWin m_historyWin;
201 	Layout m_lo;
202 
203 public:
clViewHistoryDlg(NCDialogParent * parent,PathList & dataList)204 	clViewHistoryDlg( NCDialogParent* parent, PathList& dataList )
205 	 : PathListDlg( parent, m_historyWin, _LT( "File View History" ), 0 )
206 	 , m_historyWin( this, dataList )
207 	 , m_lo( 10, 10 )
208 	{
209 		m_ListWin.Show();
210 		m_ListWin.Enable();
211 
212 		m_lo.AddWin( &m_ListWin, 0, 0, 9, 0 );
213 		m_lo.SetLineGrowth( 9 );
214 		AddLayout( &m_lo );
215 
216 		SetPosition();
217 		m_ListWin.SetFocus();
218 
219 		if ( dataList.GetCount() > 0 )
220 		{
221 			// select the last item and make it visible
222 			m_ListWin.MoveCurrent( dataList.GetCount() - 1 );
223 		}
224 	}
225 };
226 
227 
ViewHistoryDlg(NCDialogParent * Parent,clPtr<FS> * Fs,FSPath * Path,bool * IsEdit)228 bool ViewHistoryDlg( NCDialogParent* Parent, clPtr<FS>* Fs, FSPath* Path, bool* IsEdit )
229 {
230 	clViewHistoryDlg Dlg( Parent, g_ViewList );
231 	Dlg.SetEnterCmd( 0 );
232 
233 	const int Res = Dlg.DoModal();
234 	const PathList::Data* Data = Dlg.GetSelected();
235 
236 	if ( Res == CMD_OK && Data && Fs && Path )
237 	{
238 		*IsEdit = Data->conf->GetIntVal( IS_EDIT ) != 0;
239 		return PathListDataToFS( Data, Fs, Path );
240 	}
241 
242 	return false;
243 }
244