Gedit New MDI

Gedit "New MDI" is a developement branch of gedit which features a substantial rework of the codebase aimed at fixing various longstanding design issues and bugs and at modernizing the whole program. We refer to this work as "New MDI" since one of the core issues is to rewrite how gedit handles its tabbed interface.

Note: the new_mdi branch has been merged to CVS HEAD

Goals

  • Rework the MDI widget fix many problems (see bug #131953) and get rid of libbonoboui using UIManager for menus and toolbars

  • Add a bottom panel and a side panel (the panels will have to support multiple pages eventually using a notebook like in Kate, etc).

  • Revamp the plugin system (breaking compatibility is necessary anyway since bonoboui is currently exposed in the plugin interface). See Gedit/NewMDIPluginHowTo

  • python bindings for the plugin systems
  • get rid of all the modal dialogs which block the whole gedit GUI. Opening a dialog in a window should never affect another window... in fact each window should appear to the user as if it was a separate instance of the app
  • Rework the search interface (not strictly related to the MDI, but since we are at it)
  • Rework File Saving and File Loading routines fixing many limitations including remote vfs saving (once again not strictly related to mdi, but...)
  • others I forgot about :)

Architecture

GeditMDIClassDiagram.gif

Argo UML file: geditMDI.zargo

Notes:

  • GeditNotebook: it will be a modified version of EphyNotebook. Do we want "tab reordering" working as in gaim (you see where the tab will go) or as in epiphany (live reordering)? I'd prefer like gaim but with a better graphic feedbak.

  • GeditView: current GeditView should be modified to extend GtkSourceView (see below)

  • GeditPanel: some code has been already written (see below). GeditPanelItem will be private.

Internals

I started writing down some notes about the gedit's internals in the hope that it's useful to anyone who wants to get involved. The document doesn't contain much yet, but it's better than nothing.

Open questions

  • Do we need to support multiple views for documents?
  • Do we need to use some "dock" widget (like the one in GDL)? Note that ATM there is not standard docking system in gtk+, but it seems a widget will be developed in the future).

Progress Tracker

Done

  • [X] new MDI structure (gedit-window, gedit-notebook, gedit-tab, gedit-statusbar, etc)
  • [X] UIManager for menus and toolbars
  • [X] Side-pane and Bottom-pane infrastructure
  • [X] docs list sidepane
  • [X] unique-app: we used bacon-message-connection (according to hadess, b-m-c may wrap d-bus in the future)
  • [X] gedit-document cleanup.
  • [X] doc-loader (local mmap, remote vfs)
  • [X] doc-saver (local and remote)
  • [X] New plugin system
  • [X] Python support for plugins
  • [X] New incremental search
  • [X] Use GOption instead of popt
  • [X] Migrate docs to gnome-doc-utils

Need finishing

  • [W] Reimplement all UI sensitivity update (mostly done, some places may still be missing)
    • plugins
    • sensitivity of close button of the tab during save, load, print etc
    • sensitivity for non-editable docs (including the search panel)
    • sensitivity of recent files (needs api in egg-recent-ui-manager?)
  • [W] Fix 'close all' for good
  • [W] Plugins porting: ported all the plugins except
    • shell command: needs rewriting and an output widget (see below)
    • savecopy: needs a file handling plugin api (see below)
  • [W] Session management: mostly done, needs final touches:
    • Show statusbar messages ("Saving session", "Saving session failed", etc)
    • Abort session saving on file save error
    • Abort session saving on untitled saving Cancel
    • make sure we switch to the proper workspace when showing the confirmation dialog
    • Prevent session shutdown when the window state is "complicated" (printing, saving error, etc). Either show a dialog or use some euristic like waiting a few seconds for print to finish
  • [W] Python plugin bindings:
    • bind some more objects
    • provide plugin api to load and save files
    • fix python greedy refcounting (python keeps references to objects preventing them to be finalized)
  • [W] Support for Read Only files (paolo is on it)

