Keep up with our latest news and site updates

Subscribe Via RSS Reader

Powered by

Mail.app에서 기본 설정으로 Gmail 계정을 입력하면 받은 편지함, 보낸 편지함, 임시 보관함, 휴지통, 스팸함 등의 메일 폴더가 링크되며, [Gmail]이라는 폴더가 생성되고 이 폴더 내에 다시 동일한 이름의 메일 폴더들이 중복으로 생성된다. 물론, 메일 역시도 중복으로 관리된다.

Gmail의 또 다른 문제는 메일 클라이언트와 Gmail의 보낸 편지함과 임시 편지함이 일치하지 않는다는 점이다.
작성 중인 메일을 저장하는 경우 보통 Draft라는 형태로 저장되는데, Gmail에서는 임시 보관함에 저장된다. 그러나, Mail.app이 저장하는 임시 보관함과 Gmail에서 관리하는 임시 보관함이 달라서 Mail.app에서 저장한 임시 보관함을 Gmail에서 마저 편집한 뒤 보낼 수가 없다. 보낸 편지함 역시 메일 클라이언트에서 작성하여 발송한 메일은 Gmail의 보낸 편지함에 저장되지 있지 않기 때문에 Gmail에서 보는 보낸 편지함의 내용과 메일 클라이언트에서의 보낸 편지함의 내용이 다르다.

마지막으로, Gmail은 전체보관함이라는 특별한 폴더가 존재하는데, 이 폴더는 스팸 메일을 제외한 모든 메일의 사본을 저장하고 있는 메일 폴더이다. 전체 보관함의 경우는 메일 관리를 잘못하여 실수로 삭제한 경우에서 복구할 수 있는 유용한 수단으로 사용할 수 있는데, Mail.app은 전체 보관함 역시 링크하기 때문에 실제로 Gmail의 메일은 총 3개의 복사본이 저장되게 된다.

이는 저장 공간의 낭비뿐만 아니라 메일을 처리하기 위한 시간 역시 3배로 소모된다는 얘기다.

이런 문제를 해결하는 방법은 의외로 간단하다. 아래 그림과 같이 ‘고급’ 탭을 선택한 뒤 ‘IMAP 경로 접두어’에 ‘[Gmail]‘을 입력하면 된다.

mail-gmail-setting.png

‘전체 보관함’도 동기화되는 문제는 해결되지 않지만, Gmail의 실험실 중 ‘고급 IMAP 기능’을 ‘사용’으로 바꾼 뒤, ‘라벨’ 관리에서 ‘전체 보관함’ 옆의 ‘IMAP에 표시’의 클릭을 지우면 메일 폴더 목록에서 ‘전체 보관함’을 제거할 수 있다.

위의 설정은 Mail.app 뿐만 아니라 다른 모든 메일 클라이언트에서도 동일하게 적용할 수 있는데, 특히 Windows의 메일 클라이언트는 Mail.app과는 달리 폴더의 동기화 설정을 각각의 폴더 마다 다르게 정의할 수 있기 때문에, ‘스팸함’이나 ‘휴지통’은 간단히 목록만 동기화하거나 ‘전체보관함’의 경우는 Gmail의 실험실 기능을 사용하지 않고도 동기화를 하지 않도록 하여 저장 공간의 낭비와 처리 시간을 줄일 수 있다.

최근에 Mail.app과 Gmail의 동작 관계를 다시 확인했습니다. 그 결과 이 글에 언급된 Gmail의 문제는 더 이상 발생하지 않습니다. 다만, 이것이 Mac OS X 10.5에 의한 것인지 Gmail에서의 IMAP 동작이 변경(개선)된 것인지는 아직 알 수 없습니다.

따라서, 위 글의 내용이 현재의 Gmail에는 유용하다 할 수는 없을 겁니다. 다만, 메일 클라이언트와 Gmail의 동작이 일치하지 않는 경우가 발견된다면 위의 내용이 여전히 도움이 될 것이라 생각합니다.

