# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# Source-Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
################################################
##
## Window with all availiable tools by SN
## Copyright (c) 1999 Cygnus Solutions, Inc.
##
################################################

## Short cuts:
## edit     == editor
## classbr  == class browser
## ctree    == Class Hierarchy
## xref     == cross reference
## incbr    == include browser
## dbg      == Debug
## retr     == Retriever
## grep     == Grep
## make     == Make
#global for the hole project
itcl_class MultiWindow& {
	global sn_options sn_elix
	
	inherit Toplevel&
	
	constructor {{config ""}} {
		global sn_options
		
		Toplevel&@@constructor -class MultiWindow
		
		$this withdraw
		
		$this on_close "$this windows_close dummy"
		#don't close window by hitting Escape
		$this bind_tk <Escape> {;}
		
		sn_set_window_size $this $x $y $width $height $geometry

		#set Editor $this.nbook.nbframe.edit
		set Toolbar $this.exp
		set Statusbar $this.msg
		set Reuse $this.msg.reuse
		
		#init variables to nagivate between view points
		set view_positions(next) ""
		set view_positions(prev) ""

		#Add menu
		AddMenu

		#Add the toolbar
		AddToolbar

		#Add statusbar
		AddStatusbar
		
		set NoteBook [tixNoteBook $this.nbook \
					-ipadx 0 \
					-ipady 0]

		set NotebookFrame [$NoteBook subwidget nbframe]
		$NotebookFrame config	\
			-inactivebackground lightgray
			
		$NoteBook add edit \
			-createcmd "$this AddEditor $NoteBook edit" \
			-raisecmd "$this RaiseEditor" \
			-label [get_indep String MultiEditor] \
			-under [get_indep Pos MultiEditor] \
			-state [tool_Exists edit]
			
		$NoteBook add ctree \
			-createcmd "$this AddClassHierarchy $NoteBook ctree" \
			-raisecmd "$this RaiseClassHierarchy" \
			-image tree_image \
			-label [get_indep String MultiClassHierarchy] \
			-under [get_indep Pos MultiClassHierarchy] \
			-state [tool_Exists ctree]
			
		$NoteBook add classbr \
			-createcmd "$this AddClassBrowser $NoteBook classbr" \
			-raisecmd "$this RaiseClassBrowser" \
			-label [get_indep String MultiClass] \
			-under [get_indep Pos MultiClass] \
			-state [tool_Exists classbr]
		$NoteBook add xref \
			-createcmd "$this AddXReference $NoteBook xref" \
			-raisecmd "$this RaiseXReference" \
			-label [get_indep String MultiXRef] \
			-under [get_indep Pos MultiXRef] \
			-state [tool_Exists xref]
		$NoteBook add incbr \
			-createcmd "$this AddInclude $NoteBook incbr" \
			-raisecmd "$this RaiseInclude" \
			-label [get_indep String MultiInclude] \
			-under [get_indep Pos MultiInclude] \
			-state [tool_Exists incbr]
			
		$NoteBook add retr \
			-createcmd "$this AddRetriever $NoteBook retr" \
			-raisecmd "$this RaiseRetriever" \
			-label [get_indep String MultiRetriever] \
			-under [get_indep Pos MultiRetriever] \
			-state [tool_Exists retr]
			
		$NoteBook add grep \
			-createcmd "$this AddGrep $NoteBook grep" \
			-raisecmd "$this RaiseGrep" \
			-label [get_indep String MultiGrep] \
			-under [get_indep Pos MultiGrep] \
			-state [tool_Exists grep]
		
		pack $NoteBook -fill both -side left -expand y -anchor nw

		$NoteBook raise $raise
		
		#call user function
		catch {sn_rc_mainwindow $this $this.menu}
		update idletasks
		after idle "$this deiconify"
	}
	destructor {
		foreach v [@@info globals "$this-*"] {
			catch {uplevel #0 unset $v}
		}
	}
	
	protected Activate_executed 0
	
	#activate different notebook page:
	#save filter options for the actual tool and
	#restore those for the activated tool (notebook page)
	method Activate {page paned pane tool} {
		global Switch_Is_Enabled
		
		upvar #0 $SymbolsFilter-related related
		upvar #0 $tool-related toolrel
		
		incr Activate_executed
		
		set old_view $ActiveWidget
		
		#save related for now active tool
		if {$ActiveWidget != ""} {
			upvar #0 $ActiveWidget-related rel
			@@set rel $related
			
			#dump current position
			history_stack_add_point $ActiveWidget
		}
		#save filter flags for the active widget (radios and checkbuttons)
		foreach btn [eval list $AllFilterOptions(radio) $AllFilterOptions(checkbutton)]	{
			set variable [$btn cget -variable]
			upvar #0 $variable value
			upvar #0 $ActiveWidget-Filter($btn) var
			@@set var $value
		}
		
		#get selection from current tool, only when keep
		#is seted or the global variable to disable switching
		#is on
		upvar #0 $Statusbar-keep keep
		if {$keep && $Switch_Is_Enabled > 0 && $ActiveWidget != ""} {
			set sel [$ActiveWidget Selection]
		} else {
			set sel ""
		}
		
		
		#deactivate current notepad
		catch {$ActiveWidget deactivate}
		
		#hide editor buttons, we must hide it first,
		#to enable the icons of the next view as first
		#and if an editor is availiable we put the toolbar
		#buttons on the far right side of the toolbar
		if {[$tool whoami] != "edit"} {
			pack forget $FindEditFr
		}

		#restore the information about related
		if {[catch	{@@set related $toolrel}]} {
			if {[$tool whoami] == "edit"} {
				@@set related 1
			} else {
				@@set related 0
			}
		}
		
		set ActiveWidget $tool
		set ActivePage   $page
		set ActivePaned  $paned
		set ActivePane   $pane
		
		#restore the values of the filter checkbuttons and radios
		foreach btn [eval list $AllFilterOptions(radio) $AllFilterOptions(checkbutton)] {
			catch {
				set variable [$btn cget -variable]
				upvar #0 $variable var
				upvar #0 $ActiveWidget-Filter($btn) value
				@@set var $value
			}
		}
		
		$SymbolCombo selecttext ""
		
		$ActiveWidget activate
		#if there is a selection, goto it
		if {$sel != ""} {
			@@eval $ActiveWidget gotosymbol $sel 0
		}
		$ActiveWidget SetTitle
		$ActiveWidget Focus
		
		#verify if we have an editor to display the toolbar
		#icons
		DeActivate_Editor_buttons
		
		#call user function
		catch {sn_rc_changeview $this $ActiveWidget $old_view}
	}
	
	#View toolbar buttons for the editor, if an editor is
	#availiable
	method DeActivate_Editor_buttons {} {
		if {[list_find_editor $ActiveWidget] != ""} {
			pack $FindEditFr -side left
		} else {
			pack forget $FindEditFr
		}
	}
	#####################################################
	# create editor
	#####################################################
	method AddEditor {nb page} {
		global sn_options
		
		set EditorPage  [$nb subwidget $page]
		$EditorPage	config -bg white
		set EditorPaned [tixPanedWindow $EditorPage.paned \
				     -paneborderwidth 0 \
				     -orientation \
				     $sn_options(def,window-alighment)]
		set EditorPane  [$EditorPaned add edit -size 500]
		set Editor      $EditorPane.edit
		
		Editor& $Editor \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu $EditorMenu \
			-toolbar "" \
			-mesg_area $this.msg \
			-mesg_linenumber $this.linenum \
			-filename $symbolname \
			-findcombo $FindCombo
		pack $Editor -fill both -expand y
		pack $EditorPaned -fill both -expand y
		
		lappend AvailTools $Editor
	}
	method RaiseEditor {} {
		Activate $EditorPage $EditorPaned $EditorPane $Editor
	}

	#####################################################
	# Class hierarchy
	#####################################################
	method AddClassHierarchy {nb page} {
		global sn_options
		set ClassHierarchyPage  [$nb subwidget $page]
		set ClassHierarchyPaned [tixPanedWindow $ClassHierarchyPage.paned \
									-paneborderwidth 0 \
									-orientation $sn_options(def,window-alighment)]
		set ClassHierarchyPane  [$ClassHierarchyPaned add ctree]
		set ClassHierarchy      $ClassHierarchyPane.ctree
		
		ClassTree& $ClassHierarchy \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu $ClassHierarchyMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg \
			-doubleclickcommand "$this ClassHierarchyEdit"
			# "$this EditObject"
			#-classname $symbolname \
			#"$this ClassHierarchyEdit"
		pack $ClassHierarchy -fill both -expand y
		pack $ClassHierarchyPaned -fill both -expand y
		
		lappend AvailTools $ClassHierarchy
	}
	method RaiseClassHierarchy {} {
		Activate $ClassHierarchyPage $ClassHierarchyPaned $ClassHierarchyPane $ClassHierarchy
	}
	method ClassHierarchyEdit {{scope ""} {sym ""} {cls ""} {file ""} {from ""} {type ""} {prm ""} {to ""} {always 1}} {
		sn_retrieve_symbol $sym $scope
	}

	#####################################################
	# Class Browser
	#####################################################
	method AddClassBrowser {nb page} {
		global sn_options
		set ClassBrowserPage  [$nb subwidget $page]
		set ClassBrowserPaned [tixPanedWindow \
					   $ClassBrowserPage.paned \
					   -paneborderwidth 0 \
					   -orientation $sn_options(def,window-alighment)]
		set ClassBrowserPane  [$ClassBrowserPaned add classbr]
		set ClassBrowser      $ClassBrowserPane.classbr
		
		Class& $ClassBrowser \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu $ClassBrowserMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg \
			-class_doubleclickcommand "$this ClassBrowserEditClass" \
			-doubleclickcommand "$this EditObject"
		#-classname $symbolname
		pack $ClassBrowser -fill both -expand y
		pack $ClassBrowserPaned -fill both -expand y
		
		lappend AvailTools $ClassBrowser
	}
	method RaiseClassBrowser {} {
		Activate $ClassBrowserPage $ClassBrowserPaned $ClassBrowserPane $ClassBrowser
	}
	method ClassBrowserEditClass {class} {
		sn_retrieve_symbol $class "cl" "" -beg 1 1
	}
	method EditObject {{scope ""} {sym ""} {cls ""} {file ""} {from ""} {type ""} {prm ""} {to ""} {always 1}} {
		global sn_sep
		
		#to look in the database, use sn_sep
		set lbl [string trim "$cls$sn_sep$sym" " \t$sn_sep"]
		
		if {$lbl == "" && $file == ""} {
			bell; return
		}

		#we must try to find the correct symbol, so we have to
		#accept the parameter list also.
		set cnt [read_matched_from_db "" \
						$scope \
						-exact \
						$lbl \
						$type \
						$prm \
						$file \
						$from \
						$to \
						0]
		if {$cnt == "" && $file == ""} {
			set cnt [read_matched_from_db "" $scope -exact $lbl]
		}
		if {$cnt != ""} {
			set file [lindex [split [lindex $cnt 0] \t] 4]
			set from [lindex [split [lindex $cnt 0] \t] 5]
		}
		if {$file != ""} {
			#use blank as separator
			set lbl [string trim "$cls $sym"]
			sn_edit_file [list 0 $lbl $scope] $file $from 1
		} else {
			bell; return
		}
	}

	#####################################################
	# X reference
	#####################################################
	method AddXReference {nb page} {
		global sn_options
		set XReferencePage  [$nb subwidget $page]
		set XReferencePaned [tixPanedWindow $XReferencePage.paned \
							-paneborderwidth 0 \
							-orientation $sn_options(def,window-alighment)]
		set XReferencePane  [$XReferencePaned add xref]
		set XReference      $XReferencePane.xref
		
		XRef& $XReference \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu $XReferenceMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg \
			-doubleclickcommand "$this EditObject"
			#"$XReference XRefEdit"
		pack $XReference -fill both -expand y
		pack $XReferencePaned -fill both -expand y
		
		lappend AvailTools $XReference
	}
	method RaiseXReference {} {
		Activate $XReferencePage $XReferencePaned $XReferencePane $XReference
	}
	
	#####################################################
	# Include
	#####################################################
	method AddInclude {nb page} {
		global sn_options
		set IncludePage  [$nb subwidget $page]
		set IncludePaned [tixPanedWindow $IncludePage.paned \
							-paneborderwidth 0 \
							-orientation $sn_options(def,window-alighment)]
		set IncludePane  [$IncludePaned add inc]
		set Include      $IncludePane.incbr
		
		Include& $Include \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu $IncludeMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg
		pack $Include -fill both -expand y
		pack $IncludePaned -fill both -expand y
		
		lappend AvailTools $Include
	}
	method RaiseInclude {} {
		Activate $IncludePage $IncludePaned $IncludePane $Include
	}

	#####################################################
	# Retriever
	#####################################################
	method AddRetriever {nb page} {
		global sn_options
		set RetrieverPage  [$nb subwidget $page]
		set RetrieverPaned [tixPanedWindow $RetrieverPage.paned \
							-paneborderwidth 0 \
							-orientation $sn_options(def,window-alighment)]
		set RetrieverPane  [$RetrieverPaned add retr]
		set Retriever      $RetrieverPane.retr
		
		Retr& $Retriever \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu RetrieverMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg
		pack $Retriever -fill both -expand y
		pack $RetrieverPaned -fill both -expand y
		
		lappend AvailTools $Retriever
	}
	method RaiseRetriever {} {
		Activate $RetrieverPage $RetrieverPaned $RetrieverPane $Retriever
	}
	method retr {} {
		return $Retriever
	}

	#####################################################
	# Grep
	#####################################################
	method AddGrep {nb page} {
		global sn_options
		set GrepPage  [$nb subwidget $page]
		set GrepPaned [tixPanedWindow $GrepPage.paned \
						-paneborderwidth 0 \
						-orientation $sn_options(def,window-alighment)]
		set GrepPane  [$GrepPaned add grep]
		set Grep      $GrepPane.grep
		
		Grep& $Grep \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu GrepMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg
		pack $Grep -fill both -expand y
		pack $GrepPaned -fill both -expand y
		
		lappend AvailTools $Grep
	}
	method RaiseGrep {} {
		Activate $GrepPage $GrepPaned $GrepPane $Grep
	}

	#####################################################
	# Make
	#####################################################
	method AddMake {nb page} {
		global sn_options
		set MakePage  [$nb subwidget $page]
		set MakePaned [tixPanedWindow $MakePage.paned \
							-paneborderwidth 0 \
							-orientation $sn_options(def,window-alighment)]
		set MakePane  [$MakePaned add make]
		set Make      $MakePane.make
		
		Make& $Make \
			-symbols $Toolbar.where \
			-symbols_filter $SymbolsFilter \
			-menu MakeMenu \
			-toolbar $Toolbar \
			-mesg_area $this.msg
		pack $Make -fill both -expand y
		pack $MakePaned -fill both -expand y
		
		lappend AvailTools $Make
	}
	method RaiseMake {} {
		Activate $MakePage $MakePaned $MakePane $Make
	}

	method AddMenu {} {
		global sn_options
		
		set m $this.menu
	
		set state normal
	
		menu $m -tearoff 0
	
		## File menu
		####################
		menu $m.file \
			-tearoff 0 \
			-postcommand "$this file_post $m.file"

		$m.file config -font $sn_options(def,layout-font)

		$m add cascade \
			-label [get_indep String EditFile] \
			-menu $m.file \
			-underline [get_indep Pos EditFile]
	
		$m.file add command \
			-label [get_indep String EditNewFile] \
			-underline [get_indep Pos EditNewFile] \
			-accelerator "Ctrl+N" \
			-command "$this file_new"

		$m.file add command \
			-label [get_indep String Open] \
			-underline [get_indep Pos Open]\
			-accelerator "Ctrl+O" \
			-command "$this file_open"

		$m.file add separator
		
		#Add project menu
		AddProjectMenuEntries $m.file $this 1
		
		$m.file add separator
		
		#File commands
		$m.file add command -accelerator "Ctrl+S"\
			-label [get_indep String EditSave]\
			-underline [get_indep Pos EditSave]\
			-command "watch y $this; $this file_save; watch n $this"

		$m.file add command \
			-label [get_indep String EditSaveFileAs] \
			-underline [get_indep Pos EditSaveFileAs]\
			-command "$this file_saveas"

		$m.file add command \
			-accelerator "$sn_options(sys,alt-accelpref)+S"\
			-label [get_indep String EditFastSave]\
			-underline [get_indep Pos EditFastSave]\
			-command "watch y $this; $this file_fastsave; watch n $this"

		$m.file add command \
			-accelerator "$sn_options(sys,alt-accelpref)+A"\
			-label [get_indep String EditSaveAll]\
			-underline [get_indep Pos EditSaveAll]\
			-command "watch y $this; $this file_saveall; watch n $this"

		$m.file add command \
			-label [get_indep String Revert] \
			-underline [get_indep Pos Revert] \
			-command "$this file_revert"
			
		$m.file add separator
		
		$m.file add command \
			-label [get_indep String Print] \
			-accelerator "Ctrl+P" \
			-underline [get_indep Pos Print] \
			-command "$this file_print"

		$m.file add separator
		
		#close window
		$m.file add command \
			-command "$this windows_close $m.file" \
			-label [get_indep String WindowsClose] \
			-accelerator "Ctrl+W" \
			-underline [get_indep Pos WindowsClose]
			
		$m.file add command \
			-label [get_indep String Exit] \
			-underline [get_indep Pos Exit]\
			-accelerator "Ctrl+Q" \
			-command "sn_exit"
			
		## Edit menu
		############
		menu $m.edit \
			-tearoff 0 \
			-postcommand "$this edit_post $m.edit"

		$m.edit config -font $sn_options(def,layout-font)

		$m add cascade \
			-label [get_indep String EditEdit] \
			-menu $m.edit \
			-underline [get_indep Pos EditEdit]

		$m.edit add command \
			-label [get_indep String EditUndo] \
			-underline [get_indep Pos EditUndo] -accelerator "Ctrl+Z" \
			-command "$this edit_undo" \
			-state $state

		$m.edit add command \
			-label [get_indep String EditRedo] \
			-underline [get_indep Pos EditRedo] -accelerator "Ctrl+Y" \
			-command "$this edit_redo" \
			-state $state

		$m.edit add separator
		
		$m.edit add command \
			-label [get_indep String EditCut]\
			-underline [get_indep Pos EditCut] -accelerator "Ctrl+X"\
			-command "$this edit_cut" \
			-state $state

		$m.edit add command \
			-label [get_indep String EditCopy] \
			-underline [get_indep Pos EditCopy]\
			-accelerator "Ctrl+C" \
			-command "$this edit_copy"

		$m.edit add command \
			-label [get_indep String EditPaste] \
			-underline [get_indep Pos EditPaste] \
			-accelerator "Ctrl+V" \
			-state $state \
			-command "$this edit_paste"

		$m.edit add command \
			-label [get_indep String EditDelete] \
			-underline [get_indep Pos EditDelete] \
			-accelerator "Ctrl+D" \
			-command "$this edit_delete" \
			-state $state

		$m.edit add command \
			-label [get_indep String SelectAll]\
			-underline [get_indep Pos SelectAll]\
			-command "$this edit_selectall"

		$m.edit add command \
			-label [get_indep String EditClear] \
			-underline [get_indep Pos EditClear] \
			-command "$this edit_clear" \
			-state $state

		$m.edit add separator
		
		$m.edit add command \
			-label [get_indep String EditInsertFile]\
			-underline [get_indep Pos EditInsertFile]\
			-command "$this edit_insert"
			
		$m.edit add separator

		$m.edit add command \
			-label [get_indep String EditIdent]\
			-underline [get_indep Pos EditIdent]\
			-accelerator "Ctrl+>" \
			-command "watch y $this; $this edit_indent indent; watch n $this"

		$m.edit add command \
			-label [get_indep String EditOutdent] \
			-underline [get_indep Pos EditOutdent] \
			-accelerator "Ctrl+<" \
			-command "watch y $this; $this edit_indent outdent; watch n $this"

		$m.edit add separator
		#$m.edit add command \
			-label [get_indep String ProjectPreferencesMenu] \
			-underline [get_indep Pos ProjectPreferencesMenu] \
			-command "MultiWindow& @@ edit_proj_preferences 0"

		$m.edit add command \
			-label [get_indep String EditPreferences] \
			-underline [get_indep Pos EditPreferences] \
			-command "$this edit_preferences 0"
			
		#Search menu
		menu $m.search \
			-tearoff 0 \
			-postcommand "$this search_post $m.search"

		$m.search config -font $sn_options(def,layout-font)

		$m add cascade \
			-label [get_indep String Search]\
			-underline [get_indep Pos Search] \
			-menu $m.search

		$m.search add command \
			-label	[get_indep String SearchFind]\
			-underline [get_indep Pos SearchFind]\
			-accelerator "Ctrl+F" \
			-command "$this search_findtext"

		$m.search add command \
			-label [get_indep String SearchNext] \
			-underline [get_indep Pos SearchNext] \
			-accelerator "F3"\
			-command "$this search_next"

		$m.search add command \
			-label [get_indep String SearchPrev] \
			-underline [get_indep Pos SearchPrev] \
			-accelerator "Shift+F3"\
			-command "$this search_prev"

		$m.search add command \
			-label [get_indep String SearchReplace] \
			-underline [get_indep Pos SearchReplace] \
			-command "$this search_replace" \
			-state $state

		$m.search add separator
		
		$m.search add command \
			-accelerator "$sn_options(sys,alt-accelpref)+D" \
			-label [get_indep String SearchDefinition] \
			-underline [get_indep Pos SearchDefinition] \
			-command "$this search_definition" \
			-state $state

		$m.search add command \
			-accelerator "$sn_options(sys,alt-accelpref)+I" \
			-label [get_indep String SearchImplementation] \
			-underline [get_indep Pos SearchImplementation] \
			-command "$this search_implementation" \
			-state $state

		$m.search add separator

		$m.search add command \
			-accelerator "Ctrl+Shift+G" \
			-label [get_indep String SearchGrep] \
			-underline [get_indep Pos SearchGrep] \
			-command "$this search_grep"

		$m.search add separator
		
		#Add a separate Goto sub menu
		set goto $m.search.goto
		menu $goto \
			-tearoff 0 \
			-postcommand "$this search_goto_post $goto"

		$m.search add cascade \
			-label [get_indep String Goto]\
			-underline [get_indep Pos Goto] \
			-menu $goto

		$goto add command \
			-label [get_indep String SearchGotoLine] \
			-underline [get_indep Pos SearchGotoLine] \
			-accelerator "Ctrl+G" \
			-command "$this search_gotoline"

		$goto add separator
		
		$goto add command \
			-label [get_indep String SearchSetMark] \
			-underline [get_indep Pos SearchSetMark] \
			-accelerator "Ctrl+Space"\
			-command "$this search_setmark"

		$goto add command \
			-label [get_indep String SearchGotoMark] \
			-underline [get_indep Pos SearchGotoMark] \
			-accelerator "Ctrl+M" \
			-command "$this search_gotomark"
		$goto add command \
			-label [get_indep String SearchGotoError] \
			-underline [get_indep Pos SearchGotoError] \
			-accelerator "Shift+Ctrl+E" \
			-command "MultiWindow& @@ search_gotoerror"
			
		## Tools menu column
		menu $m.tools \
			-tearoff 0 \
			-postcommand "$this tools_post $m.tools"
 
		$m.tools config -font $sn_options(def,layout-font)
			
		$m add cascade \
			-label [get_indep String Tools] \
			-menu $m.tools \
			-underline [get_indep Pos Tools]
		
		############################################################
		## Editor
		############################################################
		
		############################################################
		## Class Hierarchy
		############################################################
		set ctree $m.tools.ctree
		menu $ctree \
			-tearoff 0 \
			-postcommand "$this tools_ctree_post $ctree"
			
		$m.tools add cascade \
			-label [get_indep String MultiClassHierarchy] \
			-menu $ctree \
			-underline [get_indep Pos MultiClassHierarchy] \
			-state disabled
		set ClassHierarchyMenu $ctree

		############################################################
		## Class Browser
		############################################################
		set ctree $m.tools.classbr
		menu $ctree \
			-tearoff 0 \
			-postcommand "$this tools_classbr_post $ctree"
			
		$m.tools add cascade \
			-label [get_indep String MultiClass] \
			-menu $ctree \
			-underline [get_indep Pos MultiClass] \
			-state disabled
		set ClassBrowserMenu $ctree
			
		############################################################
		## Cross reference
		############################################################
		set ctree $m.tools.xref
		menu $ctree \
			-tearoff 0 \
			-postcommand "$this tools_xref_post $ctree"
			
		$m.tools add cascade \
			-label [get_indep String MultiXRef] \
			-menu $ctree \
			-underline [get_indep Pos MultiXRef] \
			-state disabled
		set XReferenceMenu $ctree

		############################################################
		## Include
		############################################################
		set ctree $m.tools.incbr
		menu $ctree \
			-tearoff 0 \
			-postcommand "$this tools_incbr_post $ctree"
			
		$m.tools add cascade \
			-label [get_indep String MultiInclude] \
			-menu $ctree \
			-underline [get_indep Pos MultiInclude] \
			-state disabled
		set IncludeMenu $ctree
		
		$m.tools add separator
			
		## Miscellaneous Tools and IDE features
		AddMiscSubMenu $m.tools

		## Revision control		
		$m.tools add separator

		set mk $m.tools.rcs

		menu $mk \
			-tearoff 0

		$m.tools add cascade \
			-label [get_indep String RCS] \
			-underline [get_indep Pos RCS] \
			-state $state \
			-menu $mk

		$mk config -font $sn_options(def,layout-font)

		$mk add command \
			-label [get_indep String ChooseCheckOut]\
			-underline [get_indep Pos ChooseCheckOut]\
			-command "$this Handle_Rcs sn_rcs_checkout"
		$mk add command \
			-label [get_indep String ChooseCheckIn]\
			-underline [get_indep Pos ChooseCheckIn]\
			-command "$this Handle_Rcs sn_rcs_checkin"
		$mk add command \
			-label [get_indep String ChooseDiscard] \
			-underline [get_indep Pos ChooseDiscard] \
			-command "$this Handle_Rcs sn_rcs_discard"
		$mk add command \
			-label [get_indep String ChooseLock] \
			-underline [get_indep Pos ChooseLock] \
			-command "$this Handle_Rcs sn_rcs_lockunlockdel lock"
		$mk add command \
			-label [get_indep String ChooseUnlock] \
			-underline [get_indep Pos ChooseUnlock] \
			-command "$this Handle_Rcs sn_rcs_lockunlockdel unlock"
		$mk add separator
		$mk add command \
			-label [get_indep String ChooseDiff] \
			-underline [get_indep Pos ChooseDiff] \
			-command "$this Handle_Rcs \{sn_rcs_diff $this\}"
		#revision control editor
		$mk add separator
		$mk add command \
			-label [get_indep String RevisionControlEditor] \
			-underline [get_indep Pos RevisionControlEditor] \
			-command "sn_revision_ctrl"

		## History
		AddHistMenu $m

		##Windows
		AddWindowsMenu $m $this 1 1
		
		##Help menu
		AddHelpMenu $m $this
		
		$this config -menu $m
	}
	
	method AddToolbar {} {
		set m $this.menu
		set exp $this.exp
		
		frame $exp \
				-takefocus 0 \
				-relief groove \
				-border 2

		#prev/next buttons
		button $exp.prev \
				-image prev_image \
				-takefocus 0 \
				-command "$this history_stack_goto_point prev"
		bind $exp.prev <3> "$this toolbar_post_history_stack prev $exp.prev"
		balloon_bind_info $exp.prev [get_indep String GotoPrevPosition]
		pack $exp.prev -side left
		
		button $exp.next \
				-image next2_image \
				-takefocus 0 \
				-command "$this history_stack_goto_point next"
		bind $exp.next <3> "$this toolbar_post_history_stack next $exp.next"
		balloon_bind_info $exp.next [get_indep String GotoNextPosition]
		pack $exp.next -side left
		
		history_stack_control_buttons
		
		#combobox for the file symbols
		set SymbolCombo $exp.where
		Combo& $SymbolCombo \
				-withframe n \
				-width 26 \
				-entryballoon  [get_indep String ActiveSymbol] \
				-buttonballoon [get_indep String ListRelatedSymbols] \
				-selectcommand "$this toolbar_display_selected $SymbolCombo"
		pack $exp.where -side left -fill x -padx 2
		
		Add_Symbol_Filter $exp
		
		#add/create editor command buttons
		Add_Editor_Buttons $exp
		
		pack $exp -side top -fill x
	}
	
	method Add_Symbol_Filter {exp} {
		global combobox_editor_scopes
		
		#Add symbols filter to the right side of the combobox
		set SymbolsMenu [$exp.where mnu]
		set opt [$exp.where mnu].symfilter
		set SymbolsFilter $opt
		$exp.where config \
			-postcommand "$this toolbar_post_scope_menu $opt" \
			-postentrycommand "$this toolbar_post_scope_menu $opt"
			
		if {[winfo exists $opt]} {
			destroy $opt
		}
			
		frame $opt
		#Radiobuttons (Related,All)
		uplevel #0 "set $opt-related 1"
		radiobutton $opt.related \
				-anchor w \
				-text [get_indep String Related] \
				-command "$this toolbar_symbols $SymbolsMenu" \
				-variable $opt-related \
				-value 1
		pack $opt.related -side top -fill x -expand y
		lappend AllFilterOptions(radio) $opt.related
		radiobutton $opt.all \
				-anchor w \
				-text [get_indep String All] \
				-command "$this toolbar_symbols $SymbolsMenu" \
				-variable $opt-related \
				-value 0
		pack $opt.all -side top -fill x -expand y
		lappend AllFilterOptions(radio) $opt.all
		
		#Buttons (All,None)
		frame $opt.btns
		button $opt.btns.all \
			-anchor w \
			-text [get_indep String All] \
			-command "$this toolbar_symbols $SymbolsMenu 1"
		pack $opt.btns.all -side left -fill x -expand y
		lappend AllFilterOptions(button) $opt.btns.all
		
		button $opt.btns.none \
			-anchor w \
			-text [get_indep String None]\
			-command "$this toolbar_symbols $SymbolsMenu -1"
		pack $opt.btns.none -side right -fill x -expand y
		lappend AllFilterOptions(button) $opt.btns.none
		
		pack $opt.btns -side top -fill x -expand y
		
		#Filter options (cl,com,fd,fu,...)
		foreach sc [lsort [array names combobox_editor_scopes]] {
			uplevel #0 "set $opt-$sc $sc"
			checkbutton $opt.$sc \
				-anchor w \
				-text [convert_scope_to_str $sc] \
				-command "$this toolbar_symbols $SymbolsMenu" \
				-variable $opt-$sc \
				-onvalue $sc \
				-offvalue "off"
			pack $opt.$sc -side top -fill x -expand y
			lappend AllFilterOptions(checkbutton) $opt.$sc
		}
		#Add checkbutton for undefined symbols (xref only)
		checkbutton $opt.ud \
			-anchor w \
			-text [convert_scope_to_str ud] \
			-command "$this toolbar_symbols $SymbolsMenu" \
			-variable $opt-ud \
			-onvalue ud \
			-offvalue off
		lappend AllFilterOptions(checkbutton) $opt.ud
		pack $opt.ud -side top -fill x -expand y
		
		pack $opt -side left -fill y -expand y
		$exp.where config -extended $opt
	}
	
	#add editor commands
	method Add_Editor_Buttons {exp} {
		global sn_options
		global tcl_platform
		
		set FindEditFr $exp.editfr
		pack [frame $FindEditFr] -fill x
		pack [frame $FindEditFr.grap1 -width 5] -side left
		
		#add new/open/save/print/copy/paste/undo
		if {$sn_options(def,edit-more-buttons)} {
			button $FindEditFr.new \
				-takefocus 0 \
				-image new_image\
				-command "$this file_new"
			balloon_bind_info $FindEditFr.new [get_indep String NewFileINFO]
			pack $FindEditFr.new -side left
			
			button $FindEditFr.open -image open_image\
				-takefocus 0 \
				-command "$this file_open"
			balloon_bind_info $FindEditFr.open [get_indep String EINFOOpenFile]
			pack $FindEditFr.open -side left
		
			#save
			button $FindEditFr.save -image save_image\
				-takefocus 0 \
				-command "$this file_save"
			balloon_bind_info $FindEditFr.save [get_indep String EINFOSaveChanges]
			pack $FindEditFr.save -side left
		
			if {$tcl_platform(platform) != "windows"} {
				button $FindEditFr.print \
					-takefocus 0 \
					-image print_image\
					-command "$this file_print"
				balloon_bind_info $FindEditFr.print [get_indep String PrintFile]
				pack $FindEditFr.print -side left
			}
			
			#undo
			button $FindEditFr.undo \
				-takefocus 0 \
				-image undo_image \
				-command "$this edit_undo"
			balloon_bind_info $FindEditFr.undo [get_indep String EditUndoINFO]
			pack $FindEditFr.undo -side left
		
			#delete
			button $FindEditFr.delete \
				-takefocus 0 \
				-image waste_image \
				-command "$this edit_delete"
			balloon_bind_info $FindEditFr.delete [get_indep String EINFODeleteSection]
			pack $FindEditFr.delete -side left
		
			#cut
			button $FindEditFr.cut \
				-takefocus 0 \
				-image cut_image\
				-command "$this edit_cut"
			balloon_bind_info $FindEditFr.cut [get_indep String EINFOCutSelection]
			pack $FindEditFr.cut -side left
		
			#copy
			button $FindEditFr.copy \
				-takefocus 0 \
				-image copy_image\
				-command "$this edit_copy"
			balloon_bind_info $FindEditFr.copy [get_indep String EINFOCopySelection]
			pack $FindEditFr.copy -side left
		
			#paste
			button $FindEditFr.paste \
				-takefocus 0 \
				-image paste_image\
				-command "$this edit_paste"
			balloon_bind_info $FindEditFr.paste [get_indep String EINFOPasteSelection]
			pack $FindEditFr.paste -side left
			
			#compile
			button $FindEditFr.compile \
				-takefocus 0 \
				-image compile_image\
				-command "$this do_compile_file"
			balloon_bind_info $FindEditFr.compile [get_indep String CompileINFO]
			pack $FindEditFr.compile -side left
			
		}
		
		#combobox for the find command, do not use filter
		Combo& $FindEditFr.find_hist \
				-width 16 \
				-sort "" \
				-filter "" \
				-readonly 0 \
				-entryballoon  [get_indep String EINFOEnterPattern] \
				-buttonballoon [get_indep String EINFOSearchHistory] \
				-selectcommand "$this toolbar_findtext $FindEditFr.find_hist" \
				-postcommand   "$this toolbar_findtext_postcommand $FindEditFr.find_hist"
		set FindCombo $FindEditFr.find_hist
		bind $FindEditFr.find_hist.entry <Control-f> [bind $FindEditFr.find_hist.entry <Return>]
		bind $FindEditFr.find_hist.entry <F3> [bind $FindEditFr.find_hist.entry <Return>]
		pack $FindEditFr.find_hist -side left
		#button to find next/selected entry
		button $FindEditFr.find \
			-takefocus 0 \
			-image find_image\
			-command "$this toolbar_search_pattern"
		balloon_bind_info $FindEditFr.find [get_indep String SearchFindSelectionINFO]
		pack $FindEditFr.find -side left

		#some free space
		pack [frame $FindEditFr.gap -width 5] -side left
		#Retriever
		button $FindEditFr.definition \
			-takefocus 0 \
			-image search_image \
			-command "$this toolbar_retriever"
		bind_history $FindEditFr.definition retrieve
		balloon_bind_info $FindEditFr.definition [get_indep String RetrieverINFO]
		pack $FindEditFr.definition -side left

		#Grep
		button $FindEditFr.grep \
			-takefocus 0 \
			-image grep_image \
			-command "$this toolbar_grep"
		bind_history $FindEditFr.grep grep
		balloon_bind_info $FindEditFr.grep [get_indep String INFOGrep]
		pack $FindEditFr.grep -side left
		
		#some free space
		pack [frame $FindEditFr.gap2 -width 5] -side left
	}
	
	method AddStatusbar {} {
		global sn_options
		global $Statusbar.reusable
		if {![@@info exists $Statusbar.reusable]} {
			uplevel #0 "set $Statusbar.reusable 1"
		}
		frame $Statusbar
		#use the option flag
		checkbutton $Reuse \
				-relief groove\
				-text [get_indep String Reuse] \
				-variable $Statusbar.reusable \
				-font $sn_options(def,layout-font)
		balloon_bind_info $Reuse [get_indep String ReusableINFO]
		pack $Reuse -side left
		uplevel #0 "set $Statusbar.reusable \$sn_options(def,reuse-window)"

		set Keep $Statusbar.keep
		uplevel #0 "set $Statusbar-keep \$sn_options(def,window-switchable)"
		checkbutton $Keep \
				-relief groove\
				-text [get_indep String Keep] \
				-variable $Statusbar-keep \
				-font $sn_options(def,layout-font)
		balloon_bind_info $Keep [get_indep String KeepINFO]
		pack $Keep -side left

		pack [label $Statusbar.linenum \
			-font $sn_options(def,layout-font) \
			-relief groove \
			-bd 2 \
			-anchor e \
			-width 8 \
			-textvar $this.linenum] -fill y -side left
		pack [label $Statusbar.msg \
			-font $sn_options(def,layout-font) \
			-relief groove \
			-bd 2 \
			-anchor w \
			-textvar $this.msg] -expand y -fill both -side left
		pack $Statusbar -side bottom -fill x
	}
	
	method file_post {m} {
		global sn_options
		global prj_lines_num
		
		#call post command for project menus
		ProjectMenuEntries_post $m "" .prjsub
		
		set fast_state normal
		set new_state normal
		
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			set state		disabled
			set save_state	disabled
			set fast_state	disabled
			set rev_state	disabled
		} else {
			set state normal
			if {[$ed cget -file_changed]} {
				set save_state normal
			} else {
				set save_state disabled
				set fast_state disabled
			}
			#no revert for new files
			if {[$ed cget -filename] == $sn_options(noname_file)} {
				set rev_state disabled
			} else {
				set rev_state $state
			}
		}
		
		#normal save is only possible, when no process is
		#running
		if {$save_state == "normal" && [sn_processes_running]} {
			set save_state disabled
		}
		
		#we can't create/open files by readonly-project
		if {$sn_options(readonly)} {
			set new_state "disabled"
		}
				
		#file commands
		$m entryconfig [get_indep String EditNewFile]    -state $new_state
		$m entryconfig [get_indep String Open]           -state $new_state
		$m entryconfig [get_indep String EditSave]       -state $save_state
		$m entryconfig [get_indep String EditSaveFileAs] -state $state
		$m entryconfig [get_indep String EditFastSave]   -state $fast_state
		$m entryconfig [get_indep String Revert]         -state $rev_state
	}
	
	proc post_recent_project {m topm pm} {
		#get file menu widget name
		set event_window [lmatch [winfo children $topm] {*#menu}]
		set child [lindex [winfo children $event_window] 0]
		
		#Add menu entries for project history
		return [update_project_menu_list $m $pm]
	}

	proc update_project_menu_list {menu event_window} {
		global sn_options
		global sn_projects_list
	
		set pf $sn_projects_list(filename)
		if {[info exists sn_projects_list(mtime)] &&
			$sn_projects_list(mtime) == [file mtime $pf] &&
			![catch {$menu index {*1.*}}]} {
			return 0
		}
	
		set exist_projs [sn_read_exist_projects 1]
		set proj_name $sn_options(sys,project-file)
	
		set off [lsearch -exact $exist_projs $proj_name]
		if {$off != -1} {
			set exist_projs [lreplace $exist_projs $off $off]
		}
		
		# Lets create the menu labels!
		$menu delete 0 end
		
		set menu_proj ""
		set i 1
		set idx 0
		foreach pr $exist_projs {
			set lb [file tail $pr]
			if {$i < 10} {
				$menu add command \
					-label "$i. $lb" \
					-command [list sn_open_project $pr] \
					-underline 0
			} else {
				$menu add command \
					-label "$i. $lb" \
					-command [list sn_open_project $pr]
			}
			menu_balloon_bind_info $event_window $idx $pr
	
			incr i
			incr idx
		}
		return [expr {$i > 1}]
	}

	method file_new {} {
		if {$ActiveWidget != $Editor} {
			$NoteBook raise edit
		}
		[list_find_editor $ActiveWidget] new_file
	}
	method file_open {} {
		if {$ActiveWidget != $Editor} {
			$NoteBook raise edit
		}
		[list_find_editor $ActiveWidget] open_file
	}
	
	#Project callbacks
	proc file_open_project {} {
		sn_open_project
	}
	proc file_save_project {} {
		sn_save_project
	}
	proc delete_current_project {} {
		if {[sn_delete_current_project]} {
			sn_projectmanager
			delete_interp
		}
	}
	proc file_close_project {} {
		if {[sn_quit]} {
			sn_projectmanager
			delete_interp
		}
	}
	
	#Save managment
	method file_save {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed save_file
	}
	method file_saveas {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed saveas_file 0 [$ed cget -filename]
	}
	method file_fastsave {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed fastsave_file
	}
	method file_saveall {} {
		Editor& @@ SaveAll
	}
	method file_revert {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed revert_file
	}
	method file_print {} {
		$ActiveWidget print
	}
	method edit_post {m} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			set state disabled
			set modstate disabled
		} else {
			set state normal
			if {[$ed canModify]} {
				set modstate normal
			} else {
				set modstate disabled
			}
		}
		$m entryconfig [get_indep String EditUndo] -state $modstate
		$m entryconfig [get_indep String EditRedo] -state $modstate
		$m entryconfig [get_indep String EditCut] -state $modstate
		$m entryconfig [get_indep String EditCopy] -state $state
		$m entryconfig [get_indep String EditPaste] -state $modstate
		$m entryconfig [get_indep String EditDelete] -state $modstate
		#$m entryconfig [get_indep String EditClear] -state $state
		$m entryconfig [get_indep String SelectAll] -state $state
		$m entryconfig [get_indep String EditInsertFile] -state $modstate
		$m entryconfig [get_indep String EditIdent] -state $modstate
		$m entryconfig [get_indep String EditOutdent] -state $modstate
	}
	
	method edit_undo {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Undo
	}
	
	method edit_redo {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Redo
	}
	
	method edit_cut {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Cut
	}
	
	method edit_copy {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Copy
	}
	
	method edit_paste {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Paste
	}
	
	method edit_delete {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed Delete
	}
	
	method do_compile_file {} {
		global sn_options

		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		set file [$ed cget -filename]
		if {$file == $sn_options(noname_file)} {
			bell; return
		}
		#get file name and convert it to an object file
		set tocmpfile [sn_object_file [file tail $file]]
		set tocmpdir  [file dirname $file]
		#mask the file with "" if there are blanks in it.
		if {[string first " " $tocmpfile] > 1} {
			set tocmpfile "\"$tocmpfile\""
		}
		
		set make [sn_make]
		$make.make setmakecommand "$sn_options(both,make-command) $tocmpfile"
		$make.make ExecMake
	}
	
	proc edit_proj_preferences {m} {
		sn_project_preferences
	}
	
	method edit_preferences {m} {
		sn_project_preferences 0 [$ActiveWidget whoami] $ActiveWidget $this
	}
	
	if {$sn_elix} {
		proc edit_elix_preferences {} {
			sn_elix_preferences
		}
	}

	method edit_insert {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed insert_file
	}
	
	method edit_indent {mode} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		Editor& @@ Indent $ed $mode
	}
	
	method Handle_Rcs {cmd {prm ""}} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		eval $cmd $prm [$ed cget -filename]
		$ed SetTitle
	}
 
	method edit_selectall {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		[$ed editor] tag add sel 0.0 end
	}
	method edit_clear {} {
		$ActiveWidget clearselection
	}
	method search_post {m} {
		#if we don't have an editor in the actual view,
		#disable string manipulation menu items
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			set state disabled
		} else {
			set state normal
		}


		$m entryconfig [get_indep String SearchFind] -state $state
		$m entryconfig [get_indep String SearchNext] -state $state
		$m entryconfig [get_indep String SearchPrev] -state $state
		$m entryconfig [get_indep String SearchReplace] -state $state

		#disable goto submenu too
		$m.goto entryconfig [get_indep String SearchGotoLine] -state $state
		$m.goto entryconfig [get_indep String SearchSetMark] -state $state
		$m.goto entryconfig [get_indep String SearchGotoMark] -state $state
		$m.goto entryconfig [get_indep String SearchGotoError] -state $state
		
		#verify if we can retrieve something
		if {$ed != ""} {
			set string [Get_Selection $ed $ActiveWidget]
		} else {
			set string ""
		}
		if {$string == ""} {
			set retrstate disabled
		} else {
			set retrstate normal
		}
		$m entryconfig [get_indep String SearchDefinition] -state $retrstate
		$m entryconfig [get_indep String SearchImplementation] -state $retrstate
		$m entryconfig [get_indep String SearchGrep] -state $retrstate
	}
	
	method search_findtext {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed != ""} {
			$ed FindText
		} else {
			bell
		}
	}
	method search_next {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed != ""} {
			$ed FindNext -forwards
		} else {
			bell
		}
	}
	method search_prev {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed != ""} {
			$ed FindNext -backwards
		} else {
			bell
		}
	}
	method search_replace {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed != ""} {
			$ed Replace
		} else {
			bell
		}
	}
	
	proc Get_Selection {ed active_wdg} {
		#get selection from current editor
		if {$ed != ""} {
			set string [Editor& @@ Get_XSelection $ed]
		} else {
			set string ""
		}
		#get selection from current view
		if {$string == "" && $ed != $active_wdg} {
			set sel [$active_wdg Selection]
			if {$sel != ""} {
				set string [lindex $sel 1]
				set cls [lindex $sel 2]
				if {$cls != ""} {
					set string "$cls $string"
				}
			}
		}
		return $string
	}
	
	method search_definition {} {
		upvar #0 $Statusbar-keep keep
		
		#look for an editor
		set ed [list_find_editor $ActiveWidget]
		
		#we use only the same editor, if the keep flag
		#is not seted
		if {$keep && $ed != ""} {
			set cmd "$ed gotofile_cb"
		} else {
			set cmd ""
		}
		
		if {$ed != ""} {
			return [Editor& @@ search_definition $ed]
		}
		
		set string [Get_Selection $ed $ActiveWidget]
		if {$string == ""} {
			bell; return
		}
		
		#try to find method or function definition (don't bell)
		set ret [sn_retrieve_symbol $string {md fd fr} \
				"" \
				-exact \
				1 0 \
				$cmd]
		#try to find any definition (not implementation or function body)
		#(bell if nothing found)
		if {$ret == 0} {
			sn_retrieve_symbol $string all \
				"" \
				-exact \
				1 1 \
				$cmd \
				"" \
				"" \
				"" \
				"*" \
				-1 \
				{{mi md} {fu fd}}
		}
	}
	method search_implementation {} {
		upvar #0 $Statusbar-keep keep
		set ed [list_find_editor $ActiveWidget]
		if {$keep && $ed != ""} {
			set cmd "$ed gotofile_cb"
		} else {
			set cmd ""
		}
		
		if {$ed != ""} {
			return [Editor& @@ search_implementation $ed]
		}
		
		set string [Get_Selection $ed $ActiveWidget]
		if {$string == ""} {
			bell; return
		}
		
		#find implementation
		set ret [sn_retrieve_symbol $string {fu mi} \
				"" \
				-exact \
				1 0 \
				$cmd]
				
		#find probably definition (correct for Tcl)
		if {$ret == 0} {
			sn_retrieve_symbol $string {fd md fr} \
				"" \
				-exact \
				1 1 \
				$cmd
		}
	}
	
	method search_gotoline {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed GotoLine
	}
	
	method search_setmark {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		[$ed editor] mark set markpos insert
	}
	proc search_gotoerror {} {
		if {[catch {sn_grep_edit_file [selection get]}]} {
			bell
		}
	}
	method search_gotomark {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		set t [$ed editor]
		$t mark set lastpos insert
		$t mark set insert markpos
		$t see insert
	}
	
	#Execute grep with selection, when there is no selection,
	#call grep dialog box
	method search_grep {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		#something must be selected
		if {[catch {set pat [string trim [selection get]]}]} {
			bell
			sn_error_dialog \
					[get_indep String NoSelection] \
					[get_indep String MultiGrep]
			return
		}
		sn_grep 1 $pat
	}
	
	method search_goto_post {m} {
	}

	proc history_post {m} {
		sn_post_history_menu $m
	}
	
	method tools_post {m} {

		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			set rcsstate disabled
		} else {
			if { [$ed validFilename ] } {
				set rcsstate normal
			} else {
				set rcsstate disabled
			}	
		}
		#RCS submenu is disabled when the filename isn't valid

		$m.rcs entryconfig [get_indep String ChooseCheckOut] -state $rcsstate
		$m.rcs entryconfig [get_indep String ChooseCheckIn] -state $rcsstate
		$m.rcs entryconfig [get_indep String ChooseDiscard]  -state $rcsstate
		$m.rcs entryconfig [get_indep String ChooseLock] -state $rcsstate
		$m.rcs entryconfig [get_indep String ChooseUnlock] -state $rcsstate
		$m.rcs entryconfig [get_indep String ChooseDiff] -state $rcsstate
		$m.rcs entryconfig [get_indep String RevisionControlEditor] -state $rcsstate
	}
	method tools_ctree_post {m} {
	}
	method tools_classbr_post {m} {
	}
	method tools_xref_post {m} {
	}
	method tools_incbr_post {m} {
	}
	
	#add breakpoint or execute until the specified line
	method tools_breakpoint_or_until {{until "break"}} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		set idx [[$ed editor] index insert]
		if {$idx == ""} {
			bell; return
		}
		dbg_set_breakpoint [$ed cget -filename] $idx $until
	}

	proc windows_new_window {{m ""} {page "edit"}} {
		global tkeWinNumber
		incr tkeWinNumber
		
		#verify if the tool command exists
		if {$page != "edit" && [tool_Exists $page] != "normal"} {
			bell; return
		}
		
		return [MultiWindow& .multiwindow-$tkeWinNumber \
					-raise $page]
	}
	proc windows_new_post {m} {
		set edit_state  [tool_Exists edit]
		set ctree_state [tool_Exists ctree]
		set xref_state  [tool_Exists xref]
		set retr_state  [tool_Exists retr]
		set grep_state  [tool_Exists grep]
		set inc_state   [tool_Exists incbr]
		
		$m entryconfig [get_indep String WindowsNew]   -state $edit_state
		$m entryconfig [get_indep String MultiClassHierarchy] -state $ctree_state
		$m entryconfig [get_indep String MultiClass]   -state $edit_state
		$m entryconfig [get_indep String MultiXRef]    -state $xref_state
		$m entryconfig [get_indep String MultiInclude] -state $inc_state
		
		$m entryconfig [get_indep String WindowsNewCTreeClass] -state $ctree_state
		$m entryconfig [get_indep String WindowsNewClassEditor] -state $ctree_state
		if {$ctree_state == "normal" && $xref_state == "normal"} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String WindowsNewClassXRef]  -state $state
		$m entryconfig [get_indep String WindowsNewRetrEditor] -state $retr_state
		$m entryconfig [get_indep String WindowsNewFindEditor] -state $grep_state
		$m entryconfig [get_indep String WindowsNewCTreeClassEditor] -state $ctree_state

	}
	proc windows_new_ctree_class {m} {
		set win [windows_new_window "" ctree]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_classbr"
	}
	proc windows_new_class_edit {m} {
		set win [windows_new_window "" classbr]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_edit"
	}
	proc windows_new_class_xref {m} {
		set win [windows_new_window "" classbr]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_xref"
	}
	proc windows_new_retr_edit {m} {
		set win [windows_new_window "" retr]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_edit"
	}
	proc windows_new_find_edit {m} {
		set win [windows_new_window "" grep]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_edit"
	}
	proc windows_new_ctree_class_edit {m} {
		set win [windows_new_window "" ctree]
		update idletasks
		after idle "update idletasks; $win windows_splitinto_classbr"
		update idletasks
		after idle "update idletasks; $win windows_splitinto_edit"
	}
	proc windows_new_symbr {{m ""}} {
		global tkeWinNumber
		incr tkeWinNumber
		return [SymBr& .multisymbr-$tkeWinNumber]
	}
	
	#return the number of existing windows, to verify
	#if we want to exist or close the window
	proc num_Existing_windows {} {
		set len [llength [itcl_info objects "*" -class MultiWindow&]]
		set len [expr $len + [llength [itcl_info objects "*" -class SymBr&]]]
		return $len
	}
	
	#close window, if it is not the last window
	#exit project, if it is the last window
	method windows_close {m} {
		if {[num_Existing_windows] > 1} {
			if {[Close]} {
			
				#close related preferences window, if availiable
				catch {$this-preferences exitPreferences}
				
				#close window
				$this delete
			}
		} else {
			#exit the project
			MultiWindow& @@ file_close_project
		}
	}
	
	#iconize project
	proc windows_iconize {m topw} {
		sn_hide_show_project withdraw $topw
	}
	
	method windows_split_post {m} {
		set last [list_last $ActiveWidget]
		
		#disable deleting last pane, if no panes availiable
		if {$last == $ActiveWidget} {
			set state disabled
		} else {
			set state normal
		}
		$m entryconfig [get_indep String SplitDeleteLast] -state $state
			
		$m entryconfig [get_indep String SplitIntoEditor]  -state [tool_Exists edit]
		$m entryconfig [get_indep String SplitIntoClassHierarchy] -state [tool_Exists ctree]
		$m entryconfig [get_indep String SplitIntoClass]   -state [tool_Exists class]
		$m entryconfig [get_indep String SplitIntoXRef]    -state [tool_Exists xref]
		$m entryconfig [get_indep String SplitIntoInclude] -state [tool_Exists incbr]
	}
	
	############################################
	# Views SECTION
	############################################
	proc find_mainwindow {view} {
		foreach win [itcl_info objects "*" -class MultiWindow&] {
			foreach tool [$win tools] {
				for {set nxt $tool} {$nxt != ""} {set nxt [$nxt next]} {
					if {$nxt == $view} {
						return [list $win $tool]
					}
				}
			}
		}
		return ""
	}
	
	#find the main page in corresponding to the given view,
	#it can be a sub view.
	method find_page {view} {
		foreach tool [tools] {
			for {set nxt $tool} {$nxt != ""} {set nxt [$nxt next]} {
				if {$nxt == $view} {
					return [$tool whoami]
				}
			}
		}
		return ""
	}
	
	proc find_browserwindow {view} {
		foreach win [itcl_info objects "*" -class SymBr&] {
			if {[$win symbr] == $view} {
				return $win
			}
		}
		return ""
	}
	proc windows_views_switchto {view} {
		global Switch_Is_Enabled
		
		#look for the window in the multiviews windows
		set win_tool [find_mainwindow $view]
		if {$win_tool != ""} {
			#disable switching
			@@incr Switch_Is_Enabled -1
			
			set win  [lindex $win_tool 0]
			set page [lindex $win_tool 1]
			
			[$win NoteBook] raise [$page whoami]
			$view Focus
			$win raise
			
			#reenable switching
			@@incr Switch_Is_Enabled
		} else {
			#window not found, maybe its a retriever in the symbol browser
			set win [find_browserwindow $view]
			if {$win == ""} {
				bell; return
			}
			$win raise
		}
	}
	
	proc windows_views_post {m} {
		global sn_options
		
		if {[itcl_info objects "*" -class Editor&] != ""} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String MultiEditor] -state $state
		
		if {[itcl_info objects "*" -class ClassTree&] != ""} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String MultiClassHierarchy] -state $state
		
		if {[itcl_info objects "*" -class Class&] != ""} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String MultiClass] -state $state
		
		if {[itcl_info objects "*" -class XRef&] != ""} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String MultiXRef] -state $state
		
		if {[itcl_info objects "*" -class Include&] != ""} {
			set state normal
		} else {
			set state disabled
		}
		$m entryconfig [get_indep String MultiInclude] -state $state
		
		#is a retriever-view availiable in the mainwindow (only)
		set state disabled
		foreach rtr [itcl_info objects "*" -class Retr&] {
			#only in main windows
			if {[catch {set win [[winfo toplevel $rtr] whoami]}] || $win != "mainw"} {
				continue
			} else {
				set state normal
				break
			}
		}
		$m entryconfig [get_indep String MultiRetriever] -state $state
		
		#is a grep-view avail. in the main window (only).
		set state disabled
		foreach gr [itcl_info objects "*" -class Grep&] {
			#only in main windows
			if {[catch {set win [[winfo toplevel $gr] whoami]}] || $win != "mainw"} {
				continue
			} else {
				set state normal
				break
			}
		}
		$m entryconfig [get_indep String MultiGrep] -state $state
	}
	
	proc windows_views_edit_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class Editor&] {
			catch {
				$m add command \
					-command "MultiWindow& @@ windows_views_switchto $ed" \
					-label "$i [$ed Title 0]" \
					-underline 0
				incr i
			}
		}
	}
	
	proc windows_views_ctree_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class ClassTree&] {
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label "$i [$ed Title 0]" \
				-underline 0
			incr i
		}
	}
	
	proc windows_views_class_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class Class&] {
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label "$i [$ed Title 0]" \
				-underline 0
			incr i
		}
	}
	
	proc windows_views_xref_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class XRef&] {
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label "$i [$ed Title 0]" \
				-underline 0
			incr i
		}
	}
	
	proc windows_views_inc_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class Include&] {
			if {[catch {set t "$i [$ed Title 0]"}]} {
				continue
			}
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label $t \
				-underline 0
			incr i
		}
	}
	
	proc windows_views_retr_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class Retr&] {
			#only in main windows
			if {[catch {set win [[winfo toplevel $ed] whoami]}] || $win != "mainw"} {
				continue
			}
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label "$i [$ed Title 0]" \
				-underline 0
			incr i
		}
	}
	
	proc windows_views_grep_post {m} {
		$m delete 0 end
		set i 1
		foreach gr [itcl_info objects "*" -class Grep&] {
			#only in main windows
			if {[catch {set win [[winfo toplevel $gr] whoami]}] || $win != "mainw"} {
				continue
			}
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $gr" \
				-label "$i [$gr Title 0]" \
				-underline 0
			incr i
		}
	}

	proc windows_views_make_post {m} {
		$m delete 0 end
		set i 1
		foreach ed [itcl_info objects "*" -class Make&] {
			$m add command \
				-command "MultiWindow& @@ windows_views_switchto $ed" \
				-label "$i [$ed Title 0]" \
				-underline 0
			incr i
		}
	}
	
	#########################################################
	#End of Views SECTION
	#########################################################
	
	#find the first classed (class whoami) object in the chain
	proc list_find {w whoami} {
		global last_Editor
		for {set nxt $w} {$nxt != ""} {set nxt [$nxt next]} {
			if {[$nxt whoami] == $whoami} {
				return $nxt
			}
		}
		return ""
	}
	
	#find the last accessed or the first editor in the chain
	proc list_find_editor {w} {
		global last_Editor
		set fnd ""
		for {set nxt $w} {$nxt != ""} {set nxt [$nxt next]} {
			if {[$nxt whoami] == "edit"} {
				if {$last_Editor == $nxt} {
					#return last accessed editor
					return $nxt
				} elseif {$fnd == ""} {
					#mark the first editor
					set fnd $nxt
				}
			}
		}
		#return the first found editor or the empty string
		return $fnd
	}
	
	#return all objects in the list
	proc list_items {w} {
		set items ""
		for {set nxt $w} {$nxt != ""} {set nxt [$nxt next]} {
			lappend items $nxt
		}
		return $items
	}
	
	#find the last object in the chain
	proc list_last {w {previous ""}} {
		if {$previous != ""} {
			upvar $previous prev
		}
		set prev $w
		set last $w
		for {set nxt $w} {$nxt != ""} {set nxt [$nxt next]} {
			set prev $last
			set last $nxt
		}
		return $last
	}
	
	method required_size {w} {
		global sn_options
		if {$sn_options(def,window-alighment) == "vertical"} {
			set last_height [winfo height $w]
		} else {
			set last_height [winfo width $w]
		}
		set last_height [expr $last_height / 2]
		return $last_height
	}
	
	method add_new_pane {last} {
		global tkeWinNumber
		
		set size [required_size $last]
		# Create the editor now
		incr tkeWinNumber
		set pane [$ActivePaned add pane-$tkeWinNumber \
						-size $size]
		# Give the upper pane the half size of it's
		# original size
		set lastpane [winfo parent $last]
		set lastpane [string range $lastpane [expr [string last "." $lastpane] + 1] end]
		$ActivePaned paneconfigure $lastpane -size $size
		
		return $pane
	}

	# Add an editor to current window. This is not
	# possible if we just added an editor.

	method windows_splitinto_edit {{m ""}} {
		global tkeWinNumber
		
		# Verify that the last widget is not an editor
		set last [list_last $ActiveWidget]
		#if {$last != $ActiveWidget && [$last whoami] == "edit"} {
		#	bell
		#	return ""
		#}
		
		set editpane [add_new_pane $last]
		
		incr tkeWinNumber
		set ed $editpane.edit-$tkeWinNumber
		Editor& $ed \
			-mesg_area $this.msg \
			-mesg_linenumber $this.linenum \
			-findcombo $FindCombo
			
		set who [$last whoami]
		
		# Configure selectcommand to be called whenever
		# the selection is changed.
		# Do this only when the previous command is not an editor
		if {$who == "edit"} {
			# Add the new editor into the chain
			$last config \
				-next $ed
			
			# Edit the same file as the prev. editor
			$ed config -filename [$last cget -filename]
				
		# When the active view is a retriever, bind the
		# combo box to the editor.
		} elseif {$who == "retr" || $who == "grep"} {
			# Add the new editor into the chain
			$last config	\
					-next $ed \
					-selectcommand "$ed gotosymbol"
			
			# Set related flag of the combo box to true
			upvar #0 $SymbolsFilter-related related
			@@set related 1
			
			# bind all the environment for the editor
			$ed config \
					-symbols $Toolbar.where \
					-symbols_filter $SymbolsFilter \
					-menu $EditorMenu \
					-toolbar "" \
					-mesg_area $this.msg \
					-mesg_linenumber $this.linenum \
					-findcombo $FindCombo
					
			# Enable combo box
			$Toolbar.where enable
			
			# Activate editor
			$ed activate
			
			@@eval $ed gotosymbol [$last Selection]
		} else {
			$last config \
				-next $ed \
				-selectcommand "$ed gotosymbol"
				
			@@eval $ed gotosymbol [$last Selection]
		}
		pack $ed -fill both -expand y

		# View editor commands in toolbar, if not availiable
		DeActivate_Editor_buttons
	
		return $ed
	}

	# Add a hierarchy browser to current window. This is not
	# possible if we just added a class hierarchy.

	method windows_splitinto_ctree {{m ""}} {
		global tkeWinNumber
		
		# Verify that the last widget is not a hierarchy browser
		set last [list_last $ActiveWidget]
		if {[$last whoami] == "ctree"} {
			bell
			return ""
		}
		
		# Create a new ctree pane
		set ctreepane [add_new_pane $last]
		
		incr tkeWinNumber
		set ctree $ctreepane.ctree-$tkeWinNumber
		ClassTree& $ctree \
			-mesg_area $this.msg
			
		# Configure selectcommand to be called, when
		# ever the selection is changed
		$last config \
			-selectcommand "$ctree gotosymbol" \
			-next $ctree
		pack $ctree -fill both -expand y
		
		@@eval $ctree gotosymbol [$last Selection]
		
		return $ctree
	}
	
	# Add a class browser to current window. This is not
	# possible if we just added a class browser.
	
	method windows_splitinto_classbr {{m ""}} {
		global tkeWinNumber
		
		# Verify that the last widget is not a class browser
		set last [list_last $ActiveWidget]
		if {[$last whoami] == "classbr"} {
			bell
			return ""
		}
		
		# Create the classbr now
		set classbrpane [add_new_pane $last]
		incr tkeWinNumber
		set classbr $classbrpane.classbr-$tkeWinNumber
		
		Class& $classbr \
 			-doubleclickcommand "$this EditObject" \
			-class_doubleclickcommand "$this ClassBrowserEditClass" \
			-mesg_area $this.msg
			
		# Configure selectcommand to be called, when
		# ever the selection is changed
		$last config \
			-selectcommand "$classbr gotosymbol" \
			-next $classbr
		pack $classbr -fill both -expand y
		
		@@eval $classbr gotosymbol [$last Selection]
		
		return $classbr
	}

	# Add a xref browser to current window. This is not
	# possible if we just added a xref browser.

	method windows_splitinto_xref {{m ""}} {
		global tkeWinNumber
		
		# Verify that the last widget is not a xref
		set last [list_last $ActiveWidget]
		if {[$last whoami] == "xref"} {
			bell
			return ""
		}
		
		# Create the xref now
		set xrefpane [add_new_pane $last]
		incr tkeWinNumber
		set xref $xrefpane.xref-$tkeWinNumber
		
		XRef& $xref \
			-mesg_area $this.msg
			
		# Configure selectcommand to be called, when
		# ever the selection is changed
		$last config \
			-selectcommand "$xref gotosymbol" \
			-next $xref
		pack $xref -fill both -expand y
		
		@@eval $xref gotosymbol [$last Selection]
		
		return $xref
	}

	# Add an include browser to current window. This is not
	# possible if we just added an include browser.

	method windows_splitinto_incbr {{m ""}} {
		global tkeWinNumber

		# Verify that the last widget is not an include browser
		set last [list_last $ActiveWidget]
		if {[$last whoami] == "incbr"} {
			bell
			return ""
		}

		# Create the include browser now
		set incbrpane [add_new_pane $last]
		incr tkeWinNumber
		set incbr $incbrpane.incbr-$tkeWinNumber

		Include& $incbr \
			-mesg_area $this.msg

		# Configure selectcommand to be called, when
		# ever the selection is changed
		$last config \
			-selectcommand "$incbr gotosymbol" \
			-next $incbr
		pack $incbr -fill both -expand y

		@@eval $incbr gotosymbol [$last Selection]

		return $incbr
	}

	# Add a build window to current window. This is not
	# possible if we just added a build window.

	method windows_splitinto_build {{m ""}} {
		global tkeWinNumber

		# Verify that the last widget is not a build window
		set last [list_last $ActiveWidget]
		if {[$last whoami] == "make"} {
			bell
			return ""
		}

		# Create the make window now
		set makepane [add_new_pane $last]
		incr tkeWinNumber
		set make $makepane.make-$tkeWinNumber

		Make& $make \
			-mesg_area $this.msg

		# Configure selectcommand to be called, when
		# ever the selection is changed
		$last config \
			-selectcommand "$make gotosymbol" \
			-next $make

		pack $make -fill both -expand y -padx 3 -pady 3

		# FIXME : not clear what this would do
		#@@eval $incbr gotosymbol [$last Selection]

		return $make
	}

	#deletes the last pane from a view
	method windows_delete_last_pane {m} {
		set last [list_last $ActiveWidget prev]
		if {$last == $ActiveWidget} {
			return 0
		}
		
		#Ask the object for deleting
		if {[$last Close] != 1} {
			return 0
		}
		
		#delete pointer to the deleted widget
		#and the selectcommand
		$prev config \
			-next "" \
			-selectcommand ""
		
		#delete object from the pane widget
		$last delete
		
		#delete pane page
		set pane [string range $last 0 [expr [string last "." $last] - 1]]
		set page [string range $pane [expr [string last "." $pane] + 1] end]
		set pane [string range $pane 0 [expr [string last "." $pane] - 1]]
		$pane del $page
		
		#hide editor buttons, if availiable
		DeActivate_Editor_buttons
		
		return 1
	}
	
	method switch_to_next_view {fcs} {
		for {set w $ActiveWidget} {$w != ""} {set w [$w next]} {
			if {[string first $w $fcs] == 0} {
				set nxt [$w next]
				if {$nxt != ""} {
					$nxt Focus
					return
				}
			}
		}
		$ActiveWidget Focus
	}
	
	proc windows_post {my_top w {pref 0}} {
		global sn_options
	
		#delete only the menubuttons for availiable windows
		set cnt [expr 3 + $pref]
		set num [$w index end]
		if {$num >= $cnt} {
			$w delete $cnt end
		}
	
		set proj_len [expr [string length [sn_title]] + 1]
	
		set toplevs($my_top) 1;		# Ignore the menu's toplevel window!
		set prjName [sn_title]
		set pars ""
		foreach win [winfo children .] {
			set top [winfo toplevel $win] 
	
			if {[info exists toplevs($top)] || [@@wm overrideredirect $top]} {
				continue
			}
			set toplevs($top) 1
	
			set state_ind ""
			switch [wm state $top] {
			"withdrawn" {
					continue
				}
			"iconic" {
					set state_ind {+}
				}
			"normal" {
				}
			default {
					continue
				}
			}
			set title [wm title $top]
	
			regsub -all {[ ]+} $title { } title
			set off [string first $prjName $title]
			switch -- $off {
			    -1 {
			    }
			    0 {
					incr off $proj_len
					set title [string trim [string range $title $off end]]
			    }
			    default {
					set title [string trim [string range $title 0 [expr $off - 1]]]
					if {[string index $title 0] == "*"} {
						set title [string trimleft $title "*"]
					}
					set title [string trimright $title "- "]
			    }
			}
			lappend pars [list $title $state_ind $top]
		}
	
		set i 1
		foreach p [lsort -dictionary $pars] {
			set title [lindex $p 0]
			set accel [lindex $p 1]
			set win [lindex $p 2]
	
			$w add command \
				-label "$i $title" \
				-accelerator $accel \
				-underline 0 \
				-command "raise_toplevel $win"
			incr i
		}
	}

	method toolbar_post_scope_menu {m} {
		global combobox_editor_scopes

		$ActiveWidget postcommand $m

		if {[$ActiveWidget whoami] == "edit"} {
			#enable buttons (All,Related,All,None)
			foreach btn [eval list $AllFilterOptions(radio) $AllFilterOptions(checkbutton)] {
				$btn config -state normal
			}
			foreach grp [lsort [array names combobox_editor_scopes]] {
				set st "disabled"
				set ind 0
				foreach sc $combobox_editor_scopes($grp) {
					if {[@@info commands paf_db_$sc] != ""} {
						set st "normal"
						set ind 1
						break
					}
				}
				if {$ind == 0} {
					uplevel #0 "set $m-$grp off"
					$m.$grp config -state $st
				} else {
					$m.$grp config -state $st
				}
			}
			#unknown scopes (only for xref)
			$m.ud config -state disabled
		} elseif {[$ActiveWidget whoami] == "xref"} {
			#disable All,Related
			foreach btn $AllFilterOptions(button) {
				$btn config -state disabled
			}
			#enable buttons (All,None)
			foreach btn $AllFilterOptions(radio) {
				$btn config -state normal
			}
			foreach grp [lsort [array names combobox_editor_scopes]] {
				set st "disabled"
				set ind 0
				foreach sc $combobox_editor_scopes($grp) {
					if {[@@info commands paf_db_$sc] != ""} {
						set st "normal"
						set ind 1
						break
					}
				}
				if {$ind == 0} {
					uplevel #0 "set $m-$grp off"
					$m.$grp config -state $st
				} else {
					$m.$grp config -state $st
				}
			}
			#unknown scopes (only for xref)
			$m.ud config -state normal
		} else {
			#enable All,Related radios
			foreach btn $AllFilterOptions(radio) {
				$btn config -state normal
			}

			#disable filter options (buttons and checkbuttons)
			foreach btn [eval list $AllFilterOptions(radio) $AllFilterOptions(checkbutton)] {
				$btn config -state disabled
			}
			#unknown scopes (only for xref)
			$m.ud config -state disabled
		}
	}
	
	method history_stack_control_buttons {} {
		if {$view_positions(next) == ""} {
			set next_state disabled
		} else {
			set next_state normal
		}
		if {$view_positions(prev) == ""} {
			set prev_state disabled
		} else {
			set prev_state normal
		}
		$Toolbar.prev config -state $prev_state
		$Toolbar.next config -state $next_state
	}
	
	#add into view stack
	#where: prev/next
	#wdg:   View widget (Editor, Class, Ctree, ..)
	protected history_stack_active 0
	method history_stack_add_point {wdg {where ""}} {
		global sn_options
		global sn_history
		
		#stack managment is active
		if {$history_stack_active} {
			return
		}
		#enter
		incr history_stack_active
		
		if {$where == ""} {
			set where $stack_history_side
		}
	
		#dump the current view of the widget
		set dump [$wdg Dump]
		
		#check if we have a restorable position at all.
		if {$dump == ""} {
			#leave
			incr history_stack_active -1
			#no dump position availiable
			return
		}

		#title for the list
		set title [$wdg DumpTitle $dump]
				
		#add it on the top of the stack
		set entry [list $wdg $dump $title]
		
		#Add to global (normal history from menu) history
		$wdg AddHistoryFromDump $dump $title
		
		#if view point is already availiable move it to top.
		set i [lsearch -exact $view_positions($where) $entry]
		if {$i != -1} {
			set view_positions($where) [lreplace $view_positions($where) $i $i]
		}
		set view_positions($where) [linsert $view_positions($where) 0 $entry]
		
		#if we add a view point into the prev list, we
		#must delete all the next positions.
		#Add it to the end of the previous list!!
		#Do not do it when the user navigates using the history dump
		#points.
		if {$history_stack_navigate == 0 && $where == "prev"} {
			set nlen [llength $view_positions(next)]
			set len  [llength $view_positions(prev)]
			if {[expr $nlen + $len] > $sn_history(stacksize)} {
				set len [expr $nlen + $len - $sn_history(stacksize)]
				set minlen [expr $sn_history(stacksize) / 2]
				if {$len < $minlen} {
					set len $minlen
				}
				set view_positions(prev) [lrange $view_positions(prev) 0 $len]
			}
			eval lappend view_positions(prev) $view_positions(next)
			set view_positions(next) ""
		}
		
		#limit the number of history stack dump points
		if {[llength $view_positions($where)] > $sn_history(stacksize)} {
			set view_positions($where) [lrange \
					$view_positions($where) \
					0 \
					$sn_history(stacksize)]
		}
		
		#control history/stack navigation buttons
		history_stack_control_buttons
		
		#leave stack managment
		incr history_stack_active -1
	}
	
	method toolbar_post_history_stack_menu {m what} {
		set i 0
		foreach point $view_positions($what) {
			set wdg [lindex $point 0]
			if {![winfo exists $wdg]} {
				#view removed
				continue
			}
			$m add command \
				-command "$this history_stack_goto_point $what $i" \
				-label [lindex $point 2]
			incr i
		}
	}
	
	#post menu to list all availiable saved view positions
	method toolbar_post_history_stack {what btn} {
		#nothing in the stack
		if {$view_positions($what) == ""} {
			return
		}
		
		#set (x,y) for option-menu
		set y [expr [winfo rooty $btn] + [winfo height $btn]]
		set x [winfo rootx $btn]
		
		set m .view_position_pop_menu
		catch {tk_destroy $m}
		menu $m -title "Views" \
				-tearoff 0 \
				-postcommand "$this toolbar_post_history_stack_menu $m $what"
		wm overrideredirect $m 1
		tk_popup $m $x $y
	}
	
	#true when the user navigates between the existing
	#stack dump-points
	protected history_stack_navigate 0
	protected history_stack_goto_point_active 0
	#restore the first view point in the stack
	method history_stack_goto_point {where {index 0}} {
		global Switch_Is_Enabled
		
		if {$view_positions($where) == ""} {
			return
		}
		
		if {$history_stack_goto_point_active} {
			bell; return
		}
		incr history_stack_goto_point_active 1
		
		set point [lindex $view_positions($where) $index]
		
		#fetch the widget path and verify if it exists, if not
		#delete it from the history stack
		set wdg [lindex $point 0]
		while {! [winfo exists $wdg]} {
			catch {set view_positions($where) [lreplace $view_positions($where) $index $index]}
			
			if {$view_positions($where) == ""} {
				break
			}
			
			set point [lindex $view_positions($where) $index]
			set wdg   [lindex $point 0]
			if {$point == "" || $wdg == ""} {
				break
			}
		}
		
		#stack empty
		if {$view_positions($where) == "" || $point == "" || $wdg == ""} {
			incr history_stack_goto_point_active -1
			return
		}
		
		watch y $this
		
		#we must disable auto-switching to current position
		@@incr Switch_Is_Enabled -1
		
		#navigation between stack points is active,
		#don't delete the next-stack
		incr history_stack_navigate
		
		if {$where == "prev"} {
			set stack_history_side "next"
		} else {
			set stack_history_side "prev"
		}
		
		#delete (before execution) the entry from the stack list
		catch {set view_positions($where) [lreplace $view_positions($where) $index $index]}
		
		#find page in corresponding to the widget, it can be a sub widget
		set page [find_page $wdg]
		
		#restore view point
		if {$page != ""} {
			catch {
				#popup view, don't raise the window
				view $page 0
				$wdg Restore [lindex $point 1]
				#focus on the restored view
				$wdg Focus
			} err
			if {$err != ""} {
				sn_log "stack goto history:$err"
			}
		} else {
			#a sub widget is deleted, no restore possible
			bell
		}
		
		history_stack_control_buttons
		
		#default is adding to previous list
		set stack_history_side "prev"
		
		#navigation between stack points finished
		incr history_stack_navigate -1
		
		#reenable switching
		@@incr Switch_Is_Enabled
		
		watch n $this
	
		incr history_stack_goto_point_active -1
	}
	
	method toolbar_display_selected {combo txt} {
		$ActiveWidget goto $combo $txt
	}
	method toolbar_findtext {combo txt} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed != ""} {
			$ed FindNext -forwards $txt
		} else {
			bell
		}
	}
	method toolbar_findtext_postcommand {combo} {
		global sn_options
		$combo contents $sn_options(search)
	}
	method toolbar_search_pattern {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		if {![catch {set string [selection get]}]} {
			set off [string first "\n" $string]
			if {$off != -1} {
				set string [string range $string 0 [expr $off - 1]]
			}
			$ed FindNext -forwards $string
		} else {
			$ed FindNext -forwards [$FindCombo getentry]
		}
	}
	
	method toolbar_retriever {} {
		set ed [list_find_editor $ActiveWidget]
		if {$ed == ""} {
			bell; return
		}
		$ed RetrieveObject
	}
	
	method toolbar_grep {} {
		search_grep
	}
	method toolbar_symbols {cmbmenu {all 0}} {
		$ActiveWidget filter $all
	}
	method editor {} {
		return $Editor
	}
	method editw {} {
		if {[catch {set w [$Editor editor]}]} {
			return ""
		}
		return $w
	}

	#find a reusable window
	method is_Reusable {} {
		upvar #0 $Statusbar.reusable reuse
		if {$reuse == ""} {
			set reuse 0
		}
		if {![winfo exists $this.msg.reuse] || !$reuse ||
			[$this.msg.reuse cget -state] != "normal"} {
			return 0
		}
		return 1
	}
	
	method ActiveWidget {} {
		return $ActiveWidget
	}
	
	method NoteBook {} {
		return $NoteBook
	}
	method view {page {rs 1}} {
		set old $Activate_executed
		$NoteBook raise $page
		
		#Activate isn't executed, because the page is
		#already active, add dump-point into history-stack
		if {$old == $Activate_executed} {
			history_stack_add_point $ActiveWidget
		}
		if {$rs} {
			raise
		}
	}
	
	#find a window with specified class name
	proc find_Reusable {} {
		foreach win [itcl_info objects "*" -class MultiWindow&] {
			if [$win is_Reusable] {
				return $win
			}
		}
		return ""
	}
	
	method tools {} {
		return $AvailTools
	}
	
	#Close your self
	method Close {} {
		foreach tool $AvailTools {
			for {set nxt $tool} {$nxt != ""} {set nxt [$nxt next]} {
				#By editor with more than one buffer for the
				#same file, do ask only one time!!
				if {[$nxt whoami] == "edit"} {
					if {[info exists alread_Asked([$nxt cget -filename])]} {
						continue
					}
					set alread_Asked([$nxt cget -filename]) 1
				}
				if {[$nxt Close] != 1} {
					#user canceled command
					return 0
				}
			}
		}
		#window can be closed
		return 1
	}
	
	#verify if all buffers can be refereted.
	proc CloseAll {} {
		foreach win [itcl_info objects "*" -class Editor&] {
			if {[info exists alread_Asked([$win cget -filename])]} {
				continue
			}
			set alread_Asked([$win cget -filename]) 1
			if {[$win Close] == 0} {
				return 0
			}
		}
		#close all symbol browsers
		return [SymBr& @@ CloseAll]
	}
	
	method Restore {win} {
		foreach page $win {
			set i 0
			#views in the page
			#format "<view name> <width> <height> <view flags>"
			foreach view [lrange $page 1 end] {
				if {$i == 0} {
					$NoteBook raise [lindex $view 0]
					set w $ActiveWidget
				} else {
					switch -- [lindex $view 0] {
					"edit" {
						set w [windows_splitinto_edit]
					}
					"ctree" {
						set w [windows_splitinto_ctree]
					}
					"classbr" {
						set w [windows_splitinto_classbr]
					}
					"xref" {
						set w [windows_splitinto_xref]
					}
					"incbr" {
						set w [windows_splitinto_incbr]
					}
					default {}
					}
				}
				$w Restore [lindex $view 3]
				incr i
			}
		}
	}
	
	#the function refreshes all views after updating the project
	#XRef state is handled, not the views added to xref
	#
	#vw:  EMPTY to update all the views
	#vw:  List of view names to update
	method Control_Display {{vw ""}} {
		global combobox_editor_scopes
		
		if {$vw == ""} {
			set who_views [list edit classbr ctree xref incbr retr grep]
		} else {
			set who_views xref
		}
	
		#verify if the views are still availiable
		foreach who $who_views {
			set page  [$NoteBook subwidget $who]
			set state [tool_Exists $who]
			$NoteBook pageconfigure $who -state $state
		}
		
		#delete sub windows of disabled views
		#except XRef windows, this must be updated after
		#finishing XRef process
		foreach tool [tools] {
			set who [$tool whoami]
			set page [$NoteBook subwidget $who]
			if {$vw != "" && $vw != $who} {
				continue
			} elseif {$vw == "" && $who == "xref"} {
				continue
			}
			set state [tool_Exists $who]
			
			#delete all sub views, if the view isn't more availiable
			if {$state == "disabled"} {
				set oldActive $ActiveWidget
				set ActiveWidget $tool
				while {1} {
					if {[windows_delete_last_pane ""] == 0} {
						break
					}
				}
				set ActiveWidget $oldActive
			}
		}
		
		#If xref is the active page, then configure it's combo box.
		if {$vw == "xref" && [$ActiveWidget whoami] == "xref"} {
			$ActiveWidget Reenable
		}
		
		#check wether the combobox entries are still valid
		if {$vw != "xref"} {
			set opt [$this.exp.where mnu].symfilter
			foreach sc [lsort [array names combobox_editor_scopes]] {
				if {! [winfo exists $opt.$sc]} {
					#read the filters
					Add_Symbol_Filter $this.exp
					break;
				}
			}
		}
	}
	
	method whoami {} {
		return "mainw"
	}
	
	#this function is called, when the project state is
	#changes, like file is saved and reparsed,
	#this function update the availiable views to
	#the latest state
	proc Refresh_YourSelf {} {
		
		foreach win [itcl_info objects "*" -class MultiWindow&] {
			$win Control_Display
		}
		
		#refresh editors
		foreach ed [itcl_info objects "*" -class Editor&] {
			$ed Refresh_Display
		}

		#refresh hierarchy
		foreach ct [itcl_info objects "*" -class ClassTree&] {
			$ct Refresh_Display
		}
		
		#refresh class
		foreach cl [itcl_info objects "*" -class Class&] {
			$cl Refresh_Display
		}
		
		#refresh xref
		foreach xr [itcl_info objects "*" -class XRef&] {
			$xr Refresh_Display
		}
		
		#refresh include
		foreach inc [itcl_info objects "*" -class Include&] {
			$inc Refresh_Display
		}
		
		#refresh Retriever (exclusive mode)
		foreach r [itcl_info objects "*" -class Retr&] {
			$r Refresh_Display
		}
		
		#refresh Symbol browsers
		foreach sb [itcl_info objects "*" -class SymBr&] {
			$sb Refresh_Display
		}
	}
	
	#this function is called after xref process is finished
	proc Refresh_YourSelf_After_XRef {} {
		foreach win [itcl_info objects "*" -class MultiWindow&] {
			$win Control_Display xref
		}
		#refresh xref windows
		foreach xr [itcl_info objects "*" -class XRef&] {
			$xr Refresh_Display
		}
	}
	
	#This function saves the status of all opened multiwindows
	#in the project file.
	proc SaveYourSelf {} {
	
		sn_log "MutliWindow& SaveYourSelf.."
	
		set val ""
		foreach win [itcl_info objects "*" -class MultiWindow&] {
		
			#window id
			set wdump "window"
			
			#window geom
			lappend wdump [winfo x $win]
			lappend wdump [winfo y $win]
			lappend wdump [winfo width $win]
			lappend wdump [winfo height $win]
			lappend wdump [wm geometry $win]
			lappend wdump [[$win ActiveWidget] whoami]
			
			#notepad pages
			#foreach tool [$win tools]
			#do only save the active view, don't save all views,
			#this is not nesessary
			foreach tool [$win ActiveWidget] {
				set sub "page"
				
				if {$tool == ""} {
					continue
				}
				
				#Save the tool and it's sub windows
				foreach page [MultiWindow& @@ list_items $tool] {
					if {$page == ""} {
						continue
					}
					set who [$page whoami]
					
					#we don't need to dump the settings for grep&retriever
					if {[lsearch -exact {retr grep} $who] != -1} {
						continue
					}
					
					#save geometry
					set subpage ""
					lappend subpage $who
					lappend subpage [winfo width $page]
					lappend subpage [winfo width $page]
				
					#save widget settings
					lappend subpage [$page Dump]
					lappend sub $subpage
				}
				
				lappend wdump $sub
			}
			lappend val $wdump
		}
		paf_db_proj put MultiWindows $val
		
		#save existing browsers
		SymBr& @@ SaveYourSelf
		
		sn_log "MutliWindow& SaveYourSelf..end"
	}
	
	#This function restores all the windows saved in the
	#project file
	proc RestoreYourSelf {} {
		global sn_options
		global tkeWinNumber
		global Switch_Is_Enabled

		#first disable switching
		@@incr Switch_Is_Enabled -1
		
		#let the status window be refreshed
		update idletasks
		update
		
		#first restore saved symbol browsers
		SymBr& @@ RestoreYourSelf

		set val [paf_db_proj get -key MultiWindows]
		if {$val != ""} {
			catch {
				foreach win $val {
					set id [lindex $win 0]
					if {$id != "window"} {
						continue
					}
					
					set geom [lindex $win 5]

					#create window
					incr tkeWinNumber
					set nwin ".multiwindow-$tkeWinNumber"
					MultiWindow& $nwin \
						-geometry $geom

					#restore settings
					$nwin Restore [lrange $win 7 end]

					#toggle to active page
					$nwin view [lindex $win 6]

					update idletasks
				}
			}
		}
		#reenable switching
		@@incr Switch_Is_Enabled
	}

	#create by default a window with the retriever containing
	#the file list
	#Create a symbol browser by default
	proc Default_Window {} {
		global tkeWinNumber
		global keybindings_initialized
		
		#is a main window availiable
		set wins [itcl_info objects "*" -class MultiWindow&]
		if {$wins != ""} {
			return
		}
		#is a symbol browser availiable
		set wins [itcl_info objects "*" -class SymBr&]
		if {$wins != ""} {
			return
		}
		
		#let the status window be refreshed
		update idletasks
		update
		
		windows_new_symbr ""
	}

	protected AllFilterOptions
	
	protected ActivePage ""
	protected ActivePaned ""
	protected ActivePane ""
	protected ActiveWidget ""
	
	protected NoteBook ""
	
	protected EditorPage ""
	protected EditorPaned ""
	protected EditorPane ""
	protected EditorMenu ""
	protected Editor ""
	
	protected ClassBrowserPage ""
	protected ClassBrowserPaned ""
	protected ClassBrowserPane ""
	protected ClassBrowserMenu ""
	protected ClassBrowser ""
	
	protected ClassHierarchyPage ""
	protected ClassHierarchyPaned ""
	protected ClassHierarchyPane ""
	protected ClassHierarchyMenu ""
	protected ClassHierarchy ""
	
	protected XReferencePage ""
	protected XReferencePaned ""
	protected XReferencePane ""
	protected XReferenceMenu ""
	protected XReference ""

	protected IncludePage ""
	protected IncludePaned ""
	protected IncludePane ""
	protected IncludeMenu ""
	protected Include ""

	protected RetrieverPage ""
	protected RetrieverPaned ""
	protected RetrieverPane ""
	protected Retriever ""
	protected RetrieverMenu ""
	
	protected GrepPage ""
	protected GrepPaned ""
	protected GrepPane ""
	protected Grep ""
	protected GrepMenu ""
	
	protected MakePage ""
	protected MakePaned ""
	protected MakePane ""
	protected Make ""
	protected MakeMenu ""
	
	protected Misc ""
	protected MiscMenu ""
	
	protected Toolbar ""
	protected SymbolsFilter ""
	protected Statusbar ""
	protected Reuse ""
	protected Keep ""
	protected FindCombo ""
	protected FindEditFr ""
	protected SymbolCombo ""
	protected AvailTools ""
	
	#contains all next positions
	#contains all previous positions
	protected view_positions
	protected stack_history_side "prev"
	
	public geometry ""
	public symbolname $sn_options(noname_file)
	public raise "edit"
	public x ""
	public y ""
}

