using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; using NT2chCtrl; using NT2chView.NtFile; using NT2chView.NtHtml; using NT2chView.NtNet; using NT2chObject; using System.Threading; using System.ComponentModel; using System.Windows.Media.Imaging; using System.Net; namespace NT2chView { class NTExportUtil : IUtil, ICommand2 { public event MainWindow.DelegateMsgOpenThreadTitleListRequest MsgOpenThreadTitleListRequest; static string mRootPath; const string ROOTDIR_NAME = @"\ExternalControlData"; public static void init(string rootPath) { mRootPath = rootPath + ROOTDIR_NAME; DirectoryInfo dir = new DirectoryInfo(mRootPath); if (!dir.Exists) dir.Create(); Worker.init(5); } public int GetApplicationApiVersion() { return 1; } public string GetDataPath() { return (mRootPath == null) ? string.Empty : mRootPath; } public Dictionary GetPreference() { return NTUserPreference.getExportPreference(); } public int ParseResLinkReference(string source, int startPosition) { return NTTextFormat.parse2chNumA(source, startPosition); } public int[] ParseResLinkReferenceNumber(string source) { List arr = NTTextFormat.parseReferenceNumber(source); if (arr != null) { return arr.ToArray(); } return null; } string[] httpSchem = { "http://", "https://", "ttp://", "ttps://"}; public int ParseURLString(string source, int startIndex) { foreach(string schem in httpSchem) { if (myCompare(schem, source, startIndex)) { int n = NTHtmlUtils.parseWebAddress(source, startIndex + schem.Length); if( n <= 0)// || n < (startIndex+schem.Length)) continue; return n + schem.Length; } } return -1; } private static bool myCompare(string target, string source, int startIndex) { int len= target.Length; if (source.Length < len+startIndex) return false; for (int i = 0; i < len; i++) { if (target[i] != source[i+startIndex]) return false; } return true; } public void ExecURL(string url) { if (Keyboard.Modifiers == ModifierKeys.Shift) { Process.Start(url); return; } string youtubeId; //string url = uri.AbsoluteUri; string boardAddress, datName; if (NTHttpUtils.parseBBSAddress(url, out boardAddress, out datName)) { NTBoard board = NTDataRoot.getBoardByAddress(boardAddress); if (board == null) { MessageBox.Show("そんな板無いです。" + "\nShitキーを押しながらリンクをクリックするとブラウザーで開きます。"); return; } if (!NTAppState.getMainWindow().OpenNewBoard(board)) { MessageBox.Show("板が開けませんでした。" + "\nShitキーを押しながらリンクをクリックするとブラウザーで開きます。"); return; } NTThreadTitle tt = board.findThreadTitleByDatName(datName); if (tt == null) { if (NTUserPreference.MaruIsEnabled) { tt = board.addExtraThread(datName, null); } if (tt == null) { MessageBox.Show("スレッドが見つかりませんでした。" + "\nShitキーを押しながらリンクをクリックするとブラウザーで開きます。"); return; } } NTAppState.getMainWindow().OpenNewThread(tt); } else if(NTUserPreference.OpenYoutubeOnApp && NTHttpUtils.TryParseYouTubeId(url, out youtubeId)) { NTAppState.getMainWindow().OpenMoviePanel(youtubeId); } else { Process.Start(url); } } //ユーザーの設定ファイルから //レス画面用のコンテキストメニューを生成します。 public void CreateResViewContextMenu(FlowDocumentScrollViewer sv) { NTResMenuCommand.createContextMenu(sv); } public void OpenThread(IThreadDescription threadDesc) { if (threadDesc == null) return; NTBoard board = threadDesc.getBoard() as NTBoard; if (board == null) return; string strSubject = null; if (!board.mDataInit) { if (!NTFileAccess.isSubjectExsists(board.mName)) if (!NTHttpAccess.getSubject(board.mAddress, board.mName)) return; strSubject = NTFileAccess.retrieveSubjectDataFromFile(board.mName); if (strSubject == null) return; if (!board.parseSubjectData(strSubject, NTAppState.getMainWindow().getFavoriteData())) return; } NTThreadTitle tt = board.findThreadTitleByDatName( threadDesc.getDatName()); if (tt == null) { if (NTUserPreference.MaruIsEnabled) { tt = board.addExtraThread(threadDesc.getDatName(), null); } if (tt == null) return; } NTAppState.getMainWindow().OpenNewThread(tt); } public void AddBoardToFavorite(IBoard iboard) { NTAppState.getMainWindow().addFavoriteBoard(iboard.getName()); } public bool AddThreadToFavorite(IThreadDescription threadDesc) { if (threadDesc == null) return false; NTBoard board = threadDesc.getBoard() as NTBoard; if (board == null) return false; string strSubject = null; if (!board.mDataInit) { if (!NTFileAccess.isSubjectExsists(board.mName)) if (!NTHttpAccess.getSubject(board.mAddress, board.mName)) return false; strSubject = NTFileAccess.retrieveSubjectDataFromFile(board.mName); if (strSubject == null) return false; if (!board.parseSubjectData(strSubject, NTAppState.getMainWindow().getFavoriteData())) return false; } NTThreadTitle tt = board.findThreadTitleByDatName( threadDesc.getDatName()); if (tt == null) return false; NTAppState.getMainWindow().addFavoriteThread(tt); return true; } public bool RemoveThreadFromFavorite(IThreadDescription threadDesc) { if (threadDesc == null) return false; NTBoard board = threadDesc.getBoard() as NTBoard; if (board == null) return false; string strSubject = null; if (!board.mDataInit) { if (!NTFileAccess.isSubjectExsists(board.mName)) if (!NTHttpAccess.getSubject(board.mAddress, board.mName)) return false; strSubject = NTFileAccess.retrieveSubjectDataFromFile(board.mName); if (strSubject == null) return false; if (!board.parseSubjectData(strSubject, NTAppState.getMainWindow().getFavoriteData())) return false; } NTThreadTitle tt = board.findThreadTitleByDatName( threadDesc.getDatName()); if (tt == null) return false; NTAppState.getMainWindow().removeFavoriteThread(tt); return true; } //指定したスレッドの取得済ログを消去します //クラウド同期が有効な場合、クラウドの同期情報も削除されます。 public void DeleteLog(IThread ithread) { NTThreadTitle tt = ithread as NTThreadTitle; if (tt == null) return; tt.delDat(); } //指定した板に含まれるスレッドの全ての取得済ログを消去します //クラウド同期が有効な場合、クラウドの同期情報も削除されます。 public void DeleteLog(IBoard iboard) { NTBoard board = iboard as NTBoard; if (board == null) return; board.delAllDat(); } //指定したスレッドと類似したタイトルを持つ //スレッドを検索します。表示方法はフレームワークが //決定するので、呼び出し側ではコールバックを受け取りません public void SearchSimilarTitle(IThread2 ithread) { NTThreadTitle tt = ithread.getDependencyObject() as NTThreadTitle; if (tt == null) return; NTAppState.getMainWindow().setupTitleSearchListBySimString(tt); } //レスにブックマークをつけるように要求します public bool AddBookmark(IThread ithread, IRes ires) { NTThreadTitle tt = ithread as NTThreadTitle; if (tt == null) return false; NTRes res = ires as NTRes; if (res == null) return false; res.mBookmark = true; int seqNo = ires.getSequenceNo(); tt.addBookmark(seqNo); return true; } //レスにブックマークをつけるように要求します public bool DeleteBookmark(IThread ithread, IRes ires) { NTThreadTitle tt = ithread as NTThreadTitle; if (tt == null) return false; NTRes res = ires as NTRes; if (res == null) return false; res.mBookmark = false; int seqNo = ires.getSequenceNo(); tt.removeBookmark(seqNo); return true; } //スレッドを指定して、書き込み用のダイアログを開きます。 //名前、E-Mail、メッセージの初期値を指定できます。 //指定する値がない場合、nullを指定できます。 public bool WriteMessage(IThread ithread, string message) { NTThreadTitle thread = ithread as NTThreadTitle;// findSelectedThreadTitle(); if (thread == null) { MessageBox.Show("書き込む板が見つかりません。"); return false; } NTAppState.getMainWindow().WriteRes_Invoke(thread, message); return true; } public bool CreateThread(IBoard iboard, string title, string message) { //NTAppState.getMainWindow(). NTBoard board = iboard as NTBoard; if (board == null) return false; NTCreateThreadWindow wnd = new NTCreateThreadWindow(board, title, message); wnd.ShowDialog(); return true; } public void ShowThreadInfoWindow(string title, string address) { NTThreadInfoWindow wnd = new NTThreadInfoWindow(title, address); wnd.ShowDialog(); } //板オブジェクトを指定して、板を開きます。 public void TryToOpenBoard(IBoard iboard) { NTBoard board = iboard as NTBoard; if (board == null) return; if (MsgOpenThreadTitleListRequest != null) MsgOpenThreadTitleListRequest(board); } //板オブジェクトを指定して、板を更新します。 public void UpdateBoard(IBoard iboard) { NTBoard board = iboard as NTBoard; if (board == null) return; board.Update(null); } //NGワード編集ダイアログを開きます。 //iresを指定すると、そのレスからNGに指定する各項目の文字列を //抽出して初期設定します。 public void ShowNgwordDialog(IRes ires) { NTRes res = ires as NTRes; if(res != null) NTAppState.getMainWindow().NgEdit_setResSection(res); } //設定されているNGワード文字列のリストを取得します public string[] GetNgWordList() { NTNgItems ngItem = NTNgItems.getContext(); List list = ngItem.getNgWords(); return list.ToArray(); } //設定されているNG-ID文字列のリストを取得します public string[] GetNgIdList() { NTNgItems ngItem = NTNgItems.getContext(); List list = ngItem.getNgIds(); return list.ToArray(); } //設定されているNG-NAME文字列のリストを取得します public string[] GetNgNameList() { NTNgItems ngItem = NTNgItems.getContext(); List list = ngItem.getNgNames(); return list.ToArray(); } public IAmbiguousSearch CreateAmbiguousSearchInstance(string word) { NTVagueSearchWord v = new NTVagueSearchWord(word); return v; } public void SetThumbnailImage(ThumbnailImageHelper helper, string url) { Worker.RunWorker(helper, url); //BackgroundWorker worker = new BackgroundWorker(); //worker.DoWork += DoWork; //+= new DoWorkEventHandler(DoWork); //worker.RunWorkerCompleted += RunWorkerCompleted; //+= // new RunWorkerCompletedEventHandler(RunCompleted); //worker.Run(url); } public class Worker// : BackgroundWorker { static Semaphore mSemaphore; static int mConnections; public static void init(int nSemaphoreCount) { if (nSemaphoreCount <= 0) nSemaphoreCount = 1; else if (nSemaphoreCount > 20) nSemaphoreCount = 20; mConnections = nSemaphoreCount; mSemaphore = new Semaphore(nSemaphoreCount, nSemaphoreCount); } public static void resetConnectionCount(int count) { if (mConnections == count) return; init(count); } static Dictionary mFileNameLock = new Dictionary(); static object GetLock(string path) { object o; lock (mFileNameLock) { if (mFileNameLock.ContainsKey(path)) { if (mFileNameLock.TryGetValue(path, out o)) return o; } else { o = new object(); mFileNameLock.Add(path, o); } } return o; } ThumbnailImageHelper mParent; string mUrl; string mFullPath; public static void RunWorker(ThumbnailImageHelper helper, string url) { string path; string file; try { if (NtFile.NTFileUtil.Url2FilePath(url, out path, out file)) { Directory.CreateDirectory(path); Worker w = new Worker(); w.mParent = helper; w.mUrl = url; w.mFullPath = path + '\\' + file; BackgroundWorker mWorker = new BackgroundWorker(); mWorker.DoWork += worker_DoWork; mWorker.RunWorkerCompleted += worker_RunWorkerCompleted; mWorker.RunWorkerAsync(w); } } catch (DirectoryNotFoundException e) { } } static void worker_DoWork(object sender, DoWorkEventArgs e) { Worker w = e.Argument as Worker; if (w == null) return; if (w.mUrl == null) return; if (w.mFullPath == null) return; try { object objLock = GetLock(w.mFullPath); if (objLock == null) objLock = new object(); lock (objLock) { if (!File.Exists(w.mFullPath)) { WebClient wc = new WebClient(); try { mSemaphore.WaitOne(); wc.DownloadFile(new Uri(w.mUrl), w.mFullPath); } finally { mSemaphore.Release(); } wc.Dispose(); } } e.Result = w; } catch (Exception ex) { } finally { } } static void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { Worker w = e.Result as Worker; if (w == null) return; object objLock = GetLock(w.mFullPath); if (objLock == null) objLock = new object(); BitmapImage bi = new BitmapImage(); lock (objLock) { bi.BeginInit(); bi.CacheOption = BitmapCacheOption.OnDemand; bi.CreateOptions = BitmapCreateOptions.DelayCreation; bi.DecodePixelHeight = NTUserPreference.ResViewThumbnailHeight; bi.DecodePixelWidth = NTUserPreference.ResViewThumbnailWidth; bi.UriSource = new Uri(w.mFullPath, UriKind.Absolute); bi.EndInit(); } Image img = new Image(); img.Stretch = System.Windows.Media.Stretch.UniformToFill; img.Width = NTUserPreference.ResViewThumbnailWidth; img.Height = NTUserPreference.ResViewThumbnailHeight; img.Source = bi; img.MouseLeftButtonDown += img_MouseLeftButtonDown; //img.MouseLeftButtonUp += img_MouseLeftButtonUp; img.Tag = w.mFullPath; w.mParent.SetImage(img); //mParent.setImage(image); } // static Image mClickedImage; static void img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { //if (mClickedImage == null) // return; //if (!sender.Equals(mClickedImage)) //{ // mClickedImage = null; // return; //} } static void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Image img = sender as Image; if (img == null) return; string path = img.Tag as string; if (path == null) return; NTAppState.getMainWindow().AddGraphic(path); } } } }