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