ToDo (and known bugs)

  • [ ] Write an output windo widget for the bottom pane
  • [ ] gedit-debug: add debugging log for the new widgets and use it
  • [ ] check finalizers (doc, loader, saver and all the rest... seems all clean but extra valgrinding doesn't hurt)
  • [ ] gnome-doc: use (and revise) set_encoding after save/load (fixed?)
  • [ ] check that mime, language and encoding are always set correctly on loading and saving
  • [ ] manage the case of local files that do not support mmap
  • [ ] do not allow both the file save and file open dialogs to be displayed at the same time
  • [ ] update doc icons in the document list
  • [ ] move all the plugins files from ~/.gedit to ~/.gnome2/gedit
  • [ ] Missing icon during revert (_gedit_tab_get_icon returns NULL... gtk?? maybe not... fixed?)
  • [ ] Handling invalid URIs leads to various problems
  • [ ] Do not load "concatenated" URIs
  • [ ] Do not allow saving a document to a uri with a non-writable uri (put a warning dialog in the Save As dialog and a g_return_if_fail in gedit_document_save[_as])
  • [ ] Test File->Revert and implement Cancel for revert

  • [ ] Use G_CONST_RETURN instead of const where appropriated (PaoloBorelli: uhm... do we really want this?)

  • [ ] Do not update default path (in GeditWindow) while reverting a document

  • [ ] Undo/Redo should be unsensitive when the view is not editable (to reproduce it, force the GEDIT_TAB_STATE_CLOSING state for the tab). Probably it is required to fix gtksourceview so that it report can_undo/redo=FALSE when the view is not editable.
  • [ ] Never ever use gtk_dialog_run (mostly done)
  • [ ] Markup text should be escaped before using it in gtk+ (gedit-io-error-message.c needs to be fixed, but probably we have the same problem in other places too).
  • [ ] Closing the main window is very slow
  • [ ] reordering tabs, when moving a shorter tab over a longer one there is oscillation (muntyan has better code for tab reordering that fixes this)
  • [ ] Before Merging: Check all the points marked "//CHECK" in the code. Check all the patches applied to HEAD after the branch
  • [ ] Get last searched (and replaced) string from metadata
  • [ ] Implement a multiple file search, i.e. being able to search a string within a file collection according to a pattern (e.g. *.txt).

Fixes outside of gedit and Enanchements

  • [ ] gnome-vfs enanchements needed: async_get_info_from_handle
  • [ ] doc-saver: implement separate backup dir
  • [ ] lockdown (see love tasks)
  • [ ] Tooltip on the taglist combo box (Not possible, gtk limitation)
  • [ ] add preview to the taglist plugin
  • [ ] key nav for the taglist plugin
  • [ ] Enable File->Close while saving (the tab is closed when the saving operation terminates)

  • [ ] Enable document editing while saving

Love tasks

Hi GNOME lovers,
        as you may or may not know, a big rework of gedit internals is under
way with the goal of fixing various longstanding issues and improving
the quality of the whole codebase. You can find more info about this
work on http://live.gnome.org/Gedit_2fNewMdi

If you want to see this work to succeed, it is time to put your fingers
on the keyboard and help us with this titanic effort.

So, be a gedit lover and take a task from the Love Tasks list on
http://live.gnome.org/Gedit_2fNewMdi#LoveTasks

The most proficuous contributor will get two bottles of Barolo (the most
esteemed Italian wine, http://www.barolo.net/scoprire/index.asp) or a
3Kg package of Nutella (http://www.nutellausa.com/).

Love gedit,
  the gedit team

If you are interested in one of this tasks, please contact paolo or pbor on IRC (#gedit) or by mail (paolo AT gnome org, pborelli AT katamail.com). See the top of this page, to see how to obtain the new_mdi sources from cvs.

  • [X] Writing a GeditPreferencesDialog widget (easy) [done by MichaelTerry]

    • The widget will have a single public function: gedit_preferences_dialog_new
    • Most of the current well tested code in gedit/dialogs/gedit-preferences-dialog.[ch] should be reused
    • Before re-using the current code, it is worth synchronizing the code in the new_mdi with the one in CVS HEAD.
    • As all the other gedit dialogs, it must be a non-modal dialog. Modal dialogs that are opened by the preferences dialog itself must not block user interaction with the main window.
    • In a second step we could try to improve the UI (but this is not a primary goal for this task).
  • [X] Writing a GeditPageSetupDialog widget (easy) [done by JavierFernandez]

    • The widget will have a single public function: gedit_page_setup_dialog_new
    • Most of the current well tested code in gedit/dialogs/gedit-page-setup-dialog.[ch] should be reused
    • Before re-using the current code, it is worth synchronizing the code in the new_mdi with the one in CVS HEAD (if needed)
    • As all the other gedit dialogs, it must be a non-modal dialog. Modal dialogs that are opened by the preferences dialog itself must not block user interaction with the main window.
  • [X] Writing a GeditPluginManager widget (easy) [done by ChemaCasanova]

    • The widget will have a single public function: gedit_plugin_manager_new
    • Most of the current well tested code in gedit/dialogs/gedit-plugin-manager.[ch] should be reused
    • Before re-using the current code, it is worth synchronizing the code in the new_mdi with the one in CVS HEAD (if needed)
    • (seems fixed) Fixing sensitivity of the "About Plugin" and "Configure Plugin" buttons when no plugins are installed
  • [X] Adding G_CONST_RETURN to every get_type function (very easy) [Done by Chris Kelso]

  • [A] Rewriting the taglist plugin in python (medium) [JavierFernandez is working on it]

    • Tha taglist plugin needs a lot of love, it is one of the main reason of the long startup time of gedit, it allocates about 17Mb at startup while parsing the XML .tags files -> it clearly need to be rewritten from scratch

    • We need to redesign its UI and we should also add some features (see bugzilla and the TODO list below)
  • [X] Fixing the print preview widget (easy-medium) [done by IkeGingerich]

    • The print preview widget is a copied and pasted version of the print preview widget and it still needs to be finalized
    • Removing unused code
    • Reorganize the code to be more "standard" (it is a very bad code and it is not up to the quality level we are trying to achieve in gedit new_mdi)
    • Fixing runtime warnings
  • [X] Writing a gedit_util_get_glade_widgets function and convert the whole codebase to it (medium) [done by 'henrym]

    • in many places in the codebase, especially in dialogs, a glade file is loaded and some widgets are fetched from it with libglade: this is done manually and error checking (check if the requested file is installed and check that the file contains the requested widgets) is repeated many times.
    • this should be factored out in a utility function that takes care of the error checking, the utility function would return a boolean reporting success and take the following arguments: the glade filename, a GtkWidget **error_widget, a variadic list of pairs of char *widget_name and GtkWidget *widget, that is gboolean gedit_util_get_glade_widgets (const gchar *filename, GtkWidget **error_widget, const gchar *widget_name, GtkWidget *widget, ...)

    • err_widget should be set to NULL on success while on error it should contain a label with the error message.
    • the whole codebase should be converted to use this utility function, taking care in case of error to show the error widget instead of the requested widgets.
  • [X] Adding properties to GeditDocument (medium) - [done by EmmanueleBassi]

    • The following properties should be added:
      • uri (G_PARAM_READABLE)
      • uri_for_display (G_PARAM_READABLE)
      • short_name_for_display (G_PARAM_READABLE)
      • mime_type (G_PARAM_READABLE)
      • readonly (G_PARAM_READWRITE)
      • language (G_PARAM_READWRITE) [Is it already a GtkSourceBuffer property? Need to check]

      • encoding (G_PARAM_READABLE)
    • The following signals must be removed
      • name_changed (replaced by notify::uri)
      • readonly_changed (replaced by notify::readonlly)
    • The whole codebase should be converted to use "notify::uri" and "notify::readonly" instead of the removed signals.
  • [X] Take advantage of the new confirmation dialog of GtkFileChooser (easy) - [done by JuanjoSanchezPenas]

    • see Federico's blog entry for details

    • relevant gedit code is in gedit-commands and gedit-file-chooser-dialog
  • [A] docinfo plugin enanchements (easy/medium) [JuanjoSanchezPenas is working on this]

    • provide stats about the selected part of the text, if any
    • smart handling of the sensitivity of the "update" button (insentive if there is no doc, insensitive after pressing once until the documents contents changes, etc)
  • [ ] improve the tools/generate-plugin.py script (medium)
    • this python script generates scheleton code for a plugin in order to make writing a plugin easier, it can be enanched in many ways:
    • add a switch to generate scheleton code for plugins written in python
    • add a switch to also generate autotools files
    • add support for generating the plugin as an external project, separated from the gedit tarball
  • [ ] Lockdown support: gedit should obey some generic gnome lockdown GConf keys (easy/medium)
    • a partial patch is attached to gnomebug:165568 : the patch should be ported to the new_mdi codebase and completed
  • [X] Migrate the documentation build system to use gnome-doc-utils (medium) [done by MichaelTerry]

  • [ ] Write a gedit_encodings_option_menu_set_encoding_sensitivity function to set the sensitivity of a specified encoding in GeditEncodingsOptionMenu (easy)

  • [ ] Fix bug gnomebug:318461 (easy)
    • Prorer fix requires to create gedit-stocks.[ch] files
  • [ ] If the print-preview is shown, update it if the URI or the language of the current document change (easy/medium)
  • [ ] Cleaning up gedit-utils.[ch] (easy)
    • This task consists in reviewing the funciont in gedit-utils.[ch] and removing the ones that are never used
  • More tasks will follow...

Scenarios to be tested

<!> If you are going to test these scenarios please check all the possible details (the scenario works as expected, no warning is printed on the console, the errors are correctly managed, the UI sensitivity is correctly updated, the mime-type and the language is correctly set, the etc.) before marking it as passed.

<!> Note that we are going to use these scenarios not only to detect bugs but also to detect unimplemented or partially implemented features.

Lists of test cases can also be found at:

Opening a local file

  • [ ] Verify that it is possible to open an existing (writable) file from command line
  • [ ] Verify that it is possible to open an existing (writable) file using the "File->Open" menu item

    • Testing this test case I have found the following problems:
      • (./) FIXED -> The directory of last opened file is not saved and so the open dialog always open the HOME directory

      • (./) FIXED -> the "language" metadata is saved also when the language is automatically recognized

      • (./) FIXED -> the metadata file is not saved every 2 seconds as expected

      • <!> opening files with a broken file name "(invalid encoding)" is displayed. This is not a problem but there are some differences on how the file path is displayed in the status bar, in the tooltip and the in the recent files menu

      • (./) FIXED -> sometimes the language is not set as expected

      • (./) FIXED -> there is a problem with the Documents menu:

        • run gedit
        • open a file
        • select the file name in the Document menu
        • the status bar shows "Activate Unsaved Document 1"
      • (./) FIXED (it was the gedit_utils_str_middle_truncate function not being utf-8 safe (already fixed in CVS HEAD) -> it you open twice a file with a name containing non Latin1 chars you get a problem when its name is inserted in the message area.

  • [ ] Verify that it is possible to open an existing (writable) file using the "File->Open Location" menu item

    • Test with the same URI used for the test case for the command line.
    • <!> problems when opening a broken uri with spaces like "./gedit /opt/gnome/test_files/stack_trace_157121.tx" (yes, with ./gedit too).

  • [ ] Verify that it is possible to open an existing (read-only) file from command line
  • [ ] Verify that it is possible to open an existing (read-only) file using the "File->Open" menu item

  • [ ] Verify that it is possible to open an existing (read-only) file using the "File->Open Location" menu item

  • [ ] Verify that gedit creates a new empty document with the right name when opening a non-existing writable file from the command line

  • [ ] Verify that gedit shows an appropriate error message when opening a non-existing read-only file from the command line

  • [ ] Verify that gedit shows an appropriate error message when opening a non-existing file using the "File->Open" menu item (uses a dangling link)

  • [ ] Verify that gedit shows an appropriate error message when opening a non-existing file using the "File->Open Location" menu item

  • [ ] Verify that gedit shows an appropriate error message when opening a broken URI using the "File->Open Location" menu item

  • [ ] Verify that gedit shows an appropriate error message when opening a directory from the command line
  • [ ] Verify that gedit shows an appropriate error message when opening a directory using the "File->Open Location" menu item

  • [ ] Verify that gedit shows an appropriate error message when opening a non-readable file from the command line
  • [ ] Verify that gedit shows an appropriate error message when opening a non-readable file using the "File->Open" menu item

  • [ ] Verify that gedit shows an appropriate error message when opening a non-readable file using the "File->Open Location" menu item

  • [ ] Verify that gedit shows an appropriate warning message when opening an already open file and that both the buttons in the warning message work as expected.
  • [ ] Verify that gedit shows an appropriate warning message when trying to open a binary file (Should we enable the read-only opening of binary files?)
  • [ ] Verify that it is possible to open an existing (writable) file from command line selecting a specified encoding
  • [ ] Verify that it is possible to open an existing (writable) file using the "File->Open" menu item selecting a specified encoding

  • [ ] Verify that it is possible to open an existing (writable) file using the "File->Open Location" menu item selecting a specified encoding

  • [ ] Verify that it is possible to open an existing (read-only) file from command line selecting a specified encoding
  • [ ] Verify that it is possible to open an existing (read-only) file using the "File->Open" menu item selecting a specified encoding

  • [ ] Verify that it is possible to open an existing (read-only) file using the "File->Open Location" menu item selecting a specified encoding

  • [ ] Verify that it is possible to re-try to open a file with a specified encoding from the error message displayed by gedit when it fails to open the file due to a coversione error (when the file is open from the command line).
  • [ ] Verify that it is possible to re-try to open a file with a specified encoding from the error message displayed by gedit when it fails to open the file due to a coversione error (when the file is open using the "File->Open" menu item)

  • [ ] Verify that it is possible to re-try to open a file with a specified encoding from the error message displayed by gedit when it fails to open the file due to a coversione error (when the file is open using the "File->Open Location" menu item)

  • [ ] Verify that it is possible to open an existing file from command line specifying a line number and that the view scrolls to that number
  • TODO: add other scenarios

Opening a list of local files

  • TODO: add scenarios

Opening a remote file

  • TODO: add scenarios

Opening a list of remote files

  • TODO: add scenarios

Opening a list of local and remote files

  • TODO: add scenarios

Apps/Gedit/Attic/NewMdi (last edited 2020-04-14 13:24:07 by SébastienWilmet)