note description : "Main window for this application" author : "Generated by the New Vision2 Application Wizard." date : "$Date$" revision : "1.0.0" class CTR_WINDOW inherit EV_TITLED_WINDOW redefine initialize, is_in_default_state, create_interface_objects end EV_SHARED_APPLICATION undefine default_create, copy end INTERFACE_NAMES export {NONE} all undefine default_create, copy end CTR_SHARED_RESOURCES export {NONE} all undefine default_create, copy end CTR_SHARED_GUI_PREFERENCES export {NONE} all undefine default_create, copy end create default_create feature {NONE} -- Initialization docking_manager: detachable like new_docking_manager new_docking_manager: SD_DOCKING_MANAGER do create Result.make (main_container, Current) end create_interface_objects local args: ARGUMENTS l_preferences: CTR_GUI_PREFERENCES do Precursor create args if attached args.separate_word_option_value (names.opt_word_config) as s and then not s.is_empty then set_common_data_folder (s) else set_common_data_folder ("data") end create l_preferences.make (preferences_xml_filename) set_preferences (l_preferences) create catalog_grid create catalog_content.make_with_widget (catalog_grid, Names.t_catalog, docking_manager) create standard_status_bar create standard_status_label create main_container create logs_tool.make (Names.t_logs, docking_manager) create info_tool.make (Names.t_info, docking_manager) create console_tool.make (Names.t_console, docking_manager) end initialize -- Build the interface for this window. local dm: like docking_manager do Precursor {EV_TITLED_WINDOW} logs_tool.set_ctr_window (Current) info_tool.set_ctr_window (Current) console_tool.set_ctr_window (Current) -- Create and add the status bar. build_standard_status_bar lower_bar.extend (standard_status_bar) extend (main_container) dm := docking_manager if dm = Void then dm := new_docking_manager docking_manager := dm end build_tools restore_docking_layout -- apply_default_layout -- Execute `request_close_window' when the user clicks -- on the cross in the title bar. close_request_actions.extend (agent request_close_window) -- Set the title of the window set_title (Window_title) -- Set the initial size of the window set_size (Window_width, Window_height) show_actions.extend_kamikaze (agent on_first_shown) console.register_observer (console_tool) init_accelerators console_log ("Opening configuration from %"" + common_data_folder + "%"") end init_accelerators local acc: EV_ACCELERATOR acc_n_key: ACCELERATOR_AND_THEN_KEY k: EV_KEY do --| Ctrl+G ... ? create k.make_with_code ({EV_KEY_CONSTANTS}.key_G) create acc.make_with_key_combination (k, True, False, False) create acc_n_key.make (acc, Current) create k.make_with_code ({EV_KEY_CONSTANTS}.key_C) acc_n_key.register_action (k, agent console_tool.set_focus, [Names.t_console, Names.d_go_to_console_tool]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_R) acc_n_key.register_action (k, agent catalog_grid.set_focus, [Names.t_repositories, Names.d_go_to_catalog_tool]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_L) acc_n_key.register_action (k, agent logs_tool.set_focus, [Names.t_logs, Names.d_go_to_logs_tool]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_I) acc_n_key.register_action (k, agent info_tool.set_focus, [Names.t_info, Names.d_go_to_info_tool]) acc_n_key.enable_popup acc_n_key.attach_to (accelerators, True) --| Ctrl+E ... ? create k.make_with_code ({EV_KEY_CONSTANTS}.key_E) create acc.make_with_key_combination (k, True, False, False) create acc_n_key.make (acc, Current) create k.make_with_code ({EV_KEY_CONSTANTS}.key_A) acc_n_key.register_action (k, agent check_all_repositories, [Names.t_check_all_repositories, Names.d_check_all_repositories]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_C) acc_n_key.register_action (k, agent edit_configuration, [Names.t_edit_repositories, Names.d_edit_repositories]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_P) acc_n_key.register_action (k, agent edit_preferences, [Names.t_edit_preferences, Names.d_edit_preferences]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_I) acc_n_key.register_action (k, agent show_information, [Names.t_show_information, Names.d_show_information]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_L) acc_n_key.register_action (k, agent apply_default_layout, [Names.t_reset_layout, Void]) create k.make_with_code ({EV_KEY_CONSTANTS}.key_X) acc_n_key.register_action (k, agent export_to, [Names.t_export_to, Void]) acc_n_key.enable_popup acc_n_key.attach_to (accelerators, True) create k.make_with_code ({EV_KEY_CONSTANTS}.key_F5) create acc.make_with_key_combination (k, False, False, False) acc.actions.extend (agent do logs_tool.check_current_repositories end) accelerators.extend (acc) end is_in_default_state: BOOLEAN -- Is the window in its default state -- (as stated in `initialize') do Result := (width = Window_width) and then (height = Window_height) and then (title.is_equal (Window_title)) end feature {NONE} -- Events reload_catalog do load_catalog_from_ini update_catalog end on_first_shown do load_catalog_from_ini if True then save_catalog_as_ini (".bak") end update_catalog -- check_all_repositories end on_quit local r: INTEGER g: like catalog_grid l_row: EV_GRID_ROW do if attached catalog as cat then from g := catalog_grid r := 1 until r > g.row_count loop l_row := g.row (r) if l_row.parent_row = Void and attached repository_from_row (l_row) as rdata then rdata.save_unread_logs end r := r + 1 end end save_docking_layout if attached preferences as prefs then prefs.save_preferences end end feature -- Data export_to do if attached selected_repositories as repos then across repos as c loop c.item.export_to_sqlite end end end feature -- Layout save_docking_layout local b: BOOLEAN do if attached docking_manager as dm then b := dm.save_data (docking_layout_filename) -- b := dm.save_editors_data (docking_layout_editors_filename) -- b := dm.save_tools_data (docking_layout_tools_filename) end end docking_layout_filename: STRING once Result := "data" + operating_environment.directory_separator.out + "layout.db" end docking_layout_tools_filename: STRING once Result := "data" + operating_environment.directory_separator.out + "layout-tools.db" end docking_layout_editors_filename: STRING once Result := "data" + operating_environment.directory_separator.out + "layout-editors.db" end restore_docking_layout local b, layout_set: BOOLEAN retried: BOOLEAN do if not retried then if attached docking_manager as dm then b := True layout_set := False if dm.is_config_data_valid (docking_layout_filename) then b := dm.open_config (docking_layout_filename) layout_set := True end if dm.is_config_data_valid (docking_layout_editors_filename) then dm.open_editors_config (docking_layout_editors_filename) layout_set := True end if dm.is_config_data_valid (docking_layout_tools_filename) then b := dm.open_tools_config (docking_layout_tools_filename) layout_set := True end end if not layout_set or not b then apply_default_layout end else apply_default_layout end rescue retried := True retry end apply_default_layout do if attached docking_manager as dm then catalog_content.set_top ({SD_ENUMERATION}.top) logs_tool.sd_content.set_top ({SD_ENUMERATION}.right) info_tool.sd_content.set_relative (logs_tool.sd_content, {SD_ENUMERATION}.bottom) -- console_tool.sd_content.set_relative (logs_tool.sd_content, {SD_ENUMERATION}.bottom) console_tool.sd_content.set_auto_hide ({SD_ENUMERATION}.bottom) console_tool.sd_content.set_floating_height (200) if not catalog_content.is_visible then catalog_content.show end if not logs_tool.sd_content.is_visible then logs_tool.sd_content.show end if not info_tool.sd_content.is_visible then info_tool.sd_content.show end if not console_tool.sd_content.is_visible then console_tool.sd_content.show end dm.close_editor_place_holder end show_actions.extend_kamikaze (agent (ac0,ac1,ac2: SD_CONTENT) do ac0.set_split_proportion ({REAL_32} 0.3) ac1.set_split_proportion ({REAL_32} 0.3) ac2.set_split_proportion ({REAL_32} 0.7) end (catalog_content, logs_tool.sd_content, info_tool.sd_content) ) ensure catalog_visible: catalog_content.is_visible logs_visible: logs_tool.sd_content.is_visible info_visible: info_tool.sd_content.is_visible end feature -- Storage preferences_xml_filename: STRING local fn: FILE_NAME once create fn.make_from_string (common_data_folder) fn.set_file_name ("preferences") fn.add_extension ("xml") Result := fn.string end catalog_ini_filename: STRING local fn: FILE_NAME once create fn.make_from_string (common_data_folder) fn.set_file_name ("catalog") fn.add_extension ("ini") Result := fn.string end load_catalog_from_ini local cat: like catalog rf: RAW_FILE repo: detachable REPOSITORY svnrepo: detachable REPOSITORY_SVN n,k: detachable STRING p,i: INTEGER s,s2,s3: STRING v: STRING l_svn_path_pref: detachable STRING_PREFERENCE do create rf.make (catalog_ini_filename) if rf.exists then if attached preferences as prefs then l_svn_path_pref := prefs.svn_executable_pref -- l_svn_path_pref.change_actions.extend (agent -- do -- reload_catalog -- end -- ) end rf.open_read from create cat.make rf.start until rf.exhausted loop rf.read_line s := rf.last_string s.left_adjust if s.count > 0 then if s.item (1) = '#' then --| skip if repo /= Void then s.remove_head (1) repo.add_comment (s.string) end elseif s.item (1) = '[' then if repo /= Void and then attached repo.location as loc then if n /= Void then cat.add_repository (n, repo) else cat.add_repository (loc, repo) end end s.right_adjust n := s.substring (2, s.last_index_of (']', s.count) - 1) i := n.index_of (':', 1) if i > 0 then k := n.substring (1, i - 1) k.left_adjust k.right_adjust k.to_lower n := n.substring (i + 1, n.count) end n.left_adjust n.right_adjust if k /= Void and then not k.is_empty then if k.same_string ("svn") then create svnrepo.make repo := svnrepo if l_svn_path_pref /= Void and then not l_svn_path_pref.value.is_empty then svnrepo.set_svn_executable_path (l_svn_path_pref.value) end else --|, cvs, git, ... create {REPOSITORY_SVN} repo.make end end elseif repo /= Void then p := s.index_of ('=', 1) v := s.substring (p + 1, s.count) if p = 0 then print ("???: " + s + "%N") elseif s.substring (1, p -1).same_string ("uuid") then v.left_adjust; v.right_adjust repo.set_uuid (create {UUID}.make_from_string (v)) elseif s.substring (1, p -1).same_string ("location") then v.left_adjust; v.right_adjust repo.set_location (v) elseif s.substring (1, p -1).same_string ("username") then v.left_adjust; v.right_adjust repo.set_username (v) elseif s.substring (1, p -1).same_string ("password") then repo.set_password (v) elseif s.substring (1, 6).same_string ("review") then s2 := s.substring (7, p - 1) s2.to_lower if s2.is_empty then v.left_adjust; v.right_adjust repo.set_review_enabled (v.is_case_insensitive_equal ("on")) elseif s2.item (1) = '.' then s2.remove_head (1) s2.left_adjust; s2.right_adjust s2.to_lower v.left_adjust; v.right_adjust repo.add_review_variable (v, s2) end elseif s.substring (1, 6).same_string ("tokens") then s2 := s.substring (7, p - 1) s2.to_lower if s2.is_empty then elseif s2.item (1) = '.' then s2.remove_head (1) p := s2.index_of ('.', 1) if p > 0 then k := s2.substring (1, p - 1).as_lower s3 := s2.substring (p + 1, s2.count).as_lower if s3.same_string ("key") then v.left_adjust; v.right_adjust repo.add_token (k, v, Void) elseif s3.same_string ("url") then v.left_adjust; v.right_adjust repo.add_token (k, Void, v) end end end elseif s.substring (1, 7).same_string ("filters") then s2 := s.substring (8, p - 1) s2.to_lower if s2.is_empty then elseif s2.item (1) = '.' then s2.remove_head (1) p := s2.last_index_of ('.', s2.count) if p = 0 then k := s2 v.left_adjust; v.right_adjust s3 := "" else k := s2.substring (1, p - 1) s3 := s2.substring (p + 1, s2.count).as_lower end if s3.is_empty then repo.add_filter (k, v) else if s3.same_string ("author") then if repo.filter (k) = Void then repo.add_filter (k, k) end v.left_adjust; v.right_adjust repo.add_filter_to (k, create {REPOSITORY_LOG_AUTHOR_FILTER}.make (v)) elseif s3.same_string ("path") then if repo.filter (k) = Void then repo.add_filter (k, k) end v.left_adjust; v.right_adjust repo.add_filter_to (k, create {REPOSITORY_LOG_PATH_FILTER}.make (v)) elseif s3.same_string ("message") then if repo.filter (k) = Void then repo.add_filter (k, k) end -- v.left_adjust; v.right_adjust repo.add_filter_to (k, create {REPOSITORY_LOG_MESSAGE_FILTER}.make (v)) elseif s3.same_string ("read") then if repo.filter (k) = Void then repo.add_filter (k, k) end v.left_adjust; v.right_adjust v.to_lower repo.add_filter_to (k, create {REPOSITORY_LOG_READ_STATUS_FILTER}.make_read ( v.same_string ("yes") or v.same_string ("true") ) ) else k := s2 if repo.filter (k) = Void then repo.add_filter (k, v) end end end end else s2 := s.substring (1, p - 1) if not s2.is_empty then p := s2.index_of ('.', 1) repo.add_free_configuration (s2, v) else print ("???: " + s + "%N") end end else print ("???: " + s + "%N") end end end if repo /= Void and then attached repo.location as loc then if n /= Void then cat.add_repository (n, repo) else cat.add_repository (loc, repo) end end rf.close end -- if cat = Void or else cat.repositories.is_empty then -- create cat.make -- create svn_repo.make_with_location ("https://svn.eiffel.com/eiffelstudio/trunk") -- cat.add_repository ("EiffelStudio/trunk", svn_repo) -- create svn_repo.make_with_location ("https://svn.eiffel.com/eiffelstudio/branches/Eiffel_66") -- cat.add_repository ("EiffelStudio/66", svn_repo) -- end catalog := cat end save_catalog_as_ini (a_extra: detachable STRING) local rf: RAW_FILE do if attached catalog_to_ini as t then if a_extra /= Void then create rf.make (catalog_ini_filename + a_extra) else create rf.make (catalog_ini_filename) end if not rf.exists or else rf.is_writable then rf.create_read_write rf.put_string (t) rf.close end end end catalog_to_ini: detachable STRING local n: STRING t: STRING do if attached catalog as cat then create Result.make (100) across cat.repositories as c loop n := c.key.string t := c.item.kind n.replace_substring_all ("]", " ") Result.append_string ("[" + t + ":" + n + "]%N") Result.append_string ("uuid=" + c.item.uuid.out + "%N") Result.append_string ("location=" + c.item.location + "%N") if attached c.item.username as u then Result.append_string ("username=" + u.out + "%N") end if attached c.item.password as p then Result.append_string ("password=" + p.out + "%N") end if c.item.review_enabled then Result.append_string ("review=on%N") end if attached c.item.review_variables as l_rev_vars then across l_rev_vars as rvc loop Result.append_string ("review." + rvc.key + "=" + rvc.item + "%N") end end if attached c.item.tokens as l_tokens then across l_tokens as tok loop Result.append_string ("tokens." + tok.key + ".key=" + tok.item.key + "%N") Result.append_string ("tokens." + tok.key + ".url=" + tok.item.url_pattern + "%N") end end if attached c.item.filters as l_filters then across l_filters as flt loop if not flt.key.same_string (flt.item.name) then Result.append_string ("filters." + flt.key + "=" + flt.item.name + "%N") end Result.append_string (filter_to_ini_line (flt.key, flt.item.filter)) end end -- if attached c.item.services as l_services then -- across -- l_services as l_services_cursor -- loop -- Result.append_string ("service.") -- Result.append_string (l_services_cursor.key.name) -- if attached l_services_cursor.key.param as l_param then -- Result.append_charactor ('.') -- Result.append_string (l_param) -- end -- Result.append_charactor ('=') -- Result.append_string (l_services_cursor.item) -- Result.append_charactor ('%N') -- end -- end if attached c.item.free_configuration_values as l_free_configuration_values then across l_free_configuration_values as l_free_vals_cursor loop if attached l_free_vals_cursor.item as l_free_opt then if l_free_opt.name.item (1) = '#' then Result.append_string ("#" + l_free_opt.value + "%N") else Result.append_string (l_free_opt.name + "=" + l_free_opt.value + "%N") end end end end Result.append_character ('%N') end end end filter_to_ini_line (k: STRING; f: detachable REPOSITORY_LOG_FILTER): STRING do if f = Void then create Result.make_empty elseif attached {REPOSITORY_LOG_GROUP_FILTER} f as fg then create Result.make_empty across fg.filters as fi loop Result.append_string (filter_to_ini_line (k, fi.item)) end else Result := "filters." + k if attached {REPOSITORY_LOG_AUTHOR_FILTER} f as fauth then Result.append_string (".author=") Result.append_string (fauth.author) elseif attached {REPOSITORY_LOG_PATH_FILTER} f as fpath then Result.append_string (".path=") Result.append_string (fpath.path) elseif attached {REPOSITORY_LOG_MESSAGE_FILTER} f as fmsg then Result.append_string (".message=") Result.append_string (fmsg.message) else end Result.append_character ('%N') end end feature -- Preferences internal_preferences_dialog: detachable PREFERENCES_GRID_DIALOG edit_preferences local dlg: like internal_preferences_dialog do dlg := internal_preferences_dialog if dlg = Void then if attached preferences as p then create dlg.make (p.preferences) end end if dlg /= Void then dlg.show_relative_to_window (Current) end end feature -- Information show_information local dlg: EV_POPUP_WINDOW txt: EV_TEXT but: EV_BUTTON b: EV_VERTICAL_BOX do create dlg.make_with_shadow create txt create but.make_with_text_and_action ("Close", agent dlg.destroy) create b dlg.extend (b) b.extend (txt) b.extend (but) b.disable_item_expand (but) txt.set_text ("Information") txt.append_text ("%Ndata folder=" + common_data_folder + "%N") if attached txt.font.string_size (txt.text) as t then dlg.set_size (t.width, t.height) dlg.set_position (x_position + (width - dlg.width) // 2, y_position + (height - dlg.height) // 2) else dlg.set_size (width, height) dlg.set_position (x_position, y_position) end dlg.close_request_actions.extend (agent dlg.destroy) dlg.show_relative_to_window (Current) end feature -- Configuration edit_configuration local dlg: EV_TITLED_WINDOW but: EV_BUTTON m: EV_VERTICAL_BOX t: EV_TEXT s: detachable STRING do s := catalog_to_ini create dlg create m create t create but.make_with_text_and_action ("Save", agent (a_dlg: EV_WINDOW; a_text: EV_TEXT) local i_txt: STRING i_pf: PLAIN_TEXT_FILE do i_txt := a_text.text.as_string_8 create i_pf.make (catalog_ini_filename) if not i_pf.exists or else i_pf.is_writable then i_pf.create_read_write i_pf.put_string (i_txt) i_pf.close end a_dlg.destroy reload_catalog end (dlg, t) ) dlg.extend (m) m.extend (t) m.extend (but) m.disable_item_expand (but) -- create but.make_with_text_and_action ("Cancel", agent dlg.destroy) -- m.extend (but) -- m.disable_item_expand (but) if s = Void then s := "[ [svn:EiffelStudio/trunk] location=https://svn.eiffel.com/eiffelstudio/trunk review=on review.user=your_login review.password=your_password review.domain=community.ise review.apikey=d0e8536407db776b80225d7d3c1750a2 review.endpoint=/ctr/services/xmlrpc tokens.issue.key=bug tokens.issue.url=https://www2.eiffel.com/support/protected/report.aspx?pr=$$ tokens.test.key=test tokens.test.url=http://svn.origo.ethz.ch/viewvc/eiffelstudio/trunk/eweasel/tests/$$/tcf?view=markup ]" end t.set_text (s) dlg.close_request_actions.extend (agent dlg.destroy) dlg.set_position (x_position, y_position) dlg.set_size (width, height) dlg.enable_border dlg.enable_user_resize dlg.show_relative_to_window (Current) end show_help local dlg: EV_TITLED_WINDOW m: EV_VERTICAL_BOX t: EV_TEXT s: detachable STRING do create dlg create m create t dlg.extend (m) m.extend (t) s := "[ Quick Help: (For now, there is no documentation for buttons, and whatever you can figure out by looking at the interface) Hidden commands: Ctrl+E ... and see popup window Ctrl+G ... and see popup window F5: refresh logs Logs tool: Space: mark selected logs as read Ins: toggle selected logs between read and unread Command line: -$OPT_WORD_CONFIG: path to data folder ]" s.replace_substring_all ("$OPT_WORD_CONFIG", names.opt_word_config) t.set_text (s) dlg.close_request_actions.extend (agent dlg.destroy) dlg.set_position (x_position, y_position) dlg.set_size (width, height) dlg.enable_border dlg.enable_user_resize dlg.show_relative_to_window (Current) end not_yet_implemented local p: EV_POPUP_WINDOW lab: EV_LABEL do create p.make_with_shadow create lab.make_with_text ("Not Yet Implemented") p.extend (lab) p.set_size (200,50) p.set_position ((x_position + width) // 2 + (p.width // 2), (y_position + height) // 2 + (p.height // 2)) lab.pointer_button_press_actions.force_extend (agent p.destroy) lab.focus_out_actions.extend (agent p.destroy) p.show_relative_to_window (Current) lab.set_focus end feature -- Check/Update/Refresh selected_repositories: detachable LIST [REPOSITORY_DATA] local g: like catalog_grid l_rows: LIST [EV_GRID_ROW] r: EV_GRID_ROW do g := catalog_grid l_rows := g.selected_rows if l_rows.count = 1 then r := l_rows.first if attached r.parent_row_root as pr then r := pr end if attached repository_from_row (r) as d then create {LINKED_LIST [REPOSITORY_DATA]} Result.make Result.extend (d) end elseif l_rows.count > 0 then create {LINKED_LIST [REPOSITORY_DATA]} Result.make across l_rows as c loop r := c.item if attached r.parent_row_root as pr then r := pr end if attached repository_from_row (r) as d then Result.extend (d) end end if Result.count = 0 then Result := Void end else Result := all_repositories end end all_repositories: like selected_repositories local g: like catalog_grid r: EV_GRID_ROW i: INTEGER do g := catalog_grid create {LINKED_LIST [REPOSITORY_DATA]} Result.make from i := 1 until i > g.row_count loop r := g.row (i) if r.parent_row = Void and attached repository_from_row (r) as d then Result.extend (d) end i := i + 1 end end check_selected_repositories local g: like catalog_grid l_rows: LIST [EV_GRID_ROW] r: EV_GRID_ROW do g := catalog_grid l_rows := g.selected_rows if l_rows.count = 1 then r := l_rows.first if attached r.parent_row_root as pr then r := pr end if attached repository_from_row (r) as d then check_repository (d) end elseif l_rows.count > 0 then across l_rows as c loop r := c.item if attached r.parent_row_root as pr then r := pr end if attached repository_from_row (r) as d then check_repository (d) end end else check_all_repositories end end check_all_repositories local g: like catalog_grid r: EV_GRID_ROW i: INTEGER do console_log ("Check all repositories") g := catalog_grid from i := 1 until i > g.row_count loop r := g.row (i) if r.parent_row = Void and attached repository_from_row (r) as d then check_repository (d) end i := i + 1 end end check_repository (a_repo: REPOSITORY_DATA) do console_log ("Check repository: " + a_repo.repository_location) if ev_application.ctrl_pressed then gui_check_repository (a_repo) else if attached {REPOSITORY_SVN_DATA} a_repo as rsvndata then if not rsvndata.is_asynchronious_fetching then ev_application.do_once_on_idle (agent add_asynchronious_svn_task (rsvndata)) end else ev_application.do_once_on_idle (agent a_repo.fetch_logs) end end end gui_check_repository (a_repo: REPOSITORY_DATA) local dlg: EV_DIALOG hb: EV_HORIZONTAL_BOX tf1,tf2: EV_TEXT_FIELD but: EV_BUTTON do if attached {REPOSITORY_SVN_DATA} a_repo as rsvndata then create dlg.make_with_title ("Fetch svn logs from to") create hb dlg.extend (hb) create tf1.make_with_text (rsvndata.revision_first_known.out) create tf2.make_with_text (rsvndata.revision_last_known.out) hb.extend (tf1) hb.extend (tf2) create but.make_with_text_and_action ("Close", agent dlg.destroy) dlg.set_default_cancel_button (but) create but.make_with_text_and_action ("Fetch", agent (ia_dlg: EV_DIALOG; ia_t1, ia_t2: EV_TEXTABLE; ia_repo: REPOSITORY_DATA) local r1,r2: INTEGER s: STRING_8 do s := ia_t1.text.as_string_8 if s.is_integer then r1 := s.to_integer end s := ia_t2.text.as_string_8 if s.is_integer then r2 := s.to_integer end if r2 > r1 then set_busy ia_repo.fetch_range_of_logs (r1, r2) unset_busy end ia_dlg.destroy end(dlg, tf1, tf2, rsvndata) ) hb.extend (but) hb.disable_item_expand (but) dlg.show_modal_to_window (Current) end end feature {NONE} -- Asynchronious operation asynchronious_svn_tasks: detachable ARRAYED_LIST [REPOSITORY_SVN_DATA] asynchronious_svn_tasks_scheduler_action: detachable PROCEDURE check_asynchronious_svn_tasks do debug if attached standard_status_label.text as s then if s.same_string ("_") then standard_status_label.set_text (" ") else standard_status_label.set_text ("_") end end end if attached asynchronious_svn_tasks as l_tasks then check has_task: not l_tasks.is_empty end from l_tasks.start until l_tasks.after loop if attached l_tasks.item as rsvndata and then rsvndata.has_fetched_data then l_tasks.remove if l_tasks.is_empty then if attached asynchronious_svn_tasks_scheduler as l_scheduler then l_scheduler.destroy asynchronious_svn_tasks_scheduler := Void else check scheduler_exists: False end end end standard_status_label.set_text ("Get logs for " + rsvndata.repository_location) rsvndata.import_fetched_logs if rsvndata = logs_tool.current_repository then logs_tool.update info_tool.update_current_repository (rsvndata) end if attached catalog_repository_row (rsvndata) as l_row then update_catalog_row (l_row) l_row.set_background_color (bgcolor_checked) end standard_status_label.set_text ("Updated: " + rsvndata.repository_location) else l_tasks.forth end end end end asynchronious_svn_tasks_scheduler: detachable EV_TIMEOUT add_asynchronious_svn_task (a_rsvndata: REPOSITORY_SVN_DATA) local l_asynchronious_svn_tasks: like asynchronious_svn_tasks l_asynchronious_svn_tasks_scheduler: like asynchronious_svn_tasks_scheduler l_asynchronious_svn_tasks_scheduler_action: like asynchronious_svn_tasks_scheduler_action do --| Execute task a_rsvndata.asynchronious_fetch_logs standard_status_label.set_text ("Check: " + a_rsvndata.repository_location) if attached catalog_repository_row (a_rsvndata) as l_row then l_row.set_background_color (bgcolor_checking) end --| Handle scheduler l_asynchronious_svn_tasks := asynchronious_svn_tasks if l_asynchronious_svn_tasks = Void then create l_asynchronious_svn_tasks.make (10) asynchronious_svn_tasks := l_asynchronious_svn_tasks end l_asynchronious_svn_tasks.extend (a_rsvndata) l_asynchronious_svn_tasks_scheduler_action := asynchronious_svn_tasks_scheduler_action if l_asynchronious_svn_tasks_scheduler_action = Void then l_asynchronious_svn_tasks_scheduler_action := agent check_asynchronious_svn_tasks asynchronious_svn_tasks_scheduler_action := l_asynchronious_svn_tasks_scheduler_action end l_asynchronious_svn_tasks_scheduler := asynchronious_svn_tasks_scheduler if l_asynchronious_svn_tasks_scheduler = Void then create l_asynchronious_svn_tasks_scheduler asynchronious_svn_tasks_scheduler := l_asynchronious_svn_tasks_scheduler l_asynchronious_svn_tasks_scheduler.actions.extend (l_asynchronious_svn_tasks_scheduler_action) l_asynchronious_svn_tasks_scheduler.set_interval (1_000) end end feature {CTR_TOOL} -- Catalog catalog_repository_view_row (a_repo_view: detachable REPOSITORY_DATA_VIEW): detachable EV_GRID_ROW local g: like catalog_grid r,l_count: INTEGER do if a_repo_view /= Void then g := catalog_grid l_count := g.row_count if l_count > 0 then from r := 1 until r > l_count or Result /= Void loop Result := g.row (r) if Result.data /= a_repo_view then Result := Void r := r + 1 end end end end end catalog_repository_row (a_repo: detachable REPOSITORY_DATA): detachable EV_GRID_ROW local g: like catalog_grid r,l_count: INTEGER do if a_repo /= Void then g := catalog_grid l_count := g.row_count if l_count > 0 then from r := 1 until r > l_count or Result /= Void loop Result := g.row (r) if Result.data /= a_repo then Result := Void r := r + 1 end end end end end update_catalog local g: like catalog_grid repo: REPOSITORY repo_data: detachable REPOSITORY_DATA cat: like catalog glab: EV_GRID_LABEL_ITEM l_row, l_subrow: detachable EV_GRID_ROW tt,k,kp: STRING p: INTEGER l_filter_rows: HASH_TABLE [EV_GRID_ROW, STRING] do g := catalog_grid g.wipe_out cat := catalog if cat /= Void then g.set_column_count_to (2) across cat.repositories as c loop g.insert_new_row (g.row_count + 1) l_row := g.row (g.row_count) create glab.make_with_text (c.key) glab.set_data (c.key.string) l_row.set_item (cst_repo_name_column, glab) repo := c.item create tt.make_empty debug ("scm") tt.append_string ("%Nstorage: " + repo.uuid.out + "%N") end if attached {REPOSITORY_SVN} repo as rsvn then create {REPOSITORY_SVN_DATA} repo_data.make (repo.uuid, rsvn) l_row.set_data (repo_data) else repo_data := Void end tt.append_string ("Location: " + repo.Location + "%N") if attached repo.review_username as l_username then tt.append_string ("%Nusername: " + l_username.out + "%N") end if repo.review_enabled then tt.append_string ("%NReview enabled%N") end glab.set_tooltip (tt) create glab.make_with_text (repo.Location) l_row.set_item (cst_repo_uuid_column, glab) if attached repo.filters as l_filters and then l_filters.count > 0 then create l_filter_rows.make (l_filters.count) across l_filters as fcursor loop k := fcursor.key l_subrow := Void if l_filter_rows.has_key (k) then l_subrow := l_filter_rows.found_item else if k.has ('.') then p := k.last_index_of ('.', k.count) if p > 0 then kp := k.substring (1, p - 1) if l_filter_rows.has_key (kp) then if attached l_filter_rows.found_item as p_row then p_row.insert_subrow (p_row.subrow_count + 1) l_subrow := p_row.subrow (p_row.subrow_count) end end else check has_dot: False end end end end if l_subrow = Void then l_row.insert_subrow (l_row.subrow_count + 1) l_subrow := l_row.subrow (l_row.subrow_count) end l_filter_rows.force (l_subrow, k) create glab.make_with_text (fcursor.item.name) glab.set_tooltip (k) glab.set_data (fcursor.item.name) l_subrow.set_item (1, glab) if attached fcursor.item.filter as f then create glab.make_with_text ("Filter: " + f.to_string) l_subrow.set_item (2, glab) end if repo_data /= Void then l_subrow.set_data (new_repository_view (repo_data, fcursor.item.filter)) else check should_not_occurs: False end l_subrow.set_data (fcursor.item.filter) end end end if repo_data /= Void and then repo_data.unread_log_count > 0 then update_catalog_row (l_row) end end end if logs_tool.current_repository = Void and g.row_count > 0 then g.row (1).enable_select end update_catalog_layout end update_catalog_layout local g: like catalog_grid do g := catalog_grid if g.column_count >= cst_repo_name_column and then attached g.column (cst_repo_name_column) as col then col.set_width (col.required_width_of_item_span (1, g.row_count) + 4) end if g.column_count >= cst_repo_uuid_column and then attached g.column (cst_repo_uuid_column) as col then col.set_width (col.required_width_of_item_span (1, g.row_count) + 4) end end update_catalog_row_by_data (a_rdata: REPOSITORY_DATA) do if attached catalog_repository_row (a_rdata) as l_row then update_catalog_row (l_row) end end update_catalog_row (a_row: EV_GRID_ROW) do ev_application.add_idle_action_kamikaze (agent delayed_update_catalog_row (a_row)) end delayed_update_catalog_row (a_row: EV_GRID_ROW) local n: INTEGER do if a_row /= Void and then a_row.parent /= Void and then attached repository_from_row (a_row) as rdata then if a_row.count > cst_repo_name_column then if attached {EV_GRID_LABEL_ITEM} a_row.item (cst_repo_name_column) as glab then if attached {STRING_GENERAL} glab.data as l_name then n := rdata.unread_log_count if n > 0 then glab.set_text (l_name.to_string_8 + " (" + n.out + ")") mark_repository_unread (a_row) else glab.set_text (l_name) mark_repository_read (a_row) end update_catalog_layout end end end update_catalog_filter_row (a_row, rdata) end end update_catalog_filter_row (a_row: EV_GRID_ROW; a_data: REPOSITORY_DATA) local i, n: INTEGER do if attached repository_filter_from_row (a_row) as rfilter then if a_row.count > 0 then if attached {EV_GRID_LABEL_ITEM} a_row.item (1) as glab then if attached {STRING_GENERAL} glab.data as l_name then n := a_data.unread_log_count_for (rfilter) if n > 0 then glab.set_text (l_name.to_string_8 + " (" + n.out + ")") mark_repository_unread (a_row) else glab.set_text (l_name) mark_repository_read (a_row) end update_catalog_layout end end end end if a_row.subrow_count > 0 then from i := 1 until i > a_row.subrow_count loop update_catalog_filter_row (a_row.subrow (i), a_data) i := i + 1 end end end on_catalog_row_unselected (r: EV_GRID_ROW) do on_catalog_selection_changed end on_catalog_row_selected (r: EV_GRID_ROW) do on_catalog_selection_changed end on_catalog_selection_changed local lst: ARRAYED_LIST [like new_row_repository_details] do if attached catalog_grid.selected_rows as l_rows then -- if l_rows.count <= 1 then -- if attached row_repository_details (r) as d then -- select_repository (d.row, d.repo, d.filter) -- end -- else -- if False then create lst.make (l_rows.count) from l_rows.start until l_rows.after loop if attached row_repository_details (l_rows.item) as l_details then lst.force (l_details) end l_rows.forth end select_repositories (lst) -- end end end new_row_repository_details (a_row: EV_GRID_ROW; a_view: REPOSITORY_DATA_VIEW): TUPLE [row: EV_GRID_ROW; view: REPOSITORY_DATA_VIEW] do Result := [a_row, a_view] end new_repository_view (a_repo: REPOSITORY_DATA; a_filter: detachable REPOSITORY_LOG_FILTER): REPOSITORY_DATA_VIEW do create Result.make_with_filter (a_repo, a_filter) end row_repository_details (r: EV_GRID_ROW): detachable like new_row_repository_details local sr: INTEGER g_or: REPOSITORY_LOG_GROUP_OR_FILTER do if attached repository_view_from_row (r) as rview then if rview.filter = Void then if r.subrow_count > 0 then from create g_or.make (r.subrow_count) sr := 1 until sr > r.subrow_count loop if attached row_repository_details (r.subrow (sr)) as sub and then attached sub.view as subv and then attached subv.filter as subvf then g_or.add_filter (subvf) end sr := sr + 1 end if g_or.count > 0 then rview.set_filter (g_or) end end end Result := new_row_repository_details (r, rview) elseif attached repository_filter_from_row (r) as rfilter then if attached r.parent_row_root as l_row and then attached repository_from_row (l_row) as rdata then Result := new_row_repository_details (r, new_repository_view (rdata, rfilter)) end elseif attached repository_from_row (r) as rdata then Result := new_row_repository_details (r, new_repository_view (rdata, Void)) end end select_repositories (a_lst: LIST [like new_row_repository_details]) local l_view: detachable REPOSITORY_DATA_VIEW l_old_views: LIST [REPOSITORY_DATA_VIEW] l_unselected_views: ARRAYED_LIST [REPOSITORY_DATA_VIEW] l_new_views: ARRAYED_LIST [REPOSITORY_DATA_VIEW] do set_busy l_old_views := logs_tool.current_views from create l_unselected_views.make (l_old_views.count) l_unselected_views.fill (l_old_views) create l_new_views.make (a_lst.count) a_lst.start until a_lst.after loop if attached a_lst.item as l_details then l_view := l_details.view l_new_views.force (l_view) if l_old_views.has (l_view) then l_unselected_views.prune_all (l_view) end end a_lst.forth end from l_unselected_views.start until l_unselected_views.after loop if attached catalog_repository_view_row (l_unselected_views.item) as l_row then mark_repository_unselected (l_row) elseif attached catalog_repository_row (l_unselected_views.item.repo) as l_row then mark_repository_unselected (l_row) end l_unselected_views.forth end if not logs_tool.same_views (l_old_views, l_new_views) then from l_old_views.start until l_old_views.after loop l_old_views.item.repo.save_unread_logs l_old_views.forth end logs_tool.reset from l_new_views.start until l_new_views.after loop if not l_old_views.has (l_new_views.item) then l_new_views.item.repo.load_logs end l_new_views.forth end from a_lst.start until a_lst.after loop update_catalog_row (a_lst.item.row) a_lst.forth end logs_tool.update_current_repositories (l_new_views) info_tool.update_current_repository (Void) else logs_tool.update_current_repositories (l_new_views) end from a_lst.start until a_lst.after loop mark_repository_selected (a_lst.item.row) if attached {REPOSITORY_SVN_DATA} a_lst.item.view.repo as rsvndata and then not rsvndata.is_asynchronious_fetching then unset_background_color (a_lst.item.row) end a_lst.forth end -- check -- catalog_repository_row (a_repodata) = r or -- catalog_repository_row (a_repodata) = r.parent_row_root -- end unset_busy end -- select_repository (r: EV_GRID_ROW; a_repodata: REPOSITORY_DATA; a_log_filter: detachable REPOSITORY_LOG_FILTER) -- local -- l_repo: detachable REPOSITORY_DATA -- do -- l_repo := logs_tool.current_repository -- if attached catalog_repository_row (l_repo) as l_row then -- mark_repository_unselected (l_row) -- end -- if l_repo /= a_repodata then -- if l_repo /= Void then -- l_repo.save_unread_logs -- end -- logs_tool.reset -- a_repodata.load_logs -- update_catalog_row (r) -- logs_tool.update_current_repository (a_repodata, a_log_filter) -- info_tool.update_current_repository (a_repodata) -- else -- logs_tool.update_current_repository (a_repodata, a_log_filter) -- end -- mark_repository_selected (r) -- check -- catalog_repository_row (a_repodata) = r or -- catalog_repository_row (a_repodata) = r.parent_row_root -- end -- if -- attached {REPOSITORY_SVN_DATA} a_repodata as rsvndata and then -- not rsvndata.is_asynchronious_fetching -- then -- unset_background_color (r) -- end -- end feature {CTR_TOOL} -- Diff show_log (a_service: detachable STRING; a_log: REPOSITORY_LOG; a_path: detachable STRING) require info_tool.current_log = a_log local rdata: REPOSITORY_DATA l_diff: detachable STRING l_service: detachable STRING s: detachable STRING l_diff_fn: STRING e: CTR_EXTERNAL_TOOLS do rdata := a_log.parent l_service := a_service if l_service = Void then l_service := "service.diff.file" else l_diff := rdata.repository_option (l_service) if l_diff /= Void and then l_diff.is_empty then l_diff := Void end end if l_diff = Void or else l_service.same_string ("service.diff.file") then if not a_log.has_diff then set_busy rdata.fetch_diff (a_log) rdata.get_diff (a_log) unset_busy end if a_log.has_diff then info_tool.update_current_log (a_log) if l_diff = Void then popup_diff (a_log) else create e create s.make_from_string (l_diff) s.replace_substring_all ("$id", a_log.id) if attached {REPOSITORY_FILE_STORAGE} rdata.storage as fs and then attached fs.log_diff_data_filename (a_log) as fn then l_diff_fn := e.precise_file_name (fn) s.replace_substring_all ("$filename", l_diff_fn.string) end e.launch (s) end end elseif l_service.same_string ("service.diff.web") then create e create s.make_from_string (l_diff) s.replace_substring_all ("$id", a_log.id) e.open_url (s) elseif l_service.same_string ("service.diff.text") and a_path /= Void then if attached {REPOSITORY_SVN_DATA} rdata as rsvndata then set_busy if attached rsvndata.log (a_log.id) as svn_log and then attached rsvndata.previous_log (svn_log) as svn_log_prev and then ( attached rsvndata.repository_path_content (svn_log, a_path) as s_0 and attached rsvndata.repository_path_content (svn_log_prev, a_path) as s_prev ) then create e e.open_2_text_diff ("revision_" + svn_log_prev.id, "revision_" + svn_log.id, s_prev, s_0, [l_diff, "$left", "$right"]) end unset_busy end -- s := rdata. -- a_log.paths -- Need to fetch file, and previous version .. for each file -- Todo ... end end show_log_diff (a_log: REPOSITORY_LOG) require info_tool.current_log = a_log local rdata: REPOSITORY_DATA do rdata := a_log.parent if not a_log.has_diff then set_busy rdata.fetch_diff (a_log) rdata.get_diff (a_log) unset_busy end if a_log.has_diff then info_tool.update_current_log (a_log) popup_diff (a_log) end end popup_diff (a_log: REPOSITORY_LOG) local dlg: EV_TITLED_WINDOW but: EV_BUTTON m: EV_VERTICAL_BOX t: EV_TEXT l_diff_fn: STRING diff_cmd: detachable STRING e: CTR_EXTERNAL_TOOLS do if attached preferences as prefs then create diff_cmd.make_from_string (prefs.diff_viewer_command_pref.value) end if diff_cmd /= Void and then not diff_cmd.is_empty and then attached {REPOSITORY_FILE_STORAGE} a_log.parent.storage as fs and then attached fs.log_diff_data_filename (a_log) as fn then create e l_diff_fn := e.precise_file_name (fn) diff_cmd.replace_substring_all ("$filename", l_diff_fn.string) diff_cmd.replace_substring_all ("$id", a_log.id) e.launch (diff_cmd) else create dlg create m create t create but.make_with_text_and_action ("Close", agent dlg.destroy) dlg.extend (m) m.extend (t) m.extend (but) m.disable_item_expand (but) t.set_text (a_log.diff) dlg.close_request_actions.extend (agent dlg.destroy) dlg.set_position (x_position, y_position) dlg.set_size (width, height) dlg.enable_border dlg.enable_user_resize dlg.show_relative_to_window (Current) end end feature -- Access catalog: detachable REPOSITORY_CATALOG feature {NONE} -- Implementation, Close event request_close_window -- The user wants to close the window local question_dialog: EV_CONFIRMATION_DIALOG do create question_dialog.make_with_text (Label_confirm_close_window) question_dialog.show_modal_to_window (Current) if attached question_dialog.selected_button as b and then b.is_equal ((create {EV_DIALOG_CONSTANTS}).ev_ok) then -- Destroy the window quit end end frozen quit do on_quit destroy -- End the application --| TODO: Remove this line if you don't want the application --| to end when the first window is closed.. if attached (create {EV_ENVIRONMENT}).application as app then app.destroy end end feature {NONE} -- Implementation main_container: EV_VERTICAL_BOX -- Main container (contains all widgets displayed in this window) build_tools -- local cat_c: SD_CONTENT g: EV_GRID dm: like docking_manager mtb: SD_TOOL_BAR tbbut: SD_TOOL_BAR_BUTTON do dm := docking_manager if dm = Void then dm := new_docking_manager end --| Repositories g := catalog_grid g.enable_tree cat_c := catalog_content create mtb.make create tbbut.make tbbut.set_pixmap (icons.new_check_small_toolbar_button_icon) tbbut.select_actions.extend (agent check_selected_repositories) mtb.extend (tbbut) create tbbut.make tbbut.set_pixmap (icons.new_text_small_toolbar_button_standard_icon ("Config")) tbbut.select_actions.extend (agent edit_configuration) mtb.extend (tbbut) create tbbut.make tbbut.set_pixmap (icons.new_text_small_toolbar_button_standard_icon ("Help")) tbbut.select_actions.extend (agent show_help) mtb.extend (tbbut) mtb.compute_minimum_size cat_c.set_mini_toolbar (mtb) -- g.enable_tree g.enable_multiple_row_selection g.set_column_count_to (1) cat_c.set_short_title ("Catalog ...") cat_c.set_long_title ("Repositories") dm.contents.extend (cat_c) catalog_grid := g catalog_content := cat_c g.hide_header g.row_select_actions.extend (agent on_catalog_row_selected) g.row_deselect_actions.extend (agent on_catalog_row_unselected) --| Logs dm.contents.extend (logs_tool.sd_content) --| Info dm.contents.extend (info_tool.sd_content) --| Console dm.contents.extend (console_tool.sd_content) end catalog_content: SD_CONTENT catalog_grid: EV_GRID feature {NONE} -- StatusBar Implementation standard_status_bar: EV_STATUS_BAR -- Standard status bar for this window standard_status_label: EV_LABEL -- Label situated in the standard status bar. -- -- Note: Call `standard_status_label.set_text (...)' to change the text -- displayed in the status bar. build_standard_status_bar -- Create and populate the standard toolbar. do -- Create the status bar. create standard_status_bar standard_status_bar.set_border_width (2) -- Populate the status bar. create standard_status_label standard_status_label.set_text ("...") standard_status_label.align_text_left standard_status_bar.extend (standard_status_label) ensure status_bar_created: standard_status_bar /= Void and then standard_status_label /= Void end feature {CTR_TOOL} -- Tools logs_tool: CTR_LOGS_TOOL info_tool: CTR_INFO_TOOL console_tool: CTR_CONSOLE_TOOL before_busy_pointer: detachable EV_POINTER_STYLE set_busy do if before_busy_pointer = Void then before_busy_pointer := pointer_style end set_pointer_style ((create {EV_STOCK_PIXMAPS}).Busy_cursor) end unset_busy do if attached before_busy_pointer as p then set_pointer_style (p) end end feature {NONE} -- Implementation unset_background_color (a_row: EV_GRID_ROW) do if attached a_row.parent as g then a_row.set_background_color (g.background_color) end end string_started_by (s: STRING_GENERAL; pre: STRING_GENERAL; b: BOOLEAN): BOOLEAN -- local i: INTEGER do Result := s.count >= pre.count from i := 1 until i > pre.count or not Result loop Result := s.code (i) = pre.code (i) i := i + 1 end end content_of (fn: FILE_NAME): STRING local f: RAW_FILE do create f.make (fn) if f.exists then f.open_read create Result.make_empty from f.start until f.exhausted loop f.read_stream (512) Result.append_string (f.last_string) end f.close else Result := "Unable to open file %"" + fn + "%"" end end feature {NONE} -- Implementation / Constants repository_from_row (a_row: EV_GRID_ROW): detachable REPOSITORY_DATA do if attached {REPOSITORY_DATA} a_row.data as d then Result := d -- elseif repository_view_from_row (a_row) as v then -- Result := v.repo end end repository_view_from_row (a_row: EV_GRID_ROW): detachable REPOSITORY_DATA_VIEW do if attached {REPOSITORY_DATA_VIEW} a_row.data as v then Result := v end end repository_filter_from_row (a_row: EV_GRID_ROW): detachable REPOSITORY_LOG_FILTER do if attached {REPOSITORY_LOG_FILTER} a_row.data as f then Result := f elseif attached repository_view_from_row (a_row) as v then Result := v.filter end end mark_repository_selected (r: EV_GRID_ROW) do if r.count > 0 and then attached {EV_GRID_LABEL_ITEM} r.item (cst_repo_name_column) as glab then glab.set_pixmap (icons.active_cursor_icon) glab.set_font (font_selected_repository) end end mark_repository_unselected (r: EV_GRID_ROW) local i: INTEGER do if r.count > 0 and then attached {EV_GRID_LABEL_ITEM} r.item (cst_repo_name_column) as glab then glab.remove_pixmap glab.set_font (font_default) if r.subrow_count > 0 then from i := 1 until i > r.subrow_count loop mark_repository_unselected (r.subrow (i)) i := i + 1 end end end end mark_repository_unread (a_row: EV_GRID_ROW) local n,c: INTEGER ft: EV_FONT do n := a_row.count ft := font_unread_log from c := 1 until c > n loop if attached {EV_GRID_LABEL_ITEM} a_row.item (c) as l_lab then l_lab.set_font (ft) end c := c + 1 end end mark_repository_read (a_row: EV_GRID_ROW) local n,c: INTEGER ft: EV_FONT do n := a_row.count ft := font_read_log from c := 1 until c > n loop if attached {EV_GRID_LABEL_ITEM} a_row.item (c) as l_lab then l_lab.set_font (ft) end c := c + 1 end end cst_repo_name_column: INTEGER = 1 cst_repo_uuid_column: INTEGER = 2 Window_title: STRING -- Title of the window. once Result := "Commit Then Review" if debug_state then Result := "WORKBENCH " + Result end end Window_width: INTEGER = 800 -- Initial width for this window. Window_height: INTEGER = 600 -- Initial height for this window. debug_state: BOOLEAN external "C inline use %"eif_macros.h%"" alias "[ return EIF_IS_WORKBENCH; ]" end note copyright: "Copyright (c) 1984-2010, Eiffel Software" license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" licensing_options: "http://www.eiffel.com/licensing" copying: "[ This file is part of Eiffel Software's Eiffel Development Environment. Eiffel Software's Eiffel Development Environment 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, version 2 of the License (available at the URL listed under "license" above). Eiffel Software's Eiffel Development Environment 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 Eiffel Software's Eiffel Development Environment; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end