Skip to content

Commit 27769ee

Browse files
authored
Merge pull request #119 from MightyCreak/pylint
Extract dialogs and widgets into their own modules
2 parents 74ef665 + 7331912 commit 27769ee

File tree

9 files changed

+4435
-4274
lines changed

9 files changed

+4435
-4274
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: Pylint
2424
uses: cclauss/GitHub-Action-for-pylint@master
2525
with:
26-
args: "pylint src/utils.py src/vcs/"
26+
args: "pylint src/vcs/ src/dialogs.py src/preferences.py src/resources.py src/utils.py src/widgets.py"
2727

2828
meson-build-test:
2929
runs-on: ubuntu-latest

.pylintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ disable=raw-checker-failed,
100100
too-many-arguments,
101101
too-many-branches,
102102
too-many-instance-attributes,
103+
too-many-lines,
103104
too-many-locals,
104105
too-many-nested-blocks,
105106
too-many-statements,

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Added a flatpak job in the CI
1313

1414
### Changed
15-
- main.py slimmed down by about 1000 lines
15+
- main.py slimmed down by about 5000 lines
16+
- The new widgets.py is a bit fat though (~4000 lines)
1617

1718
### Fixed
1819

src/dialogs.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Diffuse: a graphical tool for merging and comparing text files.
2+
#
3+
# Copyright (C) 2019 Derrick Moser <[email protected]>
4+
# Copyright (C) 2021 Romain Failliot <[email protected]>
5+
#
6+
# This program is free software; you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation; either version 2 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License along
17+
# with this program; if not, write to the Free Software Foundation, Inc.,
18+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19+
20+
import os
21+
22+
# pylint: disable=wrong-import-position
23+
import gi
24+
gi.require_version('GObject', '2.0')
25+
gi.require_version('Gtk', '3.0')
26+
from gi.repository import GObject, Gtk
27+
# pylint: enable=wrong-import-position
28+
29+
from diffuse import constants
30+
from diffuse import utils
31+
32+
# the about dialog
33+
class AboutDialog(Gtk.AboutDialog):
34+
def __init__(self):
35+
Gtk.AboutDialog.__init__(self)
36+
self.set_logo_icon_name('io.github.mightycreak.Diffuse')
37+
self.set_program_name(constants.APP_NAME)
38+
self.set_version(constants.VERSION)
39+
self.set_comments(_('Diffuse is a graphical tool for merging and comparing text files.'))
40+
self.set_copyright(constants.COPYRIGHT)
41+
self.set_website(constants.WEBSITE)
42+
self.set_authors([ 'Derrick Moser <[email protected]>',
43+
'Romain Failliot <[email protected]>' ])
44+
self.set_translator_credits(_('translator-credits'))
45+
license_text = [
46+
constants.APP_NAME + ' ' + constants.VERSION + '\n\n',
47+
constants.COPYRIGHT + '\n\n',
48+
_('''This program is free software; you can redistribute it and/or modify
49+
it under the terms of the GNU General Public License as published by
50+
the Free Software Foundation; either version 2 of the License, or
51+
(at your option) any later version.
52+
53+
This program is distributed in the hope that it will be useful,
54+
but WITHOUT ANY WARRANTY; without even the implied warranty of
55+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56+
GNU General Public License for more details.
57+
58+
You should have received a copy of the GNU General Public License along
59+
with this program; if not, write to the Free Software Foundation, Inc.,
60+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.''') ]
61+
self.set_license(''.join(license_text))
62+
63+
# custom dialogue for picking files with widgets for specifying the encoding
64+
# and revision
65+
class FileChooserDialog(Gtk.FileChooserDialog):
66+
# record last chosen folder so the file chooser can start at a more useful
67+
# location for empty panes
68+
last_chosen_folder = os.path.realpath(os.curdir)
69+
70+
def __current_folder_changed_cb(self, widget):
71+
FileChooserDialog.last_chosen_folder = widget.get_current_folder()
72+
73+
def __init__(self, title, parent, prefs, action, accept, rev=False):
74+
Gtk.FileChooserDialog.__init__(self, title=title, parent=parent, action=action)
75+
self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
76+
self.add_button(accept, Gtk.ResponseType.OK)
77+
self.prefs = prefs
78+
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
79+
hbox.set_border_width(5)
80+
label = Gtk.Label.new(_('Encoding: '))
81+
hbox.pack_start(label, False, False, 0)
82+
label.show()
83+
self.encoding = entry = utils.EncodingMenu(
84+
prefs,
85+
action in [ Gtk.FileChooserAction.OPEN, Gtk.FileChooserAction.SELECT_FOLDER ])
86+
hbox.pack_start(entry, False, False, 5)
87+
entry.show()
88+
if rev:
89+
self.revision = entry = Gtk.Entry.new()
90+
hbox.pack_end(entry, False, False, 0)
91+
entry.show()
92+
label = Gtk.Label.new(_('Revision: '))
93+
hbox.pack_end(label, False, False, 0)
94+
label.show()
95+
96+
self.vbox.pack_start(hbox, False, False, 0) # pylint: disable=no-member
97+
hbox.show()
98+
self.set_current_folder(self.last_chosen_folder)
99+
self.connect('current-folder-changed', self.__current_folder_changed_cb)
100+
101+
def set_encoding(self, encoding):
102+
self.encoding.set_text(encoding)
103+
104+
def get_encoding(self):
105+
return self.encoding.get_text()
106+
107+
def get_revision(self):
108+
return self.revision.get_text()
109+
110+
def get_filename(self):
111+
# convert from UTF-8 string to unicode
112+
return Gtk.FileChooserDialog.get_filename(self) # pylint: disable=no-member
113+
114+
# dialogue used to search for text
115+
class NumericDialog(Gtk.Dialog):
116+
def __init__(self, parent, title, text, val, lower, upper, step=1, page=0):
117+
Gtk.Dialog.__init__(self, title=title, parent=parent, destroy_with_parent=True)
118+
self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT)
119+
self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
120+
121+
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
122+
vbox.set_border_width(10)
123+
124+
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
125+
label = Gtk.Label.new(text)
126+
hbox.pack_start(label, False, False, 0)
127+
label.show()
128+
adj = Gtk.Adjustment.new(val, lower, upper, step, page, 0)
129+
self.button = button = Gtk.SpinButton.new(adj, 1.0, 0)
130+
button.connect('activate', self.button_cb)
131+
hbox.pack_start(button, True, True, 0)
132+
button.show()
133+
134+
vbox.pack_start(hbox, True, True, 0)
135+
hbox.show()
136+
137+
self.vbox.pack_start(vbox, False, False, 0) # pylint: disable=no-member
138+
vbox.show()
139+
140+
def button_cb(self, widget):
141+
self.response(Gtk.ResponseType.ACCEPT)
142+
143+
# dialogue used to search for text
144+
class SearchDialog(Gtk.Dialog):
145+
def __init__(self, parent, pattern=None, history=None):
146+
Gtk.Dialog.__init__(self, title=_('Find...'), parent=parent, destroy_with_parent=True)
147+
self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT)
148+
self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
149+
150+
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
151+
vbox.set_border_width(10)
152+
153+
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
154+
label = Gtk.Label.new(_('Search For: '))
155+
hbox.pack_start(label, False, False, 0)
156+
label.show()
157+
combo = Gtk.ComboBoxText.new_with_entry()
158+
self.entry = combo.get_child()
159+
self.entry.connect('activate', self.entry_cb)
160+
161+
if pattern is not None:
162+
self.entry.set_text(pattern)
163+
164+
if history is not None:
165+
completion = Gtk.EntryCompletion.new()
166+
liststore = Gtk.ListStore(GObject.TYPE_STRING)
167+
completion.set_model(liststore)
168+
completion.set_text_column(0)
169+
for h in history:
170+
liststore.append([h])
171+
combo.append_text(h)
172+
self.entry.set_completion(completion)
173+
174+
hbox.pack_start(combo, True, True, 0)
175+
combo.show()
176+
vbox.pack_start(hbox, False, False, 0)
177+
hbox.show()
178+
179+
button = Gtk.CheckButton.new_with_mnemonic(_('Match Case'))
180+
self.match_case_button = button
181+
vbox.pack_start(button, False, False, 0)
182+
button.show()
183+
184+
button = Gtk.CheckButton.new_with_mnemonic(_('Search Backwards'))
185+
self.backwards_button = button
186+
vbox.pack_start(button, False, False, 0)
187+
button.show()
188+
189+
self.vbox.pack_start(vbox, False, False, 0) # pylint: disable=no-member
190+
vbox.show()
191+
192+
# callback used when the Enter key is pressed
193+
def entry_cb(self, widget):
194+
self.response(Gtk.ResponseType.ACCEPT)

0 commit comments

Comments
 (0)