proc ProjectMenuEntries_post {m {subwindow ""} {prjsub ""}} {
		#XRef process is running <==> no save & no project editor
		if {[sn_processes_running]} {
			set xref_state disabled
		} else {
			set xref_state normal
		}
		
		#No project editor/delete project during xref is running
		$m$prjsub entryconfig [get_indep String ProjectEditorMenu]  -state $xref_state
		$m$prjsub entryconfig [get_indep String DeleteProject]  -state $xref_state
		
		#close can only called, when there is another opend
		#windows, by sub windows it must be able to close
		#the window every time
		if {$subwindow == "subwindow" || [MultiWindow& @@ num_Existing_windows] > 1} {
			set closestate normal
		} else {
			set closestate disabled
		}
		$m entryconfig [get_indep String WindowsClose] -state $closestate
}
		
#Add project section
proc AddProjectMenuEntries {m topw {submenu 0}} {
	global sn_options sn_elix
	set origm $m
	
	#Add project commands into a submenu
	if {$submenu} {
		#Project submenu...
		set prjsub $m.prjsub
		menu $prjsub -tearoff 0

		$prjsub config -font $sn_options(def,layout-font)

		$m add cascade \
			-label [get_indep String ProjectMenu]\
			-underline [get_indep Pos ProjectMenu] \
			-menu $prjsub
			
		set m $prjsub
	}
	#project
	$m add command \
		-label [get_indep String NewProj] \
		-underline [get_indep Pos NewProj] \
		-command sn_new_project
		
	$m add command \
		-label [get_indep String OpenProject] \
		-underline [get_indep Pos OpenProject]\
		-command "MultiWindow& @@ file_open_project"

	$m add command \
		-label [get_indep String DeleteProject] \
		-underline [get_indep Pos DeleteProject]\
		-command "MultiWindow& @@ delete_current_project"
	
	if {$m == $origm} {
		$origm add command \
			-label [get_indep String CloseProject] \
			-underline [get_indep Pos CloseProject]\
			-command "MultiWindow& @@ file_close_project"
	}
	
	$m add separator
	
	#project editor
	$m add command \
		-label [get_indep String ProjectEditorMenu] \
		-underline [get_indep Pos ProjectEditorMenu] \
		-command project_editor
	
	#add preferences to the file menu (only in symbol browser)	
	$m add command \
			-label [get_indep String ProjectPreferencesMenu] \
			-underline [get_indep Pos ProjectPreferencesMenu] \
			-command "MultiWindow& @@ edit_proj_preferences 0"

	if {$sn_elix} {			
		# EL/IX config.
		$m add command \
			-label [get_indep String ElixPreferences] \
			-underline [get_indep Pos ElixPreferences] \
			-command "MultiWindow& @@ edit_elix_preferences"
	}

	#recent project files
	set recent $origm.recent
	menu $recent \
		-tearoff 0

	$origm add cascade \
		-label [get_indep String RecentProjects]\
		-underline [get_indep Pos RecentProjects] \
		-menu $recent
	ghosting_menu_item $origm [get_indep String RecentProjects] \
		"MultiWindow& @@ post_recent_project $recent $topw $m"

	if {$m != $origm} {
		$origm add command \
			-label [get_indep String CloseProject] \
			-underline [get_indep Pos CloseProject]\
			-command "MultiWindow& @@ file_close_project"
	}
	
}

