rtoss - Blame information for rev 124

Subversion Repositories:
Rev:
Rev Author Line No. Line
89 roytam 1  
2 #include "stdafx.h"
3 #include "ConfigManager.h"
4 #include "rsrc/resource.h"
5 #include "RSearch.h"
6 using namespace ki;
7 using namespace editwing;
8  
9  
10  
11 void BootNewProcess( const TCHAR* cmd ); // in GpMain.cpp
12  
13 //-------------------------------------------------------------------------
14 // 設定項目管理。
15 // SetDocTypeで切り替えると、文書タイプ依存の項目を自動で
16 // 入れ替えたり色々。
17 //-------------------------------------------------------------------------
18  
19 ConfigManager::ConfigManager()
20 {
21         // デフォルトのレイアウト設定は何よりも先に読んでおく
22         DocType d;
23         d.name.Load( IDS_DEFAULT );
24         d.layfile   = TEXT("default.lay");
25         LoadLayout( &d );
26         dtList_.Add( d );
27         curDt_ = dtList_.begin();
28  
29         // ini読み込み
30         LoadIni();
31         SetDocTypeByName( newfileDoctype_ );
32 }
33  
34 ConfigManager::~ConfigManager()
35 {
36         // ini保存
37         SaveIni();
38 }
39  
40 void ConfigManager::SetDocTypeByName( const ki::String& nam )
41 {
42         curDt_             = dtList_.begin();
43         DtList::iterator b = dtList_.begin();
44         DtList::iterator e = dtList_.end();
45         for( ; b!=e; ++b )
46                 if( b->name == nam )
47                 {
48                         curDt_ = b;
49                         break;
50                 }
51         LoadLayout( &*curDt_ );
52 }
53  
54 int ConfigManager::SetDocType( const Path& fname )
55 {
56         const unicode* uname = fname.ConvToWChar();
57  
58         int ct = 1;
59         DtList::iterator i=dtList_.begin(), e=dtList_.end();
60         if( fname.len() > 0 )
61         {
62                 for( ++i; i!=e; ++i, ++ct )
63                         if( i->pattern.len() > 0 )
64                         {
65                                 const unicode* upat = i->pattern.ConvToWChar();
66                                 bool b = MatchDocType( uname, upat );
67                                 i->pattern.FreeWCMem( upat );
68                                 if( b ) break;
69                         }
70                 if( i == e )
71                         ct=0, i=dtList_.begin(); // 適切なのが見つからなければ[標準]。
72         }
73         else
74         {
75                 ct = 0;
76         }
77  
78         SetDocTypeByName( i->name );
79  
80         fname.FreeWCMem( uname );
81         return ct;
82 }
83  
84 bool ConfigManager::MatchDocType
85         ( const unicode* fname, const unicode* pat )
86 {
87         // pattern と fname とのマッチをとって判定…
88         return reg_match( pat, fname, false );
89 }
90  
91  
92  
93 //-------------------------------------------------------------------------
94 // 設定ダイアログ関連
95 //-------------------------------------------------------------------------
96  
97 struct ConfigDlg : public ki::DlgImpl
98 {
99 private:
100         typedef ConfigManager::DtList::iterator DTI;
101         ulong curSel_;
102         void SaveDt()
103         {
104                 DTI p=myDtl_.begin(), e=myDtl_.end();
105                 for( ulong ct=0; p!=e && ct!=curSel_; ++ct,++p );
106                 if( p==e ) return;
107  
108                 TCHAR buf[256];
109                 SendMsgToItem(IDC_DT_PAT, WM_GETTEXT,
110                         countof(buf),reinterpret_cast<LPARAM>(buf));
111                 p->pattern = buf;
112  
113                 SendMsgToItem(IDC_PAT_KWD, CB_GETLBTEXT,
114                         SendMsgToItem(IDC_PAT_KWD, CB_GETCURSEL),
115                         reinterpret_cast<LPARAM>(buf) );
116                 p->kwdfile = buf;
117  
118                 SendMsgToItem(IDC_PAT_LAY, CB_GETLBTEXT,
119                         SendMsgToItem(IDC_PAT_LAY, CB_GETCURSEL),
120                         reinterpret_cast<LPARAM>(buf) );
121                 p->layfile = buf;
122         }
123         void SelDt(ulong i)
124         {
125                 DTI p=myDtl_.begin(), e=myDtl_.end();
126                 for( ulong ct=0; p!=e && ct!=i; ++ct,++p );
127                 if( p==e ) return;
128  
129                 curSel_ = i;
130                 SendMsgToItem(IDC_DT_PAT, WM_SETTEXT, p->pattern.c_str());
131                 if( p->kwdfile.len()==0 )
132                         SendMsgToItem(IDC_PAT_KWD, CB_SETCURSEL);
133                 else
134                         SendMsgToItem(IDC_PAT_KWD,CB_SELECTSTRING,p->kwdfile.c_str());
135                 SendMsgToItem(IDC_PAT_LAY,CB_SELECTSTRING,p->layfile.c_str());
136         }
137         void on_deldoctype()
138         {
139                 ulong ct;
140                 DTI p=myDtl_.begin(), e=myDtl_.end();
141                 for( ct=0; p!=e && ct!=curSel_; ++ct,++p );
142                 if( p==e ) return;
143  
144                 String msg = TEXT("[");
145                 msg += p->name, msg += TEXT("]"), msg += String(IDS_OKTODEL);
146                 if( IDNO ==
147                         MsgBox( msg.c_str(), String(IDS_APPNAME).c_str(), MB_YESNO ) )
148                         return;
149  
150                 myDtl_.Del(p);
151                 SendMsgToItem( IDC_DOCTYPELIST, LB_DELETESTRING, ct );
152                 SelDt(0);
153                 if( ct+1 == (ulong)SendMsgToItem(IDC_NEWDT,CB_GETCURSEL) )
154                         SendMsgToItem( IDC_NEWDT, CB_SETCURSEL );
155                 SendMsgToItem( IDC_NEWDT, CB_DELETESTRING, ct+1 );
156         }
157         void on_newdoctype()
158         {
159                 struct NewDocTypeDlg : public DlgImpl
160                 {
161                         NewDocTypeDlg(HWND wnd)
162                                 : DlgImpl(IDD_ADDDOCTYPE) { GoModal(wnd); }
163                         virtual bool on_ok()
164                         {
165                                 TCHAR buf[MAX_PATH];
166                                 SendMsgToItem(IDC_NAME, WM_GETTEXT,
167                                         countof(buf),reinterpret_cast<LPARAM>(buf));
168                                 name = buf;
169                                 SendMsgToItem(IDC_EXT, WM_GETTEXT,
170                                         countof(buf),reinterpret_cast<LPARAM>(buf));
171                                 ext=buf;
172                                 return true;
173                         }
174                         String name;
175                         String ext;
176                 } dlg( hwnd() );
177                 if( IDOK == dlg.endcode() )
178                 {
179                         ConfigManager::DocType ndt;
180                         TCHAR buf[200];
181                         SendMsgToItem(IDC_PAT_KWD, CB_GETLBTEXT,
182                                 SendMsgToItem(IDC_PAT_KWD, CB_GETCURSEL),
183                                 reinterpret_cast<LPARAM>(buf) );
184                         ndt.kwdfile = buf;
185                         SendMsgToItem(IDC_PAT_LAY, CB_GETLBTEXT,
186                                 SendMsgToItem(IDC_PAT_LAY, CB_GETCURSEL),
187                                 reinterpret_cast<LPARAM>(buf) );
188                         ndt.layfile = buf;
189                         ndt.name = dlg.name;
190                         ndt.pattern = TEXT(".*\\.")+dlg.ext+TEXT("$");
191                         myDtl_.Add(ndt);
192                         SendMsgToItem( IDC_DOCTYPELIST, LB_ADDSTRING,
193                                 ndt.name.c_str() );
194                         SendMsgToItem( IDC_NEWDT, CB_ADDSTRING,
195                                 ndt.name.c_str() );
196                 }
197         }
198  
199 public:
200         ConfigDlg( ConfigManager& cfg, HWND wnd )
201                 : cfg_( cfg )
202                 , DlgImpl( IDD_CONFIG )
203                 , curSel_( 0xffffffff )
204         {
205                 for( DTI i=++cfg_.dtList_.begin(); i!=cfg_.dtList_.end(); ++i )
206                         myDtl_.Add( *i );
207                 GoModal( wnd );
208         }
209  
210 private:
211         void on_init()
212         {
213                 SendMsgToItem(IDC_LATEST_NUM, WM_SETTEXT,
214                         String().SetInt(cfg_.mrus_).c_str() );
215                 if( cfg_.undoLimit() == -1 )
216                 {
217                         SendMsgToItem(IDC_UNDOLIM1, BM_SETCHECK, BST_CHECKED);
218                         SendMsgToItem(IDC_UNDO_CT, WM_SETTEXT, TEXT("20") );
219                 }
220                 else
221                 {
222                         SendMsgToItem(IDC_UNDOLIM2, BM_SETCHECK, BST_CHECKED);
223                         SendMsgToItem(IDC_UNDO_CT, WM_SETTEXT,
224                                 String().SetInt(cfg_.undoLimit()).c_str() );
225                 }
226                 if( cfg_.countByUnicode() )
227                 {
228                         SendMsgToItem(IDC_COUNTBYLETTER,  BM_SETCHECK, BST_CHECKED);
229                         SendMsgToItem(IDC_COUNTBYLETTER2, BM_SETCHECK);
230                 }
231                 else
232                 {
233                         SendMsgToItem(IDC_COUNTBYLETTER,  BM_SETCHECK);
234                         SendMsgToItem(IDC_COUNTBYLETTER2, BM_SETCHECK, BST_CHECKED);
235                 }
236  
237                 SendMsgToItem(IDC_TXTFILT, WM_SETTEXT,
238                         cfg_.txtFileFilter().c_str() );
239                 SendMsgToItem(IDC_EXTGREP, WM_SETTEXT,
240                         cfg_.grepExe().c_str() );
241  
242                 if( cfg_.openSame() )
243                         SendMsgToItem(IDC_OPENSAME, BM_SETCHECK, BST_CHECKED);
244                 if( cfg_.rememberWindowSize_ )
245                         SendMsgToItem(IDC_REMSIZE, BM_SETCHECK, BST_CHECKED);
246                 if( cfg_.rememberWindowPlace_ )
247                         SendMsgToItem(IDC_REMPLACE, BM_SETCHECK, BST_CHECKED);
248  
249                 CharSetList& csl = cfg_.GetCharSetList();
250                 for(ulong i=1; i<csl.size(); ++i)
251                         SendMsgToItem( IDC_NEWCS, CB_ADDSTRING, csl[i].longName );
252                 SendMsgToItem( IDC_NEWCS, CB_SETCURSEL, csl.findCsi(cfg_.newfileCharset_)-1 );
253                 SendMsgToItem( IDC_NEWLB, CB_ADDSTRING, TEXT("CR") );
254                 SendMsgToItem( IDC_NEWLB, CB_ADDSTRING, TEXT("LF") );
255                 SendMsgToItem( IDC_NEWLB, CB_ADDSTRING, TEXT("CRLF") );
256                 SendMsgToItem( IDC_NEWLB, CB_SETCURSEL, cfg_.newfileLB_ );
257  
258                 ulong nfd_idx=0, nfd_cnt=1;
259                 SendMsgToItem( IDC_NEWDT, CB_ADDSTRING,
260                         cfg_.dtList_.begin()->name.c_str() );
261                 for( DTI i=myDtl_.begin(), e=myDtl_.end(); i!=e; ++i,++nfd_cnt )
262                 {
263                         SendMsgToItem( IDC_DOCTYPELIST, LB_ADDSTRING,
264                                 i->name.c_str() );
265                         SendMsgToItem( IDC_NEWDT, CB_ADDSTRING,
266                                 i->name.c_str() );
267                         if( i->name == cfg_.newfileDoctype_ )
268                                 nfd_idx = nfd_cnt;
269                 }
270                 SendMsgToItem( IDC_NEWDT, CB_SETCURSEL, nfd_idx );
271  
272                 FindFile f;
273                 WIN32_FIND_DATA fd;
274                 f.Begin( (Path(Path::Exe)+=TEXT("type\\*.kwd")).c_str() );
275                 SendMsgToItem( IDC_PAT_KWD, CB_ADDSTRING, TEXT("") );
276                 while( f.Next(&fd) )
277                         SendMsgToItem( IDC_PAT_KWD, CB_ADDSTRING, fd.cFileName );
278                 f.Begin( (Path(Path::Exe)+=TEXT("type\\*.lay")).c_str() );
279                 while( f.Next(&fd) )
280                         SendMsgToItem( IDC_PAT_LAY, CB_ADDSTRING, fd.cFileName );
281  
282                 SelDt(0);
283  
284                 SetCenter( hwnd(), ::GetParent(hwnd()) );
285         }
286  
287         bool on_command( UINT cmd, UINT id, HWND ctrl )
288         {
289                 switch( cmd )
290                 {
291                 case LBN_SELCHANGE:
292                         SaveDt();
293                         SelDt( (ulong)SendMsgToItem( IDC_DOCTYPELIST, LB_GETCURSEL ) );
294                         break;
295                 default:
296                         TCHAR buf[256];
297                         switch( id )
298                         {
299                         case IDC_EDITKWD:
300                                 SendMsgToItem(IDC_PAT_KWD, CB_GETLBTEXT,
301                                         SendMsgToItem(IDC_PAT_KWD, CB_GETCURSEL),
302                                         reinterpret_cast<LPARAM>(buf) );
303                                 if( buf[0] != TEXT('\0') )
304                                         BootNewProcess( (TEXT("\"")+Path(Path::Exe)+
305                                                 TEXT("type\\")+buf+TEXT("\"") ).c_str());
306                                 break;
307                         case IDC_EDITLAY:
308                                 SendMsgToItem(IDC_PAT_LAY, CB_GETLBTEXT,
309                                         SendMsgToItem(IDC_PAT_LAY, CB_GETCURSEL),
310                                         reinterpret_cast<LPARAM>(buf) );
311                                 BootNewProcess( (TEXT("\"")+Path(Path::Exe)+
312                                         TEXT("type\\")+buf+TEXT("\"") ).c_str());
313                                 break;
314                         case IDC_NEWDOCTYPE:
315                                 on_newdoctype();
316                                 break;
317                         case IDC_DELDOCTYPE:
318                                 on_deldoctype();
319                                 break;
320                         default:
321                                 return false;
322                         }
323                         break;
324                 }
325                 return true;
326         }
327  
328         bool on_ok()
329         {
330                 TCHAR buf[100];
331                 SendMsgToItem(IDC_LATEST_NUM, WM_GETTEXT,
332                         countof(buf),reinterpret_cast<LPARAM>(buf));
333                 cfg_.mrus_ = String::GetInt(buf);
334                 cfg_.mrus_ = Min(Max(0, cfg_.mrus_), 20);
335  
336                 if( BST_CHECKED == SendMsgToItem(IDC_UNDOLIM1, BM_GETCHECK) )
337                 {
338                         cfg_.undoLimit_ = -1;
339                 }
340                 else
341                 {
342                         SendMsgToItem(IDC_UNDO_CT, WM_GETTEXT,
343                                 countof(buf),reinterpret_cast<LPARAM>(buf));
344                         cfg_.undoLimit_ = String::GetInt(buf);
345                 }
346  
347                 SendMsgToItem(IDC_TXTFILT, WM_GETTEXT,
348                         countof(buf),reinterpret_cast<LPARAM>(buf));
349                 cfg_.txtFilter_ = buf;
350  
351                 SendMsgToItem(IDC_EXTGREP, WM_GETTEXT,
352                         countof(buf),reinterpret_cast<LPARAM>(buf));
353                 cfg_.grepExe_ = buf;
354  
355                 cfg_.openSame_ =
356                         ( BST_CHECKED==SendMsgToItem(IDC_OPENSAME, BM_GETCHECK) );
357                 cfg_.rememberWindowSize_ =
358                         ( BST_CHECKED==SendMsgToItem(IDC_REMSIZE, BM_GETCHECK) );
359                 cfg_.rememberWindowPlace_ =
360                         ( BST_CHECKED==SendMsgToItem(IDC_REMPLACE, BM_GETCHECK) );
361  
362                 cfg_.countbyunicode_ =
363                         ( BST_CHECKED==SendMsgToItem(IDC_COUNTBYLETTER, BM_GETCHECK) );
364  
365                 cfg_.newfileCharset_ = cfg_.GetCharSetList()[1+SendMsgToItem(IDC_NEWCS, CB_GETCURSEL)].ID;
366                 cfg_.newfileLB_ = (lbcode) SendMsgToItem(IDC_NEWLB, CB_GETCURSEL);
367                 size_t nfd_idx=SendMsgToItem(IDC_NEWDT, CB_GETCURSEL), nfd_cnt=1;
368                 cfg_.newfileDoctype_ = String();
369  
370                 SaveDt();
371                 cfg_.dtList_.DelAfter( ++cfg_.dtList_.begin() );
372                 for( DTI i=myDtl_.begin(), e=myDtl_.end(); i!=e; ++i, ++nfd_cnt )
373                 {
374                         cfg_.dtList_.Add( *i );
375                         if( nfd_idx == nfd_cnt )
376                                 cfg_.newfileDoctype_ = i->name;
377                 }
378                 return true;
379         }
380  
381 private:
382         ConfigManager& cfg_;
383         ConfigManager::DtList myDtl_;
384 };
385  
386 bool ConfigManager::DoDialog( const ki::Window& parent )
387 {
388         LoadIni();
389         {
390                 ConfigDlg dlg(*this, parent.hwnd());
391                 if( IDOK != dlg.endcode() )
392                         return false;
393                 curDt_ = dtList_.begin(); // とりあえず
394         }
395         SaveIni();
396         return true;
397 }
398  
399  
400  
401 //-------------------------------------------------------------------------
402 // *.lay ファイルからの読み込み処理
403 //-------------------------------------------------------------------------
404  
405 namespace {
406         static ulong ToByte( unicode* str )
407         {
408                 ulong c = str[0];
409                          if( L'a' <= str[0] ) c -= (L'a' - 10);
410                 else if( L'A' <= str[0] ) c -= (L'A' - 10);
411                 else                      c -=  L'0';
412                 c = c*16 + str[1];
413                          if( L'a' <= str[1] ) c -= (L'a' - 10);
414                 else if( L'A' <= str[1] ) c -= (L'A' - 10);
415                 else                      c -=  L'0';
416                 return c;
417         }
418         static ulong GetColor( unicode* str )
419         {
420                 return ToByte(str) + (ToByte(str+2)<<8) + (ToByte(str+4)<<16);
421         }
422         static int GetInt( unicode* str )
423         {
424                 int c = 0;
425                 int s = 1;
426                 if( *str == L'-' )
427                         s=-1, ++str;
428                 for( ; *str!=L'\0'; ++str )
429                         c = c * 10 + *str - L'0';
430                 return c*s;
431         }
432 }
433  
434 void ConfigManager::LoadLayout( ConfigManager::DocType* dt )
435 {
436   // 1.省略値として…
437  
438         DtList::iterator ref = dtList_.begin();
439         if( ref != dtList_.end() )
440         {
441                 // default.layがロ[ドされていればそれを使う
442                 dt->vc        = ref->vc;
443                 dt->wrapWidth = ref->wrapWidth;
444                 dt->wrapType  = ref->wrapType;
445                 dt->showLN    = ref->showLN;
109 roytam 446                 dt->fontCS    = ref->fontCS;
89 roytam 447         }
448         else
449         {
450                 // 組み込みのデフォルト設定をロ[ド
451                 dt->vc.SetTabStep( 4 );
452                 dt->vc.color[TXT] = RGB(0,0,0);
453                 dt->vc.color[KWD] = RGB(0,90,230);
454                 dt->vc.color[CMT] = RGB(0,0,0);
455                 dt->vc.color[BG]  = RGB(255,255,255);
456                 dt->vc.color[CTL] = RGB(240,200,240);
457                 dt->vc.color[LN]  = RGB(0,0,0);
458                 dt->vc.sc[scEOF]  = dt->vc.sc[scEOL]=true;
459                 dt->vc.sc[scHSP]  = dt->vc.sc[scZSP]=dt->vc.sc[scTAB]=false;
460                 dt->wrapWidth  = 80;
461                 dt->wrapType   = -1;
462                 dt->showLN     = false;
109 roytam 463                 dt->fontCS     = DEFAULT_CHARSET;
464                 dt->vc.SetFont( TEXT("FixedSys"), 14, dt->fontCS );
89 roytam 465         }
466  
467   // 2.*.layファイルからの読み込み
468  
469         TextFileR tf( UTF16LE );
470         if( tf.Open( (Path(Path::Exe)+TEXT("type\\")+dt->layfile).c_str() ) )
471         {
472                 String fontname;
473                 int    fontsize=0;
474                 int    x;
475                 bool   clfound = false;
476  
477                 unicode buf[1024], *ptr=buf+3;
478                 while( tf.state() != 0 ) // !EOF
479                 {
480                         size_t len = tf.ReadLine( buf, countof(buf)-1 );
481                         if( len<=3 || buf[2]!=L'=' )
482                                 continue;
483                         buf[len] = L'\0';
484  
485                         switch( (buf[0]<<16)|buf[1] )
486                         {
487                         case 0x00630074: // ct: COLOR-TEXT
488                                 dt->vc.color[TXT] = GetColor(ptr);
489                                 break;
490                         case 0x0063006B: // ck: COLOR-KEYWORD
491                                 dt->vc.color[KWD] = GetColor(ptr);
492                                 break;
493                         case 0x00630062: // cb: COLOR-BACKGROUND
494                                 dt->vc.color[BG ] = GetColor(ptr);
495                                 break;
496                         case 0x00630063: // cc: COLOR-COMMENT
497                                 dt->vc.color[CMT] = GetColor(ptr);
498                                 break;
499                         case 0x0063006E: // cn: COLOR-CONTROL
500                                 dt->vc.color[CTL] = GetColor(ptr);
501                                 break;
502                         case 0x0063006C: // cl: COLOR-LINE
503                                 clfound = true;
504                                 dt->vc.color[LN] = GetColor(ptr);
505                                 break;
506                         case 0x00660074: // ft: FONT
507                                 fontname = ptr;
508                                 break;
509                         case 0x0073007A: // sz: SIZE
510                                 fontsize = GetInt(ptr);
511                                 break;
109 roytam 512                         case 0x00630073: // cs: FONT-CHAR-SET
513                                 dt->fontCS = GetInt(ptr);
514                                 break;
89 roytam 515                         case 0x00740062: // tb: TAB
516                                 dt->vc.SetTabStep( GetInt(ptr) );
517                                 break;
518                         case 0x00730063: // sc: SPECIAL-CHAR
519                                 x = GetInt(ptr);
520                                 dt->vc.sc[scZSP] = (0!=x%10); x/=10;
521                                 dt->vc.sc[scHSP] = (0!=x%10); x/=10;
522                                 dt->vc.sc[scTAB] = (0!=x%10); x/=10;
523                                 dt->vc.sc[scEOL] = (0!=x%10); x/=10;
524                                 dt->vc.sc[scEOF] = (0!=x%10);
525                                 break;
526                         case 0x00770070: // wp: WRAP-TYPE
527                                 dt->wrapType = GetInt(ptr);
528                                 break;
529                         case 0x00770077: // ww: WRAP-WIDTH
530                                 dt->wrapWidth = GetInt(ptr);
531                                 break;
532                         case 0x006C006E: // ln: LINE-NO
533                                 dt->showLN = (0!=GetInt(ptr));
534                                 break;
535                         }
536                 }
537  
538                 if( !clfound )
539                         dt->vc.color[LN] = dt->vc.color[TXT];
540                 if( fontname.len()!=0 && fontsize!=0 )
109 roytam 541                         dt->vc.SetFont( fontname.c_str(), fontsize, dt->fontCS );
89 roytam 542         }
543 }
544  
545  
546  
547 //-------------------------------------------------------------------------
548 // *.ini ファイルからの読み込み/書き込み処理
549 //-------------------------------------------------------------------------
550  
551 static const TCHAR s_sharedConfigSection[] = TEXT("SharedConfig");
552  
553 void ConfigManager::LoadIni()
554 {
555         {
556                 FileW fp;
557                 Path inipath(Path::Exe);
558                 inipath+=Path(Path::ExeName).body();
559                 inipath+=TEXT(".ini");
560                 if( !inipath.exist() && fp.Open(inipath.c_str()) )
561                 {
562                         static const char s_defaultIni[] =
563                         "[DocType]\r\n"
564                         "1=C/C++\r\n"
565                         "2=C#\r\n"
566                         "3=D\r\n"
567                         "4=Java\r\n"
568                         "5=HTML\r\n"
569                         "6=CSS\r\n"
570                         "7=Perl\r\n"
571                         "8=Ruby\r\n"
572                         "9=PHP\r\n"
573                         "10=Python\r\n"
574                         "11=Haskell\r\n"
575                         "12=OCaml\r\n"
576                         "13=INI\r\n"
577                         "14=UnicodeText\r\n"
578                         "\r\n"
579                         "[C/C++]\r\n"
580                         "Pattern=.*(\\.(c|cpp|cxx|cc|h|hpp)|include\\\\[^\\.]+)$\r\n"
581                         "Keyword=C.kwd\r\n"
582                         "Layout=program.lay\r\n"
583                         "\r\n"
584                         "[Java]\r\n"
585                         "Pattern=.*\\.java$\r\n"
586                         "Keyword=Java.kwd\r\n"
587                         "Layout=program.lay\r\n"
588                         "\r\n"
589                         "[HTML]\r\n"
590                         "Pattern=.*(\\.html|\\.htm|temporary internet files\\\\.+)$\r\n"
591                         "Keyword=HTML.kwd\r\n"
592                         "Layout=html.lay\r\n"
593                         "\r\n"
594                         "[CSS]\r\n"
595                         "Pattern=.*\\.css$\r\n"
596                         "Keyword=CSS.kwd\r\n"
597                         "Layout=program.lay\r\n"
598                         "\r\n"
599                         "[PHP]\r\n"
600                         "Pattern=.*\\.(php|php3|php4)$\r\n"
601                         "Keyword=PHP.kwd\r\n"
602                         "Layout=program.lay\r\n"
603                         "\r\n"
604                         "[Python]\r\n"
605                         "Pattern=.*\\.py$\r\n"
606                         "Keyword=Python.kwd\r\n"
607                         "Layout=program.lay\r\n"
608                         "\r\n"
609                         "[Ruby]\r\n"
610                         "Pattern=.*\\.rb$\r\n"
611                         "Keyword=Ruby.kwd\r\n"
612                         "Layout=program.lay\r\n"
613                         "\r\n"
614                         "[D]\r\n"
615                         "Pattern=.*\\.d$\r\n"
616                         "Keyword=D.kwd\r\n"
617                         "Layout=program.lay\r\n"
618                         "\r\n"
619                         "[Haskell]\r\n"
620                         "Pattern=.*\\.l?hs$\r\n"
621                         "Keyword=Haskell.kwd\r\n"
622                         "Layout=program.lay\r\n"
623                         "\r\n"
624                         "[OCaml]\r\n"
625                         "Pattern=.*\\.mli?$\r\n"
626                         "Keyword=OCaml.kwd\r\n"
627                         "Layout=program.lay\r\n"
628                         "\r\n"
629                         "[C#]\r\n"
630                         "Pattern=.*\\.cs$\r\n"
631                         "Keyword=C#.kwd\r\n"
632                         "Layout=program.lay\r\n"
633                         "\r\n"
634                         "[INI]\r\n"
635                         "Pattern=.*\\.ini$\r\n"
636                         "Keyword=ini.kwd\r\n"
637                         "\r\n"
638                         "[Perl]\r\n"
639                         "Pattern=.*\\.(pl|pm|cgi)$\r\n"
640                         "Keyword=perl.kwd\r\n"
641                         "Layout=program.lay\r\n"
642                         "\r\n"
643                         "[UnicodeText]\r\n"
644                         "Layout=unitext.lay\r\n"
645                         "\r\n";
646                         fp.Write( s_defaultIni, sizeof(s_defaultIni)-1 );
647                 }
648         }
649  
650         // 共通の設定の読み取りセクション
651         sharedConfigMode_ = ini_.HasSectionEnabled( s_sharedConfigSection );
652         if( sharedConfigMode_ )
653                 ini_.SetSection( s_sharedConfigSection );
654         else
655                 ini_.SetSectionAsUserName();
656  
657         // 共通の設定
658         undoLimit_ = ini_.GetInt( TEXT("UndoLimit"), -1 );
659         txtFilter_ = ini_.GetStr( TEXT("TxtFilter"),
660                 TEXT("*.txt;*.htm;*.html;*.css;*.js;*.d;*.c;*.cpp;*.cc;*.cxx;*.h;*.hpp;*.php;*.php3;*.ini") );
661         grepExe_   = ini_.GetStr( TEXT("GrepExe"), TEXT("") );
662         openSame_  = ini_.GetBool( TEXT("OpenSame"), false );
663         countbyunicode_ = ini_.GetBool( TEXT("CountUni"), false );
124 roytam 664 #if defined(TARGET_VER) && TARGET_VER==310
665         showStatusBar_ = false;
666 #else
89 roytam 667         showStatusBar_ = ini_.GetBool( TEXT("StatusBar"), true );
124 roytam 668 #endif
89 roytam 669  
94 roytam 670         dateFormat_   = ini_.GetStr( TEXT("DateFormat"), TEXT("HH:mm yyyy/MM/dd") );
671  
89 roytam 672         // wnd
673         rememberWindowSize_  = ini_.GetBool( TEXT("RememberWindowSize"), false );
674         rememberWindowPlace_ = ini_.GetBool( TEXT("RememberWindowPos"), false );
675         wndX_ = ini_.GetInt( TEXT("WndX"), CW_USEDEFAULT );
676         wndY_ = ini_.GetInt( TEXT("WndY"), CW_USEDEFAULT );
677         wndW_ = ini_.GetInt( TEXT("WndW"), CW_USEDEFAULT );
678         wndH_ = ini_.GetInt( TEXT("WndH"), CW_USEDEFAULT );
679         wndM_ = ini_.GetBool( TEXT("WndM"), false );
680  
681         // TODO: MRU
682         mrus_ = ini_.GetInt( TEXT("MRU"), 4 );
683         mrus_ = Min(Max(0, mrus_), 20);
684  
685         // 新規ファイル関係
686         newfileCharset_ = ini_.GetInt( TEXT("NewfileCharset"), charSets_.defaultCs() );
687         if(newfileCharset_ == -1) newfileCharset_ = 1252; // 1.07.4 bugfix
688         newfileDoctype_ = ini_.GetStr( TEXT("NewfileDoctype"), String() );
689         newfileLB_      = (lbcode) ini_.GetInt( TEXT("NewfileLB"), CRLF );
690  
691         // 文書タイプリストの0番以外のクリア
692         dtList_.DelAfter( ++dtList_.begin() );
693  
694         String s, r;
695         for( int i=1; true; ++i )
696         {
697                 // 文書タイプ名を読み込み
698                 ini_.SetSection( TEXT("DocType") );
699                 s.SetInt(i);
700                 r = ini_.GetStr( s.c_str(), String() );
701                 if( r.len() == 0 )
702                         break;
703  
704                 // その文書タイプを実際に読み込み
705                 ini_.SetSection( r.c_str() );
706                 {
707                         DocType d;
708                         d.name      = r;
709                         d.layfile   = ini_.GetStr( TEXT("Layout"),TEXT("default.lay"));
710                         d.kwdfile   = ini_.GetStr( TEXT("Keyword"), String() );
711                         d.pattern   = ini_.GetStr( TEXT("Pattern"), String() );
712                         dtList_.Add( d );
713                 }
714         }
715 }
716  
717 void ConfigManager::SaveIni()
718 {
719         {
720                 Path inipath(Path::Exe);
721                 inipath+=Path(Path::ExeName).body();
722                 inipath+=TEXT(".ini");
723                 if( inipath.isReadOnly() )
724                         return;
725         }
726  
727         // 共通の設定の書き込みセクション
728         if( sharedConfigMode_ )
729                 ini_.SetSection( s_sharedConfigSection );
730         else
731                 ini_.SetSectionAsUserName();
732  
733         // 共通の設定
734         ini_.PutInt( TEXT("UndoLimit"), undoLimit_ );
735         ini_.PutStr( TEXT("TxtFilter"), txtFilter_.c_str() );
736         ini_.PutStr( TEXT("GrepExe"), grepExe_.c_str() );
737         ini_.PutBool( TEXT("OpenSame"), openSame_ );
738         ini_.PutBool( TEXT("CountUni"), countbyunicode_ );
739         ini_.PutBool( TEXT("StatusBar"), showStatusBar_ );
740  
94 roytam 741         ini_.PutStr( TEXT("DateFormat"), dateFormat_.c_str() );
742  
89 roytam 743         // Wnd
744         ini_.PutBool( TEXT("RememberWindowSize"), rememberWindowSize_ );
745         ini_.PutBool( TEXT("RememberWindowPos"), rememberWindowPlace_ );
746         ini_.PutInt( TEXT("WndX"), wndX_ );
747         ini_.PutInt( TEXT("WndY"), wndY_ );
748         ini_.PutInt( TEXT("WndW"), wndW_ );
749         ini_.PutInt( TEXT("WndH"), wndH_ );
750         ini_.PutBool( TEXT("WndM"), wndM_ );
751  
752         // 新規ファイル関係
753         ini_.PutInt( TEXT("NewfileCharset"), newfileCharset_ );
754         ini_.PutStr( TEXT("NewfileDoctype"), newfileDoctype_.c_str() );
755         ini_.PutInt( TEXT("NewfileLB"),      newfileLB_      );
756  
757         // MRU
758         ini_.PutInt( TEXT("MRU"), mrus_ );
759  
760         // DocType
761         for(DtList::iterator i=++dtList_.begin(); i!=dtList_.end(); ++i )
762         {
763                 ini_.SetSection( i->name.c_str() );
764                 ini_.PutStr( TEXT("Pattern"), i->pattern.c_str() );
765                 ini_.PutStr( TEXT("Keyword"), i->kwdfile.c_str() );
766                 ini_.PutStr( TEXT("Layout"), i->layfile.c_str() );
767         }
768  
769         ulong ct=1;
770         ini_.SetSection( TEXT("DocType") );
771         for(DtList::iterator i=++dtList_.begin(); i!=dtList_.end(); ++i,++ct)
772                 ini_.PutStr( String().SetInt(ct).c_str(), i->name.c_str() );
773         ini_.PutStr( String().SetInt(ct).c_str(), TEXT("") );
774 }
775  
776  
777  
778 //-------------------------------------------------------------------------
779 // [最近使ったファイル]関係
780 //-------------------------------------------------------------------------
781  
782 namespace {
783         static const TCHAR* const s_mrulock = TEXT("GreenPad_MRUMutex");
784 }
785  
786 void ConfigManager::AddMRU( const ki::Path& fname )
787 {
788         Mutex mx(s_mrulock);
789  
790         // メモリ内のMRUリストを更新
791         {
792                 int i;
793                 for( i=0; i<countof(mru_); ++i )
794                         if( mru_[i] == fname )
795                         {++i; break;}
796                 for( --i; i>0; --i )
797                         mru_[i] = mru_[i-1];
798                 mru_[0] = fname;
799         }
800  
801         // iniへ保存
802         {
803                 ini_.SetSectionAsUserName();
804                 const String key = TEXT("MRU");
805                 for( int i=0; i<countof(mru_); ++i )
806                         ini_.PutPath(
807                                 (key+String().SetInt(i+1)).c_str(), mru_[i] );
808         }
809 }
810  
811 void ConfigManager::SetUpMRUMenu( HMENU m, UINT id )
812 {
813         Mutex mx(s_mrulock);
814  
815         // iniから読み込み
816         {
817                 ini_.SetSectionAsUserName();
818                 const String key = TEXT("MRU");
819                 for( int i=0; i<countof(mru_); ++i )
820                         mru_[i] = ini_.GetPath(
821                                 (key+String().SetInt(i+1)).c_str(), Path() );
822         }
823  
824         // 全項目を削除
825         while( ::DeleteMenu( m, 0, MF_BYPOSITION ) );
826  
827         // メニュ[構築
124 roytam 828         /*if(app().isNewShell())
89 roytam 829         {
110 roytam 830                 MENUITEMINFO mi = { sizeof(MENUITEMINFO) };
831                 mi.fMask = MIIM_ID | MIIM_TYPE;
832                 mi.fType = MFT_STRING;
833                 for( int i=0; i<countof(mru_); ++i )
89 roytam 834                 {
110 roytam 835                         if( i>=mrus_ || mru_[i].len()==0 )
89 roytam 836                         {
110 roytam 837                                 if( i==0 )
838                                 {
839                                         mi.fMask     |= MIIM_STATE;
840                                         mi.wID        = id;
841                                         mi.fState     = MFS_DISABLED;
842                                         mi.dwTypeData = TEXT("no files");
843                                         mi.cch        = 0;
844                                         ::InsertMenuItem( m, 0, MF_BYPOSITION, &mi );
845                                 }
846                                 break;
89 roytam 847                         }
110 roytam 848                         String cpt = mru_[i].CompactIfPossible(60);
849                         mi.wID        = id + i;
850                         mi.dwTypeData = const_cast<TCHAR*>(cpt.c_str());
851                         mi.cch        = cpt.len();
852                         ::InsertMenuItem( m, i, MF_BYPOSITION, &mi );
89 roytam 853                 }
854         }
110 roytam 855         else
124 roytam 856         {*/
110 roytam 857                 for( int i=0; i<countof(mru_); ++i )
858                 {
859                         if( i>=mrus_ || mru_[i].len()==0 )
860                         {
861                                 if( i==0 )
862                                 {
863                                         ::InsertMenu( m, i, MF_BYPOSITION|MF_GRAYED, id, TEXT("no files") );
864                                 }
865                                 break;
866                         }
867                         String cpt = mru_[i].CompactIfPossible(60);
868                         ::InsertMenu( m, i, MF_BYPOSITION, id + i, const_cast<TCHAR*>(cpt.c_str()) );
869                 }
124 roytam 870         //}
89 roytam 871 }
872  
873 Path ConfigManager::GetMRU( int no ) const
874 {
875         return (0<=no && no<mrus_ ? mru_[no] : Path());
876 }
877  
878  
879 //-------------------------------------------------------------------------
880 // ウインドウサイズ復元処理
881 //-------------------------------------------------------------------------
882  
883 void ConfigManager::RememberWnd( ki::Window* wnd )
884 {
885         RECT rc;
886         wnd->getPos(&rc);
887         WINDOWPLACEMENT wp = {sizeof(wp)};
888         ::GetWindowPlacement( wnd->hwnd(), &wp );
889  
890         if( wp.showCmd==SW_SHOWNORMAL || wp.showCmd == SW_MAXIMIZE )
891                 wndM_ = (wp.showCmd == SW_MAXIMIZE);
892         if( wp.showCmd==SW_SHOWNORMAL )
893         {
894                 wndX_ = rc.left;
895                 wndY_ = rc.top;
896                 wndW_ = rc.right- rc.left;
897                 wndH_ = rc.bottom - rc.top;
898         }
899         //if( this->rememberWindowPlace_ || this->rememberWindowSize_ )
900         //      SaveIni();
901 }
902  
903 //-------------------------------------------------------------------------
904 // [文書タイプ]サブメニュ[の作成
905 //-------------------------------------------------------------------------
906  
907 void ConfigManager::SetDocTypeMenu( HMENU m, UINT idstart )
908 {
909         // 全項目を削除
910         while( ::DeleteMenu( m, 0, MF_BYPOSITION ) );
911  
124 roytam 912         /*if(app().isNewShell())
103 roytam 913         {
914                 // 順に追加
915                 MENUITEMINFO mi = { sizeof(MENUITEMINFO) };
916                 mi.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
917                 mi.fType = MFT_STRING | MFT_RADIOCHECK;
89 roytam 918  
103 roytam 919                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
920                 for( int ct=0; i!=e; ++i, ++ct )
921                 {
922                         mi.wID        = idstart + ct;
923                         mi.fState     = (i==curDt_ ? MFS_CHECKED : MFS_UNCHECKED);
924                         mi.dwTypeData = const_cast<TCHAR*>(i->name.c_str());
925                         mi.cch        = i->name.len();
926                         ::InsertMenuItem( m, ct, MF_BYPOSITION, &mi );
927                 }
928         }
929         else
124 roytam 930         {*/
103 roytam 931                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
932                 for( int ct=0; i!=e; ++i, ++ct )
933                 {
934                         ::InsertMenu( m, ct, MF_BYPOSITION|(i==curDt_ ? MFS_CHECKED : MFS_UNCHECKED), idstart + ct, const_cast<TCHAR*>(i->name.c_str()) );
935                 }
124 roytam 936         //}
89 roytam 937 }
938  
939 void ConfigManager::SetDocTypeByMenu( int pos, HMENU m )
940 {
124 roytam 941         /*if(app().isNewShell())
103 roytam 942         {
943                 MENUITEMINFO mi = { sizeof(MENUITEMINFO) };
944                 mi.fMask  = MIIM_STATE;
89 roytam 945  
103 roytam 946                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
947                 for( int ct=0; i!=e; ++i, ++ct )
948                 {
949                         mi.fState     = (ct==pos ? MFS_CHECKED : MFS_UNCHECKED);
950                         ::SetMenuItemInfo( m, ct, MF_BYPOSITION, &mi );
951                         if( ct == pos )
952                         {
953                                 curDt_ = i;
954                                 LoadLayout( &*curDt_ );
955                         }
956                 }
957         }
958         else
124 roytam 959         {*/
103 roytam 960                 int ct=0;
961                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
962                 for( ; i!=e; ++i, ++ct )
89 roytam 963                 {
103 roytam 964                         if( ct == pos )
965                         {
966                                 curDt_ = i;
967                                 LoadLayout( &*curDt_ );
968                                 ::CheckMenuItem( m, ct, MF_BYPOSITION|MF_CHECKED);
969                         }
970                         else
971                         {
972                                 ::CheckMenuItem( m, ct, MF_BYPOSITION|MF_UNCHECKED);
973                         }
89 roytam 974                 }
124 roytam 975         //}
89 roytam 976 }
977  
978 void ConfigManager::CheckMenu( HMENU m, int pos )
979 {
124 roytam 980         /*if(app().isNewShell())
103 roytam 981         {
982                 MENUITEMINFO mi = { sizeof(MENUITEMINFO) };
983                 mi.fMask  = MIIM_STATE;
89 roytam 984  
103 roytam 985                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
986                 for( int ct=0; i!=e; ++i, ++ct )
987                 {
988                         mi.fState     = (ct==pos ? MFS_CHECKED : MFS_UNCHECKED);
989                         ::SetMenuItemInfo( m, ct, MF_BYPOSITION, &mi );
990                 }
991         }
992         else
124 roytam 993         {*/
103 roytam 994                 int ct=0;
995                 DtList::iterator i=dtList_.begin(), e=dtList_.end();
996                 for( ; i!=e; ++i, ++ct )
997                 {
998                         if( ct == pos )
999                         {
1000                                 ::CheckMenuItem( m, ct, MF_BYPOSITION|MF_CHECKED);
1001                         }
1002                         else
1003                         {
1004                                 ::CheckMenuItem( m, ct, MF_BYPOSITION|MF_UNCHECKED);
1005                         }
1006                 }
124 roytam 1007         //}
89 roytam 1008 }
1009