뿐만 아니라 Gmail에 ‘전체 보관함’의 동작 역시 이전과 많이 변경된 것 같습니다.
이전의 Gmail의 경우 삭제된 메일이라고 하더라도 ‘전체 보관함’에서 지워지는 경우는 없었지만 현재의 Gmail의 경우 ‘받은 편지함’, ‘보낸 편지함’에 관계없이 삭제된 메일(휴지통)은 모두 ‘전체 보관함’에서 제거됩니다.
제 Gmail 계정의 경우 스팸 메일은 ‘전체 보관함’에 저장되지 않는데, 스팸 메일과 관련한 설정으로 인한 것인지 찾아보았으나 관련 설정은 찾을 수 없었습니다.
따라서, Gmail에서 스팸으로 간주된 메일은 자동으로 ‘전체 보관함’에 저장하지 않는 것으로 생각합니다.

한 2년 뒤에나 나올 줄 알았는데, 요즘 페이스를 보니 상당히 빠르군요.
올해 내로 제품판 나올지도 모르겠네요.
 
비스타는 버려졌네 할 때마다 뭔 헛소리 라고 생각했는데, 이 정도 페이스면… 정말 버려진 듯.
어차피 기업용 라이센스는 특정 제품이 아닌 Windows, Office 이딴 식이니 업그레이드 주기가 빠르다고 해서 딱히 불만은 없겠지만…
내 피같은 비스타 패키지는 제기랄…
 
Windows7
원래는 한 참 뒤에나 나온 거라는 생각에 그냥 잊고 지내려고 했는데, 생각보다 개발 페이스가 빨라서 함 구해다가 설치해봤습니다. 기왕이면 싶어서 64bit 구해서 설치.
 
비스타에서 젤로 불편했던 탐색기는 XP와 비스타에서 절충을 했는데 2% 부족함이 있긴 하지만 비스타에서 폴더 찾기가 영 구렸던 것 보단 좀 나아졌군요. 태스크바가 많이 좋아지긴 했는데, 태스크바만 좋아지고 윈도 매니저는 전혀 변한것이 없다보니 전체적으로 40% 부족한 느낌을 지울 수가 없네요. 익스포제 같은 기능 좀 구현하면 안되나?
 
뭐랄까 혁명적으로 좋아졌다는 생각은 안 들고, 그냥 그나마 비스타가 좀 더 정리한 정도로 보이는 군요.
그래도 운영체제를 오직 윈도우만 썼던 시절이었다면 당장에 RC 버전으로 갈아탔을 텐데…

 