###########################################################
## Miscellaneous tools
###########################################################
proc RescanProject {} {
	global sn_options sn_product_name
	
	#display a loading window
	sn_loading_message [get_indep String Scanning]
	
	watch y
	
	sn_parse_uptodate
	
	#delete the loading window
	hide_loading_message
	
	watch n
}

proc AddMiscSubMenu {m} {
	global sn_options

	set misc $m

	$misc config -font $sn_options(def,layout-font)

	#Refresh project
	$misc add command \
		-label [get_indep String ScanProject] \
		-underline [get_indep Pos ScanProject] \
		-command "RescanProject"

	#Reparse project
	$misc add command \
		-label [get_indep String Reparse] \
		-underline [get_indep Pos Reparse] \
		-command "Preferences& @@ Reparse ask"

	$misc add separator

	AddDebugFunctionality $misc

	# Ide Target Manager
	$misc add command \
		-label [get_indep String BuildTargetManager] \
		-underline [get_indep Pos BuildTargetManager] \
		-command "sn_start_build_manager"

	#Make
	$misc add command \
		-label [get_indep String MultiMake] \
		-underline [get_indep Pos MultiMake] \
		-command "sn_make"
}
	
############################################################
## Debugger functionality
############################################################
proc AddDebugFunctionality {m {topw ""}} {
		$m add command \
			-label [get_indep String DbgTitle] \
			-underline [get_indep Pos DbgTitle] \
			-command sn_debugger
}

###########################################################
## History menu
## Make History more fun
###########################################################
proc AddHistMenu {m} {
		global sn_options
		menu $m.history \
			-tearoff 0 \
			-postcommand "MultiWindow& @@ history_post $m.history"

		$m.history config -font $sn_options(def,layout-font)

	
		$m add cascade \
			-label [get_indep String History] \
			-menu $m.history \
			-underline [get_indep Pos History]
}

###########################################################
## Windows menu
## Make Windows with more fun
###########################################################
proc AddWindowsMenu {m cls {add_split 0} {add_views 1}} {
		global sn_options
		set win $m.windows
		menu $win \
			-postcommand "MultiWindow& @@ windows_post $cls $m.windows [expr $add_split + $add_views]" \
			-tearoff 0
		$m add cascade \
			-label [get_indep String Windows] \
			-menu $win \
			-underline [get_indep Pos Windows]
		
		$m.windows config -font $sn_options(def,layout-font)

		#Submenu to create views
		set new $m.windows.new
		menu $new \
			-tearoff 0 \
			-postcommand "MultiWindow& @@ windows_new_post $new"

		$new config -font $sn_options(def,layout-font)
	
		$m.windows add cascade \
			-label [get_indep String NewWork] \
			-menu $new \
			-underline [get_indep Pos NewWork]
			
		#New editor
		$new add command \
			-command "MultiWindow& @@ windows_new_window $new" \
			-label [get_indep String WindowsNew] \
			-underline [get_indep Pos WindowsNew] \
			-accelerator "F5"
			
		#New Class Hierarchy
		$new add command \
			-command "MultiWindow& @@ windows_new_window $new ctree" \
			-label [get_indep String MultiClassHierarchy] \
			-underline [get_indep Pos MultiClassHierarchy] \
			-accelerator "F6"
			
		#New Class
		$new add command \
			-command "MultiWindow& @@ windows_new_window $new classbr" \
			-label [get_indep String MultiClass] \
			-underline [get_indep Pos MultiClass] \
			-accelerator "F7"
			
		#New Xref
		$new add command \
			-command "MultiWindow& @@ windows_new_window $new xref" \
			-label [get_indep String MultiXRef] \
			-underline [get_indep Pos MultiXRef] \
			-accelerator "F8"
			
		#New Include
		$new add command \
			-command "MultiWindow& @@ windows_new_window $new incbr" \
			-label [get_indep String MultiInclude] \
			-underline [get_indep Pos MultiInclude] \
			-accelerator "F9"
			
		$new add separator
		
		#new 	CTree-Class
		$new add command \
			-command "MultiWindow& @@ windows_new_ctree_class $new" \
			-label [get_indep String WindowsNewCTreeClass] \
			-underline [get_indep Pos WindowsNewCTreeClass]
			
		#new 	Class-Edit
		$new add command \
			-command "MultiWindow& @@ windows_new_class_edit $new" \
			-label [get_indep String WindowsNewClassEditor] \
			-underline [get_indep Pos WindowsNewClassEditor]
			
		#new 	Class-Xref
		$new add command \
			-command "MultiWindow& @@ windows_new_class_xref $new" \
			-label [get_indep String WindowsNewClassXRef] \
			-underline [get_indep Pos WindowsNewClassXRef]
			
		#new 	Retriever-Edit
		$new add command \
			-command "MultiWindow& @@ windows_new_retr_edit $new" \
			-label [get_indep String WindowsNewRetrEditor] \
			-underline [get_indep Pos WindowsNewRetrEditor]
			
		#new 	Find-Edit
		$new add command \
			-command "MultiWindow& @@ windows_new_find_edit $new" \
			-label [get_indep String WindowsNewFindEditor] \
			-underline [get_indep Pos WindowsNewFindEditor]
			
		#new 	CTreeClassEditor
		$new add command \
			-command "MultiWindow& @@ windows_new_ctree_class_edit $new" \
			-label [get_indep String WindowsNewCTreeClassEditor] \
			-underline [get_indep Pos WindowsNewCTreeClassEditor]
			
		$new add separator
		
		#New Symbol browser
		$new add command \
			-command "MultiWindow& @@ windows_new_symbr $new" \
			-label [get_indep String MultiBrowser] \
			-underline [get_indep Pos MultiBrowser] \
			-accelerator "F4"
			
		#We support now splited windows
		if {$add_split && $cls != ""} {
			set split $win.split
			menu $split \
				-postcommand "$cls windows_split_post $split" \
				-tearoff 0

			$split config -font $sn_options(def,layout-font)

			$win add cascade \
				-label [get_indep String SplitInto] \
				-menu $split \
				-underline [get_indep Pos SplitInto]
				
			#split into editor
			$split add command \
				-command "$cls windows_splitinto_edit $split" \
				-label [get_indep String SplitIntoEditor] \
				-underline [get_indep Pos SplitIntoEditor] \
				-accelerator "Ctrl+F5"
			#split into class hierarchy
			$split add command \
				-command "$cls windows_splitinto_ctree $split" \
				-label [get_indep String SplitIntoClassHierarchy] \
				-underline [get_indep Pos SplitIntoClassHierarchy] \
				-accelerator "Ctrl+F6"
			#split into class
			$split add command \
				-command "$cls windows_splitinto_classbr $split" \
				-label [get_indep String SplitIntoClass] \
				-underline [get_indep Pos SplitIntoClass] \
				-accelerator "Ctrl+F7"
			#split into xref
			$split add command \
				-command "$cls windows_splitinto_xref $split" \
				-label [get_indep String SplitIntoXRef] \
				-underline [get_indep Pos SplitIntoXRef] \
				-accelerator "Ctrl+F8"
			#split into include browser
			$split add command \
				-command "$cls windows_splitinto_incbr $split" \
				-label [get_indep String SplitIntoInclude] \
				-underline [get_indep Pos SplitIntoInclude] \
				-accelerator "Ctrl+F9"

			#split into build winow
			$split add command \
				-command "$cls windows_splitinto_build $split" \
				-label [get_indep String BuildMenuItem] \
				-underline [get_indep Pos BuildMenuItem] \
				-accelerator "Ctrl+F10"

			$split add separator
			#delete last pane
			$split add command \
				-command "$cls windows_delete_last_pane $split" \
				-label [get_indep String SplitDeleteLast] \
				-underline [get_indep Pos SplitDeleteLast] \
				-accelerator "Ctrl+F4"
		}
		######################################################
		#Availiable Views
		#To list the availiable views
		######################################################
		if {$add_views} {
			set views $win.views
			menu $views \
				-postcommand "MultiWindow& @@ windows_views_post $views" \
				-tearoff 0
			$win add cascade \
				-label [get_indep String Views] \
				-menu $views \
				-underline [get_indep Pos Views]
				
			#Editor views
			set edview $views.edit
			menu $edview \
				-postcommand "MultiWindow& @@ windows_views_edit_post $edview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiEditor] \
				-menu $edview \
				-underline [get_indep Pos MultiEditor]
				
			#Hierarchy views
			set hview $views.ctree
			menu $hview \
				-postcommand "MultiWindow& @@ windows_views_ctree_post $hview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiClassHierarchy] \
				-menu $hview \
				-underline [get_indep Pos MultiClassHierarchy]
				
			#class views
			set cview $views.class
			menu $cview \
				-postcommand "MultiWindow& @@ windows_views_class_post $cview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiClass] \
				-menu $cview \
				-underline [get_indep Pos MultiClass]
				
			#xref views
			set xview $views.xview
			menu $xview \
				-postcommand "MultiWindow& @@ windows_views_xref_post $xview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiXRef] \
				-menu $xview \
				-underline [get_indep Pos MultiXRef]
				
			#include views
			set iview $views.iview
			menu $iview \
				-postcommand "MultiWindow& @@ windows_views_inc_post $iview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiInclude] \
				-menu $iview \
				-underline [get_indep Pos MultiInclude]
				
			#retriever views
			set rview $views.rview
			menu $rview \
				-postcommand "MultiWindow& @@ windows_views_retr_post $rview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiRetriever] \
				-menu $rview \
				-underline [get_indep Pos MultiRetriever]
				
			#grep views
			set gview $views.gview
			menu $gview \
				-postcommand "MultiWindow& @@ windows_views_grep_post $gview" \
				-tearoff 0
			$views add cascade \
				-label [get_indep String MultiGrep] \
				-menu $gview \
				-underline [get_indep Pos MultiGrep]
		}
		######################################################
		#END of availiable views
		######################################################
			
		#iconize project
		$m.windows add command \
			-command "MultiWindow& @@ windows_iconize $m.windows $cls" \
			-label [get_indep String WindowsIconize] \
			-underline [get_indep Pos WindowsIconize]
		$m.windows add separator
		$m.windows add command \
			-label "dummy"
}
	
proc raise_toplevel {w} {
	global sn_force_flag
	if {[wm state $w] == "iconic"} {
		wm deiconify $w
	} else {
		#make sure that the window has focus on windows
		catch {
			set wdg [focus -lastfor $w]
			eval focus $sn_force_flag [$w twidget]
			focus $wdg
		}
		raise $w
	}
}

#Help menu
proc AddHelpMenu {m topw} {
		global sn_options
		menu $m.help \
			-tearoff 0
		$m add cascade \
			-label [get_indep String Help] \
			-menu $m.help \
			-underline [get_indep Pos Help]

		$m.help config -font $sn_options(def,layout-font)

		$m.help add command \
			-command "sn_help" \
			-label [get_indep String HelpContents] \
			-underline [get_indep Pos HelpContents]

		$m.help add command \
			-label [get_indep String Abrav] \
			-underline [get_indep Pos Abrav] \
			-command "sn_show_abbrav"

		$m.help add separator
		
		$m.help add command \
			-label [get_indep String Version] \
			-underline [get_indep Pos Version] \
			-command "focus $topw; sn_show_version_window"
}

#Synchronize more than one editor with the same file name
#to contain the same data.
global SyncEditors_Disabled
set SyncEditors_Disabled 0
proc SyncEditors {cls args} {
	global sn_options
	global SyncEditors_Disabled
	
	if {$SyncEditors_Disabled} {
		return
	}
	set file [$cls cget -filename]
	#edit a new file
	if {$file != $sn_options(noname_file)} {
		set editor [$cls editor]
		set cmd [lindex $args 0]
		
		switch $cmd {
		"insert" {
			set pos [$editor index [lindex $args 1]]
			set args [lreplace $args 1 1 $pos]
			if {[string compare [lindex $args 2] ""] == 0} {
				return
			}
			}
		"delete" {
			set pos1 [$editor index [lindex $args 1]]
			set args [lreplace $args 1 1 $pos1]
			set pos2 [lindex $args 2]
			if {$pos2 != ""} {
				set pos2 [$editor index $pos2]
				set args [lreplace $args 2 2 $pos2]
			}
			}
		default {
			return
			}
		}
		foreach obj [itcl_info objects "*" -class Editor&] {
			if {$obj != $cls && [$obj cget -filename] == $file} {
				eval [$obj editor] $args
				if {[$obj cget -file_changed] == 0} {
					$obj setmodified 1
					$obj SetTitle
				}
			}
		}
	}
	if {[$cls cget -file_changed] == 0} {
		$cls setmodified 1
		$cls SetTitle
	}
}

#########################################################
# Global keybindings
#########################################################

#returns the current class from the active window
proc get_active_class {} {
	set fcs [focus]
	if {$fcs == ""} {
		return ""
	}
	set cls ".[lindex [split $fcs .] 1]"
	if {$cls == "."} {
		return ""
	}
	return $cls
}
proc del_last_view {} {
	set cls [get_active_class]
	if {$cls == ""} {
		bell; return
	}
	catch {$cls windows_delete_last_pane ""}
}
proc add_view {vw} {
	set cls [get_active_class]
	if {$cls == ""} {
		bell; return
	}
	catch {$cls windows_splitinto_$vw}
}
proc switch_to_view {view} {
	set cls [get_active_class]
	if {$cls == ""} {
		bell; return
	}
	#verify if the view can be launched
	if {[tool_Exists $view] != "normal"} {
		bell; return
	}
	catch {$cls view $view}
}
proc main_print {w} {
	catch {[winfo toplevel $w] file_print}
}
proc close_main_window {w} {
	#this procedure is bound on Control-w, so don't
	#close window when it's the last one in the project
	if {[MultiWindow& @@ num_Existing_windows] > 1} {
		catch {[winfo toplevel $w] windows_close dummy}
	}
}
proc find_dialog {w} {
	catch {[winfo toplevel $w] search_findtext}
}
proc switch_to_next_view {w} {
	catch {[winfo toplevel $w] switch_to_next_view $w}
}
##############################################################
## End of keybindings
##############################################################

proc sn_start_build_manager {} {

    if {[itcl_info objects .build_manager]!=""} {
	.build_manager raise
    } else {
	snIdeTargetMgr .build_manager
    }

}

# dbg_start
# Start the nominated debugger.  Pop up an error dialog if the exec fails.

proc dbg_start {} {
	global sn_options
	
	set cmd $sn_options(def,gdb-command)
	if {[catch {exec $cmd &} msg] != 0} {
	    sn_error_dialog $msg
	}
}

#Last accessed editor
set last_Editor ""