KTS 형태소 분석기(http://chem.skku.ac.kr/~kle/main/KTS)와 libhangul(http://kldp.net/projects/hangul)의 한글/한자어 사전을 이용한 한국어 맞춤법 검사기를 만들어 봤습니다.
image33.png
[맞춤법 검사기 개요]
이 맞춤법 검사기는 Mac OSX 플랫폼에서 KTS 형태소 분석기를 사용할 수 있는지 여부를 검토하기 위한 목적과 한글/한자어 사전을 이용해서 맞춤법 검사를 했을 경우 발생할 수 있는 문제점들을 파악하기 위한 실험이 목적입니다.

[맞춤법 검사기 실행 원리]
KTS 형태소 분석기에서 명사로 인식되는 단어가 libhangul의 한글/한자 사전에 표제어로 등재되어 있을 경우 맞춤법이 맞는 것으로 그렇지 않은 경우 맞춤법이 틀린 것으로 간주합니다. 명사이외의 단어들은 항상 맞춤법이 옳다고 가정합니다.

[향후 계획]
KTS 형태소 분석기는 완성형 코드를 사용하는 등 Mac OSX에서 사용하깅는 적합하지 않는 문제점들이 몇가지 존재합니다. 그 중 가장 큰 문제점은 KTS 형태소 분석기의 분석 결과를 항상 신뢰할 수 없다는 점입니다. 예를 들어 ‘형태소’라는 단어를 분석할 경우 ‘형태소’라는 명사가 아닌 ‘형태’+'소’로 분석합니다. 분석 패러미터를 조정하여 정확도를 높일 수 있지만, 보다 면밀한 검토가 필요할 것입니다.
향후 맞춤법 검사기는 형태소 분석기와 맞춤법 검사기의 사전을 통합하는 방향으로 진행할 것이며 기능의 개선이나 추가보다는 사전 데이터 구축을 위한 작업이 주가 될 것입니다. 사전 데이터는 라이센스에 자유롭고 보다 풍부한 어휘를 담을 수 있도록 플랫폼이나 프로그램에 묶이지 않은 독자적인 사전 데이터 구축 커뮤니티 활동이 가능하도록 지원하는 방안을 모색할 것입니다.

한국어 맞춤법 검사기를 내장 스펠러로 설치한 뒤 내장 텍스트 에디터에서 맞춤법 검사를 실행한 모습image14.png
맞춤법 검사기의 디버그 화면
image24.png

- 간단한 데이터 바인딩 방법
- BindingComplete 이벤트를 구현하여 바인딩 정보를 분석하여 바인딩 데이터를 가공하는 방법
- BindingComplete 이벤트의 호출 상황을 분석하여 바인딩이 실행되는 흐름을 파악하고, 효율적인 바인딩을 구현하는 방법

BindingComplete 이벤트 구현 예제

    TRANSFORMERBindingSource.BindingComplete +=
    	new BindingCompleteEventHandler(TRANSFORMERBindingSource_BindingComplete);
 
void TRANSFORMERBindingSource_BindingComplete (
	object sender,
	BindingCompleteEventArgs e)
{
    if ( e.BindingCompleteState == BindingCompleteState.Success
    	&& e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate )
	{
        string columnname = e.Binding.BindingMemberInfo.BindingMember;
        TransformerDataSet.TRANSFORMERRow datasource
			= (TRANSFORMERBindingSource.Current as DataRowView).Row
        	as TransformerDataSet.TRANSFORMERRow;
        string controlname = e.Binding.Control.Name;
 
        MessageBox.Show(
	        controlname + "->" + "["
	        + columnname + " / "
	        + datasource[columnname] + "]");
    }
 
    if ( e.BindingCompleteState == BindingCompleteState.Success
    	&& e.BindingCompleteContext == BindingCompleteContext.ControlUpdate
    	&& e.Binding.Control == ConnectivityNodeNameEdit2 )
	{
        string controlname = e.Binding.Control.Name;
        string columnname = e.Binding.BindingMemberInfo.BindingMember;
        BindingSource bindingsource = e.Binding.DataSource as BindingSource;
 
        if ( bindingsource != null && !(bindingsource.Position < 0) )
		{
            TransformerDataSet.TRANSFORMERRow datasource
            	= (bindingsource.Current as DataRowView).Row
            	as TransformerDataSet.TRANSFORMERRow;
            MessageBox.Show("["
            	+ columnname + "/"
            	+ datasource[columnname] + "] ->"
            	+ controlname);
        } else {
            MessageBox.Show("Invalid : " + columnname + "/" + controlname);
        }
    }
 
    if ( e.BindingCompleteState == BindingCompleteState.Success
    	&& e.BindingCompleteContext == BindingCompleteContext.ControlUpdate
    	&& e.Binding.Control == fK_CONNECTIVITYNODE2SpinEdit )
	{
        string controlname = e.Binding.Control.Name;
        string columnname = e.Binding.BindingMemberInfo.BindingMember;
        BindingSource bindingsource = e.Binding.DataSource as BindingSource;
 
        if ( bindingsource != null && !(bindingsource.Position < 0) )
        {
            TransformerDataSet.TRANSFORMERRow datasource
            	= (bindingsource.Current as DataRowView).Row
            	as TransformerDataSet.TRANSFORMERRow;
            MessageBox.Show("["
            	+ columnname + "/"
            	+ datasource[columnname] + "] ->" + controlname);
        } else {
            MessageBox.Show("Invalid : " + columnname + "/" + controlname);
        }
    }
 
    if ( e.BindingCompleteState == BindingCompleteState.Success
    	&& e.BindingCompleteContext == BindingCompleteContext.ControlUpdate
    	&& e.Binding.Control == ConnectivityNodeNameEdit1 )
	{
        string controlname = e.Binding.Control.Name;
        string columnname = e.Binding.BindingMemberInfo.BindingMember;
        BindingSource bindingsource = e.Binding.DataSource as BindingSource;
 
        if ( bindingsource != null && !(bindingsource.Position < 0) )
        {
            TransformerDataSet.TRANSFORMERRow datasource
            	= (bindingsource.Current as DataRowView).Row
            	as TransformerDataSet.TRANSFORMERRow;
            MessageBox.Show("["
            	+ columnname + "/"
            	+ datasource[columnname] + "] ->"
            	+ controlname);
        } else {
            MessageBox.Show("Invalid : " + columnname + "/" + controlname);
        }
    }
 
    if ( e.BindingCompleteState == BindingCompleteState.Success
    	&& e.BindingCompleteContext == BindingCompleteContext.ControlUpdate
    	&& e.Binding.Control == fK_CONNECTIVITYNODE1SpinEdit )
	{
        string controlname = e.Binding.Control.Name;
        string columnname = e.Binding.BindingMemberInfo.BindingMember;
        BindingSource bindingsource = e.Binding.DataSource as BindingSource;
 
        if ( bindingsource != null && !(bindingsource.Position < 0) )
        {
            TransformerDataSet.TRANSFORMERRow datasource
            	= (bindingsource.Current as DataRowView).Row
            	as TransformerDataSet.TRANSFORMERRow;
            MessageBox.Show("["
            	+ columnname + "/"
            	+ datasource[columnname] + "] ->"
            	+ controlname);
        } else {
            MessageBox.Show("Invalid : " + columnname + "/" + controlname);
        }
    }
}

현재의 웹 어플리케이션들은 과거의 웹 어플리케이션과 매우 다른 양상을 보이고 있는데, 그 중 대표적인 특징이 과거의 문서 페이지와 같은 모습을 보이던 어플리케이션들이 현재는 웬만한 리치 클라이언트 어플리케이션과 비슷한 모습을 보이고 있다는 점이다.
따라서, 이러한 웹 어플리케이션이 사용하고 있는 기술들과 그 한계를 명확하게 파악함으로써 웹 어플리케이션들이 사용자의 요구 사항을 어느정도 반영할 수 있는지 아는 것이 중요하다.
이를 위해 현재 웹 어플리케이션 구현 기술에서 언급되는 다음의 대표적인 기술들에 대해서 개괄을 해본 후 이를 통해 웹 어플리케이션이 가지는 한계점에 대해서 논해 볼 것이다.

Ajax
ajax는 항상 전체 페이지를 업데이트 해야만 했던 웹 브라우저에 부분 업데이트가 가능하도록 하는 자바 스크립트의 모음이다. ajax의 가장 두드러지는 특징은 이전 DHTML 구조에서는 볼 수 없었던 HTTPRequest 객체가 추가되었다는 점이다.
이 객체를 통해 웹 서버에 새로운 페이지에 대한 요청을 하고, DHTML과 CSS를 이용하여 부분적인 업데이트 비동기적으로 처리할 수 있도록 하여 사용자의 액션에 반응하는 웹 페이지를 구성한다는 것이 ajax의 핵심이다.

Structs
스트럿츠는 프레임 웍이다. 웹 어플리케이션 개발을 위한 아키텍처 및 배포를 설계하며, 이를 위해 아키텍처적인 관점에서는 JSP, EJB 등을 이용하여 웹 어플리케이션의 Model, View, Controller를 구성하는 프레임을 제공한다. 이는 Rails와 비교해서 생각할 수 있다.

Spring
스프링은 경량형 EJB 이다. EJB는 무겁기만 할 뿐 효용성이 낮다는 주장을 바탕으로 경량화된 컴포넌트를 제공하기 위해 개발된 것으로, EJB를 대체할 수 있기 때문에 스프링은 스트럿츠의 비지니스 로직으로 통합될 수 있다.

이상이 간단히 알아본 웹 어플리케이션에서의 자바 기술들이다.
이 뿐만 아니라 CSS는 HTML 문서의 엘러먼트들의 레이아웃을 다양성을 크게 높임으로써 DHTML을 단순한 문서를 넘어서는 사용자의 액션에 대한 반응을 리치 클라이언트 수준으로 끌어올려 준다.

스트럿츠와 스프링은 아키텍처적인 성격이 강하기 때문에 웹 2.0에서 부각된 사용자 인터페이스 적인 측면에서 논할만한 것이 별로 없다. 반면 ajax는 사용자 인터페이스에 많은 변화를 가져오게 되었는데, 웹 어플리케이션에서의 인터페이스의 한계에 대해서 논해볼 필요가 있다.
앞서 언급한바와 같이 ajax의 핵심은 서버와 비동기적인 통신을 한다는 점이며, 이를 통해서 동적으로 – 별개의 화면 전환 없이 – 페이지의 갱신이 가능하다는 점이다. 즉, 사용자의 액션에 반응한 새로운 데이터의 생성과 이 데이터에 기반한 웹 페이지의 구성을 변경할 수 있지만 기존의 웹 페이지의 컨트롤에 대한 사용자 정의는 불가능하다는 점을 인식해야 한다.
즉, 리치 클라이언트 어플리케이션에서는 일반적인 사용자 정의 컨트롤 – 기존 컨트롤의 기능을 확장하여 어플리케이션 개발자가 새로이 추가하고자 하는 기능을 위해 컨트롤의 특성을 확장하는 것 -은 웹 어플리케이션에서는 적용이 불가능하다.
따라서, 웹 어플리케이션은 기존의 어플리케이션에 비해 보다 반응적인 어플리케이션의 구현은 가능하지만, 현재의 리치 클라이언트 처럼 이미 정의되어 있는 것 이상의 유저 인터페이스 요소의 구현은 불가능하다. 따라서, 사용자의 요구가 정형화된 사용자 인터페이스 요소의 이상의 것임이 예상된다면 웹 어플리케이션은 여전히 많은 한계점을 가지고 있기 때문에 리치 클라이언트를 우선 고려해야 할 것이다.

웹 어플리케이션과 같은 보안이 요구되는 도메인 영역에 코드를 넣어 실행하는 것은 자바나 닷넷같은 객체 단위의 보안 및 인증이 필요할 것이다. 따라서, 가상 머신과 같이 무거운 객체 운영소가 요구되는 것은 당연하게 여겨질 수 있다. 객체 운영의 관점에서 보았을 때 브라우저들은 대부분 자바 스크립트를 지원하고 있다 – 물론, 보안 이슈 때문에 자바 스크립트를 비활성화시키는 것도 가능하다. 이는 스크립트를 처리하기 위한 엔진이 보안 영역안에서 구현되고 있다는 점이며, 이 영역에서 운영될 수 있는 UI 객체 요소를 추가하면 웹 브라우저에서 제공하는 단순화된 사용자 인터페이스 요소를 확장할 수 있을지도 모른다. 이러한 구현을 위하여 Firefox의 확장 기능을 이용 기존 객체를 확장하는 자바 객체 라이브러리를 구성하여 실험해보는 방안을 고려할 수 있다.

또 한가지의 방법으로는 웹 표준 중의 하나인 SVG(Scalable Vector Graphics)를 이용한 사용자 인터페이스 요소의 개발이다.

ajax, struts, spring, rails와 같은 프레임 웍 및 라이브러리로부터 생각해볼 수 있는 것은 더 이상 개발 언어 및 해당 언어에서 기본적으로 제공하는 RTL 수준만으로 어플리케이션을 개발하는 것은 현 트렌드가 아니다. 보다 높은 생산성과 안정성 등을 확보하기 위하여 집중되어야 하는 것은 해당 어플리케이션 도메인에 적합한 프레임 웍이다. 완성도 높은 완전히 구동 가능한 어플리케이션 프레임 웍과 이들 프레임 웍의 확장이 다음 세대의 어플리케이션 개발의 한 축을 담당해야 한다고 본다.
따라서, 어플리케이션의 모든 설계와 구현에는 이를 프레임 웍화하기 위한 고려가 필요하며, 프레임 웍은 기존의 완전히 동작하는 어플리케이션으로부터 뽑아낸다는 관점을 넘어서 프레임 웍의 요소를 미리 예측하고 이를 선행 구현할 수 있는 능력을 필요로 할지도 모른다.

 Page 2 of 4 « 1  2  3  4 »

Information

Encore Subtitle, Tokyo, Osaka, Kyoto, Mac, iPhone, .NET, Microsoft Windows, Programming, Journey, Tips, Useful Information, TextEdit Plugin, Detective, Universal Reader, Universal Detector, Movist, SIMBL, Delphi
© 2008 Mac and PC life stories by maidaro All Rights Reserved.
An antisocialmediallc.com variation of Projection Template from